/kernel/tags/kolibri0.7.7.0/kernel.asm |
---|
0,0 → 1,5785 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. |
;; PROGRAMMING: |
;; Ivan Poddubny |
;; Marat Zakiyanov (Mario79) |
;; VaStaNi |
;; Trans |
;; Mihail Semenyako (mike.dld) |
;; Sergey Kuzmin (Wildwest) |
;; Andrey Halyavin (halyavin) |
;; Mihail Lisovin (Mihasik) |
;; Andrey Ignatiev (andrew_programmer) |
;; NoName |
;; Evgeny Grechnikov (Diamond) |
;; Iliya Mihailov (Ghost) |
;; Sergey Semyonov (Serge) |
;; Johnny_B |
;; SPraid (simba) |
;; Hidnplayr |
;; Alexey Teplov (<Lrz>) |
;; |
;; Data in this file was originally part of MenuetOS project which is |
;; distributed under the terms of GNU GPL. It is modified and redistributed as |
;; part of KolibriOS project under the terms of GNU GPL. |
;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa |
;; PROGRAMMING: |
;; |
;; Ville Mikael Turjanmaa, villemt@itu.jyu.fi |
;; - main os coding/design |
;; Jan-Michael Brummer, BUZZ2@gmx.de |
;; Felix Kaiser, info@felix-kaiser.de |
;; Paolo Minazzi, paolo.minazzi@inwind.it |
;; quickcode@mail.ru |
;; Alexey, kgaz@crosswinds.net |
;; Juan M. Caravaca, bitrider@wanadoo.es |
;; kristol@nic.fi |
;; Mike Hibbett, mikeh@oceanfree.net |
;; Lasse Kuusijarvi, kuusijar@lut.fi |
;; Jarek Pelczar, jarekp3@wp.pl |
;; |
;; KolibriOS is distributed in the hope that it will be useful, but WITHOUT ANY |
;; WARRANTY. No author or distributor accepts responsibility to anyone for the |
;; consequences of using it or for whether it serves any particular purpose or |
;; works at all, unless he says so in writing. Refer to the GNU General Public |
;; License (the "GPL") for full details. |
; |
;; Everyone is granted permission to copy, modify and redistribute KolibriOS, |
;; but only under the conditions described in the GPL. A copy of this license |
;; is supposed to have been given to you along with KolibriOS so you can know |
;; your rights and responsibilities. It should be in a file named COPYING. |
;; Among other things, the copyright notice and this notice must be preserved |
;; on all copies. |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include 'macros.inc' |
$Revision$ |
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices |
; Enabling the next line will enable serial output console |
;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used |
include "proc32.inc" |
include "kglobals.inc" |
include "lang.inc" |
include "const.inc" |
max_processes equ 255 |
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 |
os_stack equ (os_data_l-gdts) ; GDTs |
os_code equ (os_code_l-gdts) |
graph_data equ (3+graph_data_l-gdts) |
tss0 equ (tss0_l-gdts) |
app_code equ (3+app_code_l-gdts) |
app_data equ (3+app_data_l-gdts) |
app_tls equ (3+tls_data_l-gdts) |
pci_code_sel equ (pci_code_32-gdts) |
pci_data_sel equ (pci_data_32-gdts) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Included files: |
;; |
;; Kernel16.inc |
;; - Booteng.inc English text for bootup |
;; - Bootcode.inc Hardware setup |
;; - Pci16.inc PCI functions |
;; |
;; Kernel32.inc |
;; - Sys32.inc Process management |
;; - Shutdown.inc Shutdown and restart |
;; - Fat32.inc Read / write hd |
;; - Vesa12.inc Vesa 1.2 driver |
;; - Vesa20.inc Vesa 2.0 driver |
;; - Vga.inc VGA driver |
;; - Stack.inc Network interface |
;; - Mouse.inc Mouse pointer |
;; - Scincode.inc Window skinning |
;; - Pci32.inc PCI functions |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 16 BIT ENTRY FROM BOOTSECTOR ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
use16 |
org 0x0 |
jmp start_of_code |
version db 'Kolibri OS version 0.7.7.0 ',13,10,13,10,0 |
include "boot/bootstr.inc" ; language-independent boot messages |
include "boot/preboot.inc" |
if lang eq en |
include "boot/booteng.inc" ; english system boot messages |
else if lang eq ru |
include "boot/bootru.inc" ; russian system boot messages |
include "boot/ru.inc" ; Russian font |
else if lang eq et |
include "boot/bootet.inc" ; estonian system boot messages |
include "boot/et.inc" ; Estonian font |
else |
include "boot/bootge.inc" ; german system boot messages |
end if |
include "boot/bootcode.inc" ; 16 bit system boot code |
include "bus/pci/pci16.inc" |
include "detect/biosdisk.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SWITCH TO 32 BIT PROTECTED MODE ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CR0 Flags - Protected mode and Paging |
mov ecx, CR0_PE |
; Enabling 32 bit protected mode |
sidt [cs:old_ints_h] |
cli ; disable all irqs |
cld |
mov al,255 ; mask all irqs |
out 0xa1,al |
out 0x21,al |
l.5: in al, 0x64 ; Enable A20 |
test al, 2 |
jnz l.5 |
mov al, 0xD1 |
out 0x64, al |
l.6: in al, 0x64 |
test al, 2 |
jnz l.6 |
mov al, 0xDF |
out 0x60, al |
l.7: in al, 0x64 |
test al, 2 |
jnz l.7 |
mov al, 0xFF |
out 0x64, al |
lgdt [cs:tmp_gdt] ; Load GDT |
mov eax, cr0 ; protected mode |
or eax, ecx |
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled |
mov cr0, eax |
jmp pword os_code:B32 ; jmp to enable 32 bit mode |
align 8 |
tmp_gdt: |
dw 23 |
dd tmp_gdt+0x10000 |
dw 0 |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
include "data16.inc" |
use32 |
org $+0x10000 |
align 4 |
B32: |
mov ax,os_stack ; Selector for os |
mov ds,ax |
mov es,ax |
mov fs,ax |
mov gs,ax |
mov ss,ax |
mov esp,0x3ec00 ; Set stack |
; CLEAR 0x280000 - HEAP_BASE |
xor eax,eax |
mov edi,0x280000 |
mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 |
cld |
rep stosd |
mov edi,0x40000 |
mov ecx,(0x90000-0x40000)/4 |
rep stosd |
; CLEAR KERNEL UNDEFINED GLOBALS |
mov edi, endofcode-OS_BASE |
mov ecx, (uglobals_size/4)+4 |
rep stosd |
; SAVE & CLEAR 0-0xffff |
xor esi, esi |
mov edi,0x2F0000 |
mov ecx,0x10000 / 4 |
rep movsd |
mov edi,0x1000 |
mov ecx,0xf000 / 4 |
rep stosd |
call test_cpu |
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc |
call init_BIOS32 |
; MEMORY MODEL |
call mem_test |
call init_mem |
call init_page_map |
; ENABLE PAGING |
mov eax, sys_pgdir-OS_BASE |
mov cr3, eax |
mov eax,cr0 |
or eax,CR0_PG+CR0_WP |
mov cr0,eax |
lgdt [gdts] |
jmp pword os_code:high_code |
align 4 |
bios32_entry dd ? |
tmp_page_tabs dd ? |
use16 |
org $-0x10000 |
include "boot/shutdown.inc" ; shutdown or restart |
org $+0x10000 |
use32 |
__DEBUG__ fix 1 |
__DEBUG_LEVEL__ fix 1 |
include 'init.inc' |
org OS_BASE+$ |
align 4 |
high_code: |
mov ax, os_stack |
mov bx, app_data |
mov cx, app_tls |
mov ss, ax |
add esp, OS_BASE |
mov ds, bx |
mov es, bx |
mov fs, cx |
mov gs, bx |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL |
mov ebx, cr4 |
or ebx, CR4_PGE |
mov cr4, ebx |
@@: |
xor eax, eax |
mov dword [sys_pgdir], eax |
mov dword [sys_pgdir+4], eax |
mov eax, cr3 |
mov cr3, eax ; flush TLB |
; SAVE REAL MODE VARIABLES |
mov ax, [BOOT_VAR + 0x9031] |
mov [IDEContrRegsBaseAddr], ax |
; --------------- APM --------------------- |
; init selectors |
mov ebx,[BOOT_VAR+0x9040] ; offset of APM entry point |
movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of |
; protected-mode 32-bit code segment |
movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of |
; protected-mode 16-bit code segment |
movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of |
; protected-mode 16-bit data segment |
shl eax, 4 |
mov [dword apm_code_32 + 2], ax |
shr eax, 16 |
mov [dword apm_code_32 + 4], al |
shl ecx, 4 |
mov [dword apm_code_16 + 2], cx |
shr ecx, 16 |
mov [dword apm_code_16 + 4], cl |
shl edx, 4 |
mov [dword apm_data_16 + 2], dx |
shr edx, 16 |
mov [dword apm_data_16 + 4], dl |
mov dword[apm_entry], ebx |
mov word [apm_entry + 4], apm_code_32 - gdts |
mov eax, [BOOT_VAR + 0x9044] ; version & flags |
mov [apm_vf], eax |
; ----------------------------------------- |
; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port |
; mov [0xF604],byte 1 ;al |
mov al, [BOOT_VAR+0x901F] ; DMA access |
mov [allow_dma_access], al |
movzx eax, byte [BOOT_VAR+0x9000] ; bpp |
mov [ScreenBPP],al |
mov [_display.bpp], eax |
mov [_display.vrefresh], 60 |
mov [_display.disable_mouse], __sys_disable_mouse |
movzx eax,word [BOOT_VAR+0x900A] ; X max |
mov [_display.width], eax |
dec eax |
mov [Screen_Max_X],eax |
mov [screen_workarea.right],eax |
movzx eax,word [BOOT_VAR+0x900C] ; Y max |
mov [_display.height], eax |
dec eax |
mov [Screen_Max_Y],eax |
mov [screen_workarea.bottom],eax |
movzx eax,word [BOOT_VAR+0x9008] ; screen mode |
mov [SCR_MODE],eax |
mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add |
mov [BANK_SWITCH],eax |
mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine |
cmp [SCR_MODE],word 0x13 ; 320x200 |
je @f |
cmp [SCR_MODE],word 0x12 ; VGA 640x480 |
je @f |
movzx eax, word[BOOT_VAR+0x9001] ; for other modes |
mov [BytesPerScanLine],ax |
mov [_display.pitch], eax |
@@: |
mov eax, [_display.width] |
mul [_display.height] |
mov [_WinMapSize], eax |
mov esi, BOOT_VAR+0x9080 |
movzx ecx, byte [esi-1] |
mov [NumBiosDisks], ecx |
mov edi, BiosDisksData |
rep movsd |
; GRAPHICS ADDRESSES |
and byte [BOOT_VAR+0x901e],0x0 |
mov eax,[BOOT_VAR+0x9018] |
mov [LFBAddress],eax |
cmp [SCR_MODE],word 0100000000000000b |
jge setvesa20 |
cmp [SCR_MODE],word 0x13 |
je v20ga32 |
mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 |
mov [GETPIXEL],dword Vesa12_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz ga24 |
mov [PUTPIXEL],dword Vesa12_putpixel32 |
mov [GETPIXEL],dword Vesa12_getpixel32 |
ga24: |
jmp v20ga24 |
setvesa20: |
mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 |
mov [GETPIXEL],dword Vesa20_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz v20ga24 |
v20ga32: |
mov [PUTPIXEL],dword Vesa20_putpixel32 |
mov [GETPIXEL],dword Vesa20_getpixel32 |
v20ga24: |
cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 |
jne no_mode_0x12 |
mov [PUTPIXEL],dword VGA_putpixel |
mov [GETPIXEL],dword Vesa20_getpixel32 |
no_mode_0x12: |
; -------- Fast System Call init ---------- |
; Intel SYSENTER/SYSEXIT (AMD CPU support it too) |
bt [cpu_caps], CAPS_SEP |
jnc .SEnP ; SysEnter not Present |
xor edx, edx |
mov ecx, MSR_SYSENTER_CS |
mov eax, os_code |
wrmsr |
mov ecx, MSR_SYSENTER_ESP |
; mov eax, sysenter_stack ; Check it |
xor eax, eax |
wrmsr |
mov ecx, MSR_SYSENTER_EIP |
mov eax, sysenter_entry |
wrmsr |
.SEnP: |
; AMD SYSCALL/SYSRET |
cmp byte[cpu_vendor], 'A' |
jne .noSYSCALL |
mov eax, 0x80000001 |
cpuid |
test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support |
jz .noSYSCALL |
mov ecx, MSR_AMD_EFER |
rdmsr |
or eax, 1 ; bit_0 - System Call Extension (SCE) |
wrmsr |
; !!!! It`s dirty hack, fix it !!! |
; Bits of EDX : |
; Bit 3116 During the SYSRET instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; Bit 150 During the SYSCALL instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; mov edx, (os_code + 16) * 65536 + os_code |
mov edx, 0x1B0008 |
mov eax, syscall_entry |
mov ecx, MSR_AMD_STAR |
wrmsr |
.noSYSCALL: |
; ----------------------------------------- |
stdcall alloc_page |
stdcall map_page, tss-0xF80, eax, PG_SW |
stdcall alloc_page |
inc eax |
mov [SLOT_BASE+256+APPDATA.io_map], eax |
stdcall map_page, tss+0x80, eax, PG_SW |
stdcall alloc_page |
inc eax |
mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax |
stdcall map_page, tss+0x1080, eax, PG_SW |
; LOAD IDT |
call build_interrupt_table ;lidt is executed |
;lidt [idtreg] |
call init_kernel_heap |
stdcall kernel_alloc, RING0_STACK_SIZE+512 |
mov [os_stack_seg], eax |
lea esp, [eax+RING0_STACK_SIZE] |
mov [tss._ss0], os_stack |
mov [tss._esp0], esp |
mov [tss._esp], esp |
mov [tss._cs],os_code |
mov [tss._ss],os_stack |
mov [tss._ds],app_data |
mov [tss._es],app_data |
mov [tss._fs],app_data |
mov [tss._gs],app_data |
mov [tss._io],128 |
;Add IO access table - bit array of permitted ports |
mov edi, tss._io_map_0 |
xor eax, eax |
not eax |
mov ecx, 8192/4 |
rep stosd ; access to 4096*8=65536 ports |
mov ax,tss0 |
ltr ax |
mov [LFBSize], 0x800000 |
call init_LFB |
call init_fpu |
call init_malloc |
stdcall alloc_kernel_space, 0x51000 |
mov [default_io_map], eax |
add eax, 0x2000 |
mov [ipc_tmp], eax |
mov ebx, 0x1000 |
add eax, 0x40000 |
mov [proc_mem_map], eax |
add eax, 0x8000 |
mov [proc_mem_pdir], eax |
add eax, ebx |
mov [proc_mem_tab], eax |
add eax, ebx |
mov [tmp_task_pdir], eax |
add eax, ebx |
mov [tmp_task_ptab], eax |
add eax, ebx |
mov [ipc_pdir], eax |
add eax, ebx |
mov [ipc_ptab], eax |
stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \ |
(unpack.lc+unpack.lp)))*4 |
mov [unpack.p], eax |
call init_events |
mov eax, srv.fd-SRV_FD_OFFSET |
mov [srv.fd], eax |
mov [srv.bk], eax |
mov edi, irq_tab |
xor eax, eax |
mov ecx, 16 |
rep stosd |
;Set base of graphic segment to linear address of LFB |
mov eax,[LFBAddress] ; set for gs |
mov [graph_data_l+2],ax |
shr eax,16 |
mov [graph_data_l+4],al |
mov [graph_data_l+7],ah |
stdcall kernel_alloc, [_WinMapSize] |
mov [_WinMapAddress], eax |
xor eax,eax |
inc eax |
mov [CURRENT_TASK],eax ;dword 1 |
mov [TASK_COUNT],eax ;dword 1 |
mov [TASK_BASE],dword TASK_DATA |
mov [current_slot], SLOT_BASE+256 |
; set background |
mov [BgrDrawMode],eax |
mov [BgrDataWidth],eax |
mov [BgrDataHeight],eax |
mov [mem_BACKGROUND], 4 |
mov [img_background], static_background_data |
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE |
stdcall kernel_alloc, 0x10000/8 |
mov edi, eax |
mov [network_free_ports], eax |
or eax, -1 |
mov ecx, 0x10000/32 |
rep stosd |
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f |
call rerouteirqs |
; Initialize system V86 machine |
call init_sys_v86 |
; TIMER SET TO 1/100 S |
mov al,0x34 ; set to 100Hz |
out 0x43,al |
mov al,0x9b ; lsb 1193180 / 1193 |
out 0x40,al |
mov al,0x2e ; msb |
out 0x40,al |
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) |
; they are used: when partitions are scanned, hd_read relies on timer |
; Also enable IRQ2, because in some configurations |
; IRQs from slave controller are not delivered until IRQ2 on master is enabled |
mov al, 0xFA |
out 0x21, al |
mov al, 0x3F |
out 0xA1, al |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/disks.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
call Parser_params |
; READ RAMDISK IMAGE FROM HD |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'boot/rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
; mov [dma_hdd],1 |
; CALCULATE FAT CHAIN FOR RAMDISK |
call calculatefatchain |
; LOAD VMODE DRIVER |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeld.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
if 0 |
mov ax,[OS_BASE+0x10000+bx_from_load] |
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} |
je no_lib_load |
; LOADING LIBRARES |
stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files) |
call load_file_parse_table ; prepare file parse table |
call set_kernel_conf ; configure devices and gui |
no_lib_load: |
end if |
; LOAD FONTS I and II |
stdcall read_file, char, FONT_I, 0, 2304 |
stdcall read_file, char2, FONT_II, 0, 2560 |
mov esi,boot_fonts |
call boot_log |
; PRINT AMOUNT OF MEMORY |
mov esi, boot_memdetect |
call boot_log |
movzx ecx, word [boot_y] |
or ecx, (10+29*6) shl 16 ; "Determining amount of memory" |
sub ecx, 10 |
mov edx, 0xFFFFFF |
mov ebx, [MEM_AMOUNT] |
shr ebx, 20 |
xor edi,edi |
mov eax, 0x00040000 |
inc edi |
call display_number_force |
; BUILD SCHEDULER |
call build_scheduler ; sys32.inc |
mov esi,boot_devices |
call boot_log |
mov [pci_access_enabled],1 |
; SET PRELIMINARY WINDOW STACK AND POSITIONS |
mov esi,boot_windefs |
call boot_log |
call setwindowdefaults |
; SET BACKGROUND DEFAULTS |
mov esi,boot_bgr |
call boot_log |
call init_background |
call calculatebackground |
; RESERVE SYSTEM IRQ'S JA PORT'S |
mov esi,boot_resirqports |
call boot_log |
call reserve_irqs_ports |
; SET PORTS FOR IRQ HANDLERS |
mov esi,boot_setrports |
call boot_log |
;call setirqreadports |
; SET UP OS TASK |
mov esi,boot_setostask |
call boot_log |
xor eax, eax |
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data |
mov dword [SLOT_BASE+APPDATA.exc_handler], eax |
mov dword [SLOT_BASE+APPDATA.except_mask], eax |
; name for OS/IDLE process |
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' |
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' |
mov edi, [os_stack_seg] |
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi |
add edi, 0x2000-512 |
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi |
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case |
; [SLOT_BASE+256+APPDATA.io_map] was set earlier |
mov esi, fpu_data |
mov ecx, 512/4 |
cld |
rep movsd |
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax |
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax |
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET |
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx |
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx |
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path |
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax |
; task list |
mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address |
inc eax |
mov dword [CURRENT_TASK],eax |
mov dword [TASK_COUNT],eax |
mov [current_slot], SLOT_BASE+256 |
mov [TASK_BASE],dword TASK_DATA |
mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number |
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number |
call init_display |
mov eax, [def_cursor] |
mov [SLOT_BASE+APPDATA.cursor],eax |
mov [SLOT_BASE+APPDATA.cursor+256],eax |
; READ TSC / SECOND |
mov esi,boot_tsc |
call boot_log |
cli |
rdtsc ;call _rdtsc |
mov ecx,eax |
mov esi,250 ; wait 1/4 a second |
call delay_ms |
rdtsc ;call _rdtsc |
sti |
sub eax,ecx |
shl eax,2 |
mov [CPU_FREQ],eax ; save tsc / sec |
; mov ebx, 1000000 |
; div ebx |
; ¢®®¡é¥-â® ¯à®¨§¢®¤¨â¥«ì®áâì ¢ ¤ ®¬ ª®ªà¥â®¬ ¬¥á⥠|
; ᮢ¥à襮 ¥ªà¨â¨ç , ® çâ®¡ë § âªãâì «î¡¨â¥«¥© |
; ®¯â¨¬¨§¨àãîé¨å ª®¬¯¨«ïâ®à®¢ ... |
mov edx, 2251799814 |
mul edx |
shr edx, 19 |
mov [stall_mcs], edx |
; PRINT CPU FREQUENCY |
mov esi, boot_cpufreq |
call boot_log |
mov ebx, edx |
movzx ecx, word [boot_y] |
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is ' |
mov edx, 0xFFFFFF |
xor edi,edi |
mov eax, 0x00040000 |
inc edi |
call display_number_force |
; SET VARIABLES |
call set_variables |
; SET MOUSE |
;call detect_devices |
stdcall load_driver, szPS2MDriver |
; stdcall load_driver, szCOM_MDriver |
mov esi,boot_setmouse |
call boot_log |
call setmouse |
; STACK AND FDC |
call stack_init |
call fdc_init |
; PALETTE FOR 320x200 and 640x480 16 col |
cmp [SCR_MODE],word 0x12 |
jne no_pal_vga |
mov esi,boot_pal_vga |
call boot_log |
call paletteVGA |
no_pal_vga: |
cmp [SCR_MODE],word 0x13 |
jne no_pal_ega |
mov esi,boot_pal_ega |
call boot_log |
call palette320x200 |
no_pal_ega: |
; LOAD DEFAULT SKIN |
call load_default_skin |
;protect io permission map |
mov esi, [default_io_map] |
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP |
add esi, 0x1000 |
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP |
stdcall map_page,tss._io_map_0,\ |
[SLOT_BASE+256+APPDATA.io_map], PG_MAP |
stdcall map_page,tss._io_map_1,\ |
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP |
mov ax,[OS_BASE+0x10000+bx_from_load] |
cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba} |
je no_st_network |
call set_network_conf |
no_st_network: |
; LOAD FIRST APPLICATION |
cli |
cmp byte [BOOT_VAR+0x9030],1 |
jne no_load_vrr_m |
mov ebp, vrr_m |
call fs_execute_from_sysdir |
; cmp eax,2 ; if vrr_m app found (PID=2) |
sub eax,2 |
jz first_app_found |
no_load_vrr_m: |
mov ebp, firstapp |
call fs_execute_from_sysdir |
; cmp eax,2 ; continue if a process has been loaded |
sub eax,2 |
jz first_app_found |
mov esi, boot_failed |
call boot_log |
mov eax, 0xDEADBEEF ; otherwise halt |
hlt |
first_app_found: |
cli |
;mov [TASK_COUNT],dword 2 |
push 1 |
pop dword [CURRENT_TASK] ; set OS task fisrt |
; SET KEYBOARD PARAMETERS |
mov al, 0xf6 ; reset keyboard, scan enabled |
call kb_write |
; wait until 8042 is ready |
xor ecx,ecx |
@@: |
in al,64h |
and al,00000010b |
loopnz @b |
; mov al, 0xED ; svetodiody - only for testing! |
; call kb_write |
; call kb_read |
; mov al, 111b |
; call kb_write |
; call kb_read |
mov al, 0xF3 ; set repeat rate & delay |
call kb_write |
; call kb_read |
mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 |
call kb_write |
; call kb_read |
;// mike.dld [ |
call set_lights |
;// mike.dld ] |
; Setup serial output console (if enabled) |
if defined debug_com_base |
; enable Divisor latch |
mov dx, debug_com_base+3 |
mov al, 1 shl 7 |
out dx, al |
; Set speed to 115200 baud (max speed) |
mov dx, debug_com_base |
mov al, 0x01 |
out dx, al |
mov dx, debug_com_base+1 |
mov al, 0x00 |
out dx, al |
; No parity, 8bits words, one stop bit, dlab bit back to 0 |
mov dx, debug_com_base+3 |
mov al, 3 |
out dx, al |
; disable interrupts |
mov dx, debug_com_base+1 |
mov al, 0 |
out dx, al |
; clear + enable fifo (64 bits) |
mov dx, debug_com_base+2 |
mov al, 0x7 + 1 shl 5 |
out dx, al |
end if |
; START MULTITASKING |
if preboot_blogesc |
mov esi, boot_tasking |
call boot_log |
.bll1: in al, 0x60 ; wait for ESC key press |
cmp al, 129 |
jne .bll1 |
end if |
; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled |
; UNMASK ALL IRQ'S |
mov esi,boot_allirqs |
call boot_log |
cli ;guarantee forbidance of interrupts. |
mov al,0 ; unmask all irq's |
out 0xA1,al |
out 0x21,al |
mov ecx,32 |
ready_for_irqs: |
mov al,0x20 ; ready for irqs |
out 0x20,al |
out 0xa0,al |
loop ready_for_irqs ; flush the queue |
stdcall attach_int_handler, dword 1, irq1, dword 0 |
; mov [dma_hdd],1 |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
mov [timer_ticks_enable],1 ; for cd driver |
sti |
call change_task |
jmp osloop |
; jmp $ ; wait here for timer to take control |
; Fly :) |
include 'unpacker.inc' |
include 'fdo.inc' |
align 4 |
boot_log: |
pushad |
mov ebx,10*65536 |
mov bx,word [boot_y] |
add [boot_y],dword 10 |
mov ecx,0x80ffffff ; ASCIIZ string with white color |
xor edi,edi |
mov edx,esi |
inc edi |
call dtext |
mov [novesachecksum],1000 |
call checkVga_N13 |
popad |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP START ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
osloop: |
call [draw_pointer] |
call checkbuttons |
call checkwindows |
; call check_window_move_request |
call checkmisc |
call checkVga_N13 |
call stack_handler |
call checkidle |
call check_fdd_motor_status |
call check_ATAPI_device_event |
jmp osloop |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP END ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
checkidle: |
pushad |
call change_task |
jmp idle_loop_entry |
idle_loop: |
cmp eax,[idlemem] ; eax == [timer_ticks] |
jne idle_exit |
rdtsc ;call _rdtsc |
mov ecx,eax |
hlt |
rdtsc ;call _rdtsc |
sub eax,ecx |
add [idleuse],eax |
idle_loop_entry: |
mov eax,[timer_ticks] ; eax = [timer_ticks] |
cmp [check_idle_semaphore],0 |
je idle_loop |
dec [check_idle_semaphore] |
idle_exit: |
mov [idlemem],eax ; eax == [timer_ticks] |
popad |
ret |
uglobal |
idlemem dd 0x0 |
idleuse dd 0x0 |
idleusesec dd 0x0 |
check_idle_semaphore dd 0x0 |
endg |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; INCLUDED SYSTEM FILES ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include "kernel32.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; KERNEL FUNCTIONS ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
reserve_irqs_ports: |
push eax |
xor eax,eax |
inc eax |
mov byte [irq_owner+4*0],al ;1 ; timer |
;mov [irq_owner+4*1], 1 ; keyboard |
mov byte [irq_owner+4*6],al ;1 ; floppy diskette |
mov byte [irq_owner+4*13],al ;1 ; math co-pros |
mov byte [irq_owner+4*14],al ;1 ; ide I |
mov byte [irq_owner+4*15],al ;1 ; ide II |
pop eax |
; RESERVE PORTS |
push 4 |
pop dword [RESERVED_PORTS] ;,edi |
push 1 |
pop dword [RESERVED_PORTS+16+0] ;,dword 1 |
and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0 |
mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d |
push 1 |
pop dword [RESERVED_PORTS+32+0] ;,dword 1 |
push 0x30 |
pop dword [RESERVED_PORTS+32+4] ;,dword 0x30 |
push 0x4d |
pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d |
push 1 |
pop dword [RESERVED_PORTS+48+0] ;,dword 1 |
push 0x50 |
pop dword [RESERVED_PORTS+48+4] ;,dword 0x50 |
mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf |
push 1 |
pop dword [RESERVED_PORTS+64+0] ;,dword 1 |
mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5 |
mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff |
ret |
setirqreadports: |
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte |
and dword [irq12read+4],0 ; end of port list |
; mov [irq12read+4],dword 0 ; end of port list |
;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte |
;mov [irq04read+4],dword 0 ; end of port list |
;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte |
;mov [irq03read+4],dword 0 ; end of port list |
ret |
iglobal |
process_number dd 0x1 |
endg |
set_variables: |
mov ecx,0x100 ; flush port 0x60 |
.fl60: in al,0x60 |
loop .fl60 |
push eax |
mov ax,[BOOT_VAR+0x900c] |
shr ax,1 |
shl eax,16 |
mov ax,[BOOT_VAR+0x900A] |
shr ax,1 |
mov [MOUSE_X],eax |
xor eax,eax |
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list |
mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer |
mov byte [KEY_COUNT],al ; keyboard buffer |
mov byte [BTN_COUNT],al ; button buffer |
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y |
;!! IP 04.02.2005: |
mov byte [DONT_SWITCH],al ; change task if possible |
pop eax |
ret |
align 4 |
;input eax=43,bl-byte of output, ecx - number of port |
sys_outport: |
mov edi,ecx ; separate flag for read / write |
and ecx,65535 |
mov eax,[RESERVED_PORTS] |
test eax,eax |
jnz .sopl8 |
inc eax |
mov [esp+32],eax |
ret |
.sopl8: |
mov edx,[TASK_BASE] |
mov edx,[edx+0x4] |
;and ecx,65535 |
;cld - set on interrupt 0x40 |
.sopl1: |
mov esi,eax |
shl esi,4 |
add esi,RESERVED_PORTS |
cmp edx,[esi+0] |
jne .sopl2 |
cmp ecx,[esi+4] |
jb .sopl2 |
cmp ecx,[esi+8] |
jg .sopl2 |
.sopl3: |
test edi,0x80000000 ; read ? |
jnz .sopl4 |
mov eax,ebx |
mov dx,cx ; write |
out dx,al |
and [esp+32],dword 0 |
ret |
.sopl2: |
dec eax |
jnz .sopl1 |
inc eax |
mov [esp+32],eax |
ret |
.sopl4: |
mov dx,cx ; read |
in al,dx |
and eax,0xff |
and [esp+32],dword 0 |
mov [esp+20],eax |
ret |
display_number: |
; eax = print type, al=0 -> ebx is number |
; al=1 -> ebx is pointer |
; ah=0 -> display decimal |
; ah=1 -> display hexadecimal |
; ah=2 -> display binary |
; eax bits 16-21 = number of digits to display (0-32) |
; eax bits 22-31 = reserved |
; |
; ebx = number or pointer |
; ecx = x shl 16 + y |
; edx = color |
xor edi, edi |
display_number_force: |
push eax |
and eax,0x3fffffff |
cmp eax,0xffff ; length > 0 ? |
pop eax |
jge cont_displ |
ret |
cont_displ: |
push eax |
and eax,0x3fffffff |
cmp eax,61*0x10000 ; length <= 60 ? |
pop eax |
jb cont_displ2 |
ret |
cont_displ2: |
pushad |
cmp al,1 ; ecx is a pointer ? |
jne displnl1 |
mov ebp,ebx |
add ebp,4 |
mov ebp,[ebp+std_application_base_address] |
mov ebx,[ebx+std_application_base_address] |
displnl1: |
sub esp,64 |
test ah,ah ; DECIMAL |
jnz no_display_desnum |
shr eax,16 |
and eax,0xC03f |
; and eax,0x3f |
push eax |
and eax,0x3f |
mov edi,esp |
add edi,4+64-1 |
mov ecx,eax |
mov eax,ebx |
mov ebx,10 |
d_desnum: |
xor edx,edx |
call division_64_bits |
div ebx |
add dl,48 |
mov [edi],dl |
dec edi |
loop d_desnum |
pop eax |
call normalize_number |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_desnum: |
cmp ah,0x01 ; HEXADECIMAL |
jne no_display_hexnum |
shr eax,16 |
and eax,0xC03f |
; and eax,0x3f |
push eax |
and eax,0x3f |
mov edi,esp |
add edi,4+64-1 |
mov ecx,eax |
mov eax,ebx |
mov ebx,16 |
d_hexnum: |
xor edx,edx |
call division_64_bits |
div ebx |
hexletters = __fdo_hexdigits |
add edx,hexletters |
mov dl,[edx] |
mov [edi],dl |
dec edi |
loop d_hexnum |
pop eax |
call normalize_number |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_hexnum: |
cmp ah,0x02 ; BINARY |
jne no_display_binnum |
shr eax,16 |
and eax,0xC03f |
; and eax,0x3f |
push eax |
and eax,0x3f |
mov edi,esp |
add edi,4+64-1 |
mov ecx,eax |
mov eax,ebx |
mov ebx,2 |
d_binnum: |
xor edx,edx |
call division_64_bits |
div ebx |
add dl,48 |
mov [edi],dl |
dec edi |
loop d_binnum |
pop eax |
call normalize_number |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_binnum: |
add esp,64 |
popad |
ret |
normalize_number: |
test ah,0x80 |
jz .continue |
mov ecx,48 |
and eax,0x3f |
@@: |
inc edi |
cmp [edi],cl |
jne .continue |
dec eax |
cmp eax,1 |
ja @r |
mov al,1 |
.continue: |
and eax,0x3f |
ret |
division_64_bits: |
test [esp+1+4],byte 0x40 |
jz .continue |
push eax |
mov eax,ebp |
div ebx |
mov ebp,eax |
pop eax |
.continue: |
ret |
draw_num_text: |
mov esi,eax |
mov edx,64+4 |
sub edx,eax |
add edx,esp |
mov ebx,[esp+64+32-8+4] |
; add window start x & y |
mov ecx,[TASK_BASE] |
mov edi,[CURRENT_TASK] |
shl edi,8 |
mov eax,[ecx-twdw+WDATA.box.left] |
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] |
shl eax,16 |
add eax,[ecx-twdw+WDATA.box.top] |
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] |
add ebx,eax |
mov ecx,[esp+64+32-12+4] |
and ecx, not 0x80000000 ; force counted string |
mov eax, [esp+64+8] ; background color (if given) |
mov edi, [esp+64+4] |
jmp dtext |
align 4 |
sys_setup: |
; 1=roland mpu midi base , base io address |
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus |
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 5=system language, 1eng 2fi 3ger 4rus |
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 8=fat32 partition in hd |
; 9 |
; 10 = sound dma channel |
; 11 = enable lba read |
; 12 = enable pci access |
and [esp+32],dword 0 |
dec ebx ; MIDI |
jnz nsyse1 |
cmp ecx,0x100 |
jb nsyse1 |
mov esi,65535 |
cmp esi,ecx |
jb nsyse1 |
mov [midi_base],cx ;bx |
mov word [mididp],cx ;bx |
inc cx ;bx |
mov word [midisp],cx ;bx |
ret |
iglobal |
midi_base dw 0 |
endg |
nsyse1: |
dec ebx ; KEYBOARD |
jnz nsyse2 |
mov edi,[TASK_BASE] |
mov eax,[edi+TASKDATA.mem_start] |
add eax,edx |
dec ecx |
jnz kbnobase |
mov ebx,keymap |
mov ecx,128 |
call memmove |
ret |
kbnobase: |
dec ecx |
jnz kbnoshift |
mov ebx,keymap_shift |
mov ecx,128 |
call memmove |
ret |
kbnoshift: |
dec ecx |
jnz kbnoalt |
mov ebx,keymap_alt |
mov ecx,128 |
call memmove |
ret |
kbnoalt: |
sub ecx,6 |
jnz kbnocountry |
mov word [keyboard],dx |
ret |
kbnocountry: |
mov [esp+32],dword 1 |
ret |
nsyse2: |
dec ebx ; CD |
jnz nsyse4 |
test ecx,ecx |
jz nosesl |
cmp ecx, 4 |
ja nosesl |
mov [cd_base],cl |
dec ecx |
jnz noprma |
mov [cdbase],0x1f0 |
mov [cdid],0xa0 |
noprma: |
dec ecx |
jnz noprsl |
mov [cdbase],0x1f0 |
mov [cdid],0xb0 |
noprsl: |
dec ecx |
jnz nosema |
mov [cdbase],0x170 |
mov [cdid],0xa0 |
nosema: |
dec ecx |
jnz nosesl |
mov [cdbase],0x170 |
mov [cdid],0xb0 |
nosesl: |
ret |
iglobal |
cd_base db 0 |
endg |
nsyse4: |
sub ebx,2 ; SYSTEM LANGUAGE |
jnz nsyse5 |
mov [syslang],ecx |
ret |
nsyse5: |
sub ebx,2 ; HD BASE |
jnz nsyse7 |
test ecx,ecx |
jz nosethd |
cmp ecx,4 |
ja nosethd |
mov [hd_base],cl |
cmp ecx,1 |
jnz noprmahd |
mov [hdbase],0x1f0 |
and dword [hdid],0x0 |
mov dword [hdpos],ecx |
; call set_FAT32_variables |
noprmahd: |
cmp ecx,2 |
jnz noprslhd |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov dword [hdpos],ecx |
; call set_FAT32_variables |
noprslhd: |
cmp ecx,3 |
jnz nosemahd |
mov [hdbase],0x170 |
and dword [hdid],0x0 |
mov dword [hdpos],ecx |
; call set_FAT32_variables |
nosemahd: |
cmp ecx,4 |
jnz noseslhd |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov dword [hdpos],ecx |
; call set_FAT32_variables |
noseslhd: |
call reserve_hd1 |
call reserve_hd_channel |
call free_hd_channel |
and dword [hd1_status],0 ; free |
nosethd: |
ret |
iglobal |
hd_base db 0 |
endg |
nsyse7: |
; cmp eax,8 ; HD PARTITION |
dec ebx |
jnz nsyse8 |
mov [fat32part],ecx |
; call set_FAT32_variables |
call reserve_hd1 |
call reserve_hd_channel |
call free_hd_channel |
; pusha |
call choice_necessity_partition_1 |
; popa |
and dword [hd1_status],0 ; free |
ret |
nsyse8: |
; cmp eax,11 ; ENABLE LBA READ |
and ecx,1 |
sub ebx,3 |
jnz no_set_lba_read |
mov [lba_read_enabled],ecx |
ret |
no_set_lba_read: |
; cmp eax,12 ; ENABLE PCI ACCESS |
dec ebx |
jnz no_set_pci_access |
mov [pci_access_enabled],ecx |
ret |
no_set_pci_access: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeint.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
sys_setup_err: |
or [esp+32],dword -1 |
ret |
align 4 |
sys_getsetup: |
; 1=roland mpu midi base , base io address |
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus |
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 5=system language, 1eng 2fi 3ger 4rus |
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 8=fat32 partition in hd |
; 9=get hs timer tic |
; cmp eax,1 |
dec ebx |
jnz ngsyse1 |
movzx eax,[midi_base] |
mov [esp+32],eax |
ret |
ngsyse1: |
; cmp eax,2 |
dec ebx |
jnz ngsyse2 |
mov edi,[TASK_BASE] |
mov ebx,[edi+TASKDATA.mem_start] |
add ebx,edx |
; cmp ebx,1 |
dec ecx |
jnz kbnobaseret |
mov eax,keymap |
mov ecx,128 |
call memmove |
ret |
kbnobaseret: |
; cmp ebx,2 |
dec ecx |
jnz kbnoshiftret |
mov eax,keymap_shift |
mov ecx,128 |
call memmove |
ret |
kbnoshiftret: |
; cmp ebx,3 |
dec ecx |
jne kbnoaltret |
mov eax,keymap_alt |
mov ecx,128 |
call memmove |
ret |
kbnoaltret: |
; cmp ebx,9 |
sub ecx,6 |
jnz ngsyse2 |
movzx eax,word [keyboard] |
mov [esp+32],eax |
ret |
ngsyse2: |
; cmp eax,3 |
dec ebx |
jnz ngsyse3 |
movzx eax,[cd_base] |
mov [esp+32],eax |
ret |
ngsyse3: |
; cmp eax,5 |
sub ebx,2 |
jnz ngsyse5 |
mov eax,[syslang] |
mov [esp+32],eax |
ret |
ngsyse5: |
; cmp eax,7 |
sub ebx,2 |
jnz ngsyse7 |
movzx eax,[hd_base] |
mov [esp+32],eax |
ret |
ngsyse7: |
; cmp eax,8 |
dec ebx |
jnz ngsyse8 |
mov eax,[fat32part] |
mov [esp+32],eax |
ret |
ngsyse8: |
; cmp eax,9 |
dec ebx |
jnz ngsyse9 |
mov eax,[timer_ticks] ;[0xfdf0] |
mov [esp+32],eax |
ret |
ngsyse9: |
; cmp eax,11 |
sub ebx,2 |
jnz ngsyse11 |
mov eax,[lba_read_enabled] |
mov [esp+32],eax |
ret |
ngsyse11: |
; cmp eax,12 |
dec ebx |
jnz ngsyse12 |
mov eax,[pci_access_enabled] |
mov [esp+32],eax |
ret |
ngsyse12: |
mov [esp+32],dword 1 |
ret |
get_timer_ticks: |
mov eax,[timer_ticks] |
ret |
iglobal |
align 4 |
mousefn dd msscreen, mswin, msbutton, msset |
dd app_load_cursor |
dd app_set_cursor |
dd app_delete_cursor |
dd msz |
endg |
readmousepos: |
; eax=0 screen relative |
; eax=1 window relative |
; eax=2 buttons pressed |
; eax=3 set mouse pos ; reserved |
; eax=4 load cursor |
; eax=5 set cursor |
; eax=6 delete cursor ; reserved |
; eax=7 get mouse_z |
cmp ebx, 7 |
ja msset |
jmp [mousefn+ebx*4] |
msscreen: |
mov eax,[MOUSE_X] |
shl eax,16 |
mov ax,[MOUSE_Y] |
mov [esp+36-4],eax |
ret |
mswin: |
mov eax,[MOUSE_X] |
shl eax,16 |
mov ax,[MOUSE_Y] |
mov esi,[TASK_BASE] |
mov bx, word [esi-twdw+WDATA.box.left] |
shl ebx,16 |
mov bx, word [esi-twdw+WDATA.box.top] |
sub eax,ebx |
mov edi,[CURRENT_TASK] |
shl edi,8 |
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] |
rol eax,16 |
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] |
rol eax,16 |
mov [esp+36-4],eax |
ret |
msbutton: |
movzx eax,byte [BTN_DOWN] |
mov [esp+36-4],eax |
ret |
msz: |
mov edi, [TASK_COUNT] |
movzx edi, word [WIN_POS + edi*2] |
cmp edi, [CURRENT_TASK] |
jne @f |
mov ax,[MOUSE_SCROLL_H] |
shl eax,16 |
mov ax,[MOUSE_SCROLL_V] |
mov [esp+36-4],eax |
and [MOUSE_SCROLL_H],word 0 |
and [MOUSE_SCROLL_V],word 0 |
ret |
@@: |
and [esp+36-4],dword 0 |
; ret |
msset: |
ret |
app_load_cursor: |
cmp ecx, OS_BASE |
jae msset |
stdcall load_cursor, ecx, edx |
mov [esp+36-4], eax |
ret |
app_set_cursor: |
stdcall set_cursor, ecx |
mov [esp+36-4], eax |
ret |
app_delete_cursor: |
stdcall delete_cursor, ecx |
mov [esp+36-4], eax |
ret |
is_input: |
push edx |
mov dx,word [midisp] |
in al,dx |
and al,0x80 |
pop edx |
ret |
is_output: |
push edx |
mov dx,word [midisp] |
in al,dx |
and al,0x40 |
pop edx |
ret |
get_mpu_in: |
push edx |
mov dx,word [mididp] |
in al,dx |
pop edx |
ret |
put_mpu_out: |
push edx |
mov dx,word [mididp] |
out dx,al |
pop edx |
ret |
align 4 |
sys_midi: |
cmp [mididp],0 |
jnz sm0 |
mov [esp+36],dword 1 |
ret |
sm0: |
and [esp+36],dword 0 |
dec ebx |
jnz smn1 |
; call setuart |
su1: |
call is_output |
test al,al |
jnz su1 |
mov dx,word [midisp] |
mov al,0xff |
out dx,al |
su2: |
mov dx,word [midisp] |
mov al,0xff |
out dx,al |
call is_input |
test al,al |
jnz su2 |
call get_mpu_in |
cmp al,0xfe |
jnz su2 |
su3: |
call is_output |
test al,al |
jnz su3 |
mov dx,word [midisp] |
mov al,0x3f |
out dx,al |
ret |
smn1: |
dec ebx |
jnz smn2 |
sm10: |
call get_mpu_in |
call is_output |
test al,al |
jnz sm10 |
mov al,bl |
call put_mpu_out |
smn2: |
ret |
detect_devices: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
;include 'detect/commouse.inc' |
;include 'detect/ps2mouse.inc' |
;include 'detect/dev_fd.inc' |
;include 'detect/dev_hdcd.inc' |
;include 'detect/sear_par.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
ret |
sys_end: |
mov ecx, [current_slot] |
mov eax, [ecx+APPDATA.tls_base] |
test eax, eax |
jz @F |
stdcall user_free, eax |
@@: |
mov eax,[TASK_BASE] |
mov [eax+TASKDATA.state], 3 ; terminate this program |
waitterm: ; wait here for termination |
mov ebx,100 |
call delay_hs |
jmp waitterm |
iglobal |
align 4 |
sys_system_table: |
dd exit_for_anyone ; 1 = obsolete |
dd sysfn_terminate ; 2 = terminate thread |
dd sysfn_activate ; 3 = activate window |
dd sysfn_getidletime ; 4 = get idle time |
dd sysfn_getcpuclock ; 5 = get cpu clock |
dd sysfn_saveramdisk ; 6 = save ramdisk |
dd sysfn_getactive ; 7 = get active window |
dd sysfn_sound_flag ; 8 = get/set sound_flag |
dd sysfn_shutdown ; 9 = shutdown with parameter |
dd sysfn_minimize ; 10 = minimize window |
dd sysfn_getdiskinfo ; 11 = get disk subsystem info |
dd sysfn_lastkey ; 12 = get last pressed key |
dd sysfn_getversion ; 13 = get kernel version |
dd sysfn_waitretrace ; 14 = wait retrace |
dd sysfn_centermouse ; 15 = center mouse cursor |
dd sysfn_getfreemem ; 16 = get free memory size |
dd sysfn_getallmem ; 17 = get total memory size |
dd sysfn_terminate2 ; 18 = terminate thread using PID |
; instead of slot |
dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration |
dd sysfn_meminfo ; 20 = get extended memory info |
dd sysfn_pid_to_slot ; 21 = get slot number for pid |
dd sysfn_min_rest_window ; 22 = minimize and restore any window |
sysfn_num = ($ - sys_system_table)/4 |
endg |
sys_system: |
dec ebx |
cmp ebx, sysfn_num |
jae @f |
jmp dword [sys_system_table + ebx*4] |
@@: |
ret |
sysfn_shutdown: ; 18.9 = system shutdown |
cmp ecx,1 |
jl exit_for_anyone |
cmp ecx,4 |
jg exit_for_anyone |
mov [BOOT_VAR+0x9030],cl |
mov eax,[TASK_COUNT] |
mov [SYS_SHUTDOWN],al |
mov [shutdown_processes],eax |
and dword [esp+32], 0 |
exit_for_anyone: |
ret |
uglobal |
shutdown_processes: dd 0x0 |
endg |
sysfn_terminate: ; 18.2 = TERMINATE |
cmp ecx,2 |
jb noprocessterminate |
mov edx,[TASK_COUNT] |
cmp ecx,edx |
ja noprocessterminate |
mov eax,[TASK_COUNT] |
shl ecx,5 |
mov edx,[ecx+CURRENT_TASK+TASKDATA.pid] |
add ecx,CURRENT_TASK+TASKDATA.state |
cmp byte [ecx], 9 |
jz noprocessterminate |
;call MEM_Heap_Lock ;guarantee that process isn't working with heap |
mov [ecx],byte 3 ; clear possible i40's |
;call MEM_Heap_UnLock |
cmp edx,[application_table_status] ; clear app table stat |
jne noatsc |
mov [application_table_status],0 |
noatsc: |
noprocessterminate: |
ret |
sysfn_terminate2: |
;lock application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
je .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
mov eax,ecx |
call pid_to_slot |
test eax,eax |
jz .not_found |
mov ecx,eax |
cli |
call sysfn_terminate |
mov [application_table_status],0 |
sti |
and dword [esp+32],0 |
ret |
.not_found: |
mov [application_table_status],0 |
or dword [esp+32],-1 |
ret |
sysfn_activate: ; 18.3 = ACTIVATE WINDOW |
cmp ecx,2 |
jb .nowindowactivate |
cmp ecx,[TASK_COUNT] |
ja .nowindowactivate |
mov [window_minimize], 2 ; restore window if minimized |
movzx esi, word [WIN_STACK + ecx*2] |
cmp esi, [TASK_COUNT] |
je .nowindowactivate ; already active |
mov edi, ecx |
shl edi, 5 |
add edi, window_data |
movzx esi, word [WIN_STACK + ecx * 2] |
lea esi, [WIN_POS + esi * 2] |
call waredraw |
.nowindowactivate: |
ret |
sysfn_getidletime: ; 18.4 = GET IDLETIME |
mov eax,[idleusesec] |
mov [esp+32], eax |
ret |
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC |
mov eax,[CPU_FREQ] |
mov [esp+32], eax |
ret |
; SAVE ramdisk to /hd/1/menuet.img |
;!!!!!!!!!!!!!!!!!!!!!!!! |
include 'blkdev/rdsave.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!! |
align 4 |
sysfn_getactive: ; 18.7 = get active window |
mov eax, [TASK_COUNT] |
movzx eax, word [WIN_POS + eax*2] |
mov [esp+32],eax |
ret |
sysfn_sound_flag: ; 18.8 = get/set sound_flag |
; cmp ecx,1 |
dec ecx |
jnz nogetsoundflag |
movzx eax,byte [sound_flag] ; get sound_flag |
mov [esp+32],eax |
ret |
nogetsoundflag: |
; cmp ecx,2 |
dec ecx |
jnz nosoundflag |
xor byte [sound_flag], 1 |
nosoundflag: |
ret |
sysfn_minimize: ; 18.10 = minimize window |
mov [window_minimize],1 |
ret |
align 4 |
sysfn_getdiskinfo: ; 18.11 = get disk info table |
; cmp ecx,1 |
dec ecx |
jnz full_table |
small_table: |
call for_all_tables |
mov ecx,10 |
cld |
rep movsb |
ret |
for_all_tables: |
mov edi,edx |
mov esi,DRIVE_DATA |
ret |
full_table: |
; cmp ecx,2 |
dec ecx |
jnz exit_for_anyone |
call for_all_tables |
mov ecx,16384 |
cld |
rep movsd |
ret |
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) |
and dword [esp+32], 0 |
ret |
sysfn_getversion: ; 18.13 = get kernel ID and version |
mov edi,ebx |
mov esi,version_inf |
mov ecx,version_end-version_inf |
rep movsb |
ret |
sysfn_waitretrace: ; 18.14 = sys wait retrace |
;wait retrace functions |
sys_wait_retrace: |
mov edx,0x3da |
WaitRetrace_loop: |
in al,dx |
test al,1000b |
jz WaitRetrace_loop |
and [esp+32],dword 0 |
ret |
align 4 |
sysfn_centermouse: ; 18.15 = mouse centered |
; removed here by <Lrz> |
; call mouse_centered |
;* mouse centered - start code- Mario79 |
;mouse_centered: |
; push eax |
mov eax,[Screen_Max_X] |
shr eax,1 |
mov [MOUSE_X],ax |
mov eax,[Screen_Max_Y] |
shr eax,1 |
mov [MOUSE_Y],ax |
; ret |
;* mouse centered - end code- Mario79 |
xor eax,eax |
and [esp+32],eax |
; pop eax |
ret |
align 4 |
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features |
test ecx,ecx ; get mouse speed factor |
jnz .set_mouse_acceleration |
xor eax,eax |
mov ax,[mouse_speed_factor] |
mov [esp+32],eax |
ret |
.set_mouse_acceleration: |
; cmp ecx,1 ; set mouse speed factor |
dec ecx |
jnz .get_mouse_delay |
mov [mouse_speed_factor],dx |
ret |
.get_mouse_delay: |
; cmp ecx,2 ; get mouse delay |
dec ecx |
jnz .set_mouse_delay |
mov eax,[mouse_delay] |
mov [esp+32],eax |
ret |
.set_mouse_delay: |
; cmp ecx,3 ; set mouse delay |
dec ecx |
jnz .set_pointer_position |
mov [mouse_delay],edx |
ret |
.set_pointer_position: |
; cmp ecx,4 ; set mouse pointer position |
dec ecx |
jnz .set_mouse_button |
mov [MOUSE_Y],dx ;y |
ror edx,16 |
mov [MOUSE_X],dx ;x |
rol edx,16 |
ret |
.set_mouse_button: |
; cmp ecx,5 ; set mouse button features |
dec ecx |
jnz .end |
mov [BTN_DOWN],dl |
mov [mouse_active],1 |
.end: |
ret |
sysfn_getfreemem: |
mov eax, [pg_data.pages_free] |
shl eax, 2 |
mov [esp+32],eax |
ret |
sysfn_getallmem: |
mov eax,[MEM_AMOUNT] |
shr eax, 10 |
mov [esp+32],eax |
ret |
; // Alver, 2007-22-08 // { |
sysfn_pid_to_slot: |
mov eax, ecx |
call pid_to_slot |
mov [esp+32], eax |
ret |
sysfn_min_rest_window: |
pushad |
mov eax, edx ; ebx - operating |
shr ecx, 1 |
jnc @f |
call pid_to_slot |
@@: |
or eax, eax ; eax - number of slot |
jz .error |
cmp eax, 255 ; varify maximal slot number |
ja .error |
movzx eax, word [WIN_STACK + eax*2] |
shr ecx, 1 |
jc .restore |
; .minimize: |
call minimize_window |
jmp .exit |
.restore: |
call restore_minimized_window |
.exit: |
popad |
xor eax, eax |
mov [esp+32], eax |
ret |
.error: |
popad |
xor eax, eax |
dec eax |
mov [esp+32], eax |
ret |
; } \\ Alver, 2007-22-08 \\ |
uglobal |
;// mike.dld, 2006-29-01 [ |
screen_workarea RECT |
;// mike.dld, 2006-29-01 ] |
window_minimize db 0 |
sound_flag db 0 |
endg |
iglobal |
version_inf: |
db 0,7,7,0 ; version 0.7.7.0 |
db UID_KOLIBRI |
dd __REV__ |
version_end: |
endg |
UID_NONE=0 |
UID_MENUETOS=1 ;official |
UID_KOLIBRI=2 ;russian |
sys_cachetodiskette: |
cmp ebx, 1 |
jne .no_floppy_a_save |
mov [flp_number], 1 |
jmp .save_image_on_floppy |
.no_floppy_a_save: |
cmp ebx, 2 |
jne .no_floppy_b_save |
mov [flp_number], 2 |
.save_image_on_floppy: |
call save_image |
mov [esp + 32], dword 0 |
cmp [FDC_Status], 0 |
je .yes_floppy_save |
.no_floppy_b_save: |
mov [esp + 32], dword 1 |
.yes_floppy_save: |
ret |
uglobal |
; bgrchanged dd 0x0 |
align 4 |
bgrlockpid dd 0 |
bgrlock db 0 |
endg |
sys_background: |
cmp ebx,1 ; BACKGROUND SIZE |
jnz nosb1 |
test ecx,ecx |
; cmp ecx,0 |
jz sbgrr |
test edx,edx |
; cmp edx,0 |
jz sbgrr |
@@: |
;;Maxis use atomic bts for mutexes 4.4.2009 |
bts dword [bgrlock], 0 |
jnc @f |
call change_task |
jmp @b |
@@: |
mov [BgrDataWidth],ecx |
mov [BgrDataHeight],edx |
; mov [bgrchanged],1 |
pushad |
; return memory for old background |
mov eax, [img_background] |
cmp eax, static_background_data |
jz @f |
stdcall kernel_free, eax |
@@: |
; calculate RAW size |
xor eax,eax |
inc eax |
cmp [BgrDataWidth],eax |
jae @f |
mov [BgrDataWidth],eax |
@@: |
cmp [BgrDataHeight],eax |
jae @f |
mov [BgrDataHeight],eax |
@@: |
mov eax,[BgrDataWidth] |
imul eax,[BgrDataHeight] |
lea eax,[eax*3] |
mov [mem_BACKGROUND],eax |
; get memory for new background |
stdcall kernel_alloc, eax |
test eax, eax |
jz .memfailed |
mov [img_background], eax |
jmp .exit |
.memfailed: |
; revert to static monotone data |
mov [img_background], static_background_data |
xor eax, eax |
inc eax |
mov [BgrDataWidth], eax |
mov [BgrDataHeight], eax |
mov [mem_BACKGROUND], 4 |
.exit: |
popad |
mov [bgrlock], 0 |
sbgrr: |
ret |
nosb1: |
cmp ebx,2 ; SET PIXEL |
jnz nosb2 |
mov eax, [img_background] |
test ecx, ecx |
jz @f |
cmp eax, static_background_data |
jz .ret |
@@: |
mov ebx, [mem_BACKGROUND] |
add ebx, 4095 |
and ebx, -4096 |
sub ebx, 4 |
cmp ecx, ebx |
ja .ret |
mov ebx,[eax+ecx] |
and ebx,0xFF000000 ;255*256*256*256 |
and edx,0x00FFFFFF ;255*256*256+255*256+255 |
add edx,ebx |
mov [eax+ecx],edx |
.ret: |
ret |
nosb2: |
cmp ebx,3 ; DRAW BACKGROUND |
jnz nosb3 |
draw_background_temp: |
; cmp [bgrchanged],1 ;0 |
; je nosb31 |
;draw_background_temp: |
; mov [bgrchanged],1 ;0 |
mov [background_defined], 1 |
call force_redraw_background |
mov [REDRAW_BACKGROUND], byte 2 |
nosb31: |
ret |
nosb3: |
cmp ebx,4 ; TILED / STRETCHED |
jnz nosb4 |
cmp ecx,[BgrDrawMode] |
je nosb41 |
mov [BgrDrawMode],ecx |
; mov [bgrchanged],1 |
nosb41: |
ret |
nosb4: |
cmp ebx,5 ; BLOCK MOVE TO BGR |
jnz nosb5 |
cmp [img_background], static_background_data |
jnz @f |
test edx, edx |
jnz .fin |
cmp esi, 4 |
ja .fin |
@@: |
; bughere |
mov eax, ecx |
mov ebx, edx |
add ebx, [img_background] ;IMG_BACKGROUND |
mov ecx, esi |
call memmove |
.fin: |
ret |
nosb5: |
cmp ebx, 6 |
jnz nosb6 |
;;Maxis use atomic bts for mutex 4.4.2009 |
@@: |
bts dword [bgrlock], 0 |
jnc @f |
call change_task |
jmp @b |
@@: |
mov eax, [CURRENT_TASK] |
mov [bgrlockpid], eax |
cmp [img_background], static_background_data |
jz .nomem |
stdcall user_alloc, [mem_BACKGROUND] |
mov [esp+32], eax |
test eax, eax |
jz .nomem |
mov ebx, eax |
shr ebx, 12 |
or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK |
mov esi, [img_background] |
shr esi, 12 |
mov ecx, [mem_BACKGROUND] |
add ecx, 0xFFF |
shr ecx, 12 |
.z: |
mov eax, [page_tabs+ebx*4] |
test al, 1 |
jz @f |
call free_page |
@@: |
mov eax, [page_tabs+esi*4] |
or al, PG_UW |
mov [page_tabs+ebx*4], eax |
mov eax, ebx |
shl eax, 12 |
invlpg [eax] |
inc ebx |
inc esi |
loop .z |
ret |
.nomem: |
and [bgrlockpid], 0 |
mov [bgrlock], 0 |
nosb6: |
cmp ebx, 7 |
jnz nosb7 |
cmp [bgrlock], 0 |
jz .err |
mov eax, [CURRENT_TASK] |
cmp [bgrlockpid], eax |
jnz .err |
mov eax, ecx |
mov ebx, ecx |
shr eax, 12 |
mov ecx, [page_tabs+(eax-1)*4] |
test cl, USED_BLOCK+DONT_FREE_BLOCK |
jz .err |
jnp .err |
push eax |
shr ecx, 12 |
dec ecx |
@@: |
and dword [page_tabs+eax*4], 0 |
mov edx, eax |
shl edx, 12 |
push eax |
invlpg [edx] |
pop eax |
inc eax |
loop @b |
pop eax |
and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK |
stdcall user_free, ebx |
mov [esp+32], eax |
and [bgrlockpid], 0 |
mov [bgrlock], 0 |
ret |
.err: |
and dword [esp+32], 0 |
ret |
nosb7: |
ret |
force_redraw_background: |
and [draw_data+32 + RECT.left],dword 0 |
and [draw_data+32 + RECT.top],dword 0 |
push eax ebx |
mov eax,[Screen_Max_X] |
mov ebx,[Screen_Max_Y] |
mov [draw_data+32 + RECT.right],eax |
mov [draw_data+32 + RECT.bottom],ebx |
pop ebx eax |
mov byte [REDRAW_BACKGROUND], 1 |
ret |
align 4 |
sys_getbackground: |
; cmp eax,1 ; SIZE |
dec ebx |
jnz nogb1 |
mov eax,[BgrDataWidth] |
shl eax,16 |
mov ax,[BgrDataHeight] |
mov [esp+32],eax |
ret |
nogb1: |
; cmp eax,2 ; PIXEL |
dec ebx |
jnz nogb2 |
mov eax, [img_background] |
test ecx, ecx |
jz @f |
cmp eax, static_background_data |
jz .ret |
@@: |
mov ebx, [mem_BACKGROUND] |
add ebx, 4095 |
and ebx, -4096 |
sub ebx, 4 |
cmp ecx, ebx |
ja .ret |
mov eax,[ecx+eax] |
and eax, 0xFFFFFF |
mov [esp+32],eax |
.ret: |
ret |
nogb2: |
; cmp eax,4 ; TILED / STRETCHED |
dec ebx |
dec ebx |
jnz nogb4 |
mov eax,[BgrDrawMode] |
nogb4: |
mov [esp+32],eax |
ret |
align 4 |
sys_getkey: |
mov [esp + 32],dword 1 |
; test main buffer |
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK |
movzx ecx, word [WIN_STACK + ebx * 2] |
mov edx, [TASK_COUNT] |
cmp ecx, edx |
jne .finish |
cmp [KEY_COUNT], byte 0 |
je .finish |
movzx eax, byte [KEY_BUFF] |
shl eax, 8 |
push eax |
dec byte [KEY_COUNT] |
and byte [KEY_COUNT], 127 |
movzx ecx, byte [KEY_COUNT] |
add ecx, 2 |
mov eax, KEY_BUFF + 1 |
mov ebx, KEY_BUFF |
call memmove |
pop eax |
.ret_eax: |
mov [esp + 32], eax |
ret |
.finish: |
; test hotkeys buffer |
mov ecx, hotkey_buffer |
@@: |
cmp [ecx], ebx |
jz .found |
add ecx, 8 |
cmp ecx, hotkey_buffer + 120 * 8 |
jb @b |
ret |
.found: |
mov ax, [ecx + 6] |
shl eax, 16 |
mov ah, [ecx + 4] |
mov al, 2 |
and dword [ecx + 4], 0 |
and dword [ecx], 0 |
jmp .ret_eax |
align 4 |
sys_getbutton: |
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK |
mov [esp + 32], dword 1 |
movzx ecx, word [WIN_STACK + ebx * 2] |
mov edx, [TASK_COUNT] ; less than 256 processes |
cmp ecx, edx |
jne .exit |
movzx eax, byte [BTN_COUNT] |
test eax, eax |
jz .exit |
mov eax, [BTN_BUFF] |
shl eax, 8 |
; // Alver 22.06.2008 // { |
mov al, byte [btn_down_determ] |
and al,0xFE ; delete left button bit |
; } \\ Alver \\ |
mov [BTN_COUNT], byte 0 |
mov [esp + 32], eax |
.exit: |
ret |
align 4 |
sys_cpuusage: |
; RETURN: |
; |
; +00 dword process cpu usage |
; +04 word position in windowing stack |
; +06 word windowing stack value at current position (cpu nro) |
; +10 12 bytes name |
; +22 dword start in mem |
; +26 dword used mem |
; +30 dword PID , process idenfification number |
; |
cmp ecx,-1 ; who am I ? |
jne .no_who_am_i |
mov ecx,[CURRENT_TASK] |
.no_who_am_i: |
cmp ecx, max_processes |
ja .nofillbuf |
; +4: word: position of the window of thread in the window stack |
mov ax, [WIN_STACK + ecx * 2] |
mov [ebx+4], ax |
; +6: word: number of the thread slot, which window has in the window stack |
; position ecx (has no relation to the specific thread) |
mov ax, [WIN_POS + ecx * 2] |
mov [ebx+6], ax |
shl ecx, 5 |
; +0: dword: memory usage |
mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage] |
mov [ebx], eax |
; +10: 11 bytes: name of the process |
push ecx |
lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name] |
add ebx, 10 |
mov ecx, 11 |
call memmove |
pop ecx |
; +22: address of the process in memory |
; +26: size of used memory - 1 |
push edi |
lea edi, [ebx+12] |
xor eax, eax |
mov edx, 0x100000*16 |
cmp ecx, 1 shl 5 |
je .os_mem |
mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size] |
mov eax, std_application_base_address |
.os_mem: |
stosd |
lea eax, [edx-1] |
stosd |
; +30: PID/TID |
mov eax, [ecx+CURRENT_TASK+TASKDATA.pid] |
stosd |
; window position and size |
push esi |
lea esi, [ecx + window_data + WDATA.box] |
movsd |
movsd |
movsd |
movsd |
; Process state (+50) |
mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state] |
stosd |
; Window client area box |
lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox] |
movsd |
movsd |
movsd |
movsd |
; Window state |
mov al, [ecx+window_data+WDATA.fl_wstate] |
stosb |
pop esi |
pop edi |
.nofillbuf: |
; return number of processes |
mov eax,[TASK_COUNT] |
mov [esp+32],eax |
ret |
align 4 |
sys_clock: |
cli |
; Mikhail Lisovin xx Jan 2005 |
@@: mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
jns @f |
mov esi, 1 |
call delay_ms |
jmp @b |
@@: |
; end Lisovin's fix |
xor al,al ; seconds |
out 0x70,al |
in al,0x71 |
movzx ecx,al |
mov al,02 ; minutes |
shl ecx,16 |
out 0x70,al |
in al,0x71 |
movzx edx,al |
mov al,04 ; hours |
shl edx,8 |
out 0x70,al |
in al,0x71 |
add ecx,edx |
movzx edx,al |
add ecx,edx |
sti |
mov [esp + 32], ecx |
ret |
align 4 |
sys_date: |
cli |
@@: mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
jns @f |
mov esi, 1 |
call delay_ms |
jmp @b |
@@: |
mov ch,0 |
mov al,7 ; date |
out 0x70,al |
in al,0x71 |
mov cl,al |
mov al,8 ; month |
shl ecx,16 |
out 0x70,al |
in al,0x71 |
mov ch,al |
mov al,9 ; year |
out 0x70,al |
in al,0x71 |
mov cl,al |
sti |
mov [esp+32], ecx |
ret |
; redraw status |
sys_redrawstat: |
cmp ebx, 1 |
jne no_widgets_away |
; buttons away |
mov ecx,[CURRENT_TASK] |
sys_newba2: |
mov edi,[BTN_ADDR] |
cmp [edi], dword 0 ; empty button list ? |
je end_of_buttons_away |
movzx ebx, word [edi] |
inc ebx |
mov eax,edi |
sys_newba: |
dec ebx |
jz end_of_buttons_away |
add eax, 0x10 |
cmp cx, [eax] |
jnz sys_newba |
push eax ebx ecx |
mov ecx,ebx |
inc ecx |
shl ecx, 4 |
mov ebx, eax |
add eax, 0x10 |
call memmove |
dec dword [edi] |
pop ecx ebx eax |
jmp sys_newba2 |
end_of_buttons_away: |
ret |
no_widgets_away: |
cmp ebx, 2 |
jnz srl1 |
mov edx, [TASK_BASE] ; return whole screen draw area for this app |
add edx, draw_data - CURRENT_TASK |
mov [edx + RECT.left], 0 |
mov [edx + RECT.top], 0 |
mov eax, [Screen_Max_X] |
mov [edx + RECT.right], eax |
mov eax, [Screen_Max_Y] |
mov [edx + RECT.bottom], eax |
mov edi, [TASK_BASE] |
or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app |
call sys_window_mouse |
ret |
srl1: |
ret |
sys_drawwindow: |
mov eax,edx |
shr eax,16+8 |
and eax,15 |
; cmp eax,0 ; type I - original style |
jne nosyswI |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call drawwindow_I |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswI: |
cmp al,1 ; type II - only reserve area, no draw |
jne nosyswII |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call sys_window_mouse |
dec [mouse_pause] |
call [draw_pointer] |
ret |
nosyswII: |
cmp al,2 ; type III - new style |
jne nosyswIII |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call drawwindow_III |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswIII: |
cmp al,3 ; type IV - skinned window |
je draw_skin_window |
cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window} |
jne nosyswV |
draw_skin_window: |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
mov eax, [TASK_COUNT] |
movzx eax, word [WIN_POS + eax*2] |
cmp eax, [CURRENT_TASK] |
setz al |
movzx eax, al |
push eax |
call drawwindow_IV |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswV: |
ret |
draw_window_caption: |
inc [mouse_pause] |
call [_display.disable_mouse] |
xor eax,eax |
mov edx,[TASK_COUNT] |
movzx edx,word[WIN_POS+edx*2] |
cmp edx,[CURRENT_TASK] |
jne @f |
inc eax |
@@: mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx ebx,[edx+WDATA.fl_wstyle] |
and bl,0x0F |
cmp bl,3 |
je .draw_caption_style_3 ;{for 3 and 4 style write caption} |
cmp bl,4 |
je .draw_caption_style_3 |
jmp .not_style_3 |
.draw_caption_style_3: |
push edx |
call drawwindow_IV_caption |
add esp,4 |
jmp .2 |
.not_style_3: |
cmp bl,2 |
jne .not_style_2 |
call drawwindow_III_caption |
jmp .2 |
.not_style_2: |
cmp bl,0 |
jne .2 |
call drawwindow_I_caption |
;-------------------------------------------------------------- |
.2: ;jmp @f |
mov edi,[CURRENT_TASK] |
shl edi,5 |
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
jz @f |
mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] |
or edx,edx |
jz @f |
movzx eax,[edi+window_data+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,3 |
je .skinned |
cmp al,4 |
je .skinned |
jmp .not_skinned |
.skinned: |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub ax,[_skinmargins.left] |
sub ax,[_skinmargins.right] |
push edx |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
pop edx |
or eax,eax |
js @f |
mov esi,eax |
mov ebx,dword[_skinmargins.left-2] |
mov bx,word[_skinh] |
sub bx,[_skinmargins.bottom] |
sub bx,[_skinmargins.top] |
sar bx,1 |
adc bx,0 |
add bx,[_skinmargins.top] |
add bx,-3 |
add ebx,ebp |
jmp .dodraw |
.not_skinned: |
cmp al,1 |
je @f |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub eax,16 |
push edx |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
pop edx |
or eax,eax |
js @f |
mov esi,eax |
mov ebx,0x00080007 |
add ebx,ebp |
.dodraw: |
mov ecx,[common_colours+16];0x00FFFFFF |
or ecx, 0x80000000 |
xor edi,edi |
; // Alver 22.06.2008 // { |
; call dtext |
call dtext_asciiz_esi |
; } \\ Alver \\ |
@@: |
;-------------------------------------------------------------- |
dec [mouse_pause] |
call [draw_pointer] |
ret |
iglobal |
align 4 |
window_topleft dd \ |
1, 21,\ ;type 0 |
0, 0,\ ;type 1 |
5, 20,\ ;type 2 |
5, ?,\ ;type 3 {set by skin} |
5, ? ;type 4 {set by skin} |
endg |
set_window_clientbox: |
push eax ecx edi |
mov eax,[_skinh] |
mov [window_topleft+4*7],eax |
mov [window_topleft+4*9],eax |
mov ecx,edi |
sub edi,window_data |
shl edi,3 |
test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE |
jz @f |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
mov eax,[eax*8+window_topleft+0] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
shl eax,1 |
neg eax |
add eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
push [eax*8+window_topleft+0] |
mov eax,[eax*8+window_topleft+4] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
neg eax |
sub eax,[esp] |
add eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
add esp,4 |
pop edi ecx eax |
ret |
@@: |
xor eax,eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
mov eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
mov eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
pop edi ecx eax |
ret |
sys_set_window: |
mov eax,[CURRENT_TASK] |
shl eax,5 |
add eax,window_data |
; colors |
mov [eax+WDATA.cl_workarea],edx |
mov [eax+WDATA.cl_titlebar],esi |
mov [eax+WDATA.cl_frames],edi |
mov edi, eax |
; check flag (?) |
test [edi+WDATA.fl_wdrawn],1 |
jnz newd |
mov eax,[timer_ticks] ;[0xfdf0] |
add eax,100 |
mov [new_window_starting],eax |
movsx eax,bx |
mov [edi+WDATA.box.width],eax |
movsx eax,cx |
mov [edi+WDATA.box.height],eax |
sar ebx,16 |
sar ecx,16 |
mov [edi+WDATA.box.left],ebx |
mov [edi+WDATA.box.top],ecx |
call check_window_position |
push ecx esi edi ; save for window fullscreen/resize |
;mov esi,edi |
mov cl, [edi+WDATA.fl_wstyle] |
mov eax, [edi+WDATA.cl_frames] |
sub edi,window_data |
shl edi,3 |
add edi,SLOT_BASE |
and cl,0x0F |
mov [edi+APPDATA.wnd_caption],0 |
cmp cl,3 |
je set_APPDATA_wnd_caption |
cmp cl,4 ; {SPraid.simba} |
je set_APPDATA_wnd_caption |
jmp @f |
set_APPDATA_wnd_caption: |
mov [edi+APPDATA.wnd_caption],eax |
@@: mov esi,[esp+0] |
add edi, APPDATA.saved_box |
movsd |
movsd |
movsd |
movsd |
pop edi esi ecx |
mov esi, [CURRENT_TASK] |
movzx esi, word [WIN_STACK+esi*2] |
lea esi, [WIN_POS+esi*2] |
call waredraw |
;;; mov ebx, 1 |
;;; call delay_hs |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, [edi+WDATA.box.width] |
mov edx, [edi+WDATA.box.height] |
add ecx, eax |
add edx, ebx |
call calculatescreen |
mov [KEY_COUNT],byte 0 ; empty keyboard buffer |
mov [BTN_COUNT],byte 0 ; empty button buffer |
newd: |
call set_window_clientbox |
mov [edi+WDATA.fl_redraw],byte 0 ; no redraw |
mov edx,edi |
ret |
syscall_windowsettings: |
.set_window_caption: |
dec eax ; subfunction #1 - set window caption |
jnz .get_window_caption |
; NOTE: only window owner thread can set its caption, |
; so there's no parameter for PID/TID |
mov edi,[CURRENT_TASK] |
shl edi,5 |
; have to check if caption is within application memory limit |
; check is trivial, and if application resizes its memory, |
; caption still can become over bounds |
; diamond, 31.10.2006: check removed because with new memory manager |
; there can be valid data after APPDATA.mem_size bound |
; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size] |
; add ecx,255 ; max caption length |
; cmp ebx,ecx |
; ja .exit_fail |
mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ebx |
or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
call draw_window_caption |
xor eax,eax ; eax = 0 (success) |
ret |
.get_window_caption: |
dec eax ; subfunction #2 - get window caption |
jnz .exit_fail |
; not implemented yet |
.exit_fail: |
xor eax,eax |
inc eax ; eax = 1 (fail) |
ret |
sys_window_move: |
mov edi,[CURRENT_TASK] |
shl edi,5 |
add edi,window_data |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz .window_move_return |
push dword [edi + WDATA.box.left] ; save old coordinates |
push dword [edi + WDATA.box.top] |
push dword [edi + WDATA.box.width] |
push dword [edi + WDATA.box.height] |
cmp eax,-1 ; set new position and size |
je .no_x_reposition |
mov [edi + WDATA.box.left], eax |
.no_x_reposition: |
cmp ebx,-1 |
je .no_y_reposition |
mov [edi + WDATA.box.top], ebx |
.no_y_reposition: |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .no_y_resizing |
cmp ecx,-1 |
je .no_x_resizing |
mov [edi + WDATA.box.width], ecx |
.no_x_resizing: |
cmp edx,-1 |
je .no_y_resizing |
mov [edi + WDATA.box.height], edx |
.no_y_resizing: |
call check_window_position |
call set_window_clientbox |
pushad ; save for window fullscreen/resize |
mov esi,edi |
sub edi,window_data |
shr edi,5 |
shl edi,8 |
add edi, SLOT_BASE + APPDATA.saved_box |
mov ecx,4 |
cld |
rep movsd |
popad |
pushad ; calculcate screen at new position |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx,eax |
add edx,ebx |
call calculatescreen |
popad |
pop edx ; calculcate screen at old position |
pop ecx |
pop ebx |
pop eax |
add ecx,eax |
add edx,ebx |
mov [dlx],eax ; save for drawlimits |
mov [dly],ebx |
mov [dlxe],ecx |
mov [dlye],edx |
call calculatescreen |
mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw |
mov eax,edi ; redraw screen at old position |
xor esi,esi |
call redrawscreen |
mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
mov [MOUSE_DOWN],byte 0 ; react to mouse up/down |
call [draw_pointer] |
mov [window_move_pr],0 |
.window_move_return: |
ret |
uglobal |
window_move_pr dd 0x0 |
window_move_eax dd 0x0 |
window_move_ebx dd 0x0 |
window_move_ecx dd 0x0 |
window_move_edx dd 0x0 |
endg |
;ok - 100% work |
;nt - not tested |
;--------------------------------------------------------------------------------------------- |
;eax |
;0 - task switch counter. Ret switch counter in eax. Block. ok. |
;1 - change task. Ret nothing. Block. ok. |
;2 - performance control |
; ebx |
; 0 - enable or disable (inversion) PCE flag on CR4 for rdmpc in user mode. |
; returned new cr4 in eax. Ret cr4 in eax. Block. ok. |
; 1 - is cache enabled. Ret cr0 in eax if enabled else zero in eax. Block. ok. |
; 2 - enable cache. Ret 1 in eax. Ret nothing. Block. ok. |
; 3 - disable cache. Ret 0 in eax. Ret nothing. Block. ok. |
;eax |
;3 - rdmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. |
;4 - wrmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. |
;--------------------------------------------------------------------------------------------- |
sys_sheduler: |
; old sys_sheduler ;noname & halyavin |
; cmp eax,0 |
; je shed_counter |
; cmp eax,2 |
; je perf_control |
; cmp eax,3 |
; je rdmsr_instr |
; cmp eax,4 |
; je wrmsr_instr |
; cmp eax,1 |
; jne not_supported |
; call change_task ;delay,0 |
;rewritten by <Lrz> 15.11.2009 |
test eax,eax |
jz .shed_counter ;eax=0 |
dec eax |
jz change_task ;eax=1 |
dec eax |
jz .perf_control ;eax=2 |
dec eax |
jz .rdmsr_instr ;eax=3 |
dec eax |
jnz @f |
;wrmsr_instr ;eax=4 |
;.wrmsr_instr: |
;now counter in ecx |
;(edx:eax) esi:edi => edx:esi |
; Fast Call MSR can't be destroy |
; ® MSR_AMD_EFER ¬®¦® ¨§¬¥ïâì, â.ª. ¢ í⮬ ॣ¨áâॠ«¨è |
; ¢ª«îç îâáï/¢ëª«îç îâáï à áè¨à¥ë¥ ¢®§¬®¦®á⨠|
cmp ecx, MSR_SYSENTER_CS |
je @f |
cmp ecx, MSR_SYSENTER_ESP |
je @f |
cmp ecx, MSR_SYSENTER_EIP |
je @f |
cmp ecx, MSR_AMD_STAR |
je @f |
mov eax, esi |
wrmsr |
; mov [esp + 36], eax |
; mov [esp + 24], edx ;ret in ebx? |
@@: |
ret |
.shed_counter: |
mov eax,[context_counter] |
mov [esp+36],eax |
ret |
.perf_control: |
; inc eax ;now eax=3 |
add eax,3 ;restore eax=3 |
cmp ebx,eax |
je cache_disable |
dec eax |
cmp ebx,eax |
je cache_enable |
dec eax |
cmp ebx,eax |
je is_cache_enabled |
dec eax |
cmp ebx,eax |
je modify_pce |
ret |
.rdmsr_instr: |
;now counter in ecx |
;(edx:eax) esi:edi => edx:esi |
mov eax,esi |
rdmsr |
mov [esp+36],eax |
mov [esp+24],edx ;ret in ebx? |
ret |
cache_disable: |
mov eax,cr0 |
or eax,01100000000000000000000000000000b |
mov cr0,eax |
wbinvd ;set MESI |
ret |
cache_enable: |
mov eax,cr0 |
and eax,10011111111111111111111111111111b |
mov cr0,eax |
ret |
is_cache_enabled: |
mov eax,cr0 |
mov ebx,eax |
and eax,01100000000000000000000000000000b |
jz cache_disabled |
mov [esp+36],ebx |
cache_disabled: |
mov dword [esp+36],eax ;0 |
ret |
modify_pce: |
mov eax,cr4 |
; mov ebx,0 |
; or bx,100000000b ;pce |
; xor eax,ebx ;invert pce |
bts eax,8 ;pce=cr4[8] |
mov cr4,eax |
mov [esp+36],eax |
ret |
;--------------------------------------------------------------------------------------------- |
; check if pixel is allowed to be drawn |
checkpixel: |
push eax edx |
mov edx,[Screen_Max_X] ; screen x size |
inc edx |
imul edx, ebx |
add eax, [_WinMapAddress] |
mov dl, [eax+edx] ; lea eax, [...] |
xor ecx, ecx |
mov eax, [CURRENT_TASK] |
cmp al, dl |
setne cl |
pop edx eax |
ret |
iglobal |
cpustring db 'CPU',0 |
endg |
uglobal |
background_defined db 0 ; diamond, 11.04.2006 |
endg |
align 4 |
; check misc |
checkmisc: |
cmp [ctrl_alt_del], 1 |
jne nocpustart |
mov ebp, cpustring |
call fs_execute_from_sysdir |
mov [ctrl_alt_del], 0 |
nocpustart: |
cmp [mouse_active], 1 |
jne mouse_not_active |
mov [mouse_active], 0 |
xor edi, edi |
mov ecx, [TASK_COUNT] |
set_mouse_event: |
add edi, 256 |
or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b |
loop set_mouse_event |
mouse_not_active: |
cmp [REDRAW_BACKGROUND],byte 0 ; background update ? |
jz nobackgr |
cmp [background_defined], 0 |
jz nobackgr |
cmp [REDRAW_BACKGROUND], byte 2 |
jnz no_set_bgr_event |
xor edi, edi |
mov ecx, [TASK_COUNT] |
set_bgr_event: |
add edi, 256 |
or [edi+SLOT_BASE+APPDATA.event_mask], 16 |
loop set_bgr_event |
no_set_bgr_event: |
; mov [draw_data+32 + RECT.left],dword 0 |
; mov [draw_data+32 + RECT.top],dword 0 |
; mov eax,[Screen_Max_X] |
; mov ebx,[Screen_Max_Y] |
; mov [draw_data+32 + RECT.right],eax |
; mov [draw_data+32 + RECT.bottom],ebx |
call drawbackground |
mov [REDRAW_BACKGROUND],byte 0 |
mov [MOUSE_BACKGROUND],byte 0 |
nobackgr: |
; system shutdown request |
cmp [SYS_SHUTDOWN],byte 0 |
je noshutdown |
mov edx,[shutdown_processes] |
cmp [SYS_SHUTDOWN],dl |
jne no_mark_system_shutdown |
lea ecx,[edx-1] |
mov edx,OS_BASE+0x3040 |
jecxz @f |
markz: |
mov [edx+TASKDATA.state],byte 3 |
add edx,0x20 |
loop markz |
@@: |
no_mark_system_shutdown: |
call [_display.disable_mouse] |
dec byte [SYS_SHUTDOWN] |
je system_shutdown |
noshutdown: |
mov eax,[TASK_COUNT] ; termination |
mov ebx,TASK_DATA+TASKDATA.state |
mov esi,1 |
newct: |
mov cl,[ebx] |
cmp cl,byte 3 |
jz terminate |
cmp cl,byte 4 |
jz terminate |
add ebx,0x20 |
inc esi |
dec eax |
jnz newct |
ret |
; redraw screen |
redrawscreen: |
; eax , if process window_data base is eax, do not set flag/limits |
pushad |
push eax |
;;; mov ebx,2 |
;;; call delay_hs |
;mov ecx,0 ; redraw flags for apps |
xor ecx,ecx |
newdw2: |
inc ecx |
push ecx |
mov eax,ecx |
shl eax,5 |
add eax,window_data |
cmp eax,[esp+4] |
je not_this_task |
; check if window in redraw area |
mov edi,eax |
cmp ecx,1 ; limit for background |
jz bgli |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx,eax |
add edx,ebx |
mov ecx,[dlye] ; ecx = area y end ebx = window y start |
cmp ecx,ebx |
jb ricino |
mov ecx,[dlxe] ; ecx = area x end eax = window x start |
cmp ecx,eax |
jb ricino |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx, eax |
add edx, ebx |
mov eax,[dly] ; eax = area y start edx = window y end |
cmp edx,eax |
jb ricino |
mov eax,[dlx] ; eax = area x start ecx = window x end |
cmp ecx,eax |
jb ricino |
bgli: |
cmp ecx,1 |
jnz .az |
mov al,[REDRAW_BACKGROUND] |
cmp al,2 |
jz newdw8 |
test al,al |
jz .az |
lea eax,[edi+draw_data-window_data] |
mov ebx,[dlx] |
cmp ebx,[eax+RECT.left] |
jae @f |
mov [eax+RECT.left],ebx |
@@: |
mov ebx,[dly] |
cmp ebx,[eax+RECT.top] |
jae @f |
mov [eax+RECT.top],ebx |
@@: |
mov ebx,[dlxe] |
cmp ebx,[eax+RECT.right] |
jbe @f |
mov [eax+RECT.right],ebx |
@@: |
mov ebx,[dlye] |
cmp ebx,[eax+RECT.bottom] |
jbe @f |
mov [eax+RECT.bottom],ebx |
@@: |
jmp newdw8 |
.az: |
mov eax,edi |
add eax,draw_data-window_data |
mov ebx,[dlx] ; set limits |
mov [eax + RECT.left], ebx |
mov ebx,[dly] |
mov [eax + RECT.top], ebx |
mov ebx,[dlxe] |
mov [eax + RECT.right], ebx |
mov ebx,[dlye] |
mov [eax + RECT.bottom], ebx |
sub eax,draw_data-window_data |
cmp dword [esp],1 |
jne nobgrd |
mov byte [REDRAW_BACKGROUND], 1 |
newdw8: |
nobgrd: |
mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw |
ricino: |
not_this_task: |
pop ecx |
cmp ecx,[TASK_COUNT] |
jle newdw2 |
pop eax |
popad |
ret |
calculatebackground: ; background |
mov edi, [_WinMapAddress] ; set os to use all pixels |
mov eax,0x01010101 |
mov ecx, [_WinMapSize] |
shr ecx, 2 |
rep stosd |
mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! |
ret |
uglobal |
imax dd 0x0 |
endg |
delay_ms: ; delay in 1/1000 sec |
push eax |
push ecx |
mov ecx,esi |
; <CPU clock fix by Sergey Kuzmin aka Wildwest> |
imul ecx, 33941 |
shr ecx, 9 |
; </CPU clock fix> |
in al,0x61 |
and al,0x10 |
mov ah,al |
cld |
cnt1: in al,0x61 |
and al,0x10 |
cmp al,ah |
jz cnt1 |
mov ah,al |
loop cnt1 |
pop ecx |
pop eax |
ret |
set_app_param: |
mov edi, [TASK_BASE] |
mov eax, [edi + TASKDATA.event_mask] |
mov [edi + TASKDATA.event_mask], ebx |
mov [esp+32], eax |
ret |
delay_hs: ; delay in 1/100 secs |
; ebx = delay time |
push ecx |
push edx |
mov edx,[timer_ticks] |
newtic: |
mov ecx,[timer_ticks] |
sub ecx,edx |
cmp ecx,ebx |
jae zerodelay |
call change_task |
jmp newtic |
zerodelay: |
pop edx |
pop ecx |
ret |
align 16 ;very often call this subrutine |
memmove: ; memory move in bytes |
; eax = from |
; ebx = to |
; ecx = no of bytes |
test ecx, ecx |
jle .ret |
push esi edi ecx |
mov edi, ebx |
mov esi, eax |
test ecx, not 11b |
jz @f |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
and ecx, 11b |
jz .finish |
@@: |
rep movsb |
.finish: |
pop ecx edi esi |
.ret: |
ret |
; <diamond> Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead. |
;align 4 |
; |
;read_floppy_file: |
; |
;; as input |
;; |
;; eax pointer to file |
;; ebx file lenght |
;; ecx start 512 byte block number |
;; edx number of blocks to read |
;; esi pointer to return/work area (atleast 20 000 bytes) |
;; |
;; |
;; on return |
;; |
;; eax = 0 command succesful |
;; 1 no fd base and/or partition defined |
;; 2 yet unsupported FS |
;; 3 unknown FS |
;; 4 partition not defined at hd |
;; 5 file not found |
;; ebx = size of file |
; |
; mov edi,[TASK_BASE] |
; add edi,0x10 |
; add esi,[edi] |
; add eax,[edi] |
; |
; pushad |
; mov edi,esi |
; add edi,1024 |
; mov esi,0x100000+19*512 |
; sub ecx,1 |
; shl ecx,9 |
; add esi,ecx |
; shl edx,9 |
; mov ecx,edx |
; cld |
; rep movsb |
; popad |
; |
; mov [esp+36],eax |
; mov [esp+24],ebx |
; ret |
align 4 |
sys_programirq: |
mov eax, [TASK_BASE] |
add ebx, [eax + TASKDATA.mem_start] |
cmp ecx, 16 |
jae .not_owner |
mov edi, [eax + TASKDATA.pid] |
cmp edi, [irq_owner + 4 * ecx] |
je .spril1 |
.not_owner: |
xor ecx, ecx |
inc ecx |
jmp .end |
.spril1: |
shl ecx, 6 |
mov esi, ebx |
lea edi, [irq00read + ecx] |
push 16 |
pop ecx |
cld |
rep movsd |
.end: |
mov [esp+32], ecx |
ret |
align 4 |
get_irq_data: |
movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data |
xor bh, bh |
cmp ebx, 16 |
jae .not_owner |
mov edx, [4 * ebx + irq_owner] ; check for irq owner |
mov eax,[TASK_BASE] |
cmp edx,[eax+TASKDATA.pid] |
je gidril1 |
.not_owner: |
xor edx, edx |
dec edx |
jmp gid1 |
gidril1: |
shl ebx, 12 |
lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size |
mov edx, [eax] ; + 0x4 - data offset |
dec esi |
jz gid1 |
test edx, edx ; check if buffer is empty |
jz gid1 |
mov ebx, [eax + 0x4] |
mov edi, ecx |
mov ecx, 4000 ; buffer size, used frequently |
cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again |
jb @f |
xor ebx, ebx |
@@: |
lea esi, [ebx + edx] ; calculate data size and offset |
cld |
cmp esi, ecx ; if greater than the buffer size, begin cycle again |
jbe @f |
sub ecx, ebx |
sub edx, ecx |
lea esi, [eax + ebx + 0x10] |
rep movsb |
xor ebx, ebx |
@@: |
lea esi, [eax + ebx + 0x10] |
mov ecx, edx |
add ebx, edx |
rep movsb |
mov edx, [eax] |
mov [eax], ecx ; set data size to zero |
mov [eax + 0x4], ebx ; set data offset |
gid1: |
mov [esp+32], edx ; eax |
ret |
set_io_access_rights: |
push edi eax |
mov edi, tss._io_map_0 |
; mov ecx,eax |
; and ecx,7 ; offset in byte |
; shr eax,3 ; number of byte |
; add edi,eax |
; mov ebx,1 |
; shl ebx,cl |
test ebp,ebp |
; cmp ebp,0 ; enable access - ebp = 0 |
jnz siar1 |
; not ebx |
; and [edi],byte bl |
btr [edi], eax |
pop eax edi |
ret |
siar1: |
bts [edi], eax |
; or [edi],byte bl ; disable access - ebp = 1 |
pop eax edi |
ret |
;reserve/free group of ports |
; * eax = 46 - number function |
; * ebx = 0 - reserve, 1 - free |
; * ecx = number start arrea of ports |
; * edx = number end arrea of ports (include last number of port) |
;Return value: |
; * eax = 0 - succesful |
; * eax = 1 - error |
; * The system has reserve this ports: |
; 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (include last number of port). |
;destroys eax,ebx, ebp |
r_f_port_area: |
test ebx, ebx |
jnz free_port_area |
; je r_port_area |
; jmp free_port_area |
; r_port_area: |
; pushad |
cmp ecx,edx ; beginning > end ? |
ja rpal1 |
cmp edx,65536 |
jae rpal1 |
mov eax,[RESERVED_PORTS] |
test eax,eax ; no reserved areas ? |
je rpal2 |
cmp eax,255 ; max reserved |
jae rpal1 |
rpal3: |
mov ebx,eax |
shl ebx,4 |
add ebx,RESERVED_PORTS |
cmp ecx,[ebx+8] |
ja rpal4 |
cmp edx,[ebx+4] |
jae rpal1 |
; jb rpal4 |
; jmp rpal1 |
rpal4: |
dec eax |
jnz rpal3 |
jmp rpal2 |
rpal1: |
; popad |
; mov eax,1 |
xor eax,eax |
inc eax |
ret |
rpal2: |
; popad |
; enable port access at port IO map |
cli |
pushad ; start enable io map |
cmp edx,65536 ;16384 |
jae no_unmask_io ; jge |
mov eax,ecx |
; push ebp |
xor ebp,ebp ; enable - eax = port |
new_port_access: |
; pushad |
call set_io_access_rights |
; popad |
inc eax |
cmp eax,edx |
jbe new_port_access |
; pop ebp |
no_unmask_io: |
popad ; end enable io map |
sti |
mov eax,[RESERVED_PORTS] |
add eax,1 |
mov [RESERVED_PORTS],eax |
shl eax,4 |
add eax,RESERVED_PORTS |
mov ebx,[TASK_BASE] |
mov ebx,[ebx+TASKDATA.pid] |
mov [eax],ebx |
mov [eax+4],ecx |
mov [eax+8],edx |
xor eax, eax |
ret |
free_port_area: |
; pushad |
mov eax,[RESERVED_PORTS] ; no reserved areas ? |
test eax,eax |
jz frpal2 |
mov ebx,[TASK_BASE] |
mov ebx,[ebx+TASKDATA.pid] |
frpal3: |
mov edi,eax |
shl edi,4 |
add edi,RESERVED_PORTS |
cmp ebx,[edi] |
jne frpal4 |
cmp ecx,[edi+4] |
jne frpal4 |
cmp edx,[edi+8] |
jne frpal4 |
jmp frpal1 |
frpal4: |
dec eax |
jnz frpal3 |
frpal2: |
; popad |
inc eax |
ret |
frpal1: |
push ecx |
mov ecx,256 |
sub ecx,eax |
shl ecx,4 |
mov esi,edi |
add esi,16 |
cld |
rep movsb |
dec dword [RESERVED_PORTS] |
;popad |
;disable port access at port IO map |
; pushad ; start disable io map |
pop eax ;start port |
cmp edx,65536 ;16384 |
jge no_mask_io |
; mov eax,ecx |
xor ebp,ebp |
inc ebp |
new_port_access_disable: |
; pushad |
; mov ebp,1 ; disable - eax = port |
call set_io_access_rights |
; popad |
inc eax |
cmp eax,edx |
jbe new_port_access_disable |
no_mask_io: |
; popad ; end disable io map |
xor eax, eax |
ret |
reserve_free_irq: |
xor esi, esi |
inc esi |
cmp ecx, 16 |
jae ril1 |
push ecx |
lea ecx, [irq_owner + 4 * ecx] |
mov edx, [ecx] |
mov eax, [TASK_BASE] |
mov edi, [eax + TASKDATA.pid] |
pop eax |
dec ebx |
jnz reserve_irq |
cmp edx, edi |
jne ril1 |
dec esi |
mov [ecx], esi |
jmp ril1 |
reserve_irq: |
cmp dword [ecx], 0 |
jne ril1 |
mov ebx, [f_irqs + 4 * eax] |
stdcall attach_int_handler, eax, ebx, dword 0 |
mov [ecx], edi |
dec esi |
ril1: |
mov [esp+32], esi ; return in eax |
ret |
iglobal |
f_irqs: |
dd 0x0 |
dd 0x0 |
dd p_irq2 |
dd p_irq3 |
dd p_irq4 |
dd p_irq5 |
dd p_irq6 |
dd p_irq7 |
dd p_irq8 |
dd p_irq9 |
dd p_irq10 |
dd p_irq11 |
dd 0x0 |
dd 0x0 |
dd p_irq14 |
dd p_irq15 |
endg |
drawbackground: |
inc [mouse_pause] |
cmp [SCR_MODE],word 0x12 |
je dbrv20 |
dbrv12: |
cmp [SCR_MODE],word 0100000000000000b |
jge dbrv20 |
cmp [SCR_MODE],word 0x13 |
je dbrv20 |
call vesa12_drawbackground |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbrv20: |
cmp [BgrDrawMode],dword 1 |
jne bgrstr |
call vesa20_drawbackground_tiled |
dec [mouse_pause] |
call [draw_pointer] |
ret |
bgrstr: |
call vesa20_drawbackground_stretch |
dec [mouse_pause] |
call [draw_pointer] |
ret |
align 4 |
syscall_putimage: ; PutImage |
sys_putimage: |
test ecx,0x80008000 |
jnz .exit |
test ecx,0x0000FFFF |
jz .exit |
test ecx,0xFFFF0000 |
jnz @f |
.exit: |
ret |
@@: |
mov edi,[current_slot] |
add dx,word[edi+APPDATA.wnd_clientbox.top] |
rol edx,16 |
add dx,word[edi+APPDATA.wnd_clientbox.left] |
rol edx,16 |
.forced: |
push ebp esi 0 |
mov ebp, putimage_get24bpp |
mov esi, putimage_init24bpp |
sys_putimage_bpp: |
; call [disable_mouse] ; this will be done in xxx_putimage |
; mov eax, vga_putimage |
cmp [SCR_MODE], word 0x12 |
jz @f ;.doit |
mov eax, vesa12_putimage |
cmp [SCR_MODE], word 0100000000000000b |
jae @f |
cmp [SCR_MODE], word 0x13 |
jnz .doit |
@@: |
mov eax, vesa20_putimage |
.doit: |
inc [mouse_pause] |
call eax |
dec [mouse_pause] |
pop ebp esi ebp |
jmp [draw_pointer] |
syscall_putimage_palette: |
mov edi, esi |
mov esi, edx |
mov edx, ecx |
mov ecx, ebx |
mov ebx, eax |
sys_putimage_palette: |
; ebx = pointer to image |
; ecx = [xsize]*65536 + [ysize] |
; edx = [xstart]*65536 + [ystart] |
; esi = number of bits per pixel, must be 8, 24 or 32 |
; edi = pointer to palette |
; ebp = row delta |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] |
rol edx, 16 |
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] |
rol edx, 16 |
.forced: |
cmp esi, 1 |
jnz @f |
push edi |
mov eax, [edi+4] |
sub eax, [edi] |
push eax |
push dword [edi] |
push 0ffffff80h |
mov edi, esp |
call put_mono_image |
add esp, 12 |
pop edi |
ret |
@@: |
cmp esi, 2 |
jnz @f |
push edi |
push 0ffffff80h |
mov edi, esp |
call put_2bit_image |
pop eax |
pop edi |
ret |
@@: |
cmp esi, 4 |
jnz @f |
push edi |
push 0ffffff80h |
mov edi, esp |
call put_4bit_image |
pop eax |
pop edi |
ret |
@@: |
push ebp esi ebp |
cmp esi, 8 |
jnz @f |
mov ebp, putimage_get8bpp |
mov esi, putimage_init8bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 15 |
jnz @f |
mov ebp, putimage_get15bpp |
mov esi, putimage_init15bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 16 |
jnz @f |
mov ebp, putimage_get16bpp |
mov esi, putimage_init16bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 24 |
jnz @f |
mov ebp, putimage_get24bpp |
mov esi, putimage_init24bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 32 |
jnz @f |
mov ebp, putimage_get32bpp |
mov esi, putimage_init32bpp |
jmp sys_putimage_bpp |
@@: |
pop ebp esi ebp |
ret |
put_mono_image: |
push ebp esi ebp |
mov ebp, putimage_get1bpp |
mov esi, putimage_init1bpp |
jmp sys_putimage_bpp |
put_2bit_image: |
push ebp esi ebp |
mov ebp, putimage_get2bpp |
mov esi, putimage_init2bpp |
jmp sys_putimage_bpp |
put_4bit_image: |
push ebp esi ebp |
mov ebp, putimage_get4bpp |
mov esi, putimage_init4bpp |
jmp sys_putimage_bpp |
putimage_init24bpp: |
lea eax, [eax*3] |
putimage_init8bpp: |
ret |
align 16 |
putimage_get24bpp: |
movzx eax, byte [esi+2] |
shl eax, 16 |
mov ax, [esi] |
add esi, 3 |
ret 4 |
align 16 |
putimage_get8bpp: |
movzx eax, byte [esi] |
push edx |
mov edx, [esp+8] |
mov eax, [edx+eax*4] |
pop edx |
inc esi |
ret 4 |
putimage_init1bpp: |
add eax, ecx |
push ecx |
add eax, 7 |
add ecx, 7 |
shr eax, 3 |
shr ecx, 3 |
sub eax, ecx |
pop ecx |
ret |
align 16 |
putimage_get1bpp: |
push edx |
mov edx, [esp+8] |
mov al, [edx] |
add al, al |
jnz @f |
lodsb |
adc al, al |
@@: |
mov [edx], al |
sbb eax, eax |
and eax, [edx+8] |
add eax, [edx+4] |
pop edx |
ret 4 |
putimage_init2bpp: |
add eax, ecx |
push ecx |
add ecx, 3 |
add eax, 3 |
shr ecx, 2 |
shr eax, 2 |
sub eax, ecx |
pop ecx |
ret |
align 16 |
putimage_get2bpp: |
push edx |
mov edx, [esp+8] |
mov al, [edx] |
mov ah, al |
shr al, 6 |
shl ah, 2 |
jnz .nonewbyte |
lodsb |
mov ah, al |
shr al, 6 |
shl ah, 2 |
add ah, 1 |
.nonewbyte: |
mov [edx], ah |
mov edx, [edx+4] |
movzx eax, al |
mov eax, [edx+eax*4] |
pop edx |
ret 4 |
putimage_init4bpp: |
add eax, ecx |
push ecx |
add ecx, 1 |
add eax, 1 |
shr ecx, 1 |
shr eax, 1 |
sub eax, ecx |
pop ecx |
ret |
align 16 |
putimage_get4bpp: |
push edx |
mov edx, [esp+8] |
add byte [edx], 80h |
jc @f |
movzx eax, byte [edx+1] |
mov edx, [edx+4] |
and eax, 0x0F |
mov eax, [edx+eax*4] |
pop edx |
ret 4 |
@@: |
movzx eax, byte [esi] |
add esi, 1 |
mov [edx+1], al |
shr eax, 4 |
mov edx, [edx+4] |
mov eax, [edx+eax*4] |
pop edx |
ret 4 |
putimage_init32bpp: |
shl eax, 2 |
ret |
align 16 |
putimage_get32bpp: |
lodsd |
ret 4 |
putimage_init15bpp: |
putimage_init16bpp: |
add eax, eax |
ret |
align 16 |
putimage_get15bpp: |
; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000 |
push ecx edx |
movzx eax, word [esi] |
add esi, 2 |
mov ecx, eax |
mov edx, eax |
and eax, 0x1F |
and ecx, 0x1F shl 5 |
and edx, 0x1F shl 10 |
shl eax, 3 |
shl ecx, 6 |
shl edx, 9 |
or eax, ecx |
or eax, edx |
pop edx ecx |
ret 4 |
align 16 |
putimage_get16bpp: |
; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000 |
push ecx edx |
movzx eax, word [esi] |
add esi, 2 |
mov ecx, eax |
mov edx, eax |
and eax, 0x1F |
and ecx, 0x3F shl 5 |
and edx, 0x1F shl 11 |
shl eax, 3 |
shl ecx, 5 |
shl edx, 8 |
or eax, ecx |
or eax, edx |
pop edx ecx |
ret 4 |
; eax x beginning |
; ebx y beginning |
; ecx x end |
; edx y end |
; edi color |
__sys_drawbar: |
mov esi,[current_slot] |
add eax,[esi+APPDATA.wnd_clientbox.left] |
add ecx,[esi+APPDATA.wnd_clientbox.left] |
add ebx,[esi+APPDATA.wnd_clientbox.top] |
add edx,[esi+APPDATA.wnd_clientbox.top] |
.forced: |
inc [mouse_pause] |
; call [disable_mouse] |
cmp [SCR_MODE],word 0x12 |
je dbv20 |
sdbv20: |
cmp [SCR_MODE],word 0100000000000000b |
jge dbv20 |
cmp [SCR_MODE],word 0x13 |
je dbv20 |
call vesa12_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbv20: |
call vesa20_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
kb_read: |
push ecx edx |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kr_loop: |
in al,0x64 |
test al,1 |
jnz kr_ready |
loop kr_loop |
mov ah,1 |
jmp kr_exit |
kr_ready: |
push ecx |
mov ecx,32 |
kr_delay: |
loop kr_delay |
pop ecx |
in al,0x60 |
xor ah,ah |
kr_exit: |
pop edx ecx |
ret |
kb_write: |
push ecx edx |
mov dl,al |
; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
; kw_loop1: |
; in al,0x64 |
; test al,0x20 |
; jz kw_ok1 |
; loop kw_loop1 |
; mov ah,1 |
; jmp kw_exit |
; kw_ok1: |
in al,0x60 |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop: |
in al,0x64 |
test al,2 |
jz kw_ok |
loop kw_loop |
mov ah,1 |
jmp kw_exit |
kw_ok: |
mov al,dl |
out 0x60,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop3: |
in al,0x64 |
test al,2 |
jz kw_ok3 |
loop kw_loop3 |
mov ah,1 |
jmp kw_exit |
kw_ok3: |
mov ah,8 |
kw_loop4: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop5: |
in al,0x64 |
test al,1 |
jnz kw_ok4 |
loop kw_loop5 |
dec ah |
jnz kw_loop4 |
kw_ok4: |
xor ah,ah |
kw_exit: |
pop edx ecx |
ret |
kb_cmd: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_wait: |
in al,0x64 |
test al,2 |
jz c_send |
loop c_wait |
jmp c_error |
c_send: |
mov al,bl |
out 0x64,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_accept: |
in al,0x64 |
test al,2 |
jz c_ok |
loop c_accept |
c_error: |
mov ah,1 |
jmp c_exit |
c_ok: |
xor ah,ah |
c_exit: |
ret |
setmouse: ; set mousepicture -pointer |
; ps2 mouse enable |
mov [MOUSE_PICTURE],dword mousepointer |
cli |
ret |
if used _rdtsc |
_rdtsc: |
bt [cpu_caps], CAPS_TSC |
jnc ret_rdtsc |
rdtsc |
ret |
ret_rdtsc: |
mov edx,0xffffffff |
mov eax,0xffffffff |
ret |
end if |
rerouteirqs: |
cli |
mov al,0x11 ; icw4, edge triggered |
out 0x20,al |
call pic_delay |
out 0xA0,al |
call pic_delay |
mov al,0x20 ; generate 0x20 + |
out 0x21,al |
call pic_delay |
mov al,0x28 ; generate 0x28 + |
out 0xA1,al |
call pic_delay |
mov al,0x04 ; slave at irq2 |
out 0x21,al |
call pic_delay |
mov al,0x02 ; at irq9 |
out 0xA1,al |
call pic_delay |
mov al,0x01 ; 8086 mode |
out 0x21,al |
call pic_delay |
out 0xA1,al |
call pic_delay |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
mov ecx,0x1000 |
cld |
picl1: call pic_delay |
loop picl1 |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
cli |
ret |
pic_delay: |
jmp pdl1 |
pdl1: ret |
sys_msg_board_str: |
pushad |
@@: |
cmp [esi],byte 0 |
je @f |
mov eax,1 |
movzx ebx,byte [esi] |
call sys_msg_board |
inc esi |
jmp @b |
@@: |
popad |
ret |
sys_msg_board_byte: |
; in: al = byte to display |
; out: nothing |
; destroys: nothing |
pushad |
mov ecx, 2 |
shl eax, 24 |
jmp @f |
sys_msg_board_word: |
; in: ax = word to display |
; out: nothing |
; destroys: nothing |
pushad |
mov ecx, 4 |
shl eax, 16 |
jmp @f |
sys_msg_board_dword: |
; in: eax = dword to display |
; out: nothing |
; destroys: nothing |
pushad |
mov ecx, 8 |
@@: |
push ecx |
rol eax, 4 |
push eax |
and al, 0xF |
cmp al, 10 |
sbb al, 69h |
das |
mov bl, al |
xor eax, eax |
inc eax |
call sys_msg_board |
pop eax |
pop ecx |
loop @b |
popad |
ret |
uglobal |
msg_board_data: times 4096 db 0 |
msg_board_count dd 0x0 |
endg |
sys_msg_board: |
; eax=1 : write : bl byte to write |
; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al |
mov ecx, [msg_board_count] |
cmp eax, 1 |
jne .smbl1 |
if defined debug_com_base |
push dx ax |
@@: ; Wait for empty transmit register (yes, this slows down system..) |
mov dx, debug_com_base+5 |
in al, dx |
test al, 1 shl 5 |
jz @r |
mov dx, debug_com_base ; Output the byte |
mov al, bl |
out dx, al |
pop ax dx |
end if |
mov [msg_board_data+ecx],bl |
inc ecx |
and ecx, 4095 |
mov [msg_board_count], ecx |
mov [check_idle_semaphore], 5 |
ret |
.smbl1: |
cmp eax, 2 |
jne .smbl2 |
test ecx, ecx |
jz .smbl21 |
mov eax, msg_board_data+1 |
mov ebx, msg_board_data |
movzx edx, byte [ebx] |
call memmove |
dec [msg_board_count] |
mov [esp + 36], edx ;eax |
mov [esp + 24], dword 1 |
ret |
.smbl21: |
mov [esp+36], ecx |
mov [esp+24], ecx |
.smbl2: |
ret |
sys_process_def: |
mov edi, [CURRENT_TASK] |
dec eax ; 1 = set keyboard mode |
jne no_set_keyboard_setup |
shl edi,8 |
mov [edi+SLOT_BASE + APPDATA.keyboard_mode],bl |
ret |
no_set_keyboard_setup: |
dec eax ; 2 = get keyboard mode |
jne no_get_keyboard_setup |
shl edi,8 |
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode] |
mov [esp+36],eax |
ret |
no_get_keyboard_setup: |
dec eax ; 3 = get keyboard ctrl, alt, shift |
jne no_get_keyboard_cas |
; xor eax,eax |
; movzx eax,byte [shift] |
; movzx ebx,byte [ctrl] |
; shl ebx,2 |
; add eax,ebx |
; movzx ebx,byte [alt] |
; shl ebx,3 |
; add eax,ebx |
;// mike.dld [ |
mov eax, [kb_state] |
;// mike.dld ] |
mov [esp+36],eax |
ret |
no_get_keyboard_cas: |
dec eax |
jnz no_add_keyboard_hotkey |
mov eax, hotkey_list |
@@: |
cmp dword [eax+8], 0 |
jz .found_free |
add eax, 16 |
cmp eax, hotkey_list+16*256 |
jb @b |
mov dword [esp+36], 1 |
ret |
.found_free: |
mov [eax+8], edi |
mov [eax+4], ecx |
movzx ebx, bl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov ecx, [ebx] |
mov [eax], ecx |
mov [ebx], eax |
mov [eax+12], ebx |
jecxz @f |
mov [ecx+12], eax |
@@: |
and dword [esp+36], 0 |
ret |
no_add_keyboard_hotkey: |
dec eax |
jnz no_del_keyboard_hotkey |
movzx ebx, bl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov eax, [ebx] |
.scan: |
test eax, eax |
jz .notfound |
cmp [eax+8], edi |
jnz .next |
cmp [eax+4], ecx |
jz .found |
.next: |
mov eax, [eax] |
jmp .scan |
.notfound: |
mov dword [esp+36], 1 |
ret |
.found: |
mov ecx, [eax] |
jecxz @f |
mov edx, [eax+12] |
mov [ecx+12], edx |
@@: |
mov ecx, [eax+12] |
mov edx, [eax] |
mov [ecx], edx |
xor edx, edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax], edx |
mov [esp+36], edx |
ret |
no_del_keyboard_hotkey: |
ret |
align 4 |
sys_gs: ; direct screen access |
cmp eax,1 ; resolution |
jne no_gs1 |
mov eax,[Screen_Max_X] |
shl eax,16 |
mov ax,[Screen_Max_Y] |
add eax,0x00010001 |
mov [esp+36],eax |
ret |
no_gs1: |
cmp eax,2 ; bits per pixel |
jne no_gs2 |
movzx eax,byte [ScreenBPP] |
mov [esp+36],eax |
ret |
no_gs2: |
cmp eax,3 ; bytes per scanline |
jne no_gs3 |
mov eax,[BytesPerScanLine] |
mov [esp+36],eax |
ret |
no_gs3: |
or [esp+36],dword -1 |
ret |
align 4 ; PCI functions |
sys_pci: |
call pci_api |
mov [esp+36],eax |
ret |
align 4 ; system functions |
syscall_setpixel: ; SetPixel |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, [TASK_BASE] |
add eax, [edx-twdw+WDATA.box.left] |
add ebx, [edx-twdw+WDATA.box.top] |
mov edi, [current_slot] |
add eax, [edi+APPDATA.wnd_clientbox.left] |
add ebx, [edi+APPDATA.wnd_clientbox.top] |
xor edi, edi ; no force |
; mov edi, 1 |
call [_display.disable_mouse] |
jmp [putpixel] |
align 4 |
syscall_writetext: ; WriteText |
mov eax,[TASK_BASE] |
mov ebp,[eax-twdw+WDATA.box.left] |
push esi |
mov esi,[current_slot] |
add ebp,[esi+APPDATA.wnd_clientbox.left] |
shl ebp,16 |
add ebp,[eax-twdw+WDATA.box.top] |
add bp,word[esi+APPDATA.wnd_clientbox.top] |
pop esi |
add ebx,ebp |
mov eax,edi |
xor edi,edi |
jmp dtext |
align 4 |
syscall_openramdiskfile: ; OpenRamdiskFile |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, esi |
mov esi, 12 |
call fileread |
mov [esp+32], eax |
ret |
align 4 |
syscall_drawrect: ; DrawRect |
mov edi, edx ; color + gradient |
and edi, 0x80FFFFFF |
test bx, bx ; x.size |
je .drectr |
test cx, cx ; y.size |
je .drectr |
mov eax, ebx ; bad idea |
mov ebx, ecx |
movzx ecx, ax ; ecx - x.size |
shr eax, 16 ; eax - x.coord |
movzx edx, bx ; edx - y.size |
shr ebx, 16 ; ebx - y.coord |
mov esi, [current_slot] |
add eax, [esi + APPDATA.wnd_clientbox.left] |
add ebx, [esi + APPDATA.wnd_clientbox.top] |
add ecx, eax |
add edx, ebx |
jmp [drawbar] |
.drectr: |
ret |
align 4 |
syscall_getscreensize: ; GetScreenSize |
mov ax, [Screen_Max_X] |
shl eax, 16 |
mov ax, [Screen_Max_Y] |
mov [esp + 32], eax |
ret |
align 4 |
syscall_cdaudio: ; CD |
cmp ebx, 4 |
jb .audio |
jz .eject |
cmp ebx, 5 |
jnz .ret |
.load: |
call .reserve |
call LoadMedium |
;call .free |
jmp .free |
; ret |
.eject: |
call .reserve |
call clear_CD_cache |
call allow_medium_removal |
call EjectMedium |
; call .free |
jmp .free |
; ret |
.audio: |
call sys_cd_audio |
mov [esp+36-4],eax |
.ret: |
ret |
.reserve: |
call reserve_cd |
mov eax, ecx |
shr eax, 1 |
and eax, 1 |
inc eax |
mov [ChannelNumber], ax |
mov eax, ecx |
and eax, 1 |
mov [DiskNumber], al |
call reserve_cd_channel |
and ebx, 3 |
inc ebx |
mov [cdpos], ebx |
add ebx, ebx |
mov cl, 8 |
sub cl, bl |
mov al, [DRIVE_DATA+1] |
shr al, cl |
test al, 2 |
jz .free;.err |
ret |
.free: |
call free_cd_channel |
and [cd_status], 0 |
ret |
.err: |
call .free |
; pop eax |
ret |
align 4 |
syscall_getpixel: ; GetPixel |
mov ecx, [Screen_Max_X] |
inc ecx |
xor edx, edx |
mov eax, ebx |
div ecx |
mov ebx, edx |
xchg eax, ebx |
call dword [GETPIXEL] ; eax - x, ebx - y |
mov [esp + 32], ecx |
ret |
align 4 |
syscall_getarea: |
;eax = 36 |
;ebx = pointer to bufer for img BBGGRRBBGGRR... |
;ecx = [size x]*65536 + [size y] |
;edx = [start x]*65536 + [start y] |
pushad |
inc [mouse_pause] |
; Check of use of the hardware cursor. |
cmp [_display.disable_mouse],__sys_disable_mouse |
jne @f |
; Since the test for the coordinates of the mouse should not be used, |
; then use the call [disable_mouse] is not possible! |
cmp dword [MOUSE_VISIBLE],dword 0 |
jne @f |
pushf |
cli |
call draw_mouse_under |
popf |
mov [MOUSE_VISIBLE],dword 1 |
@@: |
mov edi,ebx |
mov eax,edx |
shr eax,16 |
mov ebx,edx |
and ebx,0xffff |
dec eax |
dec ebx |
; eax - x, ebx - y |
mov edx,ecx |
shr ecx,16 |
and edx,0xffff |
mov esi,ecx |
; ecx - size x, edx - size y |
mov ebp,edx |
dec ebp |
lea ebp,[ebp*3] |
imul ebp,esi |
mov esi,ecx |
dec esi |
lea esi,[esi*3] |
add ebp,esi |
add ebp,edi |
add ebx,edx |
.start_y: |
push ecx edx |
.start_x: |
push eax ebx ecx |
add eax,ecx |
call dword [GETPIXEL] ; eax - x, ebx - y |
mov [ebp],cx |
shr ecx,16 |
mov [ebp+2],cl |
pop ecx ebx eax |
sub ebp,3 |
dec ecx |
jnz .start_x |
pop edx ecx |
dec ebx |
dec edx |
jnz .start_y |
dec [mouse_pause] |
; Check of use of the hardware cursor. |
cmp [_display.disable_mouse],__sys_disable_mouse |
jne @f |
call [draw_pointer] |
@@: |
popad |
ret |
align 4 |
syscall_drawline: ; DrawLine |
mov edi, [TASK_BASE] |
movzx eax, word[edi-twdw+WDATA.box.left] |
mov ebp, eax |
mov esi, [current_slot] |
add ebp, [esi+APPDATA.wnd_clientbox.left] |
add ax, word[esi+APPDATA.wnd_clientbox.left] |
add ebp,ebx |
shl eax, 16 |
movzx ebx, word[edi-twdw+WDATA.box.top] |
add eax, ebp |
mov ebp, ebx |
add ebp, [esi+APPDATA.wnd_clientbox.top] |
add bx, word[esi+APPDATA.wnd_clientbox.top] |
add ebp, ecx |
shl ebx, 16 |
xor edi, edi |
add ebx, ebp |
mov ecx, edx |
jmp [draw_line] |
align 4 |
syscall_getirqowner: ; GetIrqOwner |
cmp ebx,16 |
jae .err |
cmp [irq_rights + 4 * ebx], dword 2 |
je .err |
mov eax,[4 * ebx + irq_owner] |
mov [esp+32],eax |
ret |
.err: |
or dword [esp+32], -1 |
ret |
align 4 |
syscall_reserveportarea: ; ReservePortArea and FreePortArea |
call r_f_port_area |
mov [esp+32],eax |
ret |
align 4 |
syscall_threads: ; CreateThreads |
call sys_threads |
mov [esp+36],eax |
ret |
align 4 |
stack_driver_stat: |
call app_stack_handler ; Stack status |
; mov [check_idle_semaphore],5 ; enable these for zero delay |
; call change_task ; between sent packet |
mov [esp+36],eax |
ret |
align 4 |
socket: ; Socket interface |
call app_socket_handler |
; mov [check_idle_semaphore],5 ; enable these for zero delay |
; call change_task ; between sent packet |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
align 4 |
read_from_hd: ; Read from hd - fn not in use |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
add ecx,[edi] |
add edx,[edi] |
call file_read |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
paleholder: |
ret |
align 4 |
set_screen: |
cmp eax, [Screen_Max_X] |
jne .set |
cmp edx, [Screen_Max_Y] |
jne .set |
ret |
.set: |
pushfd |
cli |
mov [Screen_Max_X], eax |
mov [Screen_Max_Y], edx |
mov [BytesPerScanLine], ecx |
mov [screen_workarea.right],eax |
mov [screen_workarea.bottom], edx |
push ebx |
push esi |
push edi |
pushad |
stdcall kernel_free, [_WinMapAddress] |
mov eax, [_display.width] |
mul [_display.height] |
mov [_WinMapSize], eax |
stdcall kernel_alloc, eax |
mov [_WinMapAddress], eax |
test eax, eax |
jz .epic_fail |
popad |
call repos_windows |
xor eax, eax |
xor ebx, ebx |
mov ecx, [Screen_Max_X] |
mov edx, [Screen_Max_Y] |
call calculatescreen |
pop edi |
pop esi |
pop ebx |
popfd |
ret |
.epic_fail: |
hlt ; Houston, we've had a problem |
; --------------- APM --------------------- |
apm_entry dp 0 |
apm_vf dd 0 |
align 4 |
sys_apm: |
cmp word [apm_vf], 0 ; Check APM BIOS enable |
jne @f |
or [esp + 48], byte 1 ; error |
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported |
ret |
@@: |
xchg eax, ecx |
xchg ebx, ecx |
cmp al, 3 |
ja @f |
and [esp + 48], byte 0xfe ; emulate func 0..3 as func 0 |
mov eax, [apm_vf] |
mov [esp + 36], eax |
shr eax, 16 |
mov [esp + 32], eax |
ret |
@@: |
mov esi, [master_tab+(OS_BASE shr 20)] |
xchg [master_tab], esi |
push esi |
mov edi, cr3 |
mov cr3, edi ;flush TLB |
call pword [apm_entry] ; call APM BIOS |
xchg eax, [esp] |
mov [master_tab], eax |
mov eax, cr3 |
mov cr3, eax |
pop eax |
mov [esp + 8 ], edi |
mov [esp + 12], esi |
mov [esp + 24], ebx |
mov [esp + 28], edx |
mov [esp + 32], ecx |
mov [esp + 36], eax |
setc al |
and [esp + 48], byte 0xfe |
or [esp + 48], al |
ret |
; ----------------------------------------- |
align 4 |
undefined_syscall: ; Undefined system call |
mov [esp + 32], dword -1 |
ret |
align 4 |
system_shutdown: ; shut down the system |
cmp byte [BOOT_VAR+0x9030], 1 |
jne @F |
ret |
@@: |
call stop_all_services |
push 3 ; stop playing cd |
pop eax |
call sys_cd_audio |
yes_shutdown_param: |
cli |
mov eax, kernel_file ; load kernel.mnt to 0x7000:0 |
push 12 |
pop esi |
xor ebx,ebx |
or ecx,-1 |
mov edx, OS_BASE+0x70000 |
call fileread |
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0 |
mov edi,OS_BASE+0x40000 |
mov ecx,1000 |
rep movsb |
mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff |
mov edi, OS_BASE |
mov ecx,0x10000/4 |
cld |
rep movsd |
call restorefatchain |
mov al, 0xFF |
out 0x21, al |
out 0xA1, al |
if 0 |
mov word [OS_BASE+0x467+0],pr_mode_exit |
mov word [OS_BASE+0x467+2],0x1000 |
mov al,0x0F |
out 0x70,al |
mov al,0x05 |
out 0x71,al |
mov al,0xFE |
out 0x64,al |
hlt |
jmp $-1 |
else |
cmp byte [OS_BASE + 0x9030], 2 |
jnz no_acpi_power_off |
; scan for RSDP |
; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA). |
movzx eax, word [OS_BASE + 0x40E] |
shl eax, 4 |
jz @f |
mov ecx, 1024/16 |
call scan_rsdp |
jnc .rsdp_found |
@@: |
; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh. |
mov eax, 0xE0000 |
mov ecx, 0x2000 |
call scan_rsdp |
jc no_acpi_power_off |
.rsdp_found: |
mov esi, [eax+16] ; esi contains physical address of the RSDT |
mov ebp, [ipc_tmp] |
stdcall map_page, ebp, esi, PG_MAP |
lea eax, [esi+1000h] |
lea edx, [ebp+1000h] |
stdcall map_page, edx, eax, PG_MAP |
and esi, 0xFFF |
add esi, ebp |
cmp dword [esi], 'RSDT' |
jnz no_acpi_power_off |
mov ecx, [esi+4] |
sub ecx, 24h |
jbe no_acpi_power_off |
shr ecx, 2 |
add esi, 24h |
.scan_fadt: |
lodsd |
mov ebx, eax |
lea eax, [ebp+2000h] |
stdcall map_page, eax, ebx, PG_MAP |
lea eax, [ebp+3000h] |
add ebx, 0x1000 |
stdcall map_page, eax, ebx, PG_MAP |
and ebx, 0xFFF |
lea ebx, [ebx+ebp+2000h] |
cmp dword [ebx], 'FACP' |
jz .fadt_found |
loop .scan_fadt |
jmp no_acpi_power_off |
.fadt_found: |
; ebx is linear address of FADT |
mov edi, [ebx+40] ; physical address of the DSDT |
lea eax, [ebp+4000h] |
stdcall map_page, eax, edi, PG_MAP |
lea eax, [ebp+5000h] |
lea esi, [edi+0x1000] |
stdcall map_page, eax, esi, PG_MAP |
and esi, 0xFFF |
sub edi, esi |
cmp dword [esi+ebp+4000h], 'DSDT' |
jnz no_acpi_power_off |
mov eax, [esi+ebp+4004h] ; DSDT length |
sub eax, 36+4 |
jbe no_acpi_power_off |
add esi, 36 |
.scan_dsdt: |
cmp dword [esi+ebp+4000h], '_S5_' |
jnz .scan_dsdt_cont |
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode |
jnz .scan_dsdt_cont |
mov dl, [esi+ebp+4000h+6] |
cmp dl, 4 ; _S5_ package must contain 4 bytes |
; ...in theory; in practice, VirtualBox has 2 bytes |
ja .scan_dsdt_cont |
cmp dl, 1 |
jb .scan_dsdt_cont |
lea esi, [esi+ebp+4000h+7] |
xor ecx, ecx |
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx |
jz @f |
cmp byte [esi], 0xA |
jnz no_acpi_power_off |
inc esi |
mov cl, [esi] |
@@: |
inc esi |
cmp dl, 2 |
jb @f |
cmp byte [esi], 0 |
jz @f |
cmp byte [esi], 0xA |
jnz no_acpi_power_off |
inc esi |
mov ch, [esi] |
@@: |
jmp do_acpi_power_off |
.scan_dsdt_cont: |
inc esi |
cmp esi, 0x1000 |
jb @f |
sub esi, 0x1000 |
add edi, 0x1000 |
push eax |
lea eax, [ebp+4000h] |
stdcall map_page, eax, edi, PG_MAP |
push PG_MAP |
lea eax, [edi+1000h] |
push eax |
lea eax, [ebp+5000h] |
push eax |
stdcall map_page |
pop eax |
@@: |
dec eax |
jnz .scan_dsdt |
jmp no_acpi_power_off |
do_acpi_power_off: |
mov edx, [ebx+48] |
test edx, edx |
jz .nosmi |
mov al, [ebx+52] |
out dx, al |
mov edx, [ebx+64] |
@@: |
in ax, dx |
test al, 1 |
jz @b |
.nosmi: |
and cx, 0x0707 |
shl cx, 2 |
or cx, 0x2020 |
mov edx, [ebx+64] |
in ax, dx |
and ax, 203h |
or ah, cl |
out dx, ax |
mov edx, [ebx+68] |
test edx, edx |
jz @f |
in ax, dx |
and ax, 203h |
or ah, ch |
out dx, ax |
@@: |
jmp $ |
no_acpi_power_off: |
mov word [OS_BASE+0x467+0],pr_mode_exit |
mov word [OS_BASE+0x467+2],0x1000 |
mov al,0x0F |
out 0x70,al |
mov al,0x05 |
out 0x71,al |
mov al,0xFE |
out 0x64,al |
hlt |
jmp $-1 |
scan_rsdp: |
add eax, OS_BASE |
.s: |
cmp dword [eax], 'RSD ' |
jnz .n |
cmp dword [eax+4], 'PTR ' |
jnz .n |
xor edx, edx |
xor esi, esi |
@@: |
add dl, [eax+esi] |
inc esi |
cmp esi, 20 |
jnz @b |
test dl, dl |
jz .ok |
.n: |
add eax, 10h |
loop .s |
stc |
.ok: |
ret |
end if |
include "data32.inc" |
__REV__ = __REV |
uglobals_size = $ - endofcode |
diff16 "end of kernel code",0,$ |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/dll.inc |
---|
0,0 → 1,1689 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
DRV_COMPAT equ 5 ;minimal required drivers version |
DRV_CURRENT equ 5 ;current drivers model version |
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT |
PID_KERNEL equ 1 ;os_idle thread |
align 4 |
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword |
push ebx |
mov ebx, [irq] ;irq num |
test ebx, ebx |
jz .err |
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's |
ja .err |
mov eax, [handler] |
test eax, eax |
jz .err |
cmp [irq_owner + 4 * ebx], 0 |
je @f |
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden |
test ecx, ecx |
jnz .err |
@@: |
mov [irq_tab+ebx*4], eax |
mov eax, [access_rights] |
mov [irq_rights + 4 * ebx], eax |
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel |
stdcall enable_irq, [irq] |
pop ebx |
mov eax, 1 |
ret |
.err: |
pop ebx |
xor eax, eax |
ret |
endp |
uglobal |
irq_rights rd 16 |
endg |
proc get_int_handler stdcall, irq:dword |
mov eax, [irq] |
cmp [irq_rights + 4 * eax], dword 1 |
ja .err |
mov eax, [irq_tab + 4 * eax] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc detach_int_handler |
ret |
endp |
align 4 |
proc enable_irq stdcall, irq_line:dword |
mov ebx, [irq_line] |
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
mov edx, 0xA1 |
sub ebx,8 |
@@: |
in al,dx |
btr eax, ebx |
out dx, al |
ret |
endp |
align 16 |
;; proc irq_serv |
irq_serv: |
.irq_1: |
push 1 |
jmp .main |
align 4 |
.irq_2: |
push 2 |
jmp .main |
align 4 |
.irq_3: |
push 3 |
jmp .main |
align 4 |
.irq_4: |
push 4 |
jmp .main |
align 4 |
.irq_5: |
push 5 |
jmp .main |
; align 4 |
; .irq_6: |
; push 6 |
; jmp .main |
align 4 |
.irq_7: |
push 7 |
jmp .main |
align 4 |
.irq_8: |
push 8 |
jmp .main |
align 4 |
.irq_9: |
push 9 |
jmp .main |
align 4 |
.irq_10: |
push 10 |
jmp .main |
align 4 |
.irq_11: |
push 11 |
jmp .main |
align 4 |
.irq_12: |
push 12 |
jmp .main |
; align 4 |
; .irq_13: |
; push 13 |
; jmp .main |
; align 4 |
; .irq_14: |
; push 14 |
; jmp .main |
; align 4 |
; .irq_15: |
; push 15 |
; jmp .main |
align 16 |
.main: |
save_ring3_context |
mov eax, [esp + 32] |
mov bx, app_data ;os_data |
mov ds, bx |
mov es, bx |
cmp [v86_irqhooks+eax*8], 0 |
jnz v86_irq |
mov ebx, [irq_tab+eax*4] |
test ebx, ebx |
jz .exit |
call ebx |
mov [check_idle_semaphore],5 |
.exit: |
cmp dword [esp + 32], 8 |
mov al, 0x20 |
jb @f |
out 0xa0, al |
@@: |
out 0x20, al |
restore_ring3_context |
add esp, 4 |
iret |
align 4 |
proc get_notify stdcall, p_ev:dword |
.wait: |
mov ebx,[current_slot] |
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY |
jz @f |
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY |
mov edi, [p_ev] |
mov dword [edi], EV_INTR |
mov eax, [ebx+APPDATA.event] |
mov dword [edi+4], eax |
ret |
@@: |
call change_task |
jmp .wait |
endp |
align 4 |
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 6 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop ebx |
ret |
endp |
align 4 |
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 5 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop ebx |
ret |
endp |
align 4 |
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 4 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop ebx |
ret |
endp |
align 4 |
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 8 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop ebx |
ret |
endp |
align 4 |
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 9 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop ebx |
ret |
endp |
align 4 |
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 10 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop ebx |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc srv_handler stdcall, ioctl:dword |
mov esi, [ioctl] |
test esi, esi |
jz .err |
mov edi, [esi+handle] |
cmp [edi+SRV.magic], ' SRV' |
jne .fail |
cmp [edi+SRV.size], SRV.sizeof |
jne .fail |
stdcall [edi+SRV.srv_proc], esi |
ret |
.fail: |
xor eax, eax |
not eax |
mov [esi+output], eax |
mov [esi+out_size], 4 |
ret |
.err: |
xor eax, eax |
not eax |
ret |
endp |
; param |
; ebx= io_control |
; |
; retval |
; eax= error code |
align 4 |
srv_handlerEx: |
cmp ebx, OS_BASE |
jae .fail |
mov eax, [ebx+handle] |
cmp [eax+SRV.magic], ' SRV' |
jne .fail |
cmp [eax+SRV.size], SRV.sizeof |
jne .fail |
stdcall [eax+SRV.srv_proc], ebx |
ret |
.fail: |
or eax, -1 |
ret |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc get_service stdcall, sz_name:dword |
mov eax, [sz_name] |
test eax, eax |
jnz @F |
ret |
@@: |
mov edx, [srv.fd] |
@@: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .not_load |
stdcall strncmp, edx, [sz_name], 16 |
test eax, eax |
je .ok |
mov edx, [edx+SRV.fd] |
jmp @B |
.not_load: |
pop ebp |
jmp load_driver |
.ok: |
mov eax, edx |
ret |
endp |
align 4 |
proc reg_service stdcall, name:dword, handler:dword |
push ebx |
xor eax, eax |
cmp [name], eax |
je .fail |
cmp [handler], eax |
je .fail |
mov eax, SRV.sizeof |
call malloc |
test eax, eax |
jz .fail |
push esi |
push edi |
mov edi, eax |
mov esi, [name] |
movsd |
movsd |
movsd |
movsd |
pop edi |
pop esi |
mov [eax+SRV.magic], ' SRV' |
mov [eax+SRV.size], SRV.sizeof |
mov ebx, srv.fd-SRV_FD_OFFSET |
mov edx, [ebx+SRV.fd] |
mov [eax+SRV.fd], edx |
mov [eax+SRV.bk], ebx |
mov [ebx+SRV.fd], eax |
mov [edx+SRV.bk], eax |
mov ecx, [handler] |
mov [eax+SRV.srv_proc], ecx |
pop ebx |
ret |
.fail: |
xor eax, eax |
pop ebx |
ret |
endp |
align 4 |
proc get_proc stdcall, exp:dword, sz_name:dword |
mov edx, [exp] |
.next: |
mov eax, [edx] |
test eax, eax |
jz .end |
push edx |
stdcall strncmp, eax, [sz_name], 16 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
align 4 |
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword |
@@: |
stdcall strncmp, [pSym], [sz_sym], 8 |
test eax,eax |
jz .ok |
add [pSym], 18 |
dec [count] |
jnz @b |
xor eax, eax |
ret |
.ok: |
mov eax, [pSym] |
mov eax, [eax+8] |
ret |
endp |
align 4 |
proc get_curr_task |
mov eax,[CURRENT_TASK] |
shl eax, 8 |
ret |
endp |
align 4 |
proc get_fileinfo stdcall, file_name:dword, info:dword |
locals |
cmd dd ? |
offset dd ? |
dd ? |
count dd ? |
buff dd ? |
db ? |
name dd ? |
endl |
xor eax, eax |
mov ebx, [file_name] |
mov ecx, [info] |
mov [cmd], 5 |
mov [offset], eax |
mov [offset+4], eax |
mov [count], eax |
mov [buff], ecx |
mov byte [buff+4], al |
mov [name], ebx |
mov eax, 70 |
lea ebx, [cmd] |
int 0x40 |
ret |
endp |
align 4 |
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ |
bytes:dword |
locals |
cmd dd ? |
offset dd ? |
dd ? |
count dd ? |
buff dd ? |
db ? |
name dd ? |
endl |
xor eax, eax |
mov ebx, [file_name] |
mov ecx, [off] |
mov edx, [bytes] |
mov esi, [buffer] |
mov [cmd], eax |
mov [offset], ecx |
mov [offset+4], eax |
mov [count], edx |
mov [buff], esi |
mov byte [buff+4], al |
mov [name], ebx |
pushad |
push eax |
lea eax, [cmd] |
call file_system_lfn |
pop eax |
popad |
ret |
endp |
; description |
; allocate kernel memory and loads the specified file |
; |
; param |
; file_name= full path to file |
; |
; retval |
; eax= file image in kernel memory |
; ebx= size of file |
; |
; warging |
; You mast call kernel_free() to delete each file |
; loaded by the load_file() function |
align 4 |
proc load_file stdcall, file_name:dword |
locals |
attr dd ? |
flags dd ? |
cr_time dd ? |
cr_date dd ? |
acc_time dd ? |
acc_date dd ? |
mod_time dd ? |
mod_date dd ? |
file_size dd ? |
file dd ? |
file2 dd ? |
endl |
push esi |
push edi |
lea eax, [attr] |
stdcall get_fileinfo, [file_name], eax |
test eax, eax |
jnz .fail |
mov eax, [file_size] |
cmp eax, 1024*1024*16 |
ja .fail |
stdcall kernel_alloc, [file_size] |
mov [file], eax |
stdcall read_file, [file_name], eax, dword 0, [file_size] |
cmp ebx, [file_size] |
jne .cleanup |
mov eax, [file] |
cmp dword [eax], 0x4B43504B |
jne .exit |
mov ebx, [eax+4] |
mov [file_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .cleanup |
mov [file2], eax |
pushfd |
cli |
stdcall unpack, [file], eax |
popfd |
stdcall kernel_free, [file] |
mov eax, [file2] |
mov ebx, [file_size] |
.exit: |
push eax |
lea edi, [eax+ebx] ;cleanup remain space |
mov ecx, 4096 ;from file end |
and ebx, 4095 |
jz @f |
sub ecx, ebx |
xor eax, eax |
cld |
rep stosb |
@@: |
mov ebx, [file_size] |
pop eax |
pop edi |
pop esi |
ret |
.cleanup: |
stdcall kernel_free, [file] |
.fail: |
xor eax, eax |
xor ebx, ebx |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc get_proc_ex stdcall, proc_name:dword, imports:dword |
.look_up: |
mov edx, [imports] |
test edx, edx |
jz .end |
mov edx, [edx] |
test edx, edx |
jz .end |
.next: |
mov eax, [edx] |
test eax, eax |
jz .next_table |
push edx |
stdcall strncmp, eax, [proc_name], 256 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.next_table: |
add [imports], 4 |
jmp .look_up |
.ok: |
mov eax, [edx+4] |
ret |
.end: |
xor eax, eax |
ret |
endp |
align 4 |
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\ |
sym_count:dword, strings:dword, imports:dword |
locals |
retval dd ? |
endl |
mov edi, [symbols] |
mov [retval], 1 |
.fix: |
movzx ebx, [edi+CSYM.SectionNumber] |
test ebx, ebx |
jnz .internal |
mov eax, dword [edi+CSYM.Name] |
test eax, eax |
jnz @F |
mov edi, [edi+4] |
add edi, [strings] |
@@: |
push edi |
stdcall get_proc_ex, edi,[imports] |
pop edi |
xor ebx, ebx |
test eax, eax |
jnz @F |
mov esi, msg_unresolved |
call sys_msg_board_str |
mov esi, edi |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov [retval],0 |
@@: |
mov edi, [symbols] |
mov [edi+CSYM.Value], eax |
jmp .next |
.internal: |
cmp bx, -1 |
je .next |
cmp bx, -2 |
je .next |
dec ebx |
shl ebx, 3 |
lea ebx, [ebx+ebx*4] |
add ebx, [sec] |
mov eax, [ebx+CFS.VirtualAddress] |
add [edi+CSYM.Value], eax |
.next: |
add edi, CSYM_SIZE |
mov [symbols], edi |
dec [sym_count] |
jnz .fix |
mov eax, [retval] |
ret |
endp |
align 4 |
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \ |
delta:dword |
locals |
n_sec dd ? |
endl |
mov eax, [coff] |
movzx ebx, [eax+CFH.nSections] |
mov [n_sec], ebx |
lea esi, [eax+20] |
.fix_sec: |
mov edi, [esi+CFS.PtrReloc] |
add edi, [coff] |
movzx ecx, [esi+CFS.NumReloc] |
test ecx, ecx |
jz .next |
.reloc_loop: |
mov ebx, [edi+CRELOC.SymIndex] |
add ebx,ebx |
lea ebx,[ebx+ebx*8] |
add ebx, [sym] |
mov edx, [ebx+CSYM.Value] |
cmp [edi+CRELOC.Type], 6 |
je .dir_32 |
cmp [edi+CRELOC.Type], 20 |
jne .next_reloc |
.rel_32: |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [esi+CFS.VirtualAddress] |
sub edx, eax |
sub edx, 4 |
jmp .fix |
.dir_32: |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [esi+CFS.VirtualAddress] |
.fix: |
add eax, [delta] |
add [eax], edx |
.next_reloc: |
add edi, 10 |
dec ecx |
jnz .reloc_loop |
.next: |
add esi, COFF_SECTION_SIZE |
dec [n_sec] |
jnz .fix_sec |
.exit: |
ret |
endp |
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \ |
delta:dword |
locals |
n_sec dd ? |
endl |
mov eax, [coff] |
movzx ebx, [eax+CFH.nSections] |
mov [n_sec], ebx |
lea esi, [eax+20] |
mov edx, [delta] |
.fix_sec: |
mov edi, [esi+CFS.PtrReloc] |
add edi, [coff] |
movzx ecx, [esi+CFS.NumReloc] |
test ecx, ecx |
jz .next |
.reloc_loop: |
cmp [edi+CRELOC.Type], 6 |
jne .next_reloc |
.dir_32: |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [esi+CFS.VirtualAddress] |
add [eax+edx], edx |
.next_reloc: |
add edi, 10 |
dec ecx |
jnz .reloc_loop |
.next: |
add esi, COFF_SECTION_SIZE |
dec [n_sec] |
jnz .fix_sec |
.exit: |
ret |
endp |
align 4 |
proc load_driver stdcall, driver_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
start dd ? |
exports dd ? ;fake exports table |
dd ? |
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj' |
endl |
lea edx, [file_name] |
mov dword [edx], '/sys' |
mov dword [edx+4], '/dri' |
mov dword [edx+8], 'vers' |
mov byte [edx+12], '/' |
mov esi, [driver_name] |
.redo: |
lea edx, [file_name] |
lea edi, [edx+13] |
mov ecx, 16 |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
loop @b |
@@: |
mov dword [edi], '.obj' |
mov byte [edi+4], 0 |
stdcall load_file, edx |
test eax, eax |
jz .exit |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edi, eax |
xor eax, eax |
mov ecx, [img_size] |
add ecx, 4095 |
and ecx, not 4095 |
shr ecx, 2 |
cld |
rep stosd |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15 |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea ebx, [exports] |
mov dword [ebx], kernel_export |
mov dword [ebx+4], 0 |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], ebx |
test eax, eax |
jz .link_fail |
mov ebx, [coff] |
stdcall fix_coff_relocs, ebx, [sym], 0 |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion |
test eax, eax |
jz .link_fail |
mov eax, [eax] |
shr eax, 16 |
cmp eax, DRV_COMPAT |
jb .ver_fail |
cmp eax, DRV_CURRENT |
ja .ver_fail |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART |
mov [start], eax |
stdcall kernel_free, [coff] |
mov ebx, [start] |
stdcall ebx, DRV_ENTRY |
test eax, eax |
jnz .ok |
stdcall kernel_free, [img_base] |
cmp dword [file_name+13], 'SOUN' |
jnz @f |
cmp dword [file_name+17], 'D.ob' |
jnz @f |
cmp word [file_name+21], 'j' |
jnz @f |
mov esi, aSis |
jmp .redo |
@@: |
xor eax, eax |
ret |
.ok: |
mov ebx, [img_base] |
mov [eax+SRV.base], ebx |
mov ecx, [start] |
mov [eax+SRV.entry], ecx |
ret |
.ver_fail: |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, msg_version |
call sys_msg_board_str |
mov esi, msg_www |
call sys_msg_board_str |
jmp .cleanup |
.link_fail: |
mov esi, msg_module |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
.cleanup: |
stdcall kernel_free,[img_base] |
.fail: |
stdcall kernel_free, [coff] |
.exit: |
xor eax, eax |
ret |
endp |
; in: edx -> COFF_SECTION struct |
; out: eax = alignment as mask for bits to drop |
coff_get_align: |
; Rules: |
; - if alignment is not given, use default = 4K; |
; - if alignment is given and is no more than 4K, use it; |
; - if alignment is more than 4K, revert to 4K. |
push ecx |
mov cl, byte [edx+CFS.Characteristics+2] |
mov eax, 1 |
shr cl, 4 |
dec cl |
js .default |
cmp cl, 12 |
jbe @f |
.default: |
mov cl, 12 |
@@: |
shl eax, cl |
pop ecx |
dec eax |
ret |
align 4 |
proc load_library stdcall, file_name:dword |
locals |
fullname rb 260 |
fileinfo rb 40 |
coff dd ? |
img_base dd ? |
endl |
cli |
; resolve file name |
mov ebx, [file_name] |
lea edi, [fullname+1] |
mov byte [edi-1], '/' |
stdcall get_full_file_name, edi, 259 |
test al, al |
jz .fail |
; scan for required DLL in list of already loaded for this process, |
; ignore timestamp |
mov esi, [CURRENT_TASK] |
shl esi, 8 |
lea edi, [fullname] |
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr] |
test ebx, ebx |
jz .not_in_process |
mov esi, [ebx+HDLL.fd] |
.scan_in_process: |
cmp esi, ebx |
jz .not_in_process |
mov eax, [esi+HDLL.parent] |
add eax, DLLDESCR.name |
stdcall strncmp, eax, edi, -1 |
test eax, eax |
jnz .next_in_process |
; simple variant: load DLL which is already loaded in this process |
; just increment reference counters and return address of exports table |
inc [esi+HDLL.refcount] |
mov ecx, [esi+HDLL.parent] |
inc [ecx+DLLDESCR.refcount] |
mov eax, [ecx+DLLDESCR.exports] |
sub eax, [ecx+DLLDESCR.defaultbase] |
add eax, [esi+HDLL.base] |
ret |
.next_in_process: |
mov esi, [esi+HDLL.fd] |
jmp .scan_in_process |
.not_in_process: |
; scan in full list, compare timestamp |
lea eax, [fileinfo] |
stdcall get_fileinfo, edi, eax |
test eax, eax |
jnz .fail |
mov esi, [dll_list.fd] |
.scan_for_dlls: |
cmp esi, dll_list |
jz .load_new |
lea eax, [esi+DLLDESCR.name] |
stdcall strncmp, eax, edi, -1 |
test eax, eax |
jnz .continue_scan |
.test_prev_dll: |
mov eax, dword [fileinfo+24] ; last modified time |
mov edx, dword [fileinfo+28] ; last modified date |
cmp dword [esi+DLLDESCR.timestamp], eax |
jnz .continue_scan |
cmp dword [esi+DLLDESCR.timestamp+4], edx |
jz .dll_already_loaded |
.continue_scan: |
mov esi, [esi+DLLDESCR.fd] |
jmp .scan_for_dlls |
; new DLL |
.load_new: |
; load file |
stdcall load_file, edi |
test eax, eax |
jz .fail |
mov [coff], eax |
mov dword [fileinfo+32], ebx |
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name |
mov esi, edi |
mov ecx, -1 |
xor eax, eax |
repnz scasb |
not ecx |
lea eax, [ecx+DLLDESCR.sizeof] |
push ecx |
call malloc |
pop ecx |
test eax, eax |
jz .fail_and_free_coff |
; save timestamp |
lea edi, [eax+DLLDESCR.name] |
rep movsb |
mov esi, eax |
mov eax, dword [fileinfo+24] |
mov dword [esi+DLLDESCR.timestamp], eax |
mov eax, dword [fileinfo+28] |
mov dword [esi+DLLDESCR.timestamp+4], eax |
; initialize DLLDESCR struct |
and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented |
mov [esi+DLLDESCR.fd], dll_list |
mov eax, [dll_list.bk] |
mov [dll_list.bk], esi |
mov [esi+DLLDESCR.bk], eax |
mov [eax+DLLDESCR.fd], esi |
; calculate size of loaded DLL |
mov edx, [coff] |
movzx ecx, [edx+CFH.nSections] |
xor ebx, ebx |
add edx, 20 |
@@: |
call coff_get_align |
add ebx, eax |
not eax |
and ebx, eax |
add ebx, [edx+CFS.SizeOfRawData] |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
; it must be nonzero and not too big |
mov [esi+DLLDESCR.size], ebx |
test ebx, ebx |
jz .fail_and_free_dll |
cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR |
ja .fail_and_free_dll |
; allocate memory for kernel-side image |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .fail_and_free_dll |
mov [esi+DLLDESCR.data], eax |
; calculate preferred base address |
add ebx, 0x1FFF |
and ebx, not 0xFFF |
mov ecx, [dll_cur_addr] |
lea edx, [ecx+ebx] |
cmp edx, MAX_DEFAULT_DLL_ADDR |
jb @f |
mov ecx, MIN_DEFAULT_DLL_ADDR |
lea edx, [ecx+ebx] |
@@: |
mov [esi+DLLDESCR.defaultbase], ecx |
mov [dll_cur_addr], edx |
; copy sections and set correct values for VirtualAddress'es in headers |
push esi |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, eax |
add edx, 20 |
cld |
@@: |
call coff_get_align |
add ecx, eax |
add edi, eax |
not eax |
and ecx, eax |
and edi, eax |
mov [edx+CFS.VirtualAddress], ecx |
add ecx, [edx+CFS.SizeOfRawData] |
mov esi, [edx+CFS.PtrRawData] |
push ecx |
mov ecx, [edx+CFS.SizeOfRawData] |
test esi, esi |
jnz .copy |
xor eax, eax |
rep stosb |
jmp .next |
.copy: |
add esi, [coff] |
rep movsb |
.next: |
pop ecx |
add edx, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
pop esi |
; save some additional data from COFF file |
; later we will use COFF header, headers for sections and symbol table |
; and also relocations table for all sections |
mov edx, [coff] |
mov ebx, [edx+CFH.pSymTable] |
mov edi, dword [fileinfo+32] |
sub edi, ebx |
jc .fail_and_free_data |
mov [esi+DLLDESCR.symbols_lim], edi |
add ebx, edx |
movzx ecx, [edx+CFH.nSections] |
lea ecx, [ecx*5] |
lea edi, [edi+ecx*8+20] |
add edx, 20 |
@@: |
movzx eax, [edx+CFS.NumReloc] |
lea eax, [eax*5] |
lea edi, [edi+eax*2] |
add edx, COFF_SECTION_SIZE |
sub ecx, 5 |
jnz @b |
stdcall kernel_alloc, edi |
test eax, eax |
jz .fail_and_free_data |
mov edx, [coff] |
movzx ecx, [edx+CFH.nSections] |
lea ecx, [ecx*5] |
lea ecx, [ecx*2+5] |
mov [esi+DLLDESCR.coff_hdr], eax |
push esi |
mov esi, edx |
mov edi, eax |
rep movsd |
pop esi |
mov [esi+DLLDESCR.symbols_ptr], edi |
push esi |
mov ecx, [edx+CFH.nSymbols] |
mov [esi+DLLDESCR.symbols_num], ecx |
mov ecx, [esi+DLLDESCR.symbols_lim] |
mov esi, ebx |
rep movsb |
pop esi |
mov ebx, [esi+DLLDESCR.coff_hdr] |
push esi |
movzx eax, [edx+CFH.nSections] |
lea edx, [ebx+20] |
@@: |
movzx ecx, [edx+CFS.NumReloc] |
lea ecx, [ecx*5] |
mov esi, [edx+CFS.PtrReloc] |
mov [edx+CFS.PtrReloc], edi |
sub [edx+CFS.PtrReloc], ebx |
add esi, [coff] |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
add edx, COFF_SECTION_SIZE |
dec eax |
jnz @b |
pop esi |
; fixup symbols |
mov edx, ebx |
mov eax, [ebx+CFH.nSymbols] |
add edx, 20 |
mov ecx, [esi+DLLDESCR.symbols_num] |
lea ecx, [ecx*9] |
add ecx, ecx |
add ecx, [esi+DLLDESCR.symbols_ptr] |
stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\ |
ecx, 0 |
; test eax, eax |
; jnz @F |
; |
;@@: |
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS |
test eax, eax |
jnz @F |
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS |
@@: |
mov [esi+DLLDESCR.exports], eax |
; fix relocs in the hidden copy in kernel memory to default address |
; it is first fix; usually this will be enough, but second fix |
; can be necessary if real load address will not equal assumption |
mov eax, [esi+DLLDESCR.data] |
sub eax, [esi+DLLDESCR.defaultbase] |
stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax |
stdcall kernel_free, [coff] |
.dll_already_loaded: |
inc [esi+DLLDESCR.refcount] |
push esi |
call init_heap |
pop esi |
mov edi, [esi+DLLDESCR.size] |
stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi |
test eax, eax |
jnz @f |
stdcall user_alloc, edi |
test eax, eax |
jz .fail_and_dereference |
@@: |
mov [img_base], eax |
mov eax, HDLL.sizeof |
call malloc |
test eax, eax |
jz .fail_and_free_user |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov edx, [CURRENT_TASK+ebx+TASKDATA.pid] |
mov [eax+HDLL.pid], edx |
push eax |
call init_dlls_in_thread |
pop ebx |
test eax, eax |
jz .fail_and_free_user |
mov edx, [eax+HDLL.fd] |
mov [ebx+HDLL.fd], edx |
mov [ebx+HDLL.bk], eax |
mov [eax+HDLL.fd], ebx |
mov [edx+HDLL.bk], ebx |
mov eax, ebx |
mov ebx, [img_base] |
mov [eax+HDLL.base], ebx |
mov [eax+HDLL.size], edi |
mov [eax+HDLL.refcount], 1 |
mov [eax+HDLL.parent], esi |
mov edx, ebx |
shr edx, 12 |
or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK |
; copy entries of page table from kernel-side image to usermode |
; use copy-on-write for user-mode image, so map as readonly |
xor edi, edi |
mov ecx, [esi+DLLDESCR.data] |
shr ecx, 12 |
.map_pages_loop: |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
or al, PG_USER |
xchg eax, [page_tabs+edx*4] |
test al, 1 |
jz @f |
call free_page |
@@: |
invlpg [ebx+edi] |
inc ecx |
inc edx |
add edi, 0x1000 |
cmp edi, [esi+DLLDESCR.size] |
jb .map_pages_loop |
; if real user-mode base is not equal to preferred base, relocate image |
sub ebx, [esi+DLLDESCR.defaultbase] |
jz @f |
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx |
@@: |
mov eax, [esi+DLLDESCR.exports] |
sub eax, [esi+DLLDESCR.defaultbase] |
add eax, [img_base] |
ret |
.fail_and_free_data: |
stdcall kernel_free, [esi+DLLDESCR.data] |
.fail_and_free_dll: |
mov eax, esi |
call free |
.fail_and_free_coff: |
stdcall kernel_free, [coff] |
.fail: |
xor eax, eax |
ret |
.fail_and_free_user: |
stdcall user_free, [img_base] |
.fail_and_dereference: |
mov eax, 1 ; delete 1 reference |
call dereference_dll |
xor eax, eax |
ret |
endp |
; initialize [APPDATA.dlls_list_ptr] for given thread |
; DLL is per-process object, so APPDATA.dlls_list_ptr must be |
; kept in sync for all threads of one process. |
; out: eax = APPDATA.dlls_list_ptr if all is OK, |
; NULL if memory allocation failed |
init_dlls_in_thread: |
mov ebx, [current_slot] |
mov eax, [ebx+APPDATA.dlls_list_ptr] |
test eax, eax |
jnz .ret |
push [ebx+APPDATA.dir_table] |
mov eax, 8 |
call malloc |
pop edx |
test eax, eax |
jz .ret |
mov [eax], eax |
mov [eax+4], eax |
mov ecx, [TASK_COUNT] |
mov ebx, SLOT_BASE+256 |
.set: |
cmp [ebx+APPDATA.dir_table], edx |
jnz @f |
mov [ebx+APPDATA.dlls_list_ptr], eax |
@@: |
add ebx, 256 |
dec ecx |
jnz .set |
.ret: |
ret |
; in: eax = number of references to delete, esi -> DLLDESCR struc |
dereference_dll: |
sub [esi+DLLDESCR.refcount], eax |
jnz .ret |
mov eax, [esi+DLLDESCR.fd] |
mov edx, [esi+DLLDESCR.bk] |
mov [eax+DLLDESCR.bk], edx |
mov [edx+DLLDESCR.fd], eax |
stdcall kernel_free, [esi+DLLDESCR.coff_hdr] |
stdcall kernel_free, [esi+DLLDESCR.data] |
mov eax, esi |
call free |
.ret: |
ret |
destroy_hdll: |
push ebx ecx esi edi |
push eax |
mov ebx, [eax+HDLL.base] |
mov esi, [eax+HDLL.parent] |
mov edx, [esi+DLLDESCR.size] |
; The following actions require the context of application where HDLL is mapped. |
; However, destroy_hdll can be called in the context of OS thread when |
; cleaning up objects created by the application which is destroyed. |
; So remember current cr3 and set it to page table of target. |
mov eax, [ecx+APPDATA.dir_table] |
; Because we cheat with cr3, disable interrupts: task switch would restore |
; page table from APPDATA of current thread. |
; Also set [current_slot] because it is used by user_free. |
pushf |
cli |
push [current_slot] |
mov [current_slot], ecx |
mov ecx, cr3 |
push ecx |
mov cr3, eax |
push ebx ; argument for user_free |
mov eax, ebx |
shr ebx, 12 |
push ebx |
mov esi, [esi+DLLDESCR.data] |
shr esi, 12 |
.unmap_loop: |
push eax |
mov eax, 2 |
xchg eax, [page_tabs+ebx*4] |
mov ecx, [page_tabs+esi*4] |
and eax, not 0xFFF |
and ecx, not 0xFFF |
cmp eax, ecx |
jz @f |
call free_page |
@@: |
pop eax |
invlpg [eax] |
add eax, 0x1000 |
inc ebx |
inc esi |
sub edx, 0x1000 |
ja .unmap_loop |
pop ebx |
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK |
call user_free |
; Restore context. |
pop eax |
mov cr3, eax |
pop [current_slot] |
popf |
; Ok, cheating is done. |
pop eax |
push eax |
mov esi, [eax+HDLL.parent] |
mov eax, [eax+HDLL.refcount] |
call dereference_dll |
pop eax |
mov edx, [eax+HDLL.bk] |
mov ebx, [eax+HDLL.fd] |
mov [ebx+HDLL.bk], edx |
mov [edx+HDLL.fd], ebx |
call free |
pop edi esi ecx ebx |
ret |
; ecx -> APPDATA for slot, esi = dlls_list_ptr |
destroy_all_hdlls: |
test esi, esi |
jz .ret |
.loop: |
mov eax, [esi+HDLL.fd] |
cmp eax, esi |
jz free |
call destroy_hdll |
jmp .loop |
.ret: |
ret |
align 4 |
stop_all_services: |
push ebp |
mov edx, [srv.fd] |
.next: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .done |
cmp [edx+SRV.magic], ' SRV' |
jne .next |
cmp [edx+SRV.size], SRV.sizeof |
jne .next |
mov ebx, [edx+SRV.entry] |
mov edx, [edx+SRV.fd] |
test ebx, ebx |
jz .next |
push edx |
mov ebp, esp |
push 0 |
push -1 |
call ebx |
mov esp, ebp |
pop edx |
jmp .next |
.done: |
pop ebp |
ret |
; param |
; eax= size |
; ebx= pid |
align 4 |
create_kernel_object: |
push ebx |
call malloc |
pop ebx |
test eax, eax |
jz .fail |
mov ecx,[current_slot] |
add ecx, APP_OBJ_OFFSET |
pushfd |
cli |
mov edx, [ecx+APPOBJ.fd] |
mov [eax+APPOBJ.fd], edx |
mov [eax+APPOBJ.bk], ecx |
mov [eax+APPOBJ.pid], ebx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
popfd |
.fail: |
ret |
; param |
; eax= object |
align 4 |
destroy_kernel_object: |
pushfd |
cli |
mov ebx, [eax+APPOBJ.fd] |
mov ecx, [eax+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
popfd |
xor edx, edx ;clear common header |
mov [eax], edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax+16], edx |
call free ;release object memory |
ret |
if 0 |
irq: |
.irq0: |
pusfd |
pushad |
push IRQ_0 |
jmp .master |
.irq_1: |
pusfd |
pushad |
push IRQ_1 |
jmp .master |
.master: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0x21 |
bts eax, ecx |
out 0x21, al |
mov al, 0x20 |
out 0x20, al |
jmp .restart |
.slave: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
sub ecx, 8 |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0xA1 |
bts eax, ecx |
out 0xA1, al |
mov al, 0x20 |
out 0xA0, al |
out 0x20, al |
.restart: |
mov ebx, [next_slot] |
test ebx, ebx |
jz @F |
mov [next_task],0 |
mov esi, [prev_slot] |
call do_change_task |
add esp, 4 |
iretd |
end if |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/exports.inc |
---|
0,0 → 1,153 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
szKernel db 'KERNEL', 0 |
szVersion db 'version',0 |
szRegService db 'RegService',0 |
szGetService db 'GetService',0 |
szServiceHandler db 'ServiceHandler',0 |
szAttachIntHandler db 'AttachIntHandler',0 |
szGetIntHandler db 'GetIntHandler', 0 |
szFpuSave db 'FpuSave',0 |
szFpuRestore db 'FpuRestore',0 |
szReservePortArea db 'ReservePortArea',0 |
szBoot_Log db 'Boot_Log',0 |
szPciApi db 'PciApi', 0 |
szPciRead32 db 'PciRead32', 0 |
szPciRead16 db 'PciRead16', 0 |
szPciRead8 db 'PciRead8', 0 |
szPciWrite8 db 'PciWrite8',0 |
szPciWrite16 db 'PciWrite16',0 |
szPciWrite32 db 'PciWrite32',0 |
szAllocPage db 'AllocPage',0 |
szAllocPages db 'AllocPages',0 |
szFreePage db 'FreePage',0 |
szGetPgAddr db 'GetPgAddr',0 |
szMapPage db 'MapPage',0 |
szMapSpace db 'MapSpace',0 |
szMapIoMem db 'MapIoMem',0 |
szCommitPages db 'CommitPages',0 |
szReleasePages db 'ReleasePages',0 |
szAllocKernelSpace db 'AllocKernelSpace',0 |
szFreeKernelSpace db 'FreeKernelSpace',0 |
szKernelAlloc db 'KernelAlloc',0 |
szKernelFree db 'KernelFree',0 |
szUserAlloc db 'UserAlloc',0 |
szUserFree db 'UserFree',0 |
szKmalloc db 'Kmalloc',0 |
szKfree db 'Kfree',0 |
szCreateRingBuffer db 'CreateRingBuffer',0 |
szGetPid db 'GetPid',0 |
szCreateObject db 'CreateObject',0 |
szDestroyObject db 'DestroyObject',0 |
szCreateEvent db 'CreateEvent',0 |
szRaiseEvent db 'RaiseEvent',0 |
szWaitEvent db 'WaitEvent',0 |
szDestroyEvent db 'DestroyEvent',0 |
szClearEvent db 'ClearEvent',0 |
szLoadCursor db 'LoadCursor',0 |
szSysMsgBoardStr db 'SysMsgBoardStr', 0 |
szSysMsgBoardChar db 'SysMsgBoardChar', 0 |
szGetCurrentTask db 'GetCurrentTask',0 |
szLFBAddress db 'LFBAddress',0 |
szLoadFile db 'LoadFile',0 |
szSendEvent db 'SendEvent',0 |
szSetMouseData db 'SetMouseData',0 |
szSleep db 'Sleep',0 |
szGetTimerTicks db 'GetTimerTicks',0 |
szStrncat db 'strncat',0 |
szStrncpy db 'strncpy',0 |
szstrncmp db 'strncmp',0 |
szStrnlen db 'strnlen',0 |
szStrchr db 'strchr',0 |
szStrrchr db 'strrchr',0 |
align 16 |
kernel_export: |
dd szRegService , reg_service |
dd szGetService , get_service |
dd szServiceHandler , srv_handler |
dd szAttachIntHandler, attach_int_handler |
dd szGetIntHandler , get_int_handler |
dd szFpuSave , fpu_save |
dd szFpuRestore , fpu_restore |
dd szReservePortArea , r_f_port_area |
dd szBoot_Log , boot_log |
dd szPciApi , pci_api |
dd szPciRead32 , pci_read32 |
dd szPciRead16 , pci_read16 |
dd szPciRead8 , pci_read8 |
dd szPciWrite8 , pci_write8 |
dd szPciWrite16 , pci_write16 |
dd szPciWrite32 , pci_write32 |
dd szAllocPage , alloc_page ;stdcall |
dd szAllocPages , alloc_pages ;stdcall |
dd szFreePage , free_page |
dd szMapPage , map_page ;stdcall |
dd szMapSpace , map_space |
dd szMapIoMem , map_io_mem ;stdcall |
dd szGetPgAddr , get_pg_addr |
dd szCommitPages , commit_pages ;not implemented |
dd szReleasePages , release_pages |
dd szAllocKernelSpace, alloc_kernel_space ;stdcall |
dd szFreeKernelSpace , free_kernel_space ;stdcall |
dd szKernelAlloc , kernel_alloc ;stdcall |
dd szKernelFree , kernel_free ;stdcall |
dd szUserAlloc , user_alloc ;stdcall |
dd szUserFree , user_free ;stdcall |
dd szKmalloc , malloc |
dd szKfree , free |
dd szCreateRingBuffer, create_ring_buffer ;stdcall |
dd szGetPid , get_pid |
dd szCreateObject , create_kernel_object |
dd szDestroyObject , destroy_kernel_object |
dd szCreateEvent , create_event ;see EVENT.inc for specification |
dd szRaiseEvent , raise_event ;see EVENT.inc for specification |
dd szWaitEvent , wait_event ;see EVENT.inc for specification |
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification |
dd szClearEvent , clear_event ;see EVENT.inc for specification |
dd szLoadCursor , load_cursor ;stdcall |
dd szSysMsgBoardStr , sys_msg_board_str |
dd szSysMsgBoardChar , sys_msg_board |
dd szGetCurrentTask , get_curr_task |
dd szLoadFile , load_file ;retval eax, ebx |
dd szSendEvent , send_event ;see EVENT.inc for specification |
dd szSetMouseData , set_mouse_data ;stdcall |
dd szSleep , delay_ms |
dd szGetTimerTicks , get_timer_ticks |
dd szStrncat , strncat |
dd szStrncpy , strncpy |
dd szstrncmp , strncmp |
dd szStrnlen , strnlen |
dd szStrchr , strchr |
dd szStrrchr , strrchr |
exp_lfb: |
dd szLFBAddress , 0 |
dd 0 ;terminator, must be zero |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/memory.inc |
---|
0,0 → 1,1465 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
align 4 |
proc alloc_page |
pushfd |
cli |
push ebx |
mov ebx, [page_start] |
mov ecx, [page_end] |
.l1: |
bsf eax,[ebx]; |
jnz .found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
pop ebx |
popfd |
xor eax,eax |
ret |
.found: |
btr [ebx], eax |
mov [page_start],ebx |
sub ebx, sys_pgmap |
lea eax, [eax+ebx*8] |
shl eax, 12 |
dec [pg_data.pages_free] |
pop ebx |
popfd |
ret |
endp |
align 4 |
proc alloc_pages stdcall, count:dword |
pushfd |
push ebx |
push edi |
cli |
mov eax, [count] |
add eax, 7 |
shr eax, 3 |
mov [count], eax |
cmp eax, [pg_data.pages_free] |
ja .fail |
mov ecx, [page_start] |
mov ebx, [page_end] |
.find: |
mov edx, [count] |
mov edi, ecx |
.match: |
cmp byte [ecx], 0xFF |
jne .next |
dec edx |
jz .ok |
inc ecx |
cmp ecx,ebx |
jb .match |
.fail: |
xor eax, eax |
pop edi |
pop ebx |
popfd |
ret |
.next: |
inc ecx |
cmp ecx, ebx |
jb .find |
pop edi |
pop ebx |
popfd |
xor eax, eax |
ret |
.ok: |
sub ecx, edi |
inc ecx |
push esi |
mov esi, edi |
xor eax, eax |
rep stosb |
sub esi, sys_pgmap |
shl esi, 3+12 |
mov eax, esi |
mov ebx, [count] |
shl ebx, 3 |
sub [pg_data.pages_free], ebx |
pop esi |
pop edi |
pop ebx |
popfd |
ret |
endp |
align 4 |
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword |
push ebx |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, [flags] |
mov ebx, [lin_addr] |
shr ebx, 12 |
mov [page_tabs+ebx*4], eax |
mov eax, [lin_addr] |
invlpg [eax] |
pop ebx |
ret |
endp |
align 4 |
map_space: ;not implemented |
ret |
align 4 |
proc free_page |
;arg: eax page address |
pushfd |
cli |
shr eax, 12 ;page index |
bts dword [sys_pgmap], eax ;that's all! |
cmc |
adc [pg_data.pages_free], 0 |
shr eax, 3 |
and eax, not 3 ;dword offset from page_map |
add eax, sys_pgmap |
cmp [page_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [page_start], eax |
popfd |
ret |
endp |
proc map_io_mem stdcall, base:dword, size:dword, flags:dword |
push ebx |
push edi |
mov eax, [size] |
add eax, 4095 |
and eax, -4096 |
mov [size], eax |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .fail |
push eax |
mov edi, 0x1000 |
mov ebx, eax |
mov ecx,[size] |
mov edx, [base] |
shr eax, 12 |
shr ecx, 12 |
and edx, -4096 |
or edx, [flags] |
@@: |
mov [page_tabs+eax*4], edx |
; push eax |
invlpg [ebx] |
; pop eax |
inc eax |
add ebx, edi |
add edx, edi |
loop @B |
pop eax |
mov edx, [base] |
and edx, 4095 |
add eax, edx |
.fail: |
pop edi |
pop ebx |
ret |
endp |
; param |
; eax= page base + page flags |
; ebx= linear address |
; ecx= count |
align 4 |
commit_pages: |
push edi |
test ecx, ecx |
jz .fail |
mov edi, ebx |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edx, 0x1000 |
mov ebx, edi |
shr ebx, 12 |
@@: |
mov [page_tabs+ebx*4], eax |
; push eax |
invlpg [edi] |
; pop eax |
add edi, edx |
add eax, edx |
inc ebx |
dec ecx |
jnz @B |
mov [pg_data.pg_mutex],ecx |
.fail: |
pop edi |
ret |
; param |
; eax= base |
; ecx= count |
align 4 |
release_pages: |
pushad |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov esi, eax |
mov edi, eax |
shr esi, 10 |
add esi, page_tabs |
mov ebp, [pg_data.pages_free] |
mov ebx, [page_start] |
mov edx, sys_pgmap |
@@: |
xor eax, eax |
xchg eax, [esi] |
push eax |
invlpg [edi] |
pop eax |
test eax, 1 |
jz .next |
shr eax, 12 |
bts [edx], eax |
cmc |
adc ebp, 0 |
shr eax, 3 |
and eax, -4 |
add eax, edx |
cmp eax, ebx |
jae .next |
mov ebx, eax |
.next: |
add edi, 0x1000 |
add esi, 4 |
dec ecx |
jnz @B |
mov [pg_data.pages_free], ebp |
and [pg_data.pg_mutex],0 |
popad |
ret |
; param |
; eax= base |
; ecx= count |
align 4 |
unmap_pages: |
push edi |
mov edi, eax |
mov edx, eax |
shr edi, 10 |
add edi, page_tabs |
xor eax, eax |
@@: |
stosd |
invlpg [edx] |
add edx, 0x1000 |
loop @b |
pop edi |
ret |
align 4 |
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword |
push ebx |
mov ebx, [lin_addr] |
shr ebx, 22 |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, PG_UW ;+PG_NOCACHE |
mov dword [master_tab+ebx*4], eax |
mov eax, [lin_addr] |
shr eax, 10 |
add eax, page_tabs |
invlpg [eax] |
pop ebx |
ret |
endp |
align 4 |
proc init_LFB |
locals |
pg_count dd ? |
endl |
cmp dword [LFBAddress], -1 |
jne @f |
mov [BOOT_VAR+0x901c],byte 2 |
stdcall alloc_pages, (0x280000 / 4096) |
push eax |
call alloc_page |
stdcall map_page_table, LFB_BASE, eax |
pop eax |
or eax, PG_UW |
mov ebx, LFB_BASE |
mov ecx, 0x280000 / 4096 |
call commit_pages |
mov [LFBAddress], dword LFB_BASE |
ret |
@@: |
test [SCR_MODE],word 0100000000000000b |
jnz @f |
mov [BOOT_VAR+0x901c],byte 2 |
ret |
@@: |
call init_mtrr |
mov edx, LFB_BASE |
mov esi, [LFBAddress] |
mov edi, 0x00C00000 |
mov dword [exp_lfb+4], edx |
shr edi, 12 |
mov [pg_count], edi |
shr edi, 10 |
bt [cpu_caps], CAPS_PSE |
jnc .map_page_tables |
or esi, PG_LARGE+PG_UW |
mov edx, sys_pgdir+(LFB_BASE shr 20) |
@@: |
mov [edx], esi |
add edx, 4 |
add esi, 0x00400000 |
dec edi |
jnz @B |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL |
@@: |
mov dword [LFBAddress], LFB_BASE |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
.map_page_tables: |
@@: |
call alloc_page |
stdcall map_page_table, edx, eax |
add edx, 0x00400000 |
dec edi |
jnz @B |
mov eax, [LFBAddress] |
mov edi, page_tabs + (LFB_BASE shr 10) |
or eax, PG_UW |
mov ecx, [pg_count] |
cld |
@@: |
stosd |
add eax, 0x1000 |
dec ecx |
jnz @B |
mov dword [LFBAddress], LFB_BASE |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
endp |
align 4 |
proc new_mem_resize stdcall, new_size:dword |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edi, [new_size] |
add edi,4095 |
and edi,not 4095 |
mov [new_size], edi |
mov edx,[current_slot] |
cmp [edx+APPDATA.heap_base],0 |
jne .exit |
mov esi, [edx+APPDATA.mem_size] |
add esi, 4095 |
and esi, not 4095 |
cmp edi, esi |
jae .expand |
shr edi, 12 |
shr esi, 12 |
@@: |
mov eax, [app_page_tabs+edi*4] |
test eax, 1 |
jz .next |
mov dword [app_page_tabs+edi*4], 2 |
mov ebx, edi |
shl ebx, 12 |
push eax |
invlpg [ebx] |
pop eax |
call free_page |
.next: add edi, 1 |
cmp edi, esi |
jb @B |
.update_size: |
mov ebx, [new_size] |
call update_mem_size |
xor eax, eax |
dec [pg_data.pg_mutex] |
ret |
.expand: |
push esi |
push edi |
add edi, 0x3FFFFF |
and edi, not(0x3FFFFF) |
add esi, 0x3FFFFF |
and esi, not(0x3FFFFF) |
cmp esi, edi |
jae .grow |
xchg esi, edi |
@@: |
call alloc_page |
test eax, eax |
jz .exit_pop |
stdcall map_page_table, edi, eax |
push edi |
shr edi, 10 |
add edi, page_tabs |
mov ecx, 1024 |
xor eax, eax |
cld |
rep stosd |
pop edi |
add edi, 0x00400000 |
cmp edi, esi |
jb @B |
.grow: |
pop edi |
pop esi |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page,esi,eax,dword PG_UW |
push edi |
mov edi, esi |
xor eax, eax |
mov ecx, 1024 |
cld |
rep stosd |
pop edi |
add esi, 0x1000 |
cmp esi, edi |
jb @B |
jmp .update_size |
.exit_pop: |
pop edi |
pop esi |
.exit: |
xor eax, eax |
inc eax |
dec [pg_data.pg_mutex] |
ret |
endp |
update_mem_size: |
; in: edx = slot base |
; ebx = new memory size |
; destroys eax,ecx,edx |
mov [APPDATA.mem_size+edx],ebx |
;search threads and update |
;application memory size infomation |
mov ecx,[APPDATA.dir_table+edx] |
mov eax,2 |
.search_threads: |
;eax = current slot |
;ebx = new memory size |
;ecx = page directory |
cmp eax,[TASK_COUNT] |
jg .search_threads_end |
mov edx,eax |
shl edx,5 |
cmp word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty? |
jz .search_threads_next |
shl edx,3 |
cmp [SLOT_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread? |
jnz .search_threads_next |
mov [SLOT_BASE+edx+APPDATA.mem_size],ebx ;update memory size |
.search_threads_next: |
inc eax |
jmp .search_threads |
.search_threads_end: |
ret |
; param |
; eax= linear address |
; |
; retval |
; eax= phisical page address |
align 4 |
get_pg_addr: |
shr eax, 12 |
mov eax, [page_tabs+eax*4] |
and eax, 0xFFFFF000 |
ret |
align 4 |
; Now it is called from core/sys32::exc_c (see stack frame there) |
proc page_fault_handler |
.err_addr equ ebp-4 |
push ebx ;save exception number (#PF) |
mov ebp, esp |
mov ebx, cr2 |
push ebx ;that is locals: .err_addr = cr2 |
inc [pg_data.pages_faults] |
mov eax, [pf_err_code] |
cmp ebx, OS_BASE ;ebx == .err_addr |
jb .user_space ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ; |
cmp ebx, page_tabs |
jb .kernel_space ;ñòðàíèöà â ïàìÿòè ÿäðà |
cmp ebx, kernel_tabs |
jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ; |
;ïðîñòî ñîçäàäèì îäíó |
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå |
cmp ebx, LFB_BASE |
jb .core_tabs ;òàáëèöû ñòðàíèö ÿäðà |
;Îøèáêà |
.lfb: |
;îáëàñòü LFB |
;Îøèáêà |
jmp .fail |
end if |
.core_tabs: |
.fail: ;simply return to caller |
mov esp, ebp |
pop ebx ;restore exception number (#PF) |
ret |
; xchg bx, bx |
; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
; restore_ring3_context |
; iretd |
.user_space: |
test eax, PG_MAP |
jnz .err_access ;Ñòðàíèöà ïðèñóòñòâóåò |
;Îøèáêà äîñòóïà ? |
shr ebx, 12 |
mov ecx, ebx |
shr ecx, 10 |
mov edx, [master_tab+ecx*4] |
test edx, PG_MAP |
jz .fail ;òàáëèöà ñòðàíèö íå ñîçäàíà |
;íåâåðíûé àäðåñ â ïðîãðàììå |
mov eax, [page_tabs+ebx*4] |
test eax, 2 |
jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ; |
;èñïîëüçîâàíèÿ. Îøèáêà |
.alloc: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page,[.err_addr],eax,PG_UW |
mov edi, [.err_addr] |
and edi, 0xFFFFF000 |
mov ecx, 1024 |
xor eax, eax |
;cld ;caller is duty for this |
rep stosd |
.exit: ;iret with repeat fault instruction |
add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
restore_ring3_context |
iretd |
.err_access: |
; access denied? this may be a result of copy-on-write protection for DLL |
; check list of HDLLs |
and ebx, not 0xFFF |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr] |
test eax, eax |
jz .fail |
mov esi, [eax+HDLL.fd] |
.scan_hdll: |
cmp esi, eax |
jz .fail |
mov edx, ebx |
sub edx, [esi+HDLL.base] |
cmp edx, [esi+HDLL.size] |
jb .fault_in_hdll |
.scan_hdll.next: |
mov esi, [esi+HDLL.fd] |
jmp .scan_hdll |
.fault_in_hdll: |
; allocate new page, map it as rw and copy data |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page,ebx,eax,PG_UW |
mov edi, ebx |
mov ecx, 1024 |
sub ebx, [esi+HDLL.base] |
mov esi, [esi+HDLL.parent] |
mov esi, [esi+DLLDESCR.data] |
add esi, ebx |
rep movsd |
jmp .exit |
.kernel_space: |
test eax, PG_MAP |
jz .fail ;ñòðàíèöà íå ïðèñóòñòâóåò |
test eax,12 ;U/S (+below) |
jnz .fail ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè |
;ÿäðà |
;test eax, 8 |
;jnz .fail ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò |
;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon |
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà |
cmp ebx, tss._io_map_0 |
jb .fail |
cmp ebx, tss._io_map_0+8192 |
jae .fail |
; io permission map |
; copy-on-write protection |
call alloc_page |
test eax, eax |
jz .fail |
push eax |
stdcall map_page,[.err_addr],eax,dword PG_SW |
pop eax |
mov edi, [.err_addr] |
and edi, -4096 |
lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 |
mov ebx, esi |
shr ebx, 12 |
mov edx, [current_slot] |
or eax, PG_SW |
mov [edx+APPDATA.io_map+ebx*4], eax |
add esi, [default_io_map] |
mov ecx, 4096/4 |
;cld ;caller is duty for this |
rep movsd |
jmp .exit |
endp |
; returns number of mapped bytes |
proc map_mem stdcall, lin_addr:dword,slot:dword,\ |
ofs:dword,buf_size:dword,req_access:dword |
push 0 ; initialize number of mapped bytes |
cmp [buf_size], 0 |
jz .exit |
mov eax, [slot] |
shl eax, 8 |
mov eax, [SLOT_BASE+eax+APPDATA.dir_table] |
and eax, 0xFFFFF000 |
stdcall map_page,[ipc_pdir],eax,PG_UW |
mov ebx, [ofs] |
shr ebx, 22 |
mov esi, [ipc_pdir] |
mov edi, [ipc_ptab] |
mov eax, [esi+ebx*4] |
and eax, 0xFFFFF000 |
jz .exit |
stdcall map_page,edi,eax,PG_UW |
; inc ebx |
; add edi, 0x1000 |
; mov eax, [esi+ebx*4] |
; test eax, eax |
; jz @f |
; and eax, 0xFFFFF000 |
; stdcall map_page, edi, eax |
@@: mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
shr ecx, 12 |
inc ecx |
mov edx, [ofs] |
shr edx, 12 |
and edx, 0x3FF |
mov esi, [ipc_ptab] |
.map: |
stdcall safe_map_page,[slot],[req_access],[ofs] |
jnc .exit |
add dword [ebp-4], 4096 |
add [ofs], 4096 |
dec ecx |
jz .exit |
add edi, 0x1000 |
inc edx |
cmp edx, 0x400 |
jnz .map |
inc ebx |
mov eax, [ipc_pdir] |
mov eax, [eax+ebx*4] |
and eax, 0xFFFFF000 |
jz .exit |
stdcall map_page,esi,eax,PG_UW |
xor edx, edx |
jmp .map |
.exit: |
pop eax |
ret |
endp |
proc map_memEx stdcall, lin_addr:dword,slot:dword,\ |
ofs:dword,buf_size:dword,req_access:dword |
push 0 ; initialize number of mapped bytes |
cmp [buf_size], 0 |
jz .exit |
mov eax, [slot] |
shl eax, 8 |
mov eax, [SLOT_BASE+eax+APPDATA.dir_table] |
and eax, 0xFFFFF000 |
stdcall map_page,[proc_mem_pdir],eax,PG_UW |
mov ebx, [ofs] |
shr ebx, 22 |
mov esi, [proc_mem_pdir] |
mov edi, [proc_mem_tab] |
mov eax, [esi+ebx*4] |
and eax, 0xFFFFF000 |
test eax, eax |
jz .exit |
stdcall map_page,edi,eax,PG_UW |
@@: mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
shr ecx, 12 |
inc ecx |
mov edx, [ofs] |
shr edx, 12 |
and edx, 0x3FF |
mov esi, [proc_mem_tab] |
.map: |
stdcall safe_map_page,[slot],[req_access],[ofs] |
jnc .exit |
add dword [ebp-4], 0x1000 |
add edi, 0x1000 |
add [ofs], 0x1000 |
inc edx |
dec ecx |
jnz .map |
.exit: |
pop eax |
ret |
endp |
; in: esi+edx*4 = pointer to page table entry |
; in: [slot], [req_access], [ofs] on the stack |
; in: edi = linear address to map |
; out: CF cleared <=> failed |
; destroys: only eax |
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
mov eax, [esi+edx*4] |
test al, PG_MAP |
jz .not_present |
test al, PG_WRITE |
jz .resolve_readonly |
; normal case: writable page, just map with requested access |
.map: |
stdcall map_page, edi, eax, [req_access] |
stc |
.fail: |
ret |
.not_present: |
; check for alloc-on-demand page |
test al, 2 |
jz .fail |
; allocate new page, save it to source page table |
push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .fail |
or al, PG_UW |
mov [esi+edx*4], eax |
jmp .map |
.resolve_readonly: |
; readonly page, probably copy-on-write |
; check: readonly request of readonly page is ok |
test [req_access], PG_WRITE |
jz .map |
; find control structure for this page |
pushf |
cli |
cld |
push ebx ecx |
mov eax, [slot] |
shl eax, 8 |
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr] |
test eax, eax |
jz .no_hdll |
mov ecx, [eax+HDLL.fd] |
.scan_hdll: |
cmp ecx, eax |
jz .no_hdll |
mov ebx, [ofs] |
and ebx, not 0xFFF |
sub ebx, [ecx+HDLL.base] |
cmp ebx, [ecx+HDLL.size] |
jb .hdll_found |
mov ecx, [ecx+HDLL.fd] |
jmp .scan_hdll |
.no_hdll: |
pop ecx ebx |
popf |
clc |
ret |
.hdll_found: |
; allocate page, save it in page table, map it, copy contents from base |
mov eax, [ecx+HDLL.parent] |
add ebx, [eax+DLLDESCR.data] |
call alloc_page |
test eax, eax |
jz .no_hdll |
or al, PG_UW |
mov [esi+edx*4], eax |
stdcall map_page, edi, eax, [req_access] |
push esi edi |
mov esi, ebx |
mov ecx, 4096/4 |
rep movsd |
pop edi esi |
pop ecx ebx |
popf |
stc |
ret |
endp |
sys_IPC: |
;input: |
; eax=1 - set ipc buffer area |
; ebx=address of buffer |
; ecx=size of buffer |
; eax=2 - send message |
; ebx=PID |
; ecx=address of message |
; edx=size of message |
cmp eax,1 |
jne @f |
call set_ipc_buff |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 2 |
jne @f |
stdcall sys_ipc_send, ebx, ecx, edx |
mov [esp+36], eax |
ret |
@@: |
xor eax, eax |
not eax |
mov [esp+36], eax |
ret |
align 4 |
proc set_ipc_buff |
mov eax,[current_slot] |
pushf |
cli |
mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area |
mov [eax+APPDATA.ipc_size],ecx |
add ecx, ebx |
add ecx, 4095 |
and ecx, not 4095 |
.touch: mov eax, [ebx] |
add ebx, 0x1000 |
cmp ebx, ecx |
jb .touch |
popf |
xor eax, eax |
ret |
endp |
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
locals |
dst_slot dd ? |
dst_offset dd ? |
buf_size dd ? |
used_buf dd ? |
endl |
pushf |
cli |
mov eax, [PID] |
call pid_to_slot |
test eax,eax |
jz .no_pid |
mov [dst_slot], eax |
shl eax,8 |
mov edi,[eax+SLOT_BASE+0xa0] ;is ipc area defined? |
test edi,edi |
jz .no_ipc_area |
mov ebx, edi |
and ebx, 0xFFF |
mov [dst_offset], ebx |
mov esi, [eax+SLOT_BASE+0xa4] |
mov [buf_size], esi |
mov ecx, [ipc_tmp] |
cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page |
jbe @f |
push esi edi |
add esi,0x1000 |
stdcall alloc_kernel_space,esi |
mov ecx, eax |
pop edi esi |
@@: |
mov [used_buf], ecx |
stdcall map_mem, ecx, [dst_slot],\ |
edi, esi, PG_SW |
mov edi, [dst_offset] |
add edi, [used_buf] |
cmp dword [edi], 0 |
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
mov edx, dword [edi+4] |
lea ebx, [edx+8] |
add ebx, [msg_size] |
cmp ebx, [buf_size] |
ja .buffer_overflow ;esi<0 - not enough memory in buffer |
mov dword [edi+4], ebx |
mov eax,[TASK_BASE] |
mov eax, [eax+0x04] ;eax - our PID |
add edi, edx |
mov [edi], eax |
mov ecx, [msg_size] |
mov [edi+4], ecx |
add edi, 8 |
mov esi, [msg_addr] |
; add esi, new_app_base |
cld |
rep movsb |
mov ebx, [ipc_tmp] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_pdir] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_ptab] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov eax, [dst_slot] |
shl eax, 8 |
or [eax+SLOT_BASE+0xA8],dword 0x40 |
cmp dword [check_idle_semaphore],20 |
jge .ipc_no_cis |
mov dword [check_idle_semaphore],5 |
.ipc_no_cis: |
push 0 |
jmp .ret |
.no_pid: |
popf |
mov eax, 4 |
ret |
.no_ipc_area: |
popf |
xor eax, eax |
inc eax |
ret |
.ipc_blocked: |
push 2 |
jmp .ret |
.buffer_overflow: |
push 3 |
.ret: |
mov eax, [used_buf] |
cmp eax, [ipc_tmp] |
jz @f |
stdcall free_kernel_space,eax |
@@: |
pop eax |
popf |
ret |
endp |
align 4 |
sysfn_meminfo: |
; add ecx, new_app_base |
cmp ecx, OS_BASE |
jae .fail |
mov eax, [pg_data.pages_count] |
mov [ecx], eax |
shl eax, 12 |
mov [esp+32], eax |
mov eax, [pg_data.pages_free] |
mov [ecx+4], eax |
mov eax, [pg_data.pages_faults] |
mov [ecx+8], eax |
mov eax, [heap_size] |
mov [ecx+12], eax |
mov eax, [heap_free] |
mov [ecx+16], eax |
mov eax, [heap_blocks] |
mov [ecx+20], eax |
mov eax, [free_blocks] |
mov [ecx+24], eax |
ret |
.fail: |
or dword [esp+32], -1 |
ret |
iglobal |
align 4 |
f68call: |
dd f68.11 ; init_heap |
dd f68.12 ; user_alloc |
dd f68.13 ; user_free |
dd f68.14 ; get_event_ex |
dd f68.fail ;moved to f68.24 |
dd f68.16 ; get_service |
dd f68.17 ; call_service |
dd f68.fail ;moved to f68.25 |
dd f68.19 ; load_dll |
dd f68.20 ; user_realloc |
dd f68.21 ; load_driver |
dd f68.22 ; shmem_open |
dd f68.23 ; shmem_close |
dd f68.24 |
dd f68.25 |
endg |
align 4 |
f68: |
cmp eax,4 |
jle sys_sheduler |
cmp eax, 11 |
jb .fail |
cmp eax, 25 |
ja .fail |
jmp dword [f68call+eax*4-11*4] |
.11: |
call init_heap |
mov [esp+36], eax |
ret |
.12: |
stdcall user_alloc, ebx |
mov [esp+36], eax |
ret |
.13: |
stdcall user_free, ebx |
mov [esp+36], eax |
ret |
.14: |
cmp ebx, OS_BASE |
jae .fail |
mov edi,ebx |
call get_event_ex |
mov [esp+36], eax |
ret |
.16: |
test ebx, ebx |
jz .fail |
cmp ebx, OS_BASE |
jae .fail |
stdcall get_service, ebx |
mov [esp+36], eax |
ret |
.17: |
call srv_handlerEx ;ebx |
mov [esp+36], eax |
ret |
.19: |
cmp ebx, OS_BASE |
jae .fail |
stdcall load_library, ebx |
mov [esp+36], eax |
ret |
.20: |
mov eax, ecx |
call user_realloc |
mov [esp+36], eax |
ret |
.21: |
cmp ebx, OS_BASE |
jae .fail |
cmp ecx, OS_BASE |
jae .fail |
mov edi, ecx |
stdcall load_PE, ebx |
mov esi, eax |
test eax, eax |
jz @F |
push edi |
push DRV_ENTRY |
call eax |
add esp, 8 |
test eax, eax |
jz @F |
mov [eax+SRV.entry], esi |
@@: |
mov [esp+36], eax |
ret |
.22: |
cmp ebx, OS_BASE |
jae .fail |
stdcall shmem_open, ebx, ecx, edx |
mov [esp+28], edx |
mov [esp+36], eax |
ret |
.23: |
cmp ebx, OS_BASE |
jae .fail |
stdcall shmem_close, ebx |
mov [esp+36], eax |
ret |
.24: |
mov eax, [current_slot] |
xchg ebx, [eax+APPDATA.exc_handler] |
xchg ecx, [eax+APPDATA.except_mask] |
mov [esp+36], ebx ; reg_eax+8 |
mov [esp+24], ecx ; reg_ebx+8 |
ret |
.25: |
cmp ebx,32 |
jae .fail |
mov eax, [current_slot] |
btr [eax+APPDATA.except_mask],ebx |
setc byte[esp+36] |
jecxz @f |
bts [eax+APPDATA.except_mask],ebx |
@@: |
ret |
.fail: |
xor eax, eax |
mov [esp+36], eax |
ret |
align 4 |
proc load_pe_driver stdcall, file:dword |
stdcall load_PE, [file] |
test eax, eax |
jz .fail |
mov esi, eax |
stdcall eax, DRV_ENTRY |
test eax, eax |
jz .fail |
mov [eax+SRV.entry], esi |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_mtrr |
cmp [BOOT_VAR+0x901c],byte 2 |
je .exit |
bt [cpu_caps], CAPS_MTRR |
jnc .exit |
mov eax, cr0 |
or eax, 0x60000000 ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
mov ecx, 0x2FF |
rdmsr ; |
; has BIOS already initialized MTRRs? |
test ah, 8 |
jnz .skip_init |
; rarely needed, so mainly placeholder |
; main memory - cached |
push eax |
mov eax, [MEM_AMOUNT] |
; round eax up to next power of 2 |
dec eax |
bsr ecx, eax |
mov ebx, 2 |
shl ebx, cl |
dec ebx |
; base of memory range = 0, type of memory range = MEM_WB |
xor edx, edx |
mov eax, MEM_WB |
mov ecx, 0x200 |
wrmsr |
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1 |
mov eax, 0xFFFFFFFF |
mov edx, 0x0000000F |
sub eax, ebx |
sbb edx, 0 |
or eax, 0x800 |
inc ecx |
wrmsr |
; clear unused MTRRs |
xor eax, eax |
xor edx, edx |
@@: |
wrmsr |
inc ecx |
cmp ecx, 0x210 |
jb @b |
; enable MTRRs |
pop eax |
or ah, 8 |
and al, 0xF0 ; default memtype = UC |
mov ecx, 0x2FF |
wrmsr |
.skip_init: |
stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC |
wbinvd ;again invalidate |
mov eax, cr0 |
and eax, not 0x60000000 |
mov cr0, eax ; enable caching |
.exit: |
ret |
endp |
align 4 |
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword |
; find unused register |
mov ecx, 0x201 |
@@: |
rdmsr |
dec ecx |
test ah, 8 |
jz .found |
rdmsr |
mov al, 0 ; clear memory type field |
cmp eax, [base] |
jz .ret |
add ecx, 3 |
cmp ecx, 0x210 |
jb @b |
; no free registers, ignore the call |
.ret: |
ret |
.found: |
; found, write values |
xor edx, edx |
mov eax, [base] |
or eax, [mem_type] |
wrmsr |
mov ebx, [size] |
dec ebx |
mov eax, 0xFFFFFFFF |
mov edx, 0x0000000F |
sub eax, ebx |
sbb edx, 0 |
or eax, 0x800 |
inc ecx |
wrmsr |
ret |
endp |
align 4 |
proc stall stdcall, delay:dword |
push ecx |
push edx |
push ebx |
push eax |
mov eax, [delay] |
mul [stall_mcs] |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx,edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
jb @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
align 4 |
proc create_ring_buffer stdcall, size:dword, flags:dword |
locals |
buf_ptr dd ? |
endl |
mov eax, [size] |
test eax, eax |
jz .fail |
add eax, eax |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .fail |
push ebx |
mov [buf_ptr], eax |
mov ebx, [size] |
shr ebx, 12 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx |
test eax, eax |
jz .mm_fail |
push edi |
or eax, [flags] |
mov edi, [buf_ptr] |
mov ebx, [buf_ptr] |
mov edx, ecx |
shl edx, 2 |
shr edi, 10 |
@@: |
mov [page_tabs+edi], eax |
mov [page_tabs+edi+edx], eax |
invlpg [ebx] |
invlpg [ebx+0x10000] |
add eax, 0x1000 |
add ebx, 0x1000 |
add edi, 4 |
dec ecx |
jnz @B |
mov eax, [buf_ptr] |
pop edi |
pop ebx |
ret |
.mm_fail: |
stdcall free_kernel_space, [buf_ptr] |
xor eax, eax |
pop ebx |
.fail: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/peload.inc |
---|
0,0 → 1,318 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
include 'export.inc' |
align 4 |
proc load_PE stdcall, file_name:dword |
locals |
image dd ? |
entry dd ? |
base dd ? |
endl |
stdcall load_file, [file_name] |
test eax, eax |
jz .fail |
mov [image], eax |
mov edx, [eax+60] |
stdcall kernel_alloc, [eax+80+edx] |
test eax, eax |
jz .cleanup |
mov [base], eax |
stdcall map_PE, eax, [image] |
mov [entry], eax |
test eax, eax |
jnz .cleanup |
stdcall kernel_free, [base] |
.cleanup: |
stdcall kernel_free, [image] |
mov eax, [entry] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
DWORD equ dword |
PTR equ |
align 4 |
map_PE: ;stdcall base:dword, image:dword |
cld |
push ebp |
push edi |
push esi |
push ebx |
sub esp, 60 |
mov ebx, DWORD PTR [esp+84] |
mov ebp, DWORD PTR [esp+80] |
mov edx, ebx |
mov esi, ebx |
add edx, DWORD PTR [ebx+60] |
mov edi, ebp |
mov DWORD PTR [esp+32], edx |
mov ecx, DWORD PTR [edx+84] |
shr ecx, 2 |
rep movsd |
movzx eax, WORD PTR [edx+6] |
mov DWORD PTR [esp+36], 0 |
mov DWORD PTR [esp+16], eax |
jmp L2 |
L3: |
mov eax, DWORD PTR [edx+264] |
test eax, eax |
je L4 |
mov esi, ebx |
mov edi, ebp |
add esi, DWORD PTR [edx+268] |
mov ecx, eax |
add edi, DWORD PTR [edx+260] |
shr ecx, 2 |
rep movsd |
L4: |
mov ecx, DWORD PTR [edx+256] |
add ecx, 4095 |
and ecx, -4096 |
cmp ecx, eax |
jbe L6 |
sub ecx, eax |
add eax, DWORD PTR [edx+260] |
lea edi, [eax+ebp] |
xor eax, eax |
rep stosb |
L6: |
inc DWORD PTR [esp+36] |
add edx, 40 |
L2: |
mov esi, DWORD PTR [esp+16] |
cmp DWORD PTR [esp+36], esi |
jne L3 |
mov edi, DWORD PTR [esp+32] |
cmp DWORD PTR [edi+164], 0 |
je L9 |
mov esi, ebp |
mov ecx, ebp |
sub esi, DWORD PTR [edi+52] |
add ecx, DWORD PTR [edi+160] |
mov eax, esi |
shr eax, 16 |
mov DWORD PTR [esp+12], eax |
jmp L11 |
L12: |
lea ebx, [eax-8] |
xor edi, edi |
shr ebx,1 |
jmp L13 |
L14: |
movzx eax, WORD PTR [ecx+8+edi*2] |
mov edx, eax |
shr eax, 12 |
and edx, 4095 |
add edx, DWORD PTR [ecx] |
cmp ax, 2 |
je L17 |
cmp ax, 3 |
je L18 |
dec ax |
jne L15 |
mov eax, DWORD PTR [esp+12] |
add WORD PTR [edx+ebp], ax |
L17: |
add WORD PTR [edx+ebp], si |
L18: |
add DWORD PTR [edx+ebp], esi |
L15: |
inc edi |
L13: |
cmp edi, ebx |
jne L14 |
add ecx, DWORD PTR [ecx+4] |
L11: |
mov eax, DWORD PTR [ecx+4] |
test eax, eax |
jne L12 |
L9: |
mov edx, DWORD PTR [esp+32] |
cmp DWORD PTR [edx+132], 0 |
je L20 |
mov eax, ebp |
add eax, DWORD PTR [edx+128] |
mov DWORD PTR [esp+40], 0 |
add eax, 20 |
mov DWORD PTR [esp+56], eax |
L22: |
mov ecx, DWORD PTR [esp+56] |
cmp DWORD PTR [ecx-16], 0 |
jne L23 |
cmp DWORD PTR [ecx-8], 0 |
je L25 |
L23: |
mov edi, DWORD PTR [__exports+32] |
mov esi, DWORD PTR [__exports+28] |
mov eax, DWORD PTR [esp+56] |
mov DWORD PTR [esp+20], edi |
add edi, OS_BASE |
add esi, OS_BASE |
mov DWORD PTR [esp+44], esi |
mov ecx, DWORD PTR [eax-4] |
mov DWORD PTR [esp+48], edi |
mov edx, DWORD PTR [eax-20] |
mov DWORD PTR [esp+52], 0 |
add ecx, ebp |
add edx, ebp |
mov DWORD PTR [esp+24], edx |
mov DWORD PTR [esp+28], ecx |
L26: |
mov esi, DWORD PTR [esp+52] |
mov edi, DWORD PTR [esp+24] |
mov eax, DWORD PTR [edi+esi*4] |
test eax, eax |
je L27 |
test eax, eax |
js L27 |
lea edi, [ebp+eax] |
mov eax, DWORD PTR [esp+28] |
mov DWORD PTR [eax+esi*4], 0 |
lea esi, [edi+2] |
push eax |
push 32 |
movzx eax, WORD PTR [edi] |
mov edx, DWORD PTR [esp+56] |
mov eax, DWORD PTR [edx+eax*4] |
add eax, OS_BASE |
push eax |
push esi |
call strncmp |
pop ebx |
xor ebx, ebx |
test eax, eax |
jne L32 |
jmp L30 |
L33: |
push ecx |
push 32 |
mov ecx, DWORD PTR [esp+28] |
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4] |
add eax, OS_BASE |
push eax |
push esi |
call strncmp |
pop edx |
test eax, eax |
jne L34 |
mov esi, DWORD PTR [esp+44] |
mov edx, DWORD PTR [esp+52] |
mov ecx, DWORD PTR [esp+28] |
mov eax, DWORD PTR [esi+ebx*4] |
add eax, OS_BASE |
mov DWORD PTR [ecx+edx*4], eax |
jmp L36 |
L34: |
inc ebx |
L32: |
cmp ebx, DWORD PTR [__exports+24] |
jb L33 |
L36: |
cmp ebx, DWORD PTR [__exports+24] |
jne L37 |
mov esi, msg_unresolved |
call sys_msg_board_str |
lea esi, [edi+2] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov DWORD PTR [esp+40], 1 |
jmp L37 |
L30: |
movzx eax, WORD PTR [edi] |
mov esi, DWORD PTR [esp+44] |
mov edi, DWORD PTR [esp+52] |
mov edx, DWORD PTR [esp+28] |
mov eax, DWORD PTR [esi+eax*4] |
add eax, OS_BASE |
mov DWORD PTR [edx+edi*4], eax |
L37: |
inc DWORD PTR [esp+52] |
jmp L26 |
L27: |
add DWORD PTR [esp+56], 20 |
jmp L22 |
L25: |
xor eax, eax |
cmp DWORD PTR [esp+40], 0 |
jne L40 |
L20: |
mov ecx, DWORD PTR [esp+32] |
mov eax, ebp |
add eax, DWORD PTR [ecx+40] |
L40: |
add esp, 60 |
pop ebx |
pop esi |
pop edi |
pop ebp |
ret 8 |
align 16 |
__exports: |
export 'KERNEL', \ |
alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall |
alloc_page, 'AllocPage', \ ; gcc ABI |
alloc_pages, 'AllocPages', \ ; stdcall |
commit_pages, 'CommitPages', \ ; eax, ebx, ecx |
create_kernel_object, 'CreateObject', \ |
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall |
destroy_kernel_object, 'DestroyObject', \ |
free_kernel_space, 'FreeKernelSpace', \ ; stdcall |
kernel_alloc, 'KernelAlloc', \ ; stdcall |
kernel_free, 'KernelFree', \ ; stdcall |
malloc, 'Kmalloc', \ |
free, 'Kfree', \ |
map_io_mem, 'MapIoMem', \ ; stdcall |
get_pg_addr, 'GetPgAddr', \ ; eax |
\ |
get_display, 'GetDisplay', \ |
set_screen, 'SetScreen', \ |
pci_api, 'PciApi', \ |
pci_read8, 'PciRead8', \ ; stdcall |
pci_read16, 'PciRead16', \ ; stdcall |
pci_read32, 'PciRead32', \ ; stdcall |
pci_write8, 'PciWrite8', \ ; stdcall |
pci_write16, 'PciWrite16', \ ; stdcall |
pci_write32, 'PciWrite32', \ ; stdcall |
\ |
get_service, 'GetService', \ ; |
reg_service, 'RegService', \ ; stdcall |
attach_int_handler, 'AttachIntHandler', \ ; stdcall |
user_alloc, 'UserAlloc', \ ; stdcall |
user_free, 'UserFree', \ ; stdcall |
unmap_pages, 'UnmapPages', \ ; eax, ecx |
sys_msg_board_str, 'SysMsgBoardStr', \ |
delay_hs, 'Delay', \ ; ebx |
set_mouse_data, 'SetMouseData' |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/taskman.inc |
---|
0,0 → 1,1168 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
GREEDY_KERNEL equ 0 |
struc APP_HEADER_00 |
{ .banner dq ? |
.version dd ? ;+8 |
.start dd ? ;+12 |
.i_end dd ? ;+16 |
.mem_size dd ? ;+20 |
.i_param dd ? ;+24 |
} |
struc APP_HEADER_01 |
{ .banner dq ? |
.version dd ? ;+8 |
.start dd ? ;+12 |
.i_end dd ? ;+16 |
.mem_size dd ? ;+20 |
.stack_top dd ? ;+24 |
.i_param dd ? ;+28 |
.i_icon dd ? ;+32 |
} |
struc APP_PARAMS |
{ .app_cmdline ;0x00 |
.app_path ;0x04 |
.app_eip ;0x08 |
.app_esp ;0x0C |
.app_mem ;0x10 |
} |
macro _clear_ op |
{ mov ecx, op/4 |
xor eax, eax |
cld |
rep stosd |
} |
fs_execute_from_sysdir: |
xor ebx, ebx |
xor edx, edx |
mov esi, sysdir_path |
align 4 |
proc fs_execute |
;fn_read:dword, file_size:dword, cluster:dword |
; ebx - cmdline |
; edx - flags |
; ebp - full filename |
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it |
locals |
cmdline rd 64 ;256/4 |
filename rd 256 ;1024/4 |
flags dd ? |
save_cr3 dd ? |
slot dd ? |
slot_base dd ? |
file_base dd ? |
file_size dd ? |
;app header data |
hdr_cmdline dd ? ;0x00 |
hdr_path dd ? ;0x04 |
hdr_eip dd ? ;0x08 |
hdr_esp dd ? ;0x0C |
hdr_mem dd ? ;0x10 |
hdr_i_end dd ? ;0x14 |
endl |
pushad |
mov [flags], edx |
; [ebp] pointer to filename |
lea edi, [filename] |
lea ecx, [edi+1024] |
mov al, '/' |
stosb |
@@: |
cmp edi, ecx |
jae .bigfilename |
lodsb |
stosb |
test al, al |
jnz @b |
mov esi, [ebp] |
test esi, esi |
jz .namecopied |
mov byte [edi-1], '/' |
@@: |
cmp edi, ecx |
jae .bigfilename |
lodsb |
stosb |
test al, al |
jnz @b |
jmp .namecopied |
.bigfilename: |
popad |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
.namecopied: |
mov [cmdline], ebx |
test ebx, ebx |
jz @F |
lea eax, [cmdline] |
mov dword [eax+252], 0 |
stdcall strncpy, eax, ebx, 255 |
@@: |
lea eax, [filename] |
stdcall load_file, eax |
mov ecx, -ERROR_FILE_NOT_FOUND |
test eax, eax |
jz .err_file |
mov [file_base], eax |
mov [file_size], ebx |
lea ebx, [hdr_cmdline] |
call test_app_header |
mov ecx, -0x1F |
test eax, eax |
jz .err_hdr |
;mov esi, new_process_loading |
;call sys_msg_board_str ; write message to message board |
.wait_lock: |
cmp [application_table_status],0 |
je .get_lock |
call change_task |
jmp .wait_lock |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
test eax, eax |
jnz .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
mov ecx, -0x20 ; too many processes |
jz .err |
mov [slot], eax |
shl eax, 8 |
add eax, SLOT_BASE |
mov [slot_base], eax |
mov edi, eax |
_clear_ 256 ;clean extended information about process |
; write application name |
lea eax, [filename] |
stdcall strrchr, eax, '/' ; now eax points to name without path |
lea esi, [eax+1] |
test eax, eax |
jnz @F |
lea esi, [filename] |
@@: |
mov ecx, 8 ; 8 chars for name |
mov edi, [slot_base] |
.copy_process_name_loop: |
lodsb |
cmp al, '.' |
jz .copy_process_name_done |
test al, al |
jz .copy_process_name_done |
stosb |
loop .copy_process_name_loop |
.copy_process_name_done: |
mov ebx, cr3 |
mov [save_cr3], ebx |
stdcall create_app_space,[hdr_mem],[file_base],[file_size] |
mov ecx, -30 ; no memory |
test eax, eax |
jz .failed |
mov ebx,[slot_base] |
mov [ebx+APPDATA.dir_table],eax |
mov eax,[hdr_mem] |
mov [ebx+APPDATA.mem_size],eax |
xor edx, edx |
cmp word [6], '02' |
jne @f |
not edx |
@@: |
mov [ebx+APPDATA.tls_base],edx |
if GREEDY_KERNEL |
else |
mov ecx, [hdr_mem] |
mov edi, [file_size] |
add edi, 4095 |
and edi, not 4095 |
sub ecx, edi |
jna @F |
xor eax, eax |
cld |
rep stosb |
@@: |
end if |
; release only virtual space, not phisical memory |
stdcall free_kernel_space, [file_base] |
lea eax, [hdr_cmdline] |
lea ebx, [cmdline] |
lea ecx, [filename] |
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags] |
mov eax, [save_cr3] |
call set_cr3 |
xor ebx, ebx |
mov [application_table_status],ebx ;unlock application_table_status mutex |
mov eax,[process_number] ;set result |
ret |
.failed: |
mov eax, [save_cr3] |
call set_cr3 |
.err: |
.err_hdr: |
stdcall kernel_free,[file_base] |
.err_file: |
xor eax, eax |
mov [application_table_status],eax |
mov eax, ecx |
ret |
endp |
align 4 |
test_app_header: |
virtual at eax |
APP_HEADER_00 APP_HEADER_00 |
end virtual |
virtual at eax |
APP_HEADER_01 APP_HEADER_01 |
end virtual |
cmp dword [eax], 'MENU' |
jne .fail |
cmp word [eax+4],'ET' |
jne .fail |
cmp [eax+6], word '00' |
jne .check_01_header |
mov ecx,[APP_HEADER_00.start] |
mov [ebx+0x08], ecx ;app_eip |
mov edx,[APP_HEADER_00.mem_size] |
mov [ebx+0x10], edx ;app_mem |
shr edx,1 |
sub edx,0x10 |
mov [ebx+0x0C], edx ;app_esp |
mov ecx,[APP_HEADER_00.i_param] |
mov [ebx], ecx ;app_cmdline |
mov [ebx+4], dword 0 ;app_path |
mov edx, [APP_HEADER_00.i_end] |
mov [ebx+0x14], edx |
ret |
.check_01_header: |
cmp [eax+6], word '01' |
je @f |
cmp [eax+6], word '02' |
jne .fail |
@@: |
mov ecx,[APP_HEADER_01.start] |
mov [ebx+0x08], ecx ;app_eip |
mov edx,[APP_HEADER_01.mem_size] |
; \begin{diamond}[20.08.2006] |
; sanity check (functions 19,58 load app_i_end bytes and that must |
; fit in allocated memory to prevent kernel faults) |
cmp edx,[APP_HEADER_01.i_end] |
jb .fail |
; \end{diamond}[20.08.2006] |
mov [ebx+0x10], edx ;app_mem |
mov ecx,[APP_HEADER_01.stack_top] |
mov [ebx+0x0C], ecx ;app_esp |
mov edx,[APP_HEADER_01.i_param] |
mov [ebx], edx ;app_cmdline |
mov ecx,[APP_HEADER_01.i_icon] |
mov [ebx+4], ecx ;app_path |
mov edx, [APP_HEADER_01.i_end] |
mov [ebx+0x14], edx |
ret |
.fail: |
xor eax, eax |
ret |
align 4 |
proc get_new_process_place |
;input: |
; none |
;result: |
; eax=[new_process_place]<>0 - ok |
; 0 - failed. |
;This function find least empty slot. |
;It doesn't increase [TASK_COUNT]! |
mov eax,CURRENT_TASK |
mov ebx,[TASK_COUNT] |
inc ebx |
shl ebx,5 |
add ebx,eax ;ebx - address of process information for (last+1) slot |
.newprocessplace: |
;eax = address of process information for current slot |
cmp eax,ebx |
jz .endnewprocessplace ;empty slot after high boundary |
add eax,0x20 |
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty |
jnz .newprocessplace |
.endnewprocessplace: |
mov ebx,eax |
sub eax,CURRENT_TASK |
shr eax,5 ;calculate slot index |
cmp eax,256 |
jge .failed ;it should be <256 |
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) |
ret |
.failed: |
xor eax,eax |
ret |
endp |
align 4 |
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword |
locals |
app_pages dd ? |
img_pages dd ? |
dir_addr dd ? |
app_tabs dd ? |
endl |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
xor eax, eax |
mov [dir_addr], eax |
mov eax, [app_size] |
add eax, 4095 |
and eax, NOT(4095) |
mov [app_size], eax |
mov ebx, eax |
shr eax, 12 |
mov [app_pages], eax |
add ebx, 0x3FFFFF |
and ebx, NOT(0x3FFFFF) |
shr ebx, 22 |
mov [app_tabs], ebx |
mov ecx, [img_size] |
add ecx, 4095 |
and ecx, NOT(4095) |
mov [img_size], ecx |
shr ecx, 12 |
mov [img_pages], ecx |
if GREEDY_KERNEL |
lea eax, [ecx+ebx+2] ;only image size |
else |
lea eax, [eax+ebx+2] ;all requested memory |
end if |
cmp eax, [pg_data.pages_free] |
ja .fail |
call alloc_page |
test eax, eax |
jz .fail |
mov [dir_addr], eax |
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW |
mov edi, [tmp_task_pdir] |
mov ecx, (OS_BASE shr 20)/4 |
xor eax, eax |
cld |
rep stosd |
mov ecx, (OS_BASE shr 20)/4 |
mov esi, sys_pgdir+(OS_BASE shr 20) |
rep movsd |
mov eax, [dir_addr] |
or eax, PG_SW |
mov [edi-4096+(page_tabs shr 20)], eax |
and eax, -4096 |
call set_cr3 |
mov edx, [app_tabs] |
mov edi, new_app_base |
@@: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page_table, edi, eax |
add edi, 0x00400000 |
dec edx |
jnz @B |
mov edi, new_app_base |
shr edi, 10 |
add edi, page_tabs |
mov ecx, [app_tabs] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov ecx, [img_pages] |
mov ebx, PG_UW |
mov edx, new_app_base |
mov esi, [img_base] |
mov edi, new_app_base |
shr esi, 10 |
shr edi, 10 |
add esi, page_tabs |
add edi, page_tabs |
.remap: |
lodsd |
or eax, ebx ; force user level r/w access |
stosd |
add edx, 0x1000 |
dec [app_pages] |
dec ecx |
jnz .remap |
mov ecx, [app_pages] |
test ecx, ecx |
jz .done |
if GREEDY_KERNEL |
mov eax, 0x02 |
rep stosd |
else |
.alloc: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page,edx,eax,dword PG_UW |
add edx, 0x1000 |
dec [app_pages] |
jnz .alloc |
end if |
.done: |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
dec [pg_data.pg_mutex] |
mov eax, [dir_addr] |
ret |
.fail: |
dec [pg_data.pg_mutex] |
cmp [dir_addr], 0 |
je @f |
stdcall destroy_app_space, [dir_addr], 0 |
@@: |
xor eax, eax |
ret |
endp |
align 4 |
set_cr3: |
mov ebx, [current_slot] |
mov [ebx+APPDATA.dir_table], eax |
mov cr3, eax |
ret |
align 4 |
proc destroy_page_table stdcall, pg_tab:dword |
push esi |
mov esi, [pg_tab] |
mov ecx, 1024 |
.free: |
mov eax, [esi] |
test eax, 1 |
jz .next |
test eax, 1 shl 9 |
jnz .next ;skip shared pages |
call free_page |
.next: |
add esi, 4 |
dec ecx |
jnz .free |
pop esi |
ret |
endp |
align 4 |
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword |
xor edx,edx |
push edx |
mov eax,0x2 |
mov ebx, [pg_dir] |
.loop: |
;eax = current slot of process |
mov ecx,eax |
shl ecx,5 |
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running? |
jz @f ;skip empty slots |
shl ecx,3 |
add ecx,SLOT_BASE |
cmp [ecx+APPDATA.dir_table],ebx ;compare page directory addresses |
jnz @f |
mov [ebp-4],ecx |
inc edx ;thread found |
@@: |
inc eax |
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes |
jle .loop |
;edx = number of threads |
;our process is zombi so it isn't counted |
pop ecx |
cmp edx,1 |
jg .ret |
;if there isn't threads then clear memory. |
mov esi, [dlls_list] |
call destroy_all_hdlls |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov eax, [pg_dir] |
and eax, not 0xFFF |
stdcall map_page,[tmp_task_pdir],eax,PG_SW |
mov esi, [tmp_task_pdir] |
mov edi, (OS_BASE shr 20)/4 |
.destroy: |
mov eax, [esi] |
test eax, 1 |
jz .next |
and eax, not 0xFFF |
stdcall map_page,[tmp_task_ptab],eax,PG_SW |
stdcall destroy_page_table, [tmp_task_ptab] |
mov eax, [esi] |
call free_page |
.next: |
add esi, 4 |
dec edi |
jnz .destroy |
mov eax, [pg_dir] |
call free_page |
.exit: |
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP |
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP |
dec [pg_data.pg_mutex] |
.ret: |
ret |
endp |
align 4 |
get_pid: |
mov eax, [TASK_BASE] |
mov eax, [eax+TASKDATA.pid] |
ret |
pid_to_slot: |
;Input: |
; eax - pid of process |
;Output: |
; eax - slot of process or 0 if process don't exists |
;Search process by PID. |
push ebx |
push ecx |
mov ebx,[TASK_COUNT] |
shl ebx,5 |
mov ecx,2*32 |
.loop: |
;ecx=offset of current process info entry |
;ebx=maximum permitted offset |
cmp byte [CURRENT_TASK+ecx+0xa],9 |
jz .endloop ;skip empty slots |
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID |
jz .pid_found |
.endloop: |
add ecx,32 |
cmp ecx,ebx |
jle .loop |
pop ecx |
pop ebx |
xor eax,eax |
ret |
.pid_found: |
shr ecx,5 |
mov eax,ecx ;convert offset to index of slot |
pop ecx |
pop ebx |
ret |
check_region: |
;input: |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
mov eax,[CURRENT_TASK] |
jmp check_process_region |
;----------------------------------------------------------------------------- |
check_process_region: |
;input: |
; eax - slot |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
test ecx,ecx |
jle .ok |
shl eax,5 |
cmp word [CURRENT_TASK+eax+0xa],0 |
jnz .failed |
shl eax,3 |
mov eax,[SLOT_BASE+eax+0xb8] |
test eax,eax |
jz .failed |
mov eax,1 |
ret |
; call MEM_Get_Linear_Address |
; push ebx |
; push ecx |
; push edx |
; mov edx,ebx |
; and edx,not (4096-1) |
; sub ebx,edx |
; add ecx,ebx |
; mov ebx,edx |
; add ecx,(4096-1) |
; and ecx,not (4096-1) |
;.loop: |
;;eax - linear address of page directory |
;;ebx - current page |
;;ecx - current size |
; mov edx,ebx |
; shr edx,22 |
; mov edx,[eax+4*edx] |
; and edx,not (4096-1) |
; test edx,edx |
; jz .failed1 |
; push eax |
; mov eax,edx |
; call MEM_Get_Linear_Address |
; mov edx,ebx |
; shr edx,12 |
; and edx,(1024-1) |
; mov eax,[eax+4*edx] |
; and eax,not (4096-1) |
; test eax,eax |
; pop eax |
; jz .failed1 |
; add ebx,4096 |
; sub ecx,4096 |
; jg .loop |
; pop edx |
; pop ecx |
; pop ebx |
.ok: |
mov eax,1 |
ret |
; |
;.failed1: |
; pop edx |
; pop ecx |
; pop ebx |
.failed: |
xor eax,eax |
ret |
align 4 |
proc read_process_memory |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - start address in other process |
;Output: |
; eax - number of bytes read. |
locals |
slot dd ? |
buff dd ? |
r_count dd ? |
offset dd ? |
tmp_r_cnt dd ? |
endl |
mov [slot], eax |
mov [buff], ebx |
and [r_count], 0 |
mov [tmp_r_cnt], ecx |
mov [offset], edx |
pushad |
.read_mem: |
mov edx, [offset] |
mov ebx, [tmp_r_cnt] |
mov ecx, 0x400000 |
and edx, 0x3FFFFF |
sub ecx, edx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
cmp ecx, 0x8000 |
jna @F |
mov ecx, 0x8000 |
@@: |
mov ebx, [offset] |
push ecx |
stdcall map_memEx, [proc_mem_map],\ |
[slot], ebx, ecx, PG_MAP |
pop ecx |
mov esi, [offset] |
and esi, 0xfff |
sub eax, esi |
jbe .ret |
cmp ecx, eax |
jbe @f |
mov ecx, eax |
mov [tmp_r_cnt], eax |
@@: |
add esi, [proc_mem_map] |
mov edi, [buff] |
mov edx, ecx |
rep movsb |
add [r_count], edx |
add [offset], edx |
sub [tmp_r_cnt], edx |
jnz .read_mem |
.ret: |
popad |
mov eax, [r_count] |
ret |
endp |
align 4 |
proc write_process_memory |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - start address in other process |
;Output: |
; eax - number of bytes written |
locals |
slot dd ? |
buff dd ? |
w_count dd ? |
offset dd ? |
tmp_w_cnt dd ? |
endl |
mov [slot], eax |
mov [buff], ebx |
and [w_count], 0 |
mov [tmp_w_cnt], ecx |
mov [offset], edx |
pushad |
.read_mem: |
mov edx, [offset] |
mov ebx, [tmp_w_cnt] |
mov ecx, 0x400000 |
and edx, 0x3FFFFF |
sub ecx, edx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
cmp ecx, 0x8000 |
jna @F |
mov ecx, 0x8000 |
@@: |
mov ebx, [offset] |
; add ebx, new_app_base |
push ecx |
stdcall map_memEx, [proc_mem_map],\ |
[slot], ebx, ecx, PG_SW |
pop ecx |
mov edi, [offset] |
and edi, 0xfff |
sub eax, edi |
jbe .ret |
cmp ecx, eax |
jbe @f |
mov ecx, eax |
mov [tmp_w_cnt], eax |
@@: |
add edi, [proc_mem_map] |
mov esi, [buff] |
mov edx, ecx |
rep movsb |
add [w_count], edx |
add [offset], edx |
sub [tmp_w_cnt], edx |
jnz .read_mem |
.ret: |
popad |
mov eax, [w_count] |
ret |
endp |
align 4 |
proc new_sys_threads |
locals |
slot dd ? |
app_cmdline dd ? ;0x00 |
app_path dd ? ;0x04 |
app_eip dd ? ;0x08 |
app_esp dd ? ;0x0C |
app_mem dd ? ;0x10 |
endl |
cmp eax,1 |
jne .failed ;other subfunctions |
xor eax,eax |
mov [app_cmdline], eax |
mov [app_path], eax |
mov [app_eip], ebx |
mov [app_esp], ecx |
;mov esi,new_process_loading |
;call sys_msg_board_str |
.wait_lock: |
cmp [application_table_status],0 |
je .get_lock |
call change_task |
jmp .wait_lock |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
cmp eax, 0 |
jne .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
jz .failed |
mov [slot], eax |
mov esi,[current_slot] |
mov ebx,esi ;ebx=esi - pointer to extended information about current thread |
mov edi, eax |
shl edi,8 |
add edi,SLOT_BASE |
mov edx,edi ;edx=edi - pointer to extended infomation about new thread |
mov ecx,256/4 |
xor eax, eax |
cld |
rep stosd ;clean extended information about new thread |
mov esi,ebx |
mov edi,edx |
mov ecx,11 |
rep movsb ;copy process name |
mov eax,[ebx+APPDATA.heap_base] |
mov [edx+APPDATA.heap_base], eax |
mov ecx,[ebx+APPDATA.heap_top] |
mov [edx+APPDATA.heap_top], ecx |
mov eax,[ebx+APPDATA.mem_size] |
mov [edx+APPDATA.mem_size], eax |
mov ecx,[ebx+APPDATA.dir_table] |
mov [edx+APPDATA.dir_table],ecx ;copy page directory |
mov eax,[ebx+APPDATA.dlls_list_ptr] |
mov [edx+APPDATA.dlls_list_ptr],eax |
mov eax, [ebx+APPDATA.tls_base] |
test eax, eax |
jz @F |
push edx |
stdcall user_alloc, 4096 |
pop edx |
test eax, eax |
jz .failed |
@@: |
mov [edx+APPDATA.tls_base], eax |
lea eax, [app_cmdline] |
stdcall set_app_params ,[slot],eax,dword 0,\ |
dword 0,dword 0 |
;mov esi,new_process_running |
;call sys_msg_board_str ;output information about succefull startup |
mov [application_table_status],0 ;unlock application_table_status mutex |
mov eax,[process_number] ;set result |
ret |
.failed: |
mov [application_table_status],0 |
mov eax,-1 |
ret |
endp |
; param |
; ebx=mutex |
align 4 |
wait_mutex: |
;;Maxis use atomic bts for mutex 4.4.2009 |
push eax |
push ebx |
.do_wait: |
bts dword [ebx],0 |
jnc .locked |
call change_task |
jmp .do_wait |
.locked: |
pop ebx |
pop eax |
ret |
align 4 |
tls_app_entry: |
call init_heap |
stdcall user_alloc, 4096 |
mov edx, [current_slot] |
mov [edx+APPDATA.tls_base], eax |
mov [tls_data_l+2],ax |
shr eax,16 |
mov [tls_data_l+4],al |
mov [tls_data_l+7],ah |
mov dx, app_tls |
mov fs, dx |
popad |
iretd |
EFL_IF equ 0x0200 |
EFL_IOPL1 equ 0x1000 |
EFL_IOPL2 equ 0x2000 |
EFL_IOPL3 equ 0x3000 |
align 4 |
proc set_app_params stdcall,slot:dword, params:dword,\ |
cmd_line:dword, app_path:dword, flags:dword |
locals |
pl0_stack dd ? |
endl |
stdcall kernel_alloc, RING0_STACK_SIZE+512 |
mov [pl0_stack], eax |
lea edi, [eax+RING0_STACK_SIZE] |
mov eax, [slot] |
mov ebx, eax |
shl eax, 8 |
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi |
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0 |
mov [eax+SLOT_BASE+APPDATA.except_mask], 0 |
;set default io permission map |
mov ecx, [SLOT_BASE+256+APPDATA.io_map] |
mov [eax+SLOT_BASE+APPDATA.io_map], ecx |
mov ecx, [SLOT_BASE+256+APPDATA.io_map+4] |
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx |
mov esi, fpu_data |
mov ecx, 512/4 |
rep movsd |
cmp ebx,[TASK_COUNT] |
jle .noinc |
inc dword [TASK_COUNT] ;update number of processes |
.noinc: |
shl ebx,8 |
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET] |
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx |
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx |
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET |
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx |
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx |
mov ecx, [def_cursor] |
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx |
mov eax, [pl0_stack] |
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax |
add eax, RING0_STACK_SIZE |
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax |
push ebx |
stdcall kernel_alloc, 0x1000 |
pop ebx |
mov esi,[current_slot] |
mov esi,[esi+APPDATA.cur_dir] |
mov ecx,0x1000/4 |
mov edi,eax |
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax |
rep movsd |
shr ebx,3 |
mov eax, new_app_base |
mov dword [CURRENT_TASK+ebx+0x10],eax |
.add_command_line: |
mov edx,[params] |
mov edx,[edx] ;app_cmdline |
test edx,edx |
jz @f ;application doesn't need parameters |
mov eax, edx |
add eax, 256 |
jc @f |
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] |
ja @f |
mov byte [edx], 0 ;force empty string if no cmdline given |
mov eax, [cmd_line] |
test eax, eax |
jz @f |
stdcall strncpy, edx, eax, 256 |
@@: |
mov edx,[params] |
mov edx, [edx+4] ;app_path |
test edx,edx |
jz @F ;application don't need path of file |
mov eax, edx |
add eax, 1024 |
jc @f |
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] |
ja @f |
stdcall strncpy, edx, [app_path], 1024 |
@@: |
mov ebx,[slot] |
mov eax,ebx |
shl ebx,5 |
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data |
mov edx, irq0.return |
cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1 |
jne @F |
mov edx, tls_app_entry |
@@: |
; set window state to 'normal' (non-minimized/maximized/rolled-up) state |
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL |
mov [ebx+window_data+WDATA.fl_redraw], 1 |
add ebx,CURRENT_TASK ;ebx - pointer to information about process |
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot |
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) |
inc dword [process_number] |
mov eax,[process_number] |
mov [ebx+4],eax ;set PID |
;set draw data to full screen |
mov [ecx+0],dword 0 |
mov [ecx+4],dword 0 |
mov eax,[Screen_Max_X] |
mov [ecx+8],eax |
mov eax,[Screen_Max_Y] |
mov [ecx+12],eax |
mov ebx, [pl0_stack] |
mov esi,[params] |
lea ecx, [ebx+REG_EIP] |
xor eax, eax |
mov [ebx+REG_RET], edx |
mov [ebx+REG_EDI], eax |
mov [ebx+REG_ESI], eax |
mov [ebx+REG_EBP], eax |
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP |
mov [ebx+REG_EBX], eax |
mov [ebx+REG_EDX], eax |
mov [ebx+REG_ECX], eax |
mov [ebx+REG_EAX], eax |
mov eax, [esi+0x08] ;app_eip |
mov [ebx+REG_EIP], eax ;app_entry |
mov [ebx+REG_CS], dword app_code |
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF |
mov eax, [esi+0x0C] ;app_esp |
mov [ebx+REG_APP_ESP], eax ;app_stack |
mov [ebx+REG_SS], dword app_data |
lea ecx, [ebx+REG_RET] |
mov ebx, [slot] |
shl ebx, 5 |
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx |
xor ecx, ecx ; process state - running |
; set if debuggee |
test byte [flags], 1 |
jz .no_debug |
inc ecx ; process state - suspended |
mov eax,[CURRENT_TASK] |
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax |
.no_debug: |
mov [CURRENT_TASK+ebx+TASKDATA.state], cl |
;mov esi,new_process_running |
;call sys_msg_board_str ;output information about succefull startup |
ret |
endp |
include "debug.inc" |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/sys32.inc |
---|
0,0 → 1,844 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; MenuetOS process management, protected ring3 ;; |
;; ;; |
;; Distributed under GPL. See file COPYING for details. ;; |
;; Copyright 2003 Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
align 4 ;3A08 |
build_interrupt_table: |
mov edi, idts |
mov esi, sys_int |
mov ecx, 0x40 |
mov eax, (10001110b shl 24) + os_code |
@@: movsw ;low word of code-entry |
stosd ;interrupt gate type : os_code selector |
movsw ;high word of code-entry |
loop @b |
movsd ;copy low dword of trap gate for int 0x40 |
movsd ;copy high dword of trap gate for int 0x40 |
lidt [esi] |
ret |
iglobal |
align 4 |
sys_int: |
;exception handlers addresses (for interrupt gate construction) |
dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc |
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 |
dd e16, e17,e18, e19 |
times 12 dd unknown_interrupt ;int_20..int_31 |
;interrupt handlers addresses (for interrupt gate construction) |
dd irq0, irq_serv.irq_1, irq_serv.irq_2 |
if USE_COM_IRQ |
dd irq_serv.irq_3, irq_serv.irq_4 |
else |
dd p_irq3, p_irq4 ;??? íåñòûêîâêà |
end if |
dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 |
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 |
dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15 |
times 16 dd unknown_interrupt ;int_0x30..int_0x3F |
;int_0x40 gate trap (for directly copied) |
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 |
idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) |
dw 2*($-sys_int-4)-1 |
dd idts ;0x8000B100 |
dw 0 ;ïðîñòî âûðàâíèâàíèå |
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b |
dd msg_exc_c,msg_exc_d,msg_exc_e |
msg_exc_8 db "Double fault", 0 |
msg_exc_u db "Undefined Exception", 0 |
msg_exc_a db "Invalid TSS", 0 |
msg_exc_b db "Segment not present", 0 |
msg_exc_c db "Stack fault", 0 |
msg_exc_d db "General protection fault", 0 |
msg_exc_e db "Page fault", 0 |
msg_sel_ker db "kernel", 0 |
msg_sel_app db "application", 0 |
endg |
macro save_ring3_context { |
pushad |
} |
macro restore_ring3_context { |
popad |
} |
macro exc_wo_code [num] { |
e#num : |
save_ring3_context |
mov bl, num |
jmp exc_c |
} exc_wo_code 0,1,2,3,4,5,6,15,16,19 |
macro exc_w_code [num] { |
e#num : |
add esp, 4 |
save_ring3_context |
mov bl, num |
jmp exc_c |
} exc_w_code 8,9,10,11,12,13,17,18 |
uglobal |
pf_err_code dd ? |
endg |
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû... |
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF |
save_ring3_context |
mov bl,14 |
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM) |
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü) |
reg_ss equ esp+0x30 |
reg_esp3 equ esp+0x2C |
reg_eflags equ esp+0x28 |
reg_cs3 equ esp+0x24 |
reg_eip equ esp+0x20 |
; ýòî ôðýéì îò pushad |
reg_eax equ esp+0x1C |
reg_ecx equ esp+0x18 |
reg_edx equ esp+0x14 |
reg_ebx equ esp+0x10 |
reg_esp0 equ esp+0x0C |
reg_ebp equ esp+0x08 |
reg_esi equ esp+0x04 |
reg_edi equ esp+0x00 |
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ |
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû |
cld ; è ïðèâîäèì DF ê ñòàíäàðòó |
movzx ebx,bl |
; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
test byte[reg_eflags+2],2 |
jnz v86_exc_c |
cmp bl,14 ; #PF |
jne @f |
call page_fault_handler ; SEE: core/memory.inc |
@@: mov esi, [current_slot] |
btr [esi+APPDATA.except_mask], ebx |
jnc @f |
mov eax,[esi+APPDATA.exc_handler] |
test eax, eax |
jnz IRetToUserHook |
@@: cli |
mov eax, [esi+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
call show_error_parameters ;; only ONE using, inline ??? |
;mov edx, [TASK_BASE] |
mov [edx + TASKDATA.state], byte 4 ; terminate |
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
; eax=debugger PID |
mov ecx,1 ; debug_message code=other_exception |
cmp bl,1 ; #DB |
jne .notify ; notify debugger and suspend ourself |
mov ebx, dr6 ; debug_message data=DR6_image |
xor edx, edx |
mov dr6, edx |
mov edx, dr7 |
mov cl, not 8 |
.l1: shl dl,2 |
jc @f |
and bl, cl |
@@: sar cl,1 |
jc .l1 |
mov cl, 3 ; debug_message code=debug_exception |
.notify: |
push ebx ; debug_message data |
mov ebx, [TASK_BASE] |
push [ebx+TASKDATA.pid] ; PID |
push ecx ; debug_message code ((here: ecx==1/3)) |
mov cl, 12 ; debug_message size |
call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc |
add esp,12 |
mov edx, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task ; SEE: core/shed.inc |
restore_ring3_context |
iretd |
IRetToUserHook: |
xchg eax, [reg_eip] |
sub dword[reg_esp3], 8 |
mov edi, [reg_esp3] |
stosd |
mov [edi], ebx |
restore_ring3_context |
unknown_interrupt: |
iretd |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
show_error_parameters: |
mov edx,[TASK_BASE] ;not scratched below |
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] |
cmp bl, 0x08 |
jb .l0 |
cmp bl, 0x0e |
jbe .l1 |
.l0: mov bl, 0x09 |
.l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4] |
DEBUGF 1, "K : %s\n", eax |
mov eax, [reg_cs3+4] |
mov edi, msg_sel_app |
mov ebx, [reg_esp3+4] |
cmp eax, app_code |
je @f |
mov edi, msg_sel_ker |
mov ebx, [reg_esp0+4] |
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] |
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx |
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi |
ret |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
restore reg_ss |
restore reg_esp3 |
restore reg_eflags |
restore reg_cs |
restore reg_eip |
restore reg_eax |
restore reg_ecx |
restore reg_edx |
restore reg_ebx |
restore reg_esp0 |
restore reg_ebp |
restore reg_esi |
restore reg_edi |
; irq1 -> hid/keyboard.inc |
macro irqh [num] { |
p_irq#num : |
mov edi, num |
jmp irqhandler |
} |
p_irq6: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 6 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
call fdc_irq |
call ready_for_next_irq |
restore_ring3_context |
iret |
p_irq14: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 14 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
; mov byte [BOOT_VAR + 0x48E], 0xFF |
call [irq14_func] |
call ready_for_next_irq_1 |
restore_ring3_context |
iret |
p_irq15: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 15 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
; mov byte [BOOT_VAR + 0x48E], 0xFF |
call [irq15_func] |
call ready_for_next_irq_1 |
restore_ring3_context |
iret |
ready_for_next_irq: |
mov eax,5 |
mov [check_idle_semaphore],eax |
; mov al, 0x20 |
add eax,(0x20-0x5) |
out 0x20, al |
ret |
;destroy eax |
ready_for_next_irq_1: |
mov eax,5 |
mov [check_idle_semaphore],eax |
; mov al, 0x20 |
add eax,(0x20-0x5) |
out 0xa0,al |
out 0x20, al |
ret |
irqD: |
push eax |
xor eax,eax |
out 0xf0,al |
mov al,0x20 |
out 0xa0,al |
out 0x20,al |
pop eax |
iret |
irqh 2,3,4,5,7,8,9,10,11 |
irqhandler: |
mov esi,edi ; 1 |
shl esi,6 ; 1 |
add esi,irq00read ; 1 |
shl edi,12 ; 1 |
add edi,IRQ_SAVE |
mov ecx,16 |
irqnewread: |
dec ecx |
js irqover |
movzx edx, word [esi] ; 2+ |
test edx, edx ; 1 |
jz irqover |
mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size |
mov eax, 4000 ; + 0x4 dword - data begin offset |
cmp ebx, eax |
je irqfull |
add ebx, [edi + 0x4] ; add data size to data begin offset |
cmp ebx, eax ; if end of buffer, begin cycle again |
jb @f |
xor ebx, ebx |
@@: |
add ebx, edi |
movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word |
dec eax |
jz irqbyte |
dec eax |
jnz noirqword |
in ax,dx |
cmp ebx, 3999 ; check for address odd in the end of buffer |
jne .odd |
mov [ebx + 0x10], ax |
jmp .add_size |
.odd: |
mov [ebx + 0x10], al ; I could make mistake here :) |
mov [edi + 0x10], ah |
.add_size: |
add dword [edi], 2 |
jmp nextport |
irqbyte: |
in al,dx |
mov [ebx + 0x10],al |
inc dword [edi] |
nextport: |
add esi,4 |
jmp irqnewread |
noirqword: |
irqfull: |
irqover: |
ret |
set_application_table_status: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax, 5 |
add eax,CURRENT_TASK+TASKDATA.pid |
mov eax,[eax] |
mov [application_table_status],eax |
pop eax |
ret |
clear_application_table_status: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax, 5 |
add eax,CURRENT_TASK+TASKDATA.pid |
mov eax,[eax] |
cmp eax,[application_table_status] |
jne apptsl1 |
xor eax,eax |
mov [application_table_status],eax |
apptsl1: |
pop eax |
ret |
; * eax = 64 - íîìåð ôóíêöèè |
; * ebx = 1 - åäèíñòâåííàÿ ïîäôóíêöèÿ |
; * ecx = íîâûé ðàçìåð ïàìÿòè |
;Âîçâðàùàåìîå çíà÷åíèå: |
; * eax = 0 - óñïåøíî |
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè |
sys_resize_app_memory: |
; ebx = 1 - resize |
; ecx = new amount of memory |
; cmp eax,1 |
dec ebx |
jnz .no_application_mem_resize |
stdcall new_mem_resize, ecx |
mov [esp+32], eax |
.no_application_mem_resize: |
ret |
sys_threads: |
; eax=1 create thread |
; |
; ebx=thread start |
; ecx=thread stack value |
; |
; on return : eax = pid |
jmp new_sys_threads |
iglobal |
; process_terminating db 'K : Process - terminating',13,10,0 |
; process_terminated db 'K : Process - done',13,10,0 |
msg_obj_destroy db 'K : destroy app object',13,10,0 |
endg |
; param |
; esi= slot |
terminate: ; terminate application |
.slot equ esp ;locals |
push esi ;save .slot |
shl esi, 8 |
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 |
jne @F |
pop esi |
shl esi, 5 |
mov [CURRENT_TASK+esi+TASKDATA.state], 9 |
ret |
@@: |
;mov esi,process_terminating |
;call sys_msg_board_str |
@@: |
cli |
cmp [application_table_status],0 |
je term9 |
sti |
call change_task |
jmp @b |
term9: |
call set_application_table_status |
; if the process is in V86 mode... |
mov eax, [.slot] |
shl eax, 8 |
mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack] |
add esi, RING0_STACK_SIZE |
cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi |
jz .nov86 |
; ...it has page directory for V86 mode |
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] |
mov ecx, [esi+4] |
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx |
; ...and I/O permission map for V86 mode |
mov ecx, [esi+12] |
mov [eax+SLOT_BASE+APPDATA.io_map], ecx |
mov ecx, [esi+8] |
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx |
.nov86: |
mov esi, [.slot] |
shl esi,8 |
add esi, SLOT_BASE+APP_OBJ_OFFSET |
@@: |
mov eax, [esi+APPOBJ.fd] |
test eax, eax |
jz @F |
cmp eax, esi |
je @F |
push esi |
call [eax+APPOBJ.destroy] |
DEBUGF 1,"%s",msg_obj_destroy |
pop esi |
jmp @B |
@@: |
mov eax, [.slot] |
shl eax, 8 |
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr] |
mov esi, [.slot] |
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 |
jne @F |
mov [fpu_owner],1 |
mov eax, [256+SLOT_BASE+APPDATA.fpu_state] |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxrstor [eax] |
jmp @F |
.no_SSE: |
fnclex |
frstor [eax] |
@@: |
mov [KEY_COUNT],byte 0 ; empty keyboard buffer |
mov [BTN_COUNT],byte 0 ; empty button buffer |
; remove defined hotkeys |
mov eax, hotkey_list |
.loop: |
cmp [eax+8], esi |
jnz .cont |
mov ecx, [eax] |
jecxz @f |
push dword [eax+12] |
pop dword [ecx+12] |
@@: |
mov ecx, [eax+12] |
push dword [eax] |
pop dword [ecx] |
xor ecx, ecx |
mov [eax], ecx |
mov [eax+4], ecx |
mov [eax+8], ecx |
mov [eax+12], ecx |
.cont: |
add eax, 16 |
cmp eax, hotkey_list+256*16 |
jb .loop |
; remove hotkeys in buffer |
mov eax, hotkey_buffer |
.loop2: |
cmp [eax], esi |
jnz .cont2 |
and dword [eax+4], 0 |
and dword [eax], 0 |
.cont2: |
add eax, 8 |
cmp eax, hotkey_buffer+120*8 |
jb .loop2 |
mov ecx,esi ; remove buttons |
bnewba2: |
mov edi,[BTN_ADDR] |
mov eax,edi |
cld |
movzx ebx,word [edi] |
inc bx |
bnewba: |
dec bx |
jz bnmba |
add eax,0x10 |
cmp cx,[eax] |
jnz bnewba |
pusha |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
popa |
jmp bnewba2 |
bnmba: |
pusha ; save window coordinates for window restoring |
cld |
shl esi,5 |
add esi,window_data |
mov eax,[esi+WDATA.box.left] |
mov [dlx],eax |
add eax,[esi+WDATA.box.width] |
mov [dlxe],eax |
mov eax,[esi+WDATA.box.top] |
mov [dly],eax |
add eax,[esi+WDATA.box.height] |
mov [dlye],eax |
xor eax, eax |
mov [esi+WDATA.box.left],eax |
mov [esi+WDATA.box.width],eax |
mov [esi+WDATA.box.top],eax |
mov [esi+WDATA.box.height],eax |
mov [esi+WDATA.cl_workarea],eax |
mov [esi+WDATA.cl_titlebar],eax |
mov [esi+WDATA.cl_frames],eax |
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn |
lea edi, [esi-window_data+draw_data] |
mov ecx,32/4 |
rep stosd |
popa |
; debuggee test |
pushad |
mov edi, esi |
shl edi, 5 |
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot] |
test eax, eax |
jz .nodebug |
push 8 |
pop ecx |
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID |
push 2 |
call debugger_notify |
pop ecx |
pop ecx |
.nodebug: |
popad |
mov ebx, [.slot] |
shl ebx, 8 |
push ebx |
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] |
stdcall kernel_free, ebx |
pop ebx |
mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir] |
stdcall kernel_free, ebx |
mov edi, [.slot] |
shl edi,8 |
add edi,SLOT_BASE |
mov eax, [edi+APPDATA.io_map] |
cmp eax, [SLOT_BASE+256+APPDATA.io_map] |
je @F |
call free_page |
@@: |
mov eax, [edi+APPDATA.io_map+4] |
cmp eax, [SLOT_BASE+256+APPDATA.io_map+4] |
je @F |
call free_page |
@@: |
mov eax, 0x20202020 |
stosd |
stosd |
stosd |
mov ecx,244/4 |
xor eax, eax |
rep stosd |
; activate window |
movzx eax, word [WIN_STACK + esi*2] |
cmp eax, [TASK_COUNT] |
jne .dont_activate |
pushad |
.check_next_window: |
dec eax |
cmp eax, 1 |
jbe .nothing_to_activate |
lea esi, [WIN_POS+eax*2] |
movzx edi, word [esi] ; edi = process |
shl edi, 5 |
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots |
je .check_next_window |
add edi, window_data |
; \begin{diamond}[19.09.2006] |
; skip minimized windows |
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .check_next_window |
; \end{diamond} |
call waredraw |
.nothing_to_activate: |
popad |
.dont_activate: |
push esi ; remove hd1 & cd & flp reservation |
shl esi, 5 |
mov esi, [esi+CURRENT_TASK+TASKDATA.pid] |
cmp [hd1_status], esi |
jnz @f |
call free_hd_channel |
and [hd1_status], 0 |
@@: |
cmp [cd_status], esi |
jnz @f |
call free_cd_channel |
and [cd_status], 0 |
@@: |
cmp [flp_status], esi |
jnz @f |
and [flp_status], 0 |
@@: |
pop esi |
cmp [bgrlockpid], esi |
jnz @f |
and [bgrlockpid], 0 |
and [bgrlock], 0 |
@@: |
pusha ; remove all irq reservations |
mov eax,esi |
shl eax, 5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov edi,irq_owner |
xor ebx, ebx |
xor edx, edx |
newirqfree: |
cmp [edi + 4 * ebx], eax |
jne nofreeirq |
mov [edi + 4 * ebx], edx ; remove irq reservation |
mov [irq_tab + 4 * ebx], edx ; remove irq handler |
mov [irq_rights + 4 * ebx], edx ; set access rights to full access |
nofreeirq: |
inc ebx |
cmp ebx, 16 |
jb newirqfree |
popa |
pusha ; remove all port reservations |
mov edx,esi |
shl edx, 5 |
add edx,CURRENT_TASK |
mov edx,[edx+TASKDATA.pid] |
rmpr0: |
mov esi,[RESERVED_PORTS] |
test esi,esi |
jz rmpr9 |
rmpr3: |
mov edi,esi |
shl edi,4 |
add edi,RESERVED_PORTS |
cmp edx,[edi] |
je rmpr4 |
dec esi |
jnz rmpr3 |
jmp rmpr9 |
rmpr4: |
mov ecx,256 |
sub ecx,esi |
shl ecx,4 |
mov esi,edi |
add esi,16 |
cld |
rep movsb |
dec dword [RESERVED_PORTS] |
jmp rmpr0 |
rmpr9: |
popa |
mov edi,esi ; do not run this process slot |
shl edi, 5 |
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9 |
; debugger test - terminate all debuggees |
mov eax, 2 |
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot |
.xd0: |
cmp eax, [TASK_COUNT] |
ja .xd1 |
cmp dword [ecx], esi |
jnz @f |
and dword [ecx], 0 |
pushad |
xchg eax, ecx |
mov ebx, 2 |
call sys_system |
popad |
@@: |
inc eax |
add ecx, 0x100 |
jmp .xd0 |
.xd1: |
; call systest |
sti ; .. and life goes on |
mov eax, [dlx] |
mov ebx, [dly] |
mov ecx, [dlxe] |
mov edx, [dlye] |
call calculatescreen |
xor eax, eax |
xor esi, esi |
call redrawscreen |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
and [application_table_status],0 |
;mov esi,process_terminated |
;call sys_msg_board_str |
add esp, 4 |
ret |
restore .slot |
iglobal |
boot_sched_1 db 'Building gdt tss pointer',0 |
boot_sched_2 db 'Building IDT table',0 |
endg |
build_scheduler: |
mov esi,boot_sched_1 |
call boot_log |
; call build_process_gdt_tss_pointer |
; mov esi,boot_sched_2 |
; call boot_log |
ret |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/syscall.inc |
---|
0,0 → 1,261 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Old style system call converter |
align 16 |
cross_order: |
; load all registers in crossed order |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, esi |
mov esi, edi |
movzx edi, byte[esp+28 + 4] |
call dword [servetable+edi*4] |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSENTER ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
sysenter_entry: |
; Íàñòðàèâàåì ñòåê |
mov esp, [ss:tss._esp0] |
sti |
push ebp ; save app esp + 4 |
mov ebp, [ebp] ; ebp - original ebp |
;------------------ |
pushad |
cld |
movzx eax, al |
call dword [servetable2 + eax * 4] |
popad |
;------------------ |
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4 |
sub ecx, 4 |
xchg edx, [ecx] ; edx - return point, & save original edx |
push edx |
mov edx, [ss:esp + 4] |
mov [ecx + 4], edx ; save original ecx |
pop edx |
sysexit |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSTEM CALL ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 16 |
i40: |
pushad |
cld |
movzx eax, al |
call dword [servetable2 + eax * 4] |
popad |
iretd |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSCALL ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
syscall_entry: |
; cli syscall clear IF |
xchg esp, [ss:tss._esp0] |
push ecx |
lea ecx, [esp+4] |
xchg ecx, [ss:tss._esp0] |
sti |
push ecx |
mov ecx, [ecx] |
;------------------ |
pushad |
cld |
movzx eax, al |
call dword [servetable2 + eax * 4] |
popad |
;------------------ |
mov ecx, [ss:esp+4] |
pop esp |
sysret |
iglobal |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; SYSTEM FUNCTIONS TABLE ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
servetable: |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 ; 24-PlayCdTrack,StopCd and GetCdPlaylist |
dd 0 ; 25 |
dd 0 ; 26 |
dd 0 |
dd 0 ; |
dd 0 |
dd 0 ; 30-Get/SetCurrentDirectory |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 ; 37-GetMousePosition_ScreenRelative,. |
dd 0 ; 38-DrawLine |
dd 0 ; 39-GetBackgroundSize,ReadBgrData,. |
dd 0 |
dd 0 |
dd 0 |
dd 0 ; 43-SendDeviceData |
dd 0 |
dd 0 |
dd 0 ; 46-ReservePortArea and FreePortArea |
dd display_number ; 47-WriteNum |
dd display_settings ; 48-SetRedrawType and SetButtonType |
dd sys_apm ; 49-Advanced Power Management (APM) |
dd random_shaped_window ; 50-Window shape & scale |
dd syscall_threads ; 51-Threads |
dd stack_driver_stat ; 52-Stack driver status |
dd socket ; 53-Socket interface |
dd 0 |
dd sound_interface ; 55-Sound interface |
dd 0 |
dd sys_pcibios ; 57-PCI BIOS32 |
dd file_system ; 58-Common file system interface |
dd 0 |
dd sys_IPC ; 60-Inter Process Communication |
dd sys_gs ; 61-Direct graphics access |
dd sys_pci ; 62-PCI functions |
dd sys_msg_board ; 63-System message board |
dd 0 ; 64-Resize application memory usage |
dd syscall_putimage_palette; 65-PutImagePalette |
dd sys_process_def ; 66-Process definitions - keyboard |
dd sys_window_move ; 67-Window move or resize |
dd f68 ; 68-Some internal services |
dd sys_debug_services ; 69-Debug |
dd file_system_lfn ; 70-Common file system interface, version 2 |
dd syscall_windowsettings ; 71-Window settings |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; NEW SYSTEM FUNCTIONS TABLE ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
servetable2: |
dd sys_drawwindow ; 0-DrawWindow |
dd syscall_setpixel ; 1-SetPixel |
dd sys_getkey ; 2-GetKey |
dd sys_clock ; 3-GetTime |
dd syscall_writetext ; 4-WriteText |
dd delay_hs ; 5-DelayHs |
dd syscall_openramdiskfile ; 6-OpenRamdiskFile |
dd syscall_putimage ; 7-PutImage |
dd sys_button ; 8-DefineButton |
dd sys_cpuusage ; 9-GetProcessInfo |
dd sys_waitforevent ; 10-WaitForEvent |
dd sys_getevent ; 11-CheckForEvent |
dd sys_redrawstat ; 12-BeginDraw and EndDraw |
dd syscall_drawrect ; 13-DrawRect |
dd syscall_getscreensize ; 14-GetScreenSize |
dd sys_background ; 15-bgr |
dd sys_cachetodiskette ; 16-FlushFloppyCache |
dd sys_getbutton ; 17-GetButton |
dd sys_system ; 18-System Services |
dd paleholder ; 19-reserved |
dd sys_midi ; 20-ResetMidi and OutputMidi |
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. |
dd sys_settime ; 22-setting date,time,clock and alarm-clock |
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent |
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist |
dd undefined_syscall ; 25-reserved |
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. |
dd undefined_syscall ; 27-reserved |
dd undefined_syscall ; 28-reserved |
dd sys_date ; 29-GetDate |
dd sys_current_directory ; 30-Get/SetCurrentDirectory |
dd undefined_syscall ; 31-reserved |
dd undefined_syscall ; 32-reserved |
dd undefined_syscall ; 33-reserved |
dd undefined_syscall ; 34-reserved |
dd syscall_getpixel ; 35-GetPixel |
dd syscall_getarea ; 36-GetArea |
dd readmousepos ; 37-GetMousePosition_ScreenRelative,. |
dd syscall_drawline ; 38-DrawLine |
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. |
dd set_app_param ; 40-WantEvents |
dd syscall_getirqowner ; 41-GetIrqOwner |
dd get_irq_data ; 42-ReadIrqData |
dd sys_outport ; 43-SendDeviceData |
dd sys_programirq ; 44-ProgramIrqs |
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq |
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea |
dd cross_order ; 47-WriteNum |
dd cross_order ; 48-SetRedrawType and SetButtonType |
dd cross_order ; 49-Advanced Power Management (APM) |
dd cross_order ; 50-Window shape & scale |
dd cross_order ; 51-Threads |
dd cross_order ; 52-Stack driver status |
dd cross_order ; 53-Socket interface |
dd undefined_syscall ; 54-reserved |
dd cross_order ; 55-Sound interface |
dd undefined_syscall ; 56-reserved |
dd cross_order ; 57-PCI BIOS32 |
dd cross_order ; 58-Common file system interface |
dd undefined_syscall ; 59-reserved |
dd cross_order ; 60-Inter Process Communication |
dd cross_order ; 61-Direct graphics access |
dd cross_order ; 62-PCI functions |
dd cross_order ; 63-System message board |
dd sys_resize_app_memory ; 64-Resize application memory usage |
dd cross_order ; 65-PutImagePalette |
dd cross_order ; 66-Process definitions - keyboard |
dd cross_order ; 67-Window move or resize |
dd cross_order ; 68-Some internal services |
dd cross_order ; 69-Debug |
dd cross_order ; 70-Common file system interface, version 2 |
dd cross_order ; 71-Window settings |
dd sys_sendwindowmsg ; 72-Send window message |
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall |
dd sys_end ; -1-end application |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/sched.inc |
---|
0,0 → 1,311 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; IRQ0 HANDLER (TIMER INTERRUPT) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
irq0: |
pushad |
Mov ds, ax, app_data |
mov es, ax |
inc [timer_ticks] |
mov eax, [timer_ticks] |
call playNote ; <<<--- Speaker driver |
sub eax,[next_usage_update] |
cmp eax,100 |
jb .nocounter |
add [next_usage_update],100 |
call updatecputimes |
.nocounter: |
mov al,0x20 ; send End Of Interrupt signal |
out 0x20,al |
btr dword[DONT_SWITCH], 0 |
jc .return |
call find_next_task |
jz .return ; if there is only one running process |
call do_change_task |
.return: |
popad |
iretd |
align 4 |
change_task: |
pushfd |
cli |
pushad |
if 0 |
; \begin{Mario79} ; <- must be refractoried, if used... |
cmp [dma_task_switched], 1 |
jne .find_next_task |
mov [dma_task_switched], 0 |
mov ebx, [dma_process] |
cmp [CURRENT_TASK], ebx |
je .return |
mov edi, [dma_slot_ptr] |
mov [CURRENT_TASK], ebx |
mov [TASK_BASE], edi |
jmp @f |
.find_next_task: |
; \end{Mario79} |
end if |
call find_next_task |
jz .return ; the same task -> skip switch |
@@: mov byte[DONT_SWITCH], 1 |
call do_change_task |
.return: |
popad |
popfd |
ret |
uglobal |
align 4 |
; far_jump: |
; .offs dd ? |
; .sel dw ? |
context_counter dd 0 ;noname & halyavin |
next_usage_update dd 0 |
timer_ticks dd 0 |
; prev_slot dd ? |
; event_sched dd ? |
endg |
align 4 |
update_counters: |
mov edi, [TASK_BASE] |
rdtsc |
sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add |
add [edi+TASKDATA.counter_sum], eax ; counter sum |
ret |
align 4 |
updatecputimes: |
xor eax,eax |
xchg eax,[idleuse] |
mov [idleusesec],eax |
mov ecx, [TASK_COUNT] |
mov edi, TASK_DATA |
.newupdate: |
xor eax,eax |
xchg eax,[edi+TASKDATA.counter_sum] |
mov [edi+TASKDATA.cpu_usage],eax |
add edi,0x20 |
loop .newupdate |
ret |
align 4 |
find_next_task: |
;info: |
; Find next task to execute |
;retval: |
; ebx = address of the APPDATA for the selected task (slot-base) |
; esi = previous slot-base ([current_slot] at the begin) |
; edi = address of the TASKDATA for the selected task |
; ZF = 1 if the task is the same |
;warning: |
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result |
; [current_slot] is not set to new value (ebx)!!! |
;scratched: eax,ecx |
call update_counters ; edi := [TASK_BASE] |
Mov esi, ebx, [current_slot] |
.loop: |
cmp bh,[TASK_COUNT] |
jb @f |
xor bh, bh |
mov edi,CURRENT_TASK |
@@: inc bh ; ebx += APPDATA.size |
add edi,0x20 ; edi += TASKDATA.size |
mov al, [edi+TASKDATA.state] |
test al, al |
jz .found ; state == 0 |
cmp al, 5 |
jne .loop ; state == 1,2,3,4,9 |
; state == 5 |
pushad ; more freedom for [APPDATA.wait_test] |
call [ebx+APPDATA.wait_test] |
mov [esp+28],eax |
popad |
or eax,eax |
jnz @f |
; testing for timeout |
mov ecx, [timer_ticks] |
sub ecx, [ebx+APPDATA.wait_begin] |
cmp ecx, [ebx+APPDATA.wait_timeout] |
jb .loop |
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait |
mov [edi+TASKDATA.state], 0 |
.found: |
mov [CURRENT_TASK],bh |
mov [TASK_BASE],edi |
rdtsc ;call _rdtsc |
mov [edi+TASKDATA.counter_add],eax ; for next using update_counters |
cmp ebx, esi ;esi - previous slot-base |
ret |
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86... |
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task |
align 4 |
do_change_task: |
;param: |
; ebx = address of the APPDATA for incoming task (new) |
;warning: |
; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task) |
; [current_slot] is the outcoming (old), and set here to a new value (ebx) |
;scratched: eax,ecx,esi |
mov esi,ebx |
xchg esi,[current_slot] |
; set new stack after saving old |
mov [esi+APPDATA.saved_esp], esp |
mov esp, [ebx+APPDATA.saved_esp] |
; set new thread io-map |
Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map] |
Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4] |
; set new thread memory-map |
mov ecx, APPDATA.dir_table |
mov eax, [ebx+ecx] ;offset>0x7F |
cmp eax, [esi+ecx] ;offset>0x7F |
je @f |
mov cr3, eax |
@@: |
; set tss.esp0 |
Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0] |
mov edx, [ebx+APPDATA.tls_base] |
cmp edx, [esi+APPDATA.tls_base] |
je @f |
mov [tls_data_l+2],dx |
shr edx,16 |
mov [tls_data_l+4],dl |
mov [tls_data_l+7],dh |
mov dx, app_tls |
mov fs, dx |
@@: |
; set gs selector unconditionally |
Mov gs,ax,graph_data |
; set CR0.TS |
cmp bh, byte[fpu_owner] ;bh == incoming task (new) |
clts ;clear a task switch flag |
je @f |
mov eax, cr0 ;and set it again if the owner |
or eax, CR0_TS ;of a fpu has changed |
mov cr0, eax |
@@: ; set context_counter (only for user pleasure ???) |
inc [context_counter] ;noname & halyavin |
; set debug-registers, if it's necessary |
test byte[ebx+APPDATA.dbg_state], 1 |
jz @f |
xor eax, eax |
mov dr6, eax |
lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F |
cld |
macro lodsReg [reg] { |
lodsd |
mov reg,eax |
} lodsReg dr0, dr1, dr2, dr3, dr7 |
purge lodsReg |
@@: ret |
;end. |
if 0 |
struc TIMER |
{ |
.next dd ? |
.exp_time dd ? |
.func dd ? |
.arg dd ? |
} |
MAX_PROIRITY 0 ; highest, used for kernel tasks |
MAX_USER_PRIORITY 0 ; highest priority for user processes |
USER_PRIORITY 7 ; default (should correspond to nice 0) |
MIN_USER_PRIORITY 14 ; minimum priority for user processes |
IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
uglobal |
rdy_head rd 16 |
endg |
align 4 |
pick_task: |
xor eax, eax |
.pick: |
mov ebx, [rdy_head+eax*4] |
test ebx, ebx |
jz .next |
mov [next_task], ebx |
test [ebx+flags.billable] |
jz @F |
mov [bill_task], ebx |
@@: |
ret |
.next: |
inc eax |
jmp .pick |
; param |
; eax= task |
; |
; retval |
; eax= task |
; ebx= queue |
; ecx= front if 1 or back if 0 |
align 4 |
shed: |
cmp [eax+.tics_left], 0 ;signed compare |
mov ebx, [eax+.priority] |
setg ecx |
jg @F |
mov edx, [eax+.tics_quantum] |
mov [eax+.ticks_left], edx |
cmp ebx, (IDLE_PRIORITY-1) |
je @F |
inc ebx |
@@: |
ret |
; param |
; eax= task |
align 4 |
enqueue: |
call shed ;eax |
cmp [rdy_head+ebx*4],0 |
jnz @F |
mov [rdy_head+ebx*4], eax |
mov [rdy_tail+ebx*4], eax |
mov [eax+.next_ready], 0 |
jmp .pick |
@@: |
test ecx, ecx |
jz .back |
mov ecx, [rdy_head+ebx*4] |
mov [eax+.next_ready], ecx |
mov [rdy_head+ebx*4], eax |
jmp .pick |
.back: |
mov ecx, [rdy_tail+ebx*4] |
mov [ecx+.next_ready], eax |
mov [rdy_tail+ebx*4], eax |
mov [eax+.next_ready], 0 |
.pick: |
call pick_proc ;select next task |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/malloc.inc |
---|
0,0 → 1,1025 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Small heap based on malloc/free/realloc written by Doug Lea |
; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) |
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c |
; License http://creativecommons.org/licenses/publicdomain. |
; eax= size |
; temp |
; esi= nb |
; ebx= idx |
; |
align 16 |
malloc: |
push esi |
; nb = ((size+7)&~7)+8; |
mov esi, eax ;size |
add esi, 7 |
and esi, -8 |
add esi, 8 |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
cmp esi, 256 |
jae .large |
mov ecx, esi |
shr ecx, 3 |
or eax, -1 |
shl eax, cl |
and eax, [mst.smallmap] |
jz .small |
push ebp |
push edi |
bsf eax, eax |
mov ebx, eax |
; psize= idx<<3; |
; B = &ms.smallbins[idx]; |
; p = B->fd; |
; F = p->fd; |
; rsize= psize-nb; |
lea ebp, [eax*8] ;ebp= psize |
shl eax, 4 |
lea edi, [mst.smallbins+eax] ;edi= B |
mov edx, [edi+8] ;edx= p |
mov eax, [edx+8] ;eax= F |
mov ecx, ebp |
sub ecx, esi ;ecx= rsize |
; if (B == F) |
cmp edi, eax |
jne @F |
btr [mst.smallmap], ebx |
@@: |
; B->fd = F; |
; F->bk = B; |
; if(rsize<16) |
cmp ecx, 16 |
mov [edi+8], eax |
mov [eax+12], edi |
jae .split |
; p->head = psize|PINUSE_BIT|CINUSE_BIT; |
; (p + psize)->head |= PINUSE_BIT; |
lea eax, [edx+8] |
or dword [edx+ebp+4], 1 |
or ebp, 3 |
mov [edx+4], ebp |
pop edi |
pop ebp |
.done: |
pop esi |
mov [mst.mutex], 0 |
ret |
.split: |
lea ebx, [edx+8] ;ebx=mem |
; r = chunk_plus_offset(p, nb); |
; p->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
lea eax, [edx+esi] ;eax= r |
or esi, 3 |
mov [edx+4], esi |
mov edx, ecx |
or edx, 1 |
mov [eax+4], edx |
; (r + rsize)->prev_foot = rsize; |
mov [eax+ecx], ecx |
; I = rsize>>3; |
shr ecx, 3 |
; ms.smallmap |= 1<< I; |
bts [mst.smallmap], ecx |
; B = &ms.smallbins[I]; |
shl ecx, 4 |
pop edi |
pop ebp |
add ecx, mst.smallbins ;ecx= B |
mov edx, [ecx+8] ; F = B->fd; |
mov [ecx+8], eax ; B->fd = r; |
mov [edx+12], eax ; F->bk = r; |
mov [eax+8], edx ; r->fd = F; |
mov [eax+12], ecx ; r->bk = B; |
mov eax, ebx |
pop esi |
mov [mst.mutex], 0 |
ret |
.small: |
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) |
;;;;;;;;;;; start a change <lrz> |
mov eax,[mst.treemap] |
test eax,eax |
;;;;;;;;;;; end the change <lrz> |
; cmp [mst.treemap], 0 |
jz .from_top |
mov eax, esi |
call malloc_small |
test eax, eax |
jz .from_top |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) |
cmp [mst.treemap], 0 |
je .from_top |
call malloc_large ;esi= nb |
test eax, eax |
jne .done |
.from_top: |
; if (nb < ms.topsize) |
mov eax, [mst.topsize] |
cmp esi, eax |
jae .fail |
; rsize = ms.topsize -= nb; |
; p = ms.top; |
mov ecx, [mst.top] |
sub eax, esi |
mov [mst.topsize], eax |
; r = ms.top = chunk_plus_offset(p, nb); |
; r->head = rsize | PINUSE_BIT; |
; p->head = nb |PINUSE_BIT|CINUSE_BIT; |
lea edx, [ecx+esi] |
or eax, 1 |
mov [mst.top], edx |
or esi, 3 |
mov [edx+4], eax |
mov [ecx+4], esi |
lea eax, [ecx+8] |
pop esi |
and [mst.mutex], 0 |
ret |
.fail: |
xor eax, eax |
pop esi |
and [mst.mutex], 0 |
ret |
; param |
; eax= mem |
free: |
push edi |
mov edi, eax |
add edi, -8 |
; if(p->head & CINUSE_BIT) |
test byte [edi+4], 2 |
je .fail |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
; psize = p->head & (~3); |
mov eax, [edi+4] |
push esi |
mov esi, eax |
and esi, -4 |
; next = chunk_plus_offset(p, psize); |
; if(!(p->head & PINUSE_BIT)) |
test al, 1 |
lea ebx, [esi+edi] |
jne .next |
; prevsize = p->prev_foot; |
; prev=p - prevsize; |
; psize += prevsize; |
; p = prev; |
mov ecx, [edi] ;ecx= prevsize |
add esi, ecx ;esi= psize |
sub edi, ecx ;edi= p |
; if (prevsize < 256) |
cmp ecx, 256 |
jae .unlink_large |
mov eax, [edi+8] ;F = p->fd; |
mov edx, [edi+12] ;B = p->bk; |
; if (F == B) |
; ms.smallmap &= ~(1<< I); |
shr ecx, 3 |
cmp eax, edx |
jne @F |
and [mst.smallmap], ecx |
@@: |
mov [eax+12], edx ;F->bk = B; |
mov [edx+8], eax ;B->fd = F |
jmp .next |
.unlink_large: |
mov edx, edi |
call unlink_large_chunk |
.next: |
; if(next->head & PINUSE_BIT) |
mov eax, [ebx+4] |
test al, 1 |
jz .fail2 |
; if (! (next->head & CINUSE_BIT)) |
test al, 2 |
jnz .fix_next |
; if (next == ms.top) |
cmp ebx, [mst.top] |
jne @F |
; tsize = ms.topsize += psize; |
mov eax, [mst.topsize] |
add eax, esi |
mov [mst.topsize], eax |
; ms.top = p; |
; p->head = tsize | PINUSE_BIT; |
or eax, 1 |
mov [mst.top], edi |
mov [edi+4], eax |
.fail2: |
and [mst.mutex], 0 |
pop esi |
.fail: |
pop edi |
ret |
@@: |
; nsize = next->head & ~INUSE_BITS; |
and eax, -4 |
add esi, eax ;psize += nsize; |
; if (nsize < 256) |
cmp eax, 256 |
jae .unl_large |
mov edx, [ebx+8] ;F = next->fd |
mov ebx, [ebx+12] ;B = next->bk |
; if (F == B) |
cmp edx, ebx |
jne @F |
mov ecx, eax |
shr ecx, 3 |
btr [mst.smallmap], ecx |
@@: |
mov [edx+12], ebx ;F->bk = B |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
mov [ebx+8], edx |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.unl_large: |
; unlink_large_chunk((tchunkptr)next); |
mov edx, ebx |
call unlink_large_chunk |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.fix_next: |
; (p+psize)->prev_foot = psize; |
; next->head &= ~PINUSE_BIT; |
; p->head = psize|PINUSE_BIT; |
and eax, -2 |
mov edx, esi |
mov [ebx+4], eax |
or edx, 1 |
mov [edi+4], edx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
; param |
; ecx = chunk |
; eax = size |
insert_chunk: |
cmp eax, 256 |
push esi |
mov esi, ecx |
jae .large |
; I = S>>3; |
; ms.smallmap |= 1<< I; |
shr eax, 3 |
bts [mst.smallmap], eax |
; B = &ms.smallbins[I]; |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] ;F = B->fd |
mov [eax+8], esi ;B->fd = P |
mov [edx+12], esi ;F->bk = P |
mov [esi+8], edx ;P->fd = F |
mov [esi+12], eax ;P->bk = B |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
mov ebx, eax |
call insert_large_chunk |
pop esi |
and [mst.mutex], 0 |
ret |
; param |
; esi= chunk |
; ebx= size |
insert_large_chunk: |
; I = compute_tree_index(S); |
mov edx, ebx |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
mov edx, ebx |
shr edx, cl |
and edx, 1 |
lea ecx, [edx+eax*2] |
; X->index = I; |
mov dword [esi+28], ecx |
; X->child[0] = X->child[1] = 0; |
and dword [esi+20], 0 |
and dword [esi+16], 0 |
; H = &ms.treebins[I]; |
mov eax, ecx |
lea edx, [mst.treebins+eax*4] |
; if (!(ms.treemap & 1<<I)) |
bt [mst.treemap], ecx |
jc .tree |
; ms.treemap |= 1<<I; |
bts [mst.treemap], ecx |
; *H = X; |
mov dword [edx], esi |
jmp .done |
.tree: |
; T = *H; |
mov edx, [edx] |
; K = S << leftshift_for_tree_index(I); |
mov eax, ecx |
shr eax, 1 |
sub ecx, 31 |
mov edi, 37 |
sub edi, eax |
neg ecx |
sbb ecx, ecx |
and ecx, edi |
mov eax, ebx |
shl eax, cl ;eax= K |
jmp .loop |
.not_eq_size: |
; C = &(T->child[(K >> 31) & 1]); |
mov ecx, eax |
shr ecx, 31 |
lea ecx, [edx+ecx*4+16] |
; K <<= 1; |
; if (*C != 0) |
mov edi, [ecx] |
add eax, eax |
test edi, edi |
jz .insert_child |
; T = *C; |
mov edx, edi |
.loop: |
; for (;;) |
; if ((T->head & ~INUSE_BITS) != S) |
mov ecx, [edx+4] |
and ecx, not 3 |
cmp ecx, ebx |
jne .not_eq_size |
; F = T->fd; |
mov eax, [edx+8] |
; T->fd = F->bk = X; |
mov [eax+12], esi |
mov [edx+8], esi |
; X->fd = F; |
; X->bk = T; |
; X->parent = 0; |
and dword [esi+24], 0 |
mov [esi+8], eax |
mov [esi+12], edx |
ret |
.insert_child: |
; *C = X; |
mov [ecx], esi |
.done: |
; X->parent = T; |
mov [esi+24], edx |
; X->fd = X->bk = X; |
mov [esi+12], esi |
mov [esi+8], esi |
ret |
; param |
; edx= chunk |
unlink_large_chunk: |
mov eax, [edx+12] |
cmp eax, edx |
push edi |
mov edi, [edx+24] |
je @F |
mov ecx, [edx+8] ;F = X->fd |
mov [ecx+12], eax ;F->bk = R; |
mov [eax+8], ecx ;R->fd = F |
jmp .parent |
@@: |
mov eax, [edx+20] |
test eax, eax |
push esi |
lea esi, [edx+20] |
jne .loop |
mov eax, [edx+16] |
test eax, eax |
lea esi, [edx+16] |
je .l2 |
.loop: |
cmp dword [eax+20], 0 |
lea ecx, [eax+20] |
jne @F |
cmp dword [eax+16], 0 |
lea ecx, [eax+16] |
je .l1 |
@@: |
mov eax, [ecx] |
mov esi, ecx |
jmp .loop |
.l1: |
mov dword [esi], 0 |
.l2: |
pop esi |
.parent: |
test edi, edi |
je .done |
mov ecx, [edx+28] |
cmp edx, [mst.treebins+ecx*4] |
lea ecx, [mst.treebins+ecx*4] |
jne .l3 |
test eax, eax |
mov [ecx], eax |
jne .l5 |
mov ecx, [edx+28] |
btr [mst.treemap], ecx |
pop edi |
ret |
.l3: |
cmp [edi+16], edx |
jne @F |
mov [edi+16], eax |
jmp .l4 |
@@: |
mov [edi+20], eax |
.l4: |
test eax, eax |
je .done |
.l5: |
mov [eax+24], edi |
mov ecx, [edx+16] |
test ecx, ecx |
je .l6 |
mov [eax+16], ecx |
mov [ecx+24], eax |
.l6: |
mov edx, [edx+20] |
test edx, edx |
je .done |
mov [eax+20], edx |
mov [edx+24], eax |
.done: |
pop edi |
ret |
; param |
; esi= nb |
malloc_small: |
push ebp |
mov ebp, esi |
push edi |
bsf eax,[mst.treemap] |
mov ecx, [mst.treebins+eax*4] |
; rsize = (t->head & ~INUSE_BITS) - nb; |
mov edi, [ecx+4] |
and edi, -4 |
sub edi, esi |
.loop: |
mov ebx, ecx |
.loop_1: |
; while ((t = leftmost_child(t)) != 0) |
mov eax, [ecx+16] |
test eax, eax |
jz @F |
mov ecx, eax |
jmp .l1 |
@@: |
mov ecx, [ecx+20] |
.l1: |
test ecx, ecx |
jz .unlink |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov eax, [ecx+4] |
and eax, -4 |
sub eax, ebp |
; if (trem < rsize) |
cmp eax, edi |
jae .loop_1 |
; rsize = trem; |
mov edi, eax |
jmp .loop |
.unlink: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebx |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .split |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebp] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebx |
lea eax, [edi+ebp+4] |
pop edi |
or ecx, 3 |
mov [ebx+4], ecx |
or dword [eax], 1 |
pop ebp |
lea eax, [ebx+8] |
ret |
.split: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
; (r+rsize)->prev_foot = rsize; |
or ebp, 3 |
mov edx, edi |
or edx, 1 |
cmp edi, 256 |
mov [ebx+4], ebp |
mov [esi+4], edx |
mov [esi+edi], edi |
jae .large |
shr edi, 3 |
bts [mst.smallmap], edi |
mov eax, edi |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] |
mov [eax+8], esi |
mov [edx+12], esi |
pop edi |
mov [esi+12], eax |
mov [esi+8], edx |
pop ebp |
lea eax, [ebx+8] |
ret |
.large: |
lea eax, [ebx+8] |
push eax |
mov ebx, edi |
call insert_large_chunk |
pop eax |
pop edi |
pop ebp |
ret |
; param |
; esi= nb |
malloc_large: |
.idx equ esp+4 |
.rst equ esp |
push ebp |
push edi |
sub esp, 8 |
; v = 0; |
; rsize = -nb; |
mov edi, esi |
mov ebx, esi |
xor ebp, ebp |
neg edi |
; idx = compute_tree_index(nb); |
mov edx, esi |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
shr esi, cl |
and esi, 1 |
lea ecx, [esi+eax*2] |
mov [.idx], ecx |
; if ((t = ms.treebins[idx]) != 0) |
mov eax, [mst.treebins+ecx*4] |
test eax, eax |
jz .l3 |
; sizebits = nb << leftshift_for_tree_index(idx); |
cmp ecx, 31 |
jne @F |
xor ecx, ecx |
jmp .l1 |
@@: |
mov edx, ecx |
shr edx, 1 |
mov ecx, 37 |
sub ecx, edx |
.l1: |
mov edx, ebx |
shl edx, cl |
; rst = 0; |
mov [.rst], ebp |
.loop: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; v = t; |
; if ((rsize = trem) == 0) |
test ecx, ecx |
mov ebp, eax |
mov edi, ecx |
je .l2 |
@@: |
; rt = t->child[1]; |
mov ecx, [eax+20] |
; t = t->child[(sizebits >> 31) & 1]; |
mov esi, edx |
shr esi, 31 |
; if (rt != 0 && rt != t) |
test ecx, ecx |
mov eax, [eax+esi*4+16] |
jz @F |
cmp ecx, eax |
jz @F |
; rst = rt; |
mov [.rst], ecx |
@@: |
; if (t == 0) |
test eax, eax |
jz @F |
; sizebits <<= 1; |
add edx, edx |
jmp .loop |
@@: |
; t = rst; |
mov eax, [.rst] |
.l2: |
; if (t == 0 && v == 0) |
test eax, eax |
jne .l4 |
test ebp, ebp |
jne .l7 |
mov ecx, [.idx] |
.l3: |
; leftbits = (-1<<idx) & ms.treemap; |
; if (leftbits != 0) |
or edx, -1 |
shl edx, cl |
and edx, [mst.treemap] |
jz @F |
bsf eax, edx |
; t = ms.treebins[i]; |
mov eax, [mst.treebins+eax*4] |
@@: |
; while (t != 0) |
test eax, eax |
jz .l5 |
.l4: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; rsize = trem; |
mov edi, ecx |
; v = t; |
mov ebp, eax |
@@: |
; t = leftmost_child(t); |
mov ecx, [eax+16] |
test ecx, ecx |
je @F |
mov eax, ecx |
jmp .l6 |
@@: |
mov eax, [eax+20] |
.l6: |
; while (t != 0) |
test eax, eax |
jne .l4 |
.l5: |
; if (v != 0) |
test ebp, ebp |
jz .done |
.l7: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebp |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .large |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebx] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebp |
lea eax, [edi+ebx+4] |
or ecx, 3 |
mov [ebp+4], ecx |
or dword [eax], 1 |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.large: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
mov edx, edi |
or ebx, 3 |
mov [ebp+4], ebx |
or edx, 1 |
mov [esi+4], edx |
; (r+rsize)->prev_foot = rsize; |
; insert_large_chunk((tchunkptr)r, rsize); |
mov [esi+edi], edi |
mov eax, edi |
mov ecx, esi |
call insert_chunk |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.done: |
add esp, 8 |
pop edi |
pop ebp |
xor eax, eax |
ret |
init_malloc: |
stdcall kernel_alloc, 0x40000 |
mov [mst.top], eax |
mov [mst.topsize], 128*1024 |
mov dword [eax+4], (128*1024) or 1 |
mov eax, mst.smallbins |
@@: |
mov [eax+8], eax |
mov [eax+12], eax |
add eax, 16 |
cmp eax, mst.smallbins+512 |
jb @B |
ret |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/ext_lib.inc |
---|
0,0 → 1,320 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;============================================================================ |
; |
; External kernel dependencies (libraries) loading |
; |
;============================================================================ |
$Revision$ |
if 0 |
; The code currently does not work. Kill "if 0/end if" only after correcting |
; to current kernel (dll.inc). |
macro library [name,fname] |
{ |
forward |
dd __#name#_library_table__,__#name#_library_name__ |
common |
dd 0 |
forward |
__#name#_library_name__ db fname,0 |
} |
macro import lname,[name,sname] |
{ |
common |
align 4 |
__#lname#_library_table__: |
forward |
name dd __#name#_import_name__ |
common |
dd 0 |
forward |
__#name#_import_name__ db sname,0 |
} |
macro export [name,sname] |
{ |
align 4 |
forward |
dd __#name#_export_name__,name |
common |
dd 0 |
forward |
__#name#_export_name__ db sname,0 |
} |
align 4 ; loading library (use kernel functions) |
proc load_k_library stdcall, file_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
exports dd ? |
endl |
cli |
stdcall load_file, [file_name] |
test eax, eax |
jz .fail |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
stdcall kernel_alloc, [img_size] |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15 |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], dword 0 |
test eax, eax |
jnz @F |
@@: |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, 0 |
lea eax, [edx+20] |
@@: |
add [eax+CFS.VirtualAddress], edi ;patch user space offset |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
add edx, 20 |
stdcall fix_coff_relocs, [coff], edx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS |
mov [exports], eax |
stdcall kernel_free, [coff] |
mov eax, [exports] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
proc dll.Load, import_table:dword |
mov esi,[import_table] |
.next_lib: mov edx,[esi] |
or edx,edx |
jz .exit |
push esi |
mov edi,s_libname |
mov al, '/' |
stosb |
mov esi,sysdir_path |
@@: lodsb |
stosb |
or al,al |
jnz @b |
dec edi |
mov [edi], dword '/lib' |
mov [edi+4],byte '/' |
add edi,5 |
pop esi |
push esi |
mov esi,[esi+4] |
@@: lodsb |
stosb |
or al,al |
jnz @b |
pushad |
stdcall load_k_library,s_libname |
mov [esp+28],eax |
popad |
or eax,eax |
jz .fail |
stdcall dll.Link,eax,edx |
stdcall dll.Init,[eax+4] |
pop esi |
add esi,8 |
jmp .next_lib |
.exit: xor eax,eax |
ret |
.fail: add esp,4 |
xor eax,eax |
inc eax |
ret |
endp |
proc dll.Link, exp:dword,imp:dword |
push eax |
mov esi,[imp] |
test esi,esi |
jz .done |
.next: lodsd |
test eax,eax |
jz .done |
stdcall dll.GetProcAddress,[exp],eax |
or eax,eax |
jz @f |
mov [esi-4],eax |
jmp .next |
@@: mov dword[esp],0 |
.done: pop eax |
ret |
endp |
proc dll.Init, dllentry:dword |
pushad |
mov eax,mem.Alloc |
mov ebx,mem.Free |
mov ecx,mem.ReAlloc |
mov edx,dll.Load |
stdcall [dllentry] |
popad |
ret |
endp |
proc dll.GetProcAddress, exp:dword,sz_name:dword |
mov edx,[exp] |
.next: test edx,edx |
jz .end |
stdcall strncmp,[edx],[sz_name], dword -1 |
test eax,eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: mov eax,[edx+4] |
.end: ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.Alloc size ;///////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
push ebx ecx |
; mov eax,[size] |
; lea ecx,[eax+4+4095] |
; and ecx,not 4095 |
; stdcall kernel_alloc, ecx |
; add ecx,-4 |
; mov [eax],ecx |
; add eax,4 |
stdcall kernel_alloc, [size] |
pop ecx ebx |
ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
push ebx ecx esi edi eax |
mov eax,[mptr] |
mov ebx,[size] |
or eax,eax |
jz @f |
lea ecx,[ebx+4+4095] |
and ecx,not 4095 |
add ecx,-4 |
cmp ecx,[eax-4] |
je .exit |
@@: mov eax,ebx |
call mem.Alloc |
xchg eax,[esp] |
or eax,eax |
jz .exit |
mov esi,eax |
xchg eax,[esp] |
mov edi,eax |
mov ecx,[esi-4] |
cmp ecx,[edi-4] |
jbe @f |
mov ecx,[edi-4] |
@@: add ecx,3 |
shr ecx,2 |
cld |
rep movsd |
xchg eax,[esp] |
call mem.Free |
.exit: |
pop eax edi esi ecx ebx |
ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.Free mptr ;////////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; mov eax,[mptr] |
; or eax,eax |
; jz @f |
; push ebx ecx |
; lea ecx,[eax-4] |
; stdcall kernel_free, ecx |
; pop ecx ebx |
; @@: ret |
stdcall kernel_free, [mptr] |
ret |
endp |
uglobal |
s_libname db 64 dup (0) |
endg |
end if |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/heap.inc |
---|
0,0 → 1,1538 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
struc MEM_BLOCK |
{ .next_block dd ? |
.prev_block dd ? ;+4 |
.list_fd dd ? ;+8 |
.list_bk dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
} |
MEM_LIST_OFFSET equ 8 |
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
DONT_FREE_BLOCK equ 10h |
virtual at 0 |
MEM_BLOCK MEM_BLOCK |
end virtual |
MEM_BLOCK_SIZE equ 8*4 |
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_fd equ MEM_BLOCK.list_fd |
list_bk equ MEM_BLOCK.list_bk |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
macro remove_from_list op |
{ mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
test edx, edx |
jz @f |
mov [edx+list_bk], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_fd], edx |
@@: |
mov [op+list_fd],0 |
mov [op+list_bk],0 |
} |
macro remove_from_free op |
{ |
remove_from_list op |
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
macro remove_from_used op |
{ |
mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
mov [op+list_fd], 0 |
mov [op+list_bk], 0 |
} |
align 4 |
proc init_kernel_heap |
mov ecx, 64 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], HEAP_BASE |
mov eax, mem_used.fd-MEM_LIST_OFFSET |
mov [mem_used.fd], eax |
mov [mem_used.bk], eax |
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
mov edi, HEAP_BASE |
.l1: |
stdcall map_page,edi,edx,PG_SW |
add edi, 0x1000 |
add edx, 0x1000 |
dec ecx |
jnz .l1 |
mov edi, HEAP_BASE |
mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
mov [edi+list_fd], eax |
mov [edi+list_bk], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_fd], eax |
mov [ebx+list_bk], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov ecx, [pg_data.kernel_pages] |
shl ecx, 12 |
sub ecx, HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov [heap_size], ecx |
mov [heap_free], ecx |
mov [ebx+block_size], ecx |
mov [ebx+block_flags], FREE_BLOCK |
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
and [heap_mutex], 0 |
mov [heap_blocks], 4095 |
mov [free_blocks], 4094 |
ret |
endp |
; param |
; eax= required size |
; |
; retval |
; edi= memory block descriptor |
; ebx= descriptor index |
align 4 |
get_small_block: |
mov ecx, eax |
shr ecx, 12 |
dec ecx |
cmp ecx, 63 |
jle .get_index |
mov ecx, 63 |
.get_index: |
lea esi, [mem_block_mask] |
xor ebx, ebx |
or edx, -1 |
cmp ecx, 32 |
jb .bit_test |
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
.bit_test: |
shl edx, cl |
and edx, [esi] |
.find: |
bsf edi, edx |
jz .high_mask |
add ebx, edi |
mov edi, [mem_block_list+ebx*4] |
.check_size: |
cmp eax, [edi+block_size] |
ja .next |
ret |
.high_mask: |
add esi, 4 |
cmp esi, mem_block_mask+8 |
jae .err |
add ebx, 32 |
mov edx, [esi] |
jmp .find |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.err: |
xor edi, edi |
ret |
align 4 |
alloc_mem_block: |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
xor eax,eax |
ret |
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
lea eax,[eax+ebx*8] |
shl eax, 5 |
add eax, [mem_block_arr] |
dec [free_blocks] |
ret |
align 4 |
free_mem_block: |
mov dword [eax], 0 |
mov dword [eax+4], 0 |
mov dword [eax+8], 0 |
mov dword [eax+12], 0 |
mov dword [eax+16], 0 |
; mov dword [eax+20], 0 |
mov dword [eax+24], 0 |
mov dword [eax+28], 0 |
sub eax, [mem_block_arr] |
shr eax, 5 |
mov ebx, mem_block_map |
bts [ebx], eax |
inc [free_blocks] |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
ret |
@@: |
mov [mem_block_start], eax |
ret |
.err: |
xor eax, eax |
ret |
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
push ebx |
push esi |
push edi |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095 |
mov [size], eax |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
cmp eax, [heap_free] |
ja .error |
call get_small_block ; eax |
test edi, edi |
jz .error |
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
mov [block_ind], ebx ;index of allocated block |
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
call alloc_mem_block |
and eax, eax |
jz .error |
mov esi, eax ;esi - splitted block |
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_fd], 0 |
mov [esi+list_bk], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
remove_from_list edi |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], edx |
test edx, edx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [esi+list_fd], edx |
mov [esi+list_bk], ecx |
mov [ecx+list_fd], esi |
mov [edx+list_bk], esi |
mov [esi+block_flags], USED_BLOCK |
mov eax, [esi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ebx*4], edx |
and edx, edx |
jnz @f |
btr [mem_block_mask], ebx |
@@: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [edi+list_fd], edx |
mov [edi+list_bk], ecx |
mov [ecx+list_fd], edi |
mov [edx+list_bk], edi |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.error: |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
push ebx |
push esi |
push edi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
mov eax, [esi+block_size] |
add [heap_free], eax |
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
remove_from_free edi |
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
remove_from_used esi |
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
push ecx |
remove_from_list edi |
pop ecx |
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_fd], esi |
test esi, esi |
jz @f |
mov [esi+list_bk], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
ret |
.insert: |
remove_from_used esi |
mov eax, [esi+block_size] |
calc_index eax |
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_fd], edi |
test edi, edi |
jz @f |
mov [edi+list_bk], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
ret |
.fail: |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc kernel_alloc stdcall, size:dword |
locals |
lin_addr dd ? |
pages_count dd ? |
endl |
push ebx |
push edi |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095; |
mov [size], eax |
and eax, eax |
jz .err |
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .err |
mov [lin_addr], eax |
mov ecx, [pages_count] |
mov edx, eax |
mov ebx, ecx |
shr ecx, 3 |
jz .next |
and ebx, not 7 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx ; yes ecx!!! |
and eax, eax |
jz .err |
mov edi, eax |
mov edx, [lin_addr] |
@@: |
stdcall map_page,edx,edi,dword PG_SW |
add edx, 0x1000 |
add edi, 0x1000 |
dec ecx |
jnz @B |
.next: |
mov ecx, [pages_count] |
and ecx, 7 |
jz .end |
@@: |
push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .err |
stdcall map_page,edx,eax,dword PG_SW |
add edx, 0x1000 |
dec ecx |
jnz @B |
.end: |
mov eax, [lin_addr] |
pop edi |
pop ebx |
ret |
.err: |
xor eax, eax |
pop edi |
pop ebx |
ret |
endp |
align 4 |
proc kernel_free stdcall, base:dword |
push ebx esi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
and [heap_mutex], 0 |
push ecx |
mov ecx, [esi+block_size]; |
shr ecx, 12 |
call release_pages ;eax, ecx |
pop ecx |
stdcall free_kernel_space, [base] |
pop esi ebx |
ret |
.fail: |
and [heap_mutex], 0 |
pop esi ebx |
ret |
endp |
restore block_next |
restore block_prev |
restore block_list |
restore block_base |
restore block_size |
restore block_flags |
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
HEAP_TOP equ 0x5FC00000 |
align 4 |
proc init_heap |
mov ebx,[current_slot] |
mov eax, [ebx+APPDATA.heap_top] |
test eax, eax |
jz @F |
sub eax,[ebx+APPDATA.heap_base] |
sub eax, 4096 |
ret |
@@: |
mov esi, [ebx+APPDATA.mem_size] |
add esi, 4095 |
and esi, not 4095 |
mov [ebx+APPDATA.mem_size], esi |
mov eax, HEAP_TOP |
mov [ebx+APPDATA.heap_base], esi |
mov [ebx+APPDATA.heap_top], eax |
sub eax, esi |
shr esi, 10 |
mov ecx, eax |
sub eax, 4096 |
or ecx, FREE_BLOCK |
mov [page_tabs+esi], ecx |
ret |
endp |
align 4 |
proc user_alloc stdcall, alloc_size:dword |
push ebx |
push esi |
push edi |
mov ecx, [alloc_size] |
add ecx, (4095+4096) |
and ecx, not 4095 |
mov ebx, [current_slot] |
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
l_0: |
cmp esi, edi |
jae m_exit |
mov ebx, esi |
shr ebx, 12 |
mov eax, [page_tabs+ebx*4] |
test al, FREE_BLOCK |
jz test_used |
and eax, 0xFFFFF000 |
cmp eax, ecx ;alloc_size |
jb m_next |
jz @f |
lea edx, [esi+ecx] |
sub eax, ecx |
or al, FREE_BLOCK |
shr edx, 12 |
mov [page_tabs+edx*4], eax |
@@: |
or ecx, USED_BLOCK |
mov [page_tabs+ebx*4], ecx |
shr ecx, 12 |
inc ebx |
dec ecx |
jz .no |
@@: |
mov dword [page_tabs+ebx*4], 2 |
inc ebx |
dec ecx |
jnz @B |
.no: |
mov edx, [current_slot] |
mov ebx, [alloc_size] |
add ebx, 0xFFF |
and ebx, not 0xFFF |
add ebx, [edx+APPDATA.mem_size] |
call update_mem_size |
lea eax, [esi+4096] |
pop edi |
pop esi |
pop ebx |
ret |
test_used: |
test al, USED_BLOCK |
jz m_exit |
and eax, 0xFFFFF000 |
m_next: |
add esi, eax |
jmp l_0 |
m_exit: |
xor eax, eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc user_alloc_at stdcall, address:dword, alloc_size:dword |
push ebx |
push esi |
push edi |
mov ebx, [current_slot] |
mov edx, [address] |
and edx, not 0xFFF |
mov [address], edx |
sub edx, 0x1000 |
jb .error |
mov esi, [ebx+APPDATA.heap_base] |
mov edi, [ebx+APPDATA.heap_top] |
cmp edx, esi |
jb .error |
.scan: |
cmp esi, edi |
jae .error |
mov ebx, esi |
shr ebx, 12 |
mov eax, [page_tabs+ebx*4] |
mov ecx, eax |
and ecx, 0xFFFFF000 |
add ecx, esi |
cmp edx, ecx |
jb .found |
mov esi, ecx |
jmp .scan |
.error: |
xor eax, eax |
pop edi |
pop esi |
pop ebx |
ret |
.found: |
test al, FREE_BLOCK |
jz .error |
mov eax, ecx |
sub eax, edx |
sub eax, 0x1000 |
cmp eax, [alloc_size] |
jb .error |
; Here we have 1 big free block which includes requested area. |
; In general, 3 other blocks must be created instead: |
; free at [esi, edx); |
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000)); |
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx) |
; First or third block (or both) may be absent. |
mov eax, edx |
sub eax, esi |
jz .nofirst |
or al, FREE_BLOCK |
mov [page_tabs+ebx*4], eax |
.nofirst: |
mov eax, [alloc_size] |
add eax, 0x1FFF |
and eax, not 0xFFF |
mov ebx, edx |
add edx, eax |
shr ebx, 12 |
or al, USED_BLOCK |
mov [page_tabs+ebx*4], eax |
shr eax, 12 |
dec eax |
jz .second_nofill |
inc ebx |
.fill: |
mov dword [page_tabs+ebx*4], 2 |
inc ebx |
dec eax |
jnz .fill |
.second_nofill: |
sub ecx, edx |
jz .nothird |
or cl, FREE_BLOCK |
mov [page_tabs+ebx*4], ecx |
.nothird: |
mov edx, [current_slot] |
mov ebx, [alloc_size] |
add ebx, 0xFFF |
and ebx, not 0xFFF |
add ebx, [edx+APPDATA.mem_size] |
call update_mem_size |
mov eax, [address] |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc user_free stdcall, base:dword |
push esi |
mov esi, [base] |
test esi, esi |
jz .exit |
push ebx |
xor ebx, ebx |
shr esi, 12 |
mov eax, [page_tabs+(esi-1)*4] |
test al, USED_BLOCK |
jz .cantfree |
test al, DONT_FREE_BLOCK |
jnz .cantfree |
and eax, not 4095 |
mov ecx, eax |
or al, FREE_BLOCK |
mov [page_tabs+(esi-1)*4], eax |
sub ecx, 4096 |
mov ebx, ecx |
shr ecx, 12 |
jz .released |
.release: |
xor eax, eax |
xchg eax, [page_tabs+esi*4] |
test al, 1 |
jz @F |
test eax, PG_SHARED |
jnz @F |
call free_page |
mov eax, esi |
shl eax, 12 |
invlpg [eax] |
@@: |
inc esi |
dec ecx |
jnz .release |
.released: |
push edi |
mov edx, [current_slot] |
mov esi, dword [edx+APPDATA.heap_base] |
mov edi, dword [edx+APPDATA.heap_top] |
sub ebx, [edx+APPDATA.mem_size] |
neg ebx |
call update_mem_size |
call user_normalize |
pop edi |
pop ebx |
pop esi |
ret |
.exit: |
xor eax, eax |
inc eax |
pop esi |
ret |
.cantfree: |
xor eax, eax |
pop ebx |
pop esi |
ret |
endp |
user_normalize: |
; in: esi=heap_base, edi=heap_top |
; out: eax=0 <=> OK |
; destroys: ebx,edx,esi,edi |
shr esi, 12 |
shr edi, 12 |
@@: |
mov eax, [page_tabs+esi*4] |
test al, USED_BLOCK |
jz .test_free |
shr eax, 12 |
add esi, eax |
jmp @B |
.test_free: |
test al, FREE_BLOCK |
jz .err |
mov edx, eax |
shr edx, 12 |
add edx, esi |
cmp edx, edi |
jae .exit |
mov ebx, [page_tabs+edx*4] |
test bl, USED_BLOCK |
jz .next_free |
shr ebx, 12 |
add edx, ebx |
mov esi, edx |
jmp @B |
.next_free: |
test bl, FREE_BLOCK |
jz .err |
and dword [page_tabs+edx*4], 0 |
add eax, ebx |
and eax, not 4095 |
or eax, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
jmp @B |
.exit: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
user_realloc: |
; in: eax = pointer, ebx = new size |
; out: eax = new pointer or NULL |
test eax, eax |
jnz @f |
; realloc(NULL,sz) - same as malloc(sz) |
push ebx |
call user_alloc |
ret |
@@: |
push ecx edx |
lea ecx, [eax - 0x1000] |
shr ecx, 12 |
mov edx, [page_tabs+ecx*4] |
test dl, USED_BLOCK |
jnz @f |
; attempt to realloc invalid pointer |
.ret0: |
pop edx ecx |
xor eax, eax |
ret |
@@: |
test dl, DONT_FREE_BLOCK |
jnz .ret0 |
add ebx, 0x1FFF |
shr edx, 12 |
shr ebx, 12 |
; edx = allocated size, ebx = new size |
add edx, ecx |
add ebx, ecx |
cmp edx, ebx |
jb .realloc_add |
; release part of allocated memory |
.loop: |
cmp edx, ebx |
jz .release_done |
dec edx |
xor eax, eax |
xchg eax, [page_tabs+edx*4] |
test al, 1 |
jz .loop |
call free_page |
mov eax, edx |
shl eax, 12 |
invlpg [eax] |
jmp .loop |
.release_done: |
sub ebx, ecx |
cmp ebx, 1 |
jnz .nofreeall |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
mov edx, [current_slot] |
mov ebx, [APPDATA.mem_size+edx] |
sub ebx, eax |
add ebx, 0x1000 |
or al, FREE_BLOCK |
mov [page_tabs+ecx*4], eax |
push esi edi |
mov esi, [APPDATA.heap_base+edx] |
mov edi, [APPDATA.heap_top+edx] |
call update_mem_size |
call user_normalize |
pop edi esi |
jmp .ret0 ; all freed |
.nofreeall: |
sub edx, ecx |
shl ebx, 12 |
or ebx, USED_BLOCK |
xchg [page_tabs+ecx*4], ebx |
shr ebx, 12 |
sub ebx, edx |
push ebx ecx edx |
mov edx, [current_slot] |
shl ebx, 12 |
sub ebx, [APPDATA.mem_size+edx] |
neg ebx |
call update_mem_size |
pop edx ecx ebx |
lea eax, [ecx+1] |
shl eax, 12 |
push eax |
add ecx, edx |
lea edx, [ecx+ebx] |
shl ebx, 12 |
jz .ret |
push esi |
mov esi, [current_slot] |
mov esi, [APPDATA.heap_top+esi] |
shr esi, 12 |
@@: |
cmp edx, esi |
jae .merge_done |
mov eax, [page_tabs+edx*4] |
test al, USED_BLOCK |
jnz .merge_done |
and dword [page_tabs+edx*4], 0 |
shr eax, 12 |
add edx, eax |
shl eax, 12 |
add ebx, eax |
jmp @b |
.merge_done: |
pop esi |
or ebx, FREE_BLOCK |
mov [page_tabs+ecx*4], ebx |
.ret: |
pop eax edx ecx |
ret |
.realloc_add: |
; get some additional memory |
mov eax, [current_slot] |
mov eax, [APPDATA.heap_top+eax] |
shr eax, 12 |
cmp edx, eax |
jae .cant_inplace |
mov eax, [page_tabs+edx*4] |
test al, FREE_BLOCK |
jz .cant_inplace |
shr eax, 12 |
add eax, edx |
sub eax, ebx |
jb .cant_inplace |
jz @f |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+ebx*4], eax |
@@: |
mov eax, ebx |
sub eax, ecx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+ecx*4], eax |
lea eax, [ecx+1] |
shl eax, 12 |
push eax |
push edi |
lea edi, [page_tabs+edx*4] |
mov eax, 2 |
sub ebx, edx |
mov ecx, ebx |
cld |
rep stosd |
pop edi |
mov edx, [current_slot] |
shl ebx, 12 |
add ebx, [APPDATA.mem_size+edx] |
call update_mem_size |
pop eax edx ecx |
ret |
.cant_inplace: |
push esi edi |
mov eax, [current_slot] |
mov esi, [APPDATA.heap_base+eax] |
mov edi, [APPDATA.heap_top+eax] |
shr esi, 12 |
shr edi, 12 |
sub ebx, ecx |
.find_place: |
cmp esi, edi |
jae .place_not_found |
mov eax, [page_tabs+esi*4] |
test al, FREE_BLOCK |
jz .next_place |
shr eax, 12 |
cmp eax, ebx |
jae .place_found |
add esi, eax |
jmp .find_place |
.next_place: |
shr eax, 12 |
add esi, eax |
jmp .find_place |
.place_not_found: |
pop edi esi |
jmp .ret0 |
.place_found: |
sub eax, ebx |
jz @f |
push esi |
add esi, ebx |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
pop esi |
@@: |
mov eax, ebx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+esi*4], eax |
inc esi |
mov eax, esi |
shl eax, 12 |
push eax |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
or al, FREE_BLOCK |
sub edx, ecx |
mov [page_tabs+ecx*4], eax |
inc ecx |
dec ebx |
dec edx |
jz .no |
@@: |
xor eax, eax |
xchg eax, [page_tabs+ecx*4] |
mov [page_tabs+esi*4], eax |
mov eax, ecx |
shl eax, 12 |
invlpg [eax] |
inc esi |
inc ecx |
dec ebx |
dec edx |
jnz @b |
.no: |
push ebx |
mov edx, [current_slot] |
shl ebx, 12 |
add ebx, [APPDATA.mem_size+edx] |
call update_mem_size |
pop ebx |
@@: |
mov dword [page_tabs+esi*4], 2 |
inc esi |
dec ebx |
jnz @b |
pop eax edi esi edx ecx |
ret |
if 0 |
align 4 |
proc alloc_dll |
pushf |
cli |
bsf eax, [dll_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [dll_map], eax |
popf |
shl eax, 5 |
add eax, dll_tab |
ret |
endp |
align 4 |
proc alloc_service |
pushf |
cli |
bsf eax, [srv_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [srv_map], eax |
popf |
shl eax,0x02 |
lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
ret |
endp |
end if |
;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;; |
; param |
; eax= shm_map object |
align 4 |
destroy_smap: |
pushfd |
cli |
push esi |
push edi |
mov edi, eax |
mov esi, [eax+SMAP.parent] |
test esi, esi |
jz .done |
lock dec [esi+SMEM.refcount] |
jnz .done |
mov ecx, [esi+SMEM.bk] |
mov edx, [esi+SMEM.fd] |
mov [ecx+SMEM.fd], edx |
mov [edx+SMEM.bk], ecx |
stdcall kernel_free, [esi+SMEM.base] |
mov eax, esi |
call free |
.done: |
mov eax, edi |
call destroy_kernel_object |
pop edi |
pop esi |
popfd |
ret |
E_NOTFOUND equ 5 |
E_ACCESS equ 10 |
E_NOMEM equ 30 |
E_PARAM equ 33 |
SHM_READ equ 0 |
SHM_WRITE equ 1 |
SHM_ACCESS_MASK equ 3 |
SHM_OPEN equ (0 shl 2) |
SHM_OPEN_ALWAYS equ (1 shl 2) |
SHM_CREATE equ (2 shl 2) |
SHM_OPEN_MASK equ (3 shl 2) |
align 4 |
proc shmem_open stdcall name:dword, size:dword, access:dword |
locals |
action dd ? |
owner_access dd ? |
mapped dd ? |
endl |
push ebx |
push esi |
push edi |
mov [mapped], 0 |
mov [owner_access], 0 |
pushfd ;mutex required |
cli |
mov eax, [access] |
and eax, SHM_OPEN_MASK |
mov [action], eax |
mov ebx, [name] |
test ebx, ebx |
mov edx, E_PARAM |
jz .fail |
mov esi, [shmem_list.fd] |
align 4 |
@@: |
cmp esi, shmem_list |
je .not_found |
lea edx, [esi+SMEM.name] ; link , base, size |
stdcall strncmp, edx, ebx, 32 |
test eax, eax |
je .found |
mov esi, [esi+SMEM.fd] |
jmp @B |
.not_found: |
mov eax, [action] |
cmp eax, SHM_OPEN |
mov edx, E_NOTFOUND |
je .fail |
cmp eax, SHM_CREATE |
mov edx, E_PARAM |
je .create_shm |
cmp eax, SHM_OPEN_ALWAYS |
jne .fail |
.create_shm: |
mov ecx, [size] |
test ecx, ecx |
jz .fail |
add ecx, 4095 |
and ecx, -4096 |
mov [size], ecx |
mov eax, SMEM.sizeof |
call malloc |
test eax, eax |
mov esi, eax |
mov edx, E_NOMEM |
jz .fail |
stdcall kernel_alloc, [size] |
test eax, eax |
mov [mapped], eax |
mov edx, E_NOMEM |
jz .cleanup |
mov ecx, [size] |
mov edx, [access] |
and edx, SHM_ACCESS_MASK |
mov [esi+SMEM.base], eax |
mov [esi+SMEM.size], ecx |
mov [esi+SMEM.access], edx |
mov [esi+SMEM.refcount], 0 |
mov [esi+SMEM.name+28], 0 |
lea eax, [esi+SMEM.name] |
stdcall strncpy, eax, [name], 31 |
mov eax, [shmem_list.fd] |
mov [esi+SMEM.bk], shmem_list |
mov [esi+SMEM.fd], eax |
mov [eax+SMEM.bk], esi |
mov [shmem_list.fd], esi |
mov [action], SHM_OPEN |
mov [owner_access], SHM_WRITE |
.found: |
mov eax, [action] |
cmp eax, SHM_CREATE |
mov edx, E_ACCESS |
je .exit |
cmp eax, SHM_OPEN |
mov edx, E_PARAM |
je .create_map |
cmp eax, SHM_OPEN_ALWAYS |
jne .fail |
.create_map: |
mov eax, [access] |
and eax, SHM_ACCESS_MASK |
cmp eax, [esi+SMEM.access] |
mov [access], eax |
mov edx, E_ACCESS |
ja .fail |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
mov eax, SMAP.sizeof |
call create_kernel_object |
test eax, eax |
mov edi, eax |
mov edx, E_NOMEM |
jz .fail |
inc [esi+SMEM.refcount] |
mov [edi+SMAP.magic], 'SMAP' |
mov [edi+SMAP.destroy], destroy_smap |
mov [edi+SMAP.parent], esi |
mov [edi+SMAP.base], 0 |
stdcall user_alloc, [esi+SMEM.size] |
test eax, eax |
mov [mapped], eax |
mov edx, E_NOMEM |
jz .cleanup2 |
mov [edi+SMAP.base], eax |
mov ecx, [esi+SMEM.size] |
mov [size], ecx |
shr ecx, 12 |
shr eax, 10 |
mov esi, [esi+SMEM.base] |
shr esi, 10 |
lea edi, [page_tabs+eax] |
add esi, page_tabs |
mov edx, [access] |
or edx, [owner_access] |
shl edx, 1 |
or edx, PG_USER+PG_SHARED |
@@: |
lodsd |
and eax, 0xFFFFF000 |
or eax, edx |
stosd |
loop @B |
xor edx, edx |
cmp [owner_access], 0 |
jne .fail |
.exit: |
mov edx, [size] |
.fail: |
mov eax, [mapped] |
popfd |
pop edi |
pop esi |
pop ebx |
ret |
.cleanup: |
mov [size], edx |
mov eax, esi |
call free |
jmp .exit |
.cleanup2: |
mov [size], edx |
mov eax, edi |
call destroy_smap |
jmp .exit |
endp |
align 4 |
proc shmem_close stdcall, name:dword |
mov eax, [name] |
test eax, eax |
jz .fail |
push esi |
push edi |
pushfd |
cli |
mov esi, [current_slot] |
add esi, APP_OBJ_OFFSET |
.next: |
mov eax, [esi+APPOBJ.fd] |
test eax, eax |
jz @F |
cmp eax, esi |
mov esi, eax |
je @F |
cmp [eax+SMAP.magic], 'SMAP' |
jne .next |
mov edi, [eax+SMAP.parent] |
test edi, edi |
jz .next |
lea eax, [edi+SMEM.name] |
stdcall strncmp, [name], edi, 32 |
test eax, eax |
jne .next |
stdcall user_free, [esi+SMAP.base] |
call [esi+APPOBJ.destroy] |
@@: |
popfd |
pop edi |
pop esi |
.fail: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/conf_lib.inc |
---|
0,0 → 1,297 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;------------------------------------------------------------------------- |
;Loading configuration from ini file |
; {SPraid.simba} |
;------------------------------------------------------------------------- |
$Revision$ |
iglobal |
conf_path_sect: db 'path',0 |
conf_fname db '/sys/sys.conf',0 |
endg |
; set soke kernel configuration |
proc set_kernel_conf |
locals |
par db 30 dup(?) |
endl |
pushad |
;[gui] |
;mouse_speed |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed,\ |
eax,30, ugui_mouse_speed_def |
pop eax |
stdcall strtoint,eax |
mov [mouse_speed_factor], ax |
;mouse_delay |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay,\ |
eax,30, ugui_mouse_delay_def |
pop eax |
stdcall strtoint,eax |
mov [mouse_delay], eax |
;midibase |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def |
pop eax |
stdcall strtoint,eax |
cmp eax, 0x100 |
jb @f |
cmp eax, 0x10000 |
jae @f |
mov [midi_base], ax |
mov [mididp], eax |
inc eax |
mov [midisp], eax |
@@: |
popad |
ret |
endp |
iglobal |
ugui db 'gui',0 |
ugui_mouse_speed db 'mouse_speed',0 |
ugui_mouse_speed_def db '2',0 |
ugui_mouse_delay db 'mouse_delay',0 |
ugui_mouse_delay_def db '0x00A',0 |
udev db 'dev',0 |
udev_midibase db 'midibase',0 |
udev_midibase_def db '0x320',0 |
endg |
;set up netvork configuration |
proc set_network_conf |
locals |
par db 30 dup(?) |
endl |
pushad |
;[net] |
;active |
lea eax,[par] |
invoke ini.get_int,conf_fname, unet, unet_active, 0 |
or eax,eax |
jz .do_not_set_net |
mov eax, [stack_config] |
and eax, 0xFFFFFF80 |
add eax, 3 |
mov [stack_config], eax |
call ash_eth_enable |
;addr |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [stack_ip], eax |
;mask |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [subnet_mask], eax |
;gate |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [gateway_ip], eax |
.do_not_set_net: |
popad |
ret |
endp |
iglobal |
unet db 'net',0 |
unet_active db 'active',0 |
unet_addr db 'addr',0 |
unet_mask db 'mask',0 |
unet_gate db 'gate',0 |
unet_def db 0 |
endg |
; convert string to DWord |
proc strtoint stdcall,strs |
pushad |
mov eax,[strs] |
inc eax |
mov bl,[eax] |
cmp bl,'x' |
je .hex |
cmp bl,'X' |
je .hex |
jmp .dec |
.hex: |
inc eax |
stdcall strtoint_hex,eax |
jmp .exit |
.dec: |
dec eax |
stdcall strtoint_dec,eax |
.exit: |
mov [esp+28],eax |
popad |
ret |
endp |
; convert string to DWord for decimal value |
proc strtoint_dec stdcall,strs |
pushad |
xor edx,edx |
; ¯®¨áª ª®æ |
mov esi,[strs] |
@@: |
lodsb |
or al,al |
jnz @b |
mov ebx,esi |
mov esi,[strs] |
dec ebx |
sub ebx,esi |
mov ecx,1 |
@@: |
dec ebx |
or ebx,ebx |
jz @f |
imul ecx,ecx,10 ; ¯®à冷ª |
jmp @b |
@@: |
xchg ebx,ecx |
xor ecx,ecx |
@@: |
xor eax,eax |
lodsb |
cmp al,0 |
je .eend |
sub al,30h |
imul ebx |
add ecx,eax |
push ecx |
xchg eax,ebx |
mov ecx,10 |
div ecx |
xchg eax,ebx |
pop ecx |
jmp @b |
.eend: |
mov [esp+28],ecx |
popad |
ret |
endp |
;convert string to DWord for hex value |
proc strtoint_hex stdcall,strs |
pushad |
xor edx,edx |
mov esi,[strs] |
mov ebx,1 |
add esi,1 |
@@: |
lodsb |
or al,al |
jz @f |
shl ebx,4 |
jmp @b |
@@: |
xor ecx,ecx |
mov esi,[strs] |
@@: |
xor eax,eax |
lodsb |
cmp al,0 |
je .eend |
cmp al,'a' |
jae .bm |
cmp al,'A' |
jae .bb |
jmp .cc |
.bm: ; 57h |
sub al,57h |
jmp .do |
.bb: ; 37h |
sub al,37h |
jmp .do |
.cc: ; 30h |
sub al,30h |
.do: |
imul ebx |
add ecx,eax |
shr ebx,4 |
jmp @b |
.eend: |
mov [esp+28],ecx |
popad |
ret |
endp |
; convert string to DWord for IP addres |
proc do_inet_adr stdcall,strs |
pushad |
mov esi,[strs] |
mov ebx,0 |
.next: |
push esi |
@@: |
lodsb |
or al,al |
jz @f |
cmp al,'.' |
jz @f |
jmp @b |
@@: |
mov cl, al |
mov [esi-1],byte 0 |
;pop eax |
call strtoint_dec |
rol eax,24 |
ror ebx,8 |
add ebx,eax |
or cl,cl |
jz @f |
jmp .next |
@@: |
mov [esp+28],ebx |
popad |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/v86.inc |
---|
0,0 → 1,935 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Virtual-8086 mode manager |
; diamond, 2007, 2008 |
DEBUG_SHOW_IO = 0 |
struc V86_machine |
{ |
; page directory |
.pagedir dd ? |
; translation table: V86 address -> flat linear address |
.pages dd ? |
; mutex to protect all data from writing by multiple threads at one time |
.mutex dd ? |
; i/o permission map |
.iopm dd ? |
.size = $ |
} |
virtual at 0 |
V86_machine V86_machine |
end virtual |
; Create V86 machine |
; in: nothing |
; out: eax = handle (pointer to struc V86_machine) |
; eax = NULL => failure |
; destroys: ebx, ecx, edx (due to malloc) |
v86_create: |
; allocate V86_machine structure |
mov eax, V86_machine.size |
call malloc |
test eax, eax |
jz .fail |
; initialize mutex |
and dword [eax+V86_machine.mutex], 0 |
; allocate tables |
mov ebx, eax |
; We allocate 4 pages. |
; First is main page directory for V86 mode. |
; Second page: |
; first half (0x800 bytes) is page table for addresses 0 - 0x100000, |
; second half is for V86-to-linear translation. |
; Third and fourth are for I/O permission map. |
push 8000h ; blocks less than 8 pages are discontinuous |
call kernel_alloc |
test eax, eax |
jz .fail2 |
mov [ebx+V86_machine.pagedir], eax |
push edi eax |
mov edi, eax |
add eax, 1800h |
mov [ebx+V86_machine.pages], eax |
; initialize tables |
mov ecx, 2000h/4 |
xor eax, eax |
rep stosd |
mov [ebx+V86_machine.iopm], edi |
dec eax |
mov ecx, 2000h/4 |
rep stosd |
pop eax |
; page directory: first entry is page table... |
mov edi, eax |
add eax, 1000h |
push eax |
call get_pg_addr |
or al, PG_UW |
stosd |
; ...and also copy system page tables |
; thx to Serge, system is located at high addresses |
add edi, (OS_BASE shr 20) - 4 |
push esi |
mov esi, (OS_BASE shr 20) + sys_pgdir |
mov ecx, 0x80000000 shr 22 |
rep movsd |
mov eax, [ebx+V86_machine.pagedir] ;root dir also is |
call get_pg_addr ;used as page table |
or al, PG_SW |
mov [edi-4096+(page_tabs shr 20)], eax |
pop esi |
; now V86 specific: initialize known addresses in first Mb |
pop eax |
; first page - BIOS data (shared between all machines!) |
; physical address = 0x2f0000 |
; linear address = BOOT_VAR = OS_BASE + 0x2f0000 |
mov dword [eax], (BOOT_VAR - OS_BASE) or 111b |
mov dword [eax+800h], BOOT_VAR |
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) |
; physical address = 0x9C000 |
; linear address = 0x8009C000 |
; (I have seen one computer with EBDA segment = 0x9D80, |
; all other computers use less memory) |
mov ecx, 4 |
mov edx, 0x9C000 |
push eax |
lea edi, [eax+0x9C*4] |
@@: |
lea eax, [edx + OS_BASE] |
mov [edi+800h], eax |
lea eax, [edx + 111b] |
stosd |
add edx, 0x1000 |
loop @b |
pop eax |
pop edi |
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) |
; physical address = 0xC0000 |
; linear address = 0x800C0000 |
mov ecx, 0xC0 |
@@: |
mov edx, ecx |
shl edx, 12 |
push edx |
or edx, 111b |
mov [eax+ecx*4], edx |
pop edx |
add edx, OS_BASE |
mov [eax+ecx*4+0x800], edx |
inc cl |
jnz @b |
mov eax, ebx |
ret |
.fail2: |
mov eax, ebx |
call free |
.fail: |
xor eax, eax |
ret |
; Destroy V86 machine |
; in: eax = handle |
; out: nothing |
; destroys: eax, ebx, ecx, edx (due to free) |
v86_destroy: |
push eax |
stdcall kernel_free, [eax+V86_machine.pagedir] |
pop eax |
jmp free |
; Translate V86-address to linear address |
; in: eax=V86 address |
; esi=handle |
; out: eax=linear address |
; destroys: nothing |
v86_get_lin_addr: |
push ecx edx |
mov ecx, eax |
mov edx, [esi+V86_machine.pages] |
shr ecx, 12 |
and eax, 0xFFF |
add eax, [edx+ecx*4] ; atomic operation, no mutex needed |
pop edx ecx |
ret |
; Sets linear address for V86-page |
; in: eax=linear address (must be page-aligned) |
; ecx=V86 page (NOT address!) |
; esi=handle |
; out: nothing |
; destroys: nothing |
v86_set_page: |
push eax ebx |
mov ebx, [esi+V86_machine.pagedir] |
mov [ebx+ecx*4+0x1800], eax |
call get_pg_addr |
or al, 111b |
mov [ebx+ecx*4+0x1000], eax |
pop ebx eax |
ret |
; Allocate memory in V86 machine |
; in: eax=size (in bytes) |
; esi=handle |
; out: eax=V86 address, para-aligned (0x10 multiple) |
; destroys: nothing |
; ¥¤®¯¨á !!! |
;v86_alloc: |
; push ebx ecx edx edi |
; lea ebx, [esi+V86_machine.mutex] |
; call wait_mutex |
; add eax, 0x1F |
; shr eax, 4 |
; mov ebx, 0x1000 ; start with address 0x1000 (second page) |
; mov edi, [esi+V86_machine.tables] |
;.l: |
; mov ecx, ebx |
; shr ecx, 12 |
; mov edx, [edi+0x1000+ecx*4] ; get linear address |
; test edx, edx ; page allocated? |
; jz .unalloc |
; mov ecx, ebx |
; and ecx, 0xFFF |
; add edx, ecx |
; cmp dword [edx], 0 ; free block? |
; jnz .n |
; cmp dword [edx+4], |
; and [esi+V86_machine.mutex], 0 |
; pop edi edx ecx ebx |
; ret |
uglobal |
sys_v86_machine dd ? |
endg |
; Called from kernel.asm at first stages of loading |
; Initialize system V86 machine (used to simulate BIOS int 13h) |
init_sys_v86: |
call v86_create |
mov [sys_v86_machine], eax |
test eax, eax |
jz .ret |
mov byte [BOOT_VAR + 0x500], 0xCD |
mov byte [BOOT_VAR + 0x501], 0x13 |
mov byte [BOOT_VAR + 0x502], 0xF4 |
mov byte [BOOT_VAR + 0x503], 0xCD |
mov byte [BOOT_VAR + 0x504], 0x10 |
mov byte [BOOT_VAR + 0x505], 0xF4 |
mov esi, eax |
mov ebx, [eax+V86_machine.pagedir] |
; one page for stack, two pages for results (0x2000 bytes = 16 sectors) |
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b |
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000 |
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b |
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000 |
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b |
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000 |
if ~DEBUG_SHOW_IO |
; allow access to all ports |
mov ecx, [esi+V86_machine.iopm] |
xor eax, eax |
mov edi, ecx |
mov ecx, 10000h/8/4 |
rep stosd |
end if |
.ret: |
ret |
struc v86_regs |
{ |
; don't change the order, it is important |
.edi dd ? |
.esi dd ? |
.ebp dd ? |
dd ? ; ignored |
.ebx dd ? |
.edx dd ? |
.ecx dd ? |
.eax dd ? |
.eip dd ? |
.cs dd ? |
.eflags dd ? ; VM flag must be set! |
.esp dd ? |
.ss dd ? |
.es dd ? |
.ds dd ? |
.fs dd ? |
.gs dd ? |
.size = $ |
} |
virtual at 0 |
v86_regs v86_regs |
end virtual |
; Run V86 machine |
; in: ebx -> registers for V86 (two structures: in and out) |
; esi = handle |
; ecx = expected end address (CS:IP) |
; edx = IRQ to hook or -1 if not required |
; out: structure pointed to by ebx is filled with new values |
; eax = 1 - exception has occured, cl contains code |
; eax = 2 - access to disabled i/o port, ecx contains port address |
; eax = 3 - IRQ is already hooked by another VM |
; destroys: nothing |
v86_start: |
pushad |
cli |
mov ecx, [CURRENT_TASK] |
shl ecx, 8 |
add ecx, SLOT_BASE |
mov eax, [esi+V86_machine.iopm] |
call get_pg_addr |
inc eax |
push dword [ecx+APPDATA.io_map] |
push dword [ecx+APPDATA.io_map+4] |
mov dword [ecx+APPDATA.io_map], eax |
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax |
add eax, 0x1000 |
mov dword [ecx+APPDATA.io_map+4], eax |
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax |
push [ecx+APPDATA.dir_table] |
push [ecx+APPDATA.saved_esp0] |
mov [ecx+APPDATA.saved_esp0], esp |
mov [tss._esp0], esp |
mov eax, [esi+V86_machine.pagedir] |
call get_pg_addr |
mov [ecx+APPDATA.dir_table], eax |
mov cr3, eax |
; mov [irq_tab+5*4], my05 |
; We do not enable interrupts, because V86 IRQ redirector assumes that |
; machine is running |
; They will be enabled by IRET. |
; sti |
mov eax, esi |
sub esp, v86_regs.size |
mov esi, ebx |
mov edi, esp |
mov ecx, v86_regs.size/4 |
rep movsd |
cmp edx, -1 |
jz .noirqhook |
uglobal |
v86_irqhooks rd 16*2 |
endg |
cmp [v86_irqhooks+edx*8], 0 |
jz @f |
cmp [v86_irqhooks+edx*8], eax |
jz @f |
mov esi, v86_irqerr |
call sys_msg_board_str |
inc [v86_irqhooks+edx*8+4] |
mov eax, 3 |
jmp v86_exc_c.exit |
@@: |
mov [v86_irqhooks+edx*8], eax |
inc [v86_irqhooks+edx*8+4] |
.noirqhook: |
popad |
iretd |
; It is only possible to leave virtual-8086 mode by faulting to |
; a protected-mode interrupt handler (typically the general-protection |
; exception handler, which in turn calls the virtual 8086-mode monitor). |
iglobal |
v86_exc_str1 db 'V86 : unexpected exception ',0 |
v86_exc_str2 db ' at ',0 |
v86_exc_str3 db ':',0 |
v86_exc_str4 db 13,10,'V86 : faulted code:',0 |
v86_exc_str5 db ' (unavailable)',0 |
v86_newline db 13,10,0 |
v86_io_str1 db 'V86 : access to disabled i/o port ',0 |
v86_io_byte db ' (byte)',13,10,0 |
v86_io_word db ' (word)',13,10,0 |
v86_io_dword db ' (dword)',13,10,0 |
v86_irqerr db 'V86 : IRQ already hooked',13,10,0 |
endg |
v86_exc_c: |
; Did we all that we have wanted to do? |
cmp bl,1 |
jne @f |
xor eax, eax |
mov dr6, eax |
@@: mov eax, [esp+v86_regs.size+10h+18h] |
cmp word [esp+v86_regs.eip], ax |
jnz @f |
shr eax, 16 |
cmp word [esp+v86_regs.cs], ax |
jz .done |
@@: |
; Various system events, which must be handled, result in #GP |
cmp bl, 13 |
jnz .nogp |
; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error |
cmp word [esp+v86_regs.eip+2], 0 |
jnz .nogp |
; Otherwise we can safely access byte at CS:IP |
; (because it is #GP, not #PF handler) |
; ᫨ ¡ë ¬ë ¬®£«¨ áå«®¯®â âì ¨áª«î票¥ ⮫쪮 ¨§-§ çâ¥¨ï ¡ ©â®¢ ª®¤ , |
; ¬ë ¡ë ¥£® 㦥 áå«®¯®â «¨ ¨ íâ® ¡ë«® ¡ë ¥ #GP |
movzx esi, word [esp+v86_regs.cs] |
shl esi, 4 |
add esi, [esp+v86_regs.eip] |
lodsb |
cmp al, 0xCD ; int xx command = CD xx |
jz .handle_int |
cmp al, 0xCF |
jz .handle_iret |
cmp al, 0xF3 |
jz .handle_rep |
cmp al, 0xEC |
jz .handle_in |
cmp al, 0xED |
jz .handle_in_word |
cmp al, 0xEE |
jz .handle_out |
cmp al, 0xEF |
jz .handle_out_word |
cmp al, 0xE4 |
jz .handle_in_imm |
cmp al, 0xE6 |
jz .handle_out_imm |
cmp al, 0x9C |
jz .handle_pushf |
cmp al, 0x9D |
jz .handle_popf |
cmp al, 0xFA |
jz .handle_cli |
cmp al, 0xFB |
jz .handle_sti |
cmp al, 0x66 |
jz .handle_66 |
jmp .nogp |
.handle_int: |
cmp word [esp+v86_regs.eip], 0xFFFF |
jae .nogp |
xor eax, eax |
lodsb |
; call sys_msg_board_byte |
; simulate INT command |
; N.B. It is possible that some checks need to be corrected, |
; but at least in case of normal execution the code works. |
.simulate_int: |
cmp word [esp+v86_regs.esp], 6 |
jae @f |
mov bl, 12 ; #SS exception |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
push eax |
movzx eax, word [esp+4+v86_regs.esp] |
sub eax, 6 |
add edx, eax |
mov eax, edx |
mov esi, [esp+4+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
lea eax, [edx+5] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
sub word [esp+4+v86_regs.esp], 6 |
mov eax, [esp+4+v86_regs.eip] |
cmp byte [esp+1], 0 |
jnz @f |
inc eax |
inc eax |
@@: |
mov word [edx], ax |
mov eax, [esp+4+v86_regs.cs] |
mov word [edx+2], ax |
mov eax, [esp+4+v86_regs.eflags] |
mov word [edx+4], ax |
pop eax |
mov ah, 0 |
mov cx, [eax*4] |
mov word [esp+v86_regs.eip], cx |
mov cx, [eax*4+2] |
mov word [esp+v86_regs.cs], cx |
; note that interrupts will be disabled globally at IRET |
and byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags |
; continue V86 execution |
popad |
iretd |
.handle_iret: |
cmp word [esp+v86_regs.esp], 0x10000 - 6 |
jbe @f |
mov bl, 12 |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
movzx eax, word [esp+v86_regs.esp] |
add edx, eax |
mov eax, edx |
mov esi, [esp+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
lea eax, [edx+5] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
mov ax, [edx] |
mov word [esp+v86_regs.eip], ax |
mov ax, [edx+2] |
mov word [esp+v86_regs.cs], ax |
mov ax, [edx+4] |
mov word [esp+v86_regs.eflags], ax |
add word [esp+v86_regs.esp], 6 |
popad |
iretd |
.handle_pushf: |
cmp word [esp+v86_regs.esp], 1 |
jnz @f |
mov bl, 12 |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
mov eax, [esp+v86_regs.esp] |
sub eax, 2 |
movzx eax, ax |
add edx, eax |
mov eax, edx |
mov esi, [esp+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
lea eax, [edx+1] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
sub word [esp+v86_regs.esp], 2 |
mov eax, [esp+v86_regs.eflags] |
mov [edx], ax |
inc word [esp+v86_regs.eip] |
popad |
iretd |
.handle_pushfd: |
cmp word [esp+v86_regs.esp], 4 |
jae @f |
mov bl, 12 ; #SS exception |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
movzx eax, word [esp+v86_regs.esp] |
sub eax, 4 |
add edx, eax |
mov eax, edx |
mov esi, [esp+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
lea eax, [edx+3] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
sub word [esp+v86_regs.esp], 4 |
movzx eax, word [esp+v86_regs.eflags] |
mov [edx], eax |
add word [esp+v86_regs.eip], 2 |
popad |
iretd |
.handle_popf: |
cmp word [esp+v86_regs.esp], 0xFFFF |
jnz @f |
mov bl, 12 |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
movzx eax, word [esp+v86_regs.esp] |
add edx, eax |
mov eax, edx |
mov esi, [esp+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 ; #PF exception |
jmp .nogp |
@@: |
lea eax, [edx+1] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
mov ax, [edx] |
mov word [esp+v86_regs.eflags], ax |
add word [esp+v86_regs.esp], 2 |
inc word [esp+v86_regs.eip] |
popad |
iretd |
.handle_popfd: |
cmp word [esp+v86_regs.esp], 0x10000 - 4 |
jbe @f |
mov bl, 12 |
jmp .nogp |
@@: |
movzx edx, word [esp+v86_regs.ss] |
shl edx, 4 |
movzx eax, word [esp+v86_regs.esp] |
add edx, eax |
mov eax, edx |
mov esi, [esp+v86_regs.size+10h+4] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
lea eax, [edx+3] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jae @f |
mov bl, 14 |
jmp .nogp |
@@: |
mov eax, [edx] |
mov word [esp+v86_regs.eflags], ax |
add word [esp+v86_regs.esp], 4 |
add word [esp+v86_regs.eip], 2 |
popad |
iretd |
.handle_cli: |
and byte [esp+v86_regs.eflags+1], not 2 |
inc word [esp+v86_regs.eip] |
popad |
iretd |
.handle_sti: |
or byte [esp+v86_regs.eflags+1], 2 |
inc word [esp+v86_regs.eip] |
popad |
iretd |
.handle_rep: |
cmp word [esp+v86_regs.eip], 0xFFFF |
jae .nogp |
lodsb |
cmp al, 6Eh |
jz .handle_rep_outsb |
jmp .nogp |
.handle_rep_outsb: |
.handle_in: |
.handle_out: |
.invalid_io_byte: |
movzx ebx, word [esp+v86_regs.edx] |
mov ecx, 1 |
jmp .invalid_io |
.handle_in_imm: |
.handle_out_imm: |
cmp word [esp+v86_regs.eip], 0xFFFF |
jae .nogp |
lodsb |
movzx ebx, al |
mov ecx, 1 |
jmp .invalid_io |
.handle_66: |
cmp word [esp+v86_regs.eip], 0xFFFF |
jae .nogp |
lodsb |
cmp al, 0x9C |
jz .handle_pushfd |
cmp al, 0x9D |
jz .handle_popfd |
cmp al, 0xEF |
jz .handle_out_dword |
cmp al, 0xED |
jz .handle_in_dword |
jmp .nogp |
.handle_in_word: |
.handle_out_word: |
movzx ebx, word [esp+v86_regs.edx] |
mov ecx, 2 |
jmp .invalid_io |
.handle_in_dword: |
.handle_out_dword: |
.invalid_io_dword: |
movzx ebx, word [esp+v86_regs.edx] |
mov ecx, 4 |
.invalid_io: |
mov esi, v86_io_str1 |
call sys_msg_board_str |
mov eax, ebx |
call sys_msg_board_dword |
mov esi, v86_io_byte |
cmp ecx, 1 |
jz @f |
mov esi, v86_io_word |
cmp ecx, 2 |
jz @f |
mov esi, v86_io_dword |
@@: |
call sys_msg_board_str |
if DEBUG_SHOW_IO |
mov edx, ebx |
mov ebx, 200 |
call delay_hs |
mov esi, [esp+v86_regs.size+10h+4] |
mov eax, [esi+V86_machine.iopm] |
@@: |
btr [eax], edx |
inc edx |
loop @b |
popad |
iretd |
else |
mov eax, 2 |
jmp .exit |
end if |
.nogp: |
mov esi, v86_exc_str1 |
call sys_msg_board_str |
mov al, bl |
call sys_msg_board_byte |
mov esi, v86_exc_str2 |
call sys_msg_board_str |
mov ax, [esp+32+4] |
call sys_msg_board_word |
mov esi, v86_exc_str3 |
call sys_msg_board_str |
mov ax, [esp+32] |
call sys_msg_board_word |
mov esi, v86_exc_str4 |
call sys_msg_board_str |
mov ecx, 8 |
movzx edx, word [esp+32+4] |
shl edx, 4 |
add edx, [esp+32] |
@@: |
mov esi, [esp+v86_regs.size+10h+4] |
mov eax, edx |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jb .nopage |
mov esi, v86_exc_str3-2 |
call sys_msg_board_str |
mov al, [edx] |
call sys_msg_board_byte |
inc edx |
loop @b |
jmp @f |
.nopage: |
mov esi, v86_exc_str5 |
call sys_msg_board_str |
@@: |
mov esi, v86_newline |
call sys_msg_board_str |
mov eax, 1 |
jmp .exit |
.done: |
xor eax, eax |
.exit: |
mov [esp+v86_regs.size+10h+1Ch], eax |
mov [esp+v86_regs.size+10h+18h], ebx |
mov edx, [esp+v86_regs.size+10h+14h] |
cmp edx, -1 |
jz @f |
dec [v86_irqhooks+edx*8+4] |
jnz @f |
and [v86_irqhooks+edx*8], 0 |
@@: |
mov esi, esp |
mov edi, [esi+v86_regs.size+10h+10h] |
add edi, v86_regs.size |
mov ecx, v86_regs.size/4 |
rep movsd |
mov esp, esi |
cli |
mov ecx, [CURRENT_TASK] |
shl ecx, 8 |
pop eax |
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax |
mov [tss._esp0], eax |
pop eax |
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax |
pop ebx |
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx |
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx |
pop ebx |
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx |
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
mov cr3, eax |
; mov [irq_tab+5*4], 0 |
sti |
popad |
ret |
;my05: |
; mov dx, 30C2h |
; mov cx, 4 |
;.0: |
; in al, dx |
; cmp al, 0FFh |
; jz @f |
; test al, 4 |
; jnz .1 |
;@@: |
; add dx, 8 |
; in al, dx |
; cmp al, 0FFh |
; jz @f |
; test al, 4 |
; jnz .1 |
;@@: |
; loop .0 |
; ret |
;.1: |
; or al, 84h |
; out dx, al |
;.2: |
; mov dx, 30F7h |
; in al, dx |
; mov byte [BOOT_VAR + 48Eh], 0FFh |
; ret |
v86_irq: |
; push irq/pushad/jmp v86_irq |
; eax = irq |
lea esi, [esp+1Ch] |
lea edi, [esi+4] |
mov ecx, 8 |
std |
rep movsd |
cld |
mov edi, eax |
pop eax |
v86_irq2: |
mov esi, [v86_irqhooks+edi*8] ; get VM handle |
mov eax, [esi+V86_machine.pagedir] |
call get_pg_addr |
mov ecx, [CURRENT_TASK] |
shl ecx, 8 |
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax |
jnz .notcurrent |
lea eax, [edi+8] |
cmp al, 10h |
mov ah, 1 |
jb @f |
add al, 60h |
@@: |
jmp v86_exc_c.simulate_int |
.notcurrent: |
mov ebx, SLOT_BASE + 0x100 |
mov ecx, [TASK_COUNT] |
.scan: |
cmp [ebx+APPDATA.dir_table], eax |
jnz .cont |
push ecx |
mov ecx, [ebx+APPDATA.saved_esp0] |
cmp word [ecx-v86_regs.size+v86_regs.esp], 6 |
jb .cont2 |
movzx edx, word [ecx-v86_regs.size+v86_regs.ss] |
shl edx, 4 |
push eax |
movzx eax, word [ecx-v86_regs.size+v86_regs.esp] |
sub eax, 6 |
add edx, eax |
mov eax, edx |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jb .cont3 |
lea eax, [edx+5] |
call v86_get_lin_addr |
cmp eax, 0x1000 |
jb .cont3 |
pop eax |
pop ecx |
jmp .found |
.cont3: |
pop eax |
.cont2: |
pop ecx |
.cont: |
loop .scan |
mov al, 20h |
out 20h, al |
cmp edi, 8 |
jb @f |
out 0A0h, al |
@@: |
popad |
iretd |
.found: |
mov cr3, eax |
sub word [esi-v86_regs.size+v86_regs.esp], 6 |
mov ecx, [esi-v86_regs.size+v86_regs.eip] |
mov word [edx], cx |
mov ecx, [esi-v86_regs.size+v86_regs.cs] |
mov word [edx+2], cx |
mov ecx, [esi-v86_regs.size+v86_regs.eflags] |
mov word [edx+4], cx |
lea eax, [edi+8] |
cmp al, 10h |
jb @f |
add al, 60h |
@@: |
mov cx, [eax*4] |
mov word [esi-v86_regs.size+v86_regs.eip], cx |
mov cx, [eax*4+2] |
mov word [esi-v86_regs.size+v86_regs.cs], cx |
and byte [esi-v86_regs.size+v86_regs.eflags+1], not 3 |
call update_counters |
lea edi, [ebx + 0x100000000 - SLOT_BASE] |
shr edi, 3 |
add edi, TASK_DATA |
call find_next_task.found |
call do_change_task |
popad |
iretd |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/debug.inc |
---|
0,0 → 1,416 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; diamond, 2006 |
sys_debug_services: |
cmp eax, 9 |
ja @f |
jmp dword [sys_debug_services_table+eax*4] |
@@: ret |
sys_debug_services_table: |
dd debug_set_event_data |
dd debug_getcontext |
dd debug_setcontext |
dd debug_detach |
dd debug_suspend |
dd debug_resume |
dd debug_read_process_memory |
dd debug_write_process_memory |
dd debug_terminate |
dd debug_set_drx |
debug_set_event_data: |
; in: ebx = pointer |
; destroys eax |
mov eax, [current_slot] |
mov [eax+APPDATA.dbg_event_mem], ebx |
ret |
get_debuggee_slot: |
; in: ebx=PID |
; out: CF=1 if error |
; CF=0 and eax=slot*0x20 if ok |
; out: interrupts disabled |
cli |
mov eax, ebx |
call pid_to_slot |
test eax, eax |
jz .ret_bad |
shl eax, 5 |
push ebx |
mov ebx, [CURRENT_TASK] |
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx |
pop ebx |
jnz .ret_bad |
; clc ; automatically |
ret |
.ret_bad: |
stc |
ret |
debug_detach: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 |
call do_resume |
.ret: |
sti |
ret |
debug_terminate: |
; in: ebx=pid |
call get_debuggee_slot |
jc debug_detach.ret |
mov ecx, eax |
shr ecx, 5 |
push 2 |
pop ebx |
jmp sys_system |
debug_suspend: |
; in: ebx=pid |
; destroys eax,ebx |
cli |
mov eax, ebx |
call pid_to_slot |
shl eax, 5 |
jz .ret |
mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state |
test bl, bl |
jz .1 |
cmp bl, 5 |
jnz .ret |
mov bl, 2 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
.ret: |
sti |
ret |
.1: |
inc ebx |
jmp .2 |
do_resume: |
mov bl, [CURRENT_TASK+eax+TASKDATA.state] |
cmp bl, 1 |
jz .1 |
cmp bl, 2 |
jnz .ret |
mov bl, 5 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
.ret: ret |
.1: dec ebx |
jmp .2 |
debug_resume: |
; in: ebx=pid |
; destroys eax,ebx |
cli |
mov eax, ebx |
call pid_to_slot |
shl eax, 5 |
jz .ret |
call do_resume |
.ret: sti |
ret |
debug_getcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .ret |
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
lea esi, [eax+RING0_STACK_SIZE] |
mov edi, edx |
.ring0: |
; note that following code assumes that all interrupt/exception handlers |
; saves ring-3 context by pushad in this order |
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad |
sub esi, 8+12+20h |
lodsd ;edi |
mov [edi+24h], eax |
lodsd ;esi |
mov [edi+20h], eax |
lodsd ; ebp |
mov [edi+1Ch], eax |
lodsd ;esp |
lodsd ;ebx |
mov [edi+14h], eax |
lodsd ;edx |
mov [edi+10h], eax |
lodsd ;ecx |
mov [edi+0Ch], eax |
lodsd ;eax |
mov [edi+8], eax |
lodsd ;eip |
mov [edi], eax |
lodsd ;cs |
lodsd ;eflags |
mov [edi+4], eax |
lodsd ;esp |
mov [edi+18h], eax |
.ret: |
sti |
ret |
debug_setcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .stiret |
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
lea edi, [eax+RING0_STACK_SIZE] |
mov esi, edx |
.ring0: |
sub edi, 8+12+20h |
mov eax, [esi+24h] ;edi |
stosd |
mov eax, [esi+20h] ;esi |
stosd |
mov eax, [esi+1Ch] ;ebp |
stosd |
scasd |
mov eax, [esi+14h] ;ebx |
stosd |
mov eax, [esi+10h] ;edx |
stosd |
mov eax, [esi+0Ch] ;ecx |
stosd |
mov eax, [esi+8] ;eax |
stosd |
mov eax, [esi] ;eip |
stosd |
scasd |
mov eax, [esi+4] ;eflags |
stosd |
mov eax, [esi+18h] ;esp |
stosd |
.stiret: |
sti |
.ret: |
ret |
debug_set_drx: |
call get_debuggee_slot |
jc .errret |
mov ebp, eax |
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] |
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
; [eax+10]=dr7 |
cmp edx, OS_BASE |
jae .errret |
cmp cl, 3 |
ja .errret |
mov ebx, dr7 |
shr ebx, cl |
shr ebx, cl |
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable |
jnz .errret2 |
test ch, ch |
jns .new |
; clear breakpoint |
movzx ecx, cl |
add ecx, ecx |
and dword [eax+ecx*2], 0 ; clear DR<i> |
btr dword [eax+10h], ecx ; clear L<i> bit |
test byte [eax+10h], 55h |
jnz .okret |
; imul eax, ebp, tss_step/32 |
; and byte [eax + tss_data + TSS._trap], not 1 |
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1 |
.okret: |
and dword [esp+36], 0 |
sti |
ret |
.errret: |
sti |
mov dword [esp+36], 1 |
ret |
.errret2: |
sti |
mov dword [esp+36], 2 |
ret |
.new: |
; add new breakpoint |
; cl=index; ch=flags; edx=address |
test ch, 0xF0 |
jnz .errret |
mov bl, ch |
and bl, 3 |
cmp bl, 2 |
jz .errret |
mov bl, ch |
shr bl, 2 |
cmp bl, 2 |
jz .errret |
test dl, bl |
jnz .errret |
or byte [eax+10h+1], 3 ; set GE and LE flags |
movzx ebx, ch |
movzx ecx, cl |
add ecx, ecx |
bts dword [eax+10h], ecx ; set L<i> flag |
add ecx, ecx |
mov [eax+ecx], edx ; set DR<i> |
shl ebx, cl |
mov edx, 0xF |
shl edx, cl |
not edx |
and [eax+10h+2], dx |
or [eax+10h+2], bx ; set R/W and LEN fields |
; imul eax, ebp, tss_step/32 |
; or byte [eax + tss_data + TSS._trap], 1 |
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1 |
jmp .okret |
debug_read_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(read) |
; destroys all |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz .err |
call get_debuggee_slot |
jc .err |
shr eax, 5 |
mov ebx, esi |
call read_process_memory |
sti |
mov dword [esp+36], eax |
ret |
.err: |
or dword [esp+36], -1 |
ret |
debug_write_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(write) |
; destroys all |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz debug_read_process_memory.err |
call get_debuggee_slot |
jc debug_read_process_memory.err |
shr eax, 5 |
mov ebx, esi |
call write_process_memory |
sti |
mov [esp+36], eax |
ret |
debugger_notify: |
; in: eax=debugger slot |
; ecx=size of debug message |
; [esp+4]..[esp+4+ecx]=message |
; interrupts must be disabled! |
; destroys all general registers |
; interrupts remain disabled |
xchg ebp, eax |
mov edi, [timer_ticks] |
add edi, 500 ; 5 sec timeout |
.1: |
mov eax, ebp |
shl eax, 8 |
mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
test edx, edx |
jz .ret |
; read buffer header |
push ecx |
push eax |
push eax |
mov eax, ebp |
mov ebx, esp |
mov ecx, 8 |
call read_process_memory |
cmp eax, ecx |
jz @f |
add esp, 12 |
jmp .ret |
@@: |
cmp dword [ebx], 0 |
jg @f |
.2: |
pop ecx |
pop ecx |
pop ecx |
cmp dword [CURRENT_TASK], 1 |
jnz .notos |
cmp [timer_ticks], edi |
jae .ret |
.notos: |
sti |
call change_task |
cli |
jmp .1 |
@@: |
mov ecx, [ebx+8] |
add ecx, [ebx+4] |
cmp ecx, [ebx] |
ja .2 |
; advance buffer position |
push ecx |
mov ecx, 4 |
sub ebx, ecx |
mov eax, ebp |
add edx, ecx |
call write_process_memory |
pop eax |
; write message |
mov eax, ebp |
add edx, ecx |
add edx, [ebx+8] |
add ebx, 20 |
pop ecx |
pop ecx |
pop ecx |
call write_process_memory |
; new debug event |
mov eax, ebp |
shl eax, 8 |
or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
.ret: |
ret |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/fpu.inc |
---|
0,0 → 1,183 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
init_fpu: |
clts |
fninit |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
mov ebx, cr4 |
mov ecx, cr0 |
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT |
mov cr4, ebx |
and ecx, not (CR0_MP+CR0_EM) |
or ecx, CR0_NE |
mov cr0, ecx |
mov dword [esp-4], SSE_INIT |
ldmxcsr [esp-4] |
xorps xmm0, xmm0 |
xorps xmm1, xmm1 |
xorps xmm2, xmm2 |
xorps xmm3, xmm3 |
xorps xmm4, xmm4 |
xorps xmm5, xmm5 |
xorps xmm6, xmm6 |
xorps xmm7, xmm7 |
fxsave [fpu_data] ;[eax] |
ret |
.no_SSE: |
mov ecx, cr0 |
and ecx, not CR0_EM |
or ecx, CR0_MP+CR0_NE |
mov cr0, ecx |
fnsave [fpu_data] |
ret |
; param |
; eax= 512 bytes memory area |
align 4 |
fpu_save: |
push ecx |
push esi |
push edi |
pushfd |
cli |
clts |
mov edi, eax |
mov ecx, [fpu_owner] |
mov esi, [CURRENT_TASK] |
cmp ecx, esi |
jne .save |
call save_context |
jmp .exit |
.save: |
mov [fpu_owner], esi |
shl ecx, 8 |
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] |
call save_context |
shl esi, 8 |
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state] |
mov ecx, 512/4 |
cld |
rep movsd |
fninit |
.exit: |
popfd |
pop edi |
pop esi |
pop ecx |
ret |
align 4 |
save_context: |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
ret |
.no_SSE: |
fnsave [eax] |
ret |
align 4 |
fpu_restore: |
push ecx |
push esi |
mov esi, eax |
pushfd |
cli |
mov ecx, [fpu_owner] |
mov eax, [CURRENT_TASK] |
cmp ecx, eax |
jne .copy |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxrstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.no_SSE: |
fnclex ;fix possible problems |
frstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.copy: |
shl eax, 8 |
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] |
mov ecx, 512/4 |
cld |
rep movsd |
popfd |
pop esi |
pop ecx |
ret |
align 4 |
except_7: ;#NM exception handler |
save_ring3_context |
clts |
mov ax, app_data ; |
mov ds, ax |
mov es, ax |
mov ebx, [fpu_owner] |
cmp ebx, [CURRENT_TASK] |
je .exit |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
fxrstor [eax] |
.exit: |
restore_ring3_context |
iret |
.no_SSE: |
fnsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
frstor [eax] |
restore_ring3_context |
iret |
iglobal |
fpu_owner dd 0 |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/export.inc |
---|
0,0 → 1,39 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Macroinstruction for making export section |
macro export dllname,[label,string] |
{ common |
local module,addresses,names,ordinal,count |
count = 0 |
forward |
count = count+1 |
common |
dd 0,0,0, (module-OS_BASE) , 1 |
dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE) |
addresses: |
forward |
dd (label-OS_BASE) |
common |
names: |
forward |
local name |
dd (name-OS_BASE) |
common |
ordinal: count = 0 |
forward |
dw count |
count = count+1 |
common |
module db dllname,0 |
forward |
name db string,0 |
} |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/string.inc |
---|
0,0 → 1,188 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; Author: Kees J. Bot 1 Jan 1994 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; size_t strncat(char *s1, const char *s2, size_t n) |
; Append string s2 to s1. |
; char *strchr(const char *s, int c) |
; int strncmp(const char *s1, const char *s2, size_t n) |
; Compare two strings. |
; char *strncpy(char *s1, const char *s2, size_t n) |
; Copy string s2 to s1. |
; size_t strnlen(const char *s, size_t n) |
; Return the length of a string. |
; proc strrchr stdcall, s:dword, c:dword |
; Look for the last occurrence a character in a string. |
proc strncat stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov edi, [s1] ; String s1 |
mov edx, [n] ; Maximum length |
mov ecx, -1 |
xor al, al ; Null byte |
cld |
repne scasb ; Look for the zero byte in s1 |
dec edi ; Back one up (and clear 'Z' flag) |
push edi ; Save end of s1 |
mov edi, [s2] ; edi = string s2 |
mov ecx, edx ; Maximum count |
repne scasb ; Look for the end of s2 |
jne @F |
inc ecx ; Exclude null byte |
@@: |
sub edx, ecx ; Number of bytes in s2 |
mov ecx, edx |
mov esi, [s2] ; esi = string s2 |
pop edi ; edi = end of string s1 |
rep movsb ; Copy bytes |
stosb ; Add a terminating null |
mov eax, [s1] ; Return s1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strncmp stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov ecx, [n] |
test ecx, ecx ; Max length is zero? |
je .done |
mov esi, [s1] ; esi = string s1 |
mov edi, [s2] ; edi = string s2 |
cld |
.compare: |
cmpsb ; Compare two bytes |
jne .done |
cmp byte [esi-1], 0 ; End of string? |
je .done |
dec ecx ; Length limit reached? |
jne .compare |
.done: |
seta al ; al = (s1 > s2) |
setb ah ; ah = (s1 < s2) |
sub al, ah |
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strncpy stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov ecx, [n] ; Maximum length |
mov edi, [s2] ; edi = string s2 |
xor al, al ; Look for a zero byte |
mov edx, ecx ; Save maximum count |
cld |
repne scasb ; Look for end of s2 |
sub edx, ecx ; Number of bytes in s2 including null |
xchg ecx, edx |
mov esi, [s2] ; esi = string s2 |
mov edi, [s1] ; edi = string s1 |
rep movsb ; Copy bytes |
mov ecx, edx ; Number of bytes not copied |
rep stosb ; strncpy always copies n bytes by null padding |
mov eax, [s1] ; Return s1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strnlen stdcall, s:dword, n:dword |
push edi |
mov edi, [s] ; edi = string |
xor al, al ; Look for a zero byte |
mov edx, ecx ; Save maximum count |
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 |
cld |
repne scasb ; Look for zero |
jne @F |
inc ecx ; Don't count zero byte |
@@: |
mov eax, edx |
sub eax, ecx ; Compute bytes scanned |
pop edi |
ret |
endp |
align 4 |
proc strchr stdcall, s:dword, c:dword |
push edi |
cld |
mov edi, [s] ; edi = string |
mov edx, 16 ; Look at small chunks of the string |
.next: |
shl edx, 1 ; Chunks become bigger each time |
mov ecx, edx |
xor al, al ; Look for the zero at the end |
repne scasb |
pushf ; Remember the flags |
sub ecx, edx |
neg ecx ; Some or all of the chunk |
sub edi, ecx ; Step back |
mov eax, [c] ; The character to look for |
repne scasb |
je .found |
popf ; Did we find the end of string earlier? |
jne .next ; No, try again |
xor eax, eax ; Return NULL |
pop edi |
ret |
.found: |
pop eax ; Get rid of those flags |
lea eax, [edi-1] ; Address of byte found |
pop edi |
ret |
endp |
proc strrchr stdcall, s:dword, c:dword |
push edi |
mov edi, [s] ; edi = string |
mov ecx, -1 |
xor al, al |
cld |
repne scasb ; Look for the end of the string |
not ecx ; -1 - ecx = Length of the string + null |
dec edi ; Put edi back on the zero byte |
mov eax, [c] ; The character to look for |
std ; Downwards search |
repne scasb |
cld ; Direction bit back to default |
jne .fail |
lea eax, [edi+1] ; Found it |
pop edi |
ret |
.fail: |
xor eax, eax ; Not there |
pop edi |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core/sync.inc |
---|
0,0 → 1,119 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Synhronization for MenuetOS. ;; |
;; Author: Halyavin Andrey, halyavin@land.ru ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
if ~defined sync_inc |
sync_inc_fix: |
sync_inc fix sync_inc_fix |
;simplest mutex. |
macro SimpleMutex name |
{ |
; iglobal |
name dd 0 |
name#.type = 1 |
; endg |
} |
macro WaitSimpleMutex name |
{ |
local start_wait,ok |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz ok |
sti |
call change_task |
jmp start_wait |
ok=$ |
push eax |
mov eax,dword [TASK_BASE+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
mov [name],eax |
pop eax |
sti |
} |
macro ReleaseSimpleMutex name |
{ |
mov [name],dword 0 |
} |
macro TryWaitSimpleMutex name ;result in eax and in flags |
{ |
local ok,try_end |
cmp [name],dword 0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
macro SimpleCriticalSection name |
{ |
; iglobal |
name dd 0 |
dd 0 |
name#.type=2 |
; endg |
} |
macro WaitSimpleCriticalSection name |
{ |
local start_wait,first_wait,inc_counter,end_wait |
push eax |
mov eax,[TASK_BASE+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz first_wait |
cmp [name],eax |
jz inc_counter |
sti |
call change_task |
jmp start_wait |
first_wait=$ |
mov [name],eax |
mov [name+4],dword 1 |
jmp end_wait |
inc_counter=$ |
inc dword [name+4] |
end_wait=$ |
sti |
pop eax |
} |
macro ReleaseSimpleCriticalSection name |
{ |
local release_end |
dec dword [name+4] |
jnz release_end |
mov [name],dword 0 |
release_end=$ |
} |
macro TryWaitSimpleCriticalSection name ;result in eax and in flags |
{ |
local ok,try_end |
mov eax,[CURRENT_TASK+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
cmp [name],eax |
jz ok |
cmp [name],0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
_cli equ call MEM_HeapLock |
_sti equ call MEM_HeapUnLock |
end if |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/core |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/data32.inc |
---|
0,0 → 1,467 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
keymap: |
db '6',27 |
db '1234567890-=',8,9 |
db 'qwertyuiop[]',13 |
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_shift: |
db '6',27 |
db '!@#$%^&*()_+',8,9 |
db 'QWERTYUIOP{}',13 |
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_alt: |
db ' ',27 |
db ' @ $ {[]}\ ',8,9 |
db ' ',13 |
db ' ',0,' ',0,'4',0,' ' |
db ' ',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
boot_memdetect db 'Determining amount of memory',0 |
boot_fonts db 'Fonts loaded',0 |
boot_tss db 'Setting TSSs',0 |
boot_cpuid db 'Reading CPUIDs',0 |
boot_devices db 'Detecting devices',0 |
boot_timer db 'Setting timer',0 |
boot_irqs db 'Reprogramming IRQs',0 |
boot_setmouse db 'Setting mouse',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reserving IRQs & ports',0 |
boot_setrports db 'Setting addresses for IRQs',0 |
boot_setostask db 'Setting OS task',0 |
boot_allirqs db 'Unmasking all IRQs',0 |
boot_tsc db 'Reading TSC',0 |
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0 |
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 |
boot_pal_vga db 'Setting VGA 640x480 palette',0 |
boot_failed db 'Failed to start first app',0 |
boot_mtrr db 'Setting MTRR',0 |
if preboot_blogesc |
boot_tasking db 'All set - press ESC to start',0 |
end if |
;new_process_loading db 'K : New Process - loading',13,10,0 |
;new_process_running db 'K : New Process - done',13,10,0 |
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 |
msg_unresolved db 'unresolved ',0 |
msg_module db 'in module ',0 |
msg_version db 'incompatible driver version',13,10,0 |
msg_www db 'please visit www.kolibrios.org',13,10,0 |
msg_CR db 13,10,0 |
aSis db 'SIS',0 |
intel_str db "GenuineIntel",0 |
AMD_str db "AuthenticAMD",0 |
;szSound db 'SOUND',0 |
;szInfinity db 'INFINITY',0 |
szHwMouse db 'ATI2D',0 |
szPS2MDriver db 'PS2MOUSE',0 |
;szCOM_MDriver db 'COM_MOUSE',0 |
szUSB db 'USB',0 |
szAtiHW db '/rd/1/drivers/ati2d.drv',0 |
szSTART db 'START',0 |
szEXPORTS db 'EXPORTS',0 |
sz_EXPORTS db '_EXPORTS',0 |
szIMPORTS db 'IMPORTS',0 |
read_firstapp db '/sys/' |
firstapp db 'LAUNCHER',0 |
char db '/sys/FONTS/CHAR.MT',0 |
char2 db '/sys/FONTS/CHAR2.MT',0 |
bootpath db '/KOLIBRI ' |
bootpath2 db 0 |
vmode db '/sys/drivers/VMODE.MDR',0 |
vrr_m db 'VRR_M',0 |
kernel_file db 'KERNEL MNT' |
align 4 |
shmem_list: |
.bk dd shmem_list |
.fd dd shmem_list |
dll_list: |
.bk dd dll_list |
.fd dd dll_list |
MAX_DEFAULT_DLL_ADDR = 0x20000000 |
MIN_DEFAULT_DLL_ADDR = 0x10000000 |
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR |
; supported videomodes |
; mike.dld { |
db 0 |
dd servetable-0x10000 |
draw_line dd __sys_draw_line |
draw_pointer dd __sys_draw_pointer |
;//mike.dld, 2006-08-02 [ |
;drawbar dd __sys_drawbar |
drawbar dd __sys_drawbar.forced |
;//mike.dld, 2006-08-02 ] |
putpixel dd __sys_putpixel |
; } mike.dld |
align 4 |
keyboard dd 1 |
syslang dd 1 |
boot_y dd 10 |
pci_bios_entry dd 0 |
dw pci_code_sel |
if __DEBUG__ eq 1 |
include_debug_strings |
end if |
IncludeIGlobals |
align 16 |
gdts: |
dw gdte-$-1 |
dd gdts |
dw 0 |
; Attention! Do not change the order of the first four selectors. They are used in Fast System Call |
; must be : os_code, os_data, app_code, app_data, .... |
int_code_l: |
os_code_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
app_code_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db cpl3 |
dw G32+D32+0xF; |
app_data_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db drw3 |
dw G32+D32+0xF; |
; ------------- PCI BIOS ------------------ |
pci_code_32: |
dw 0 ;lim 0-15 |
dw 0 ;base 0-15 |
db 0 ;base 16-23 |
db cpl0 ;type |
db D32 ;lim 16-19+props |
db 0 ;base 24-31 |
pci_data_32: |
dw 0 ;lim 0-15 |
dw 0 ;base 0-15 |
db 0 ;base 16-23 |
db dpl0 ;type |
db D32 ;lim 16-19+props |
db 0 ;base 24-31 |
; --------------- APM --------------------- |
apm_code_32: |
dw 0x0f ; limit 64kb |
db 0, 0, 0 |
dw 11010000b *256 +10011010b |
db 0x00 |
apm_code_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10011010b |
db 0x00 |
apm_data_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10010010b |
db 0x00 |
; ----------------------------------------- |
graph_data_l: |
dw 0x7ff |
dw 0x0000 |
db 0x00 |
dw 11010000b *256 +11110010b |
db 0x00 |
tss0_l: |
dw TSS_SIZE-1 |
dw tss and 0xFFFF |
db (tss shr 16) and 0xFF |
db 10001001b |
dw (tss shr 16) and 0xFF00 |
tls_data_l: |
dw 0x0FFF |
dw 0 |
db 0 |
db drw3 |
dw D32 |
endofcode: |
gdte: |
align 16 |
cur_saved_data rb 4096 |
fpu_data: rb 512 |
; device irq owners |
irq_owner rd 16 ; process id |
; on irq read ports |
irq00read rd 16 |
irq01read rd 16 |
irq02read rd 16 |
irq03read rd 16 |
irq04read rd 16 |
irq05read rd 16 |
irq06read rd 16 |
irq07read rd 16 |
irq08read rd 16 |
irq09read rd 16 |
irq10read rd 16 |
irq11read rd 16 |
irq12read rd 16 |
irq13read rd 16 |
irq14read rd 16 |
irq15read rd 16 |
irq_tab rd 16 |
mem_block_map rb 512 |
mem_block_list rd 64 |
large_block_list rd 31 |
mem_block_mask rd 2 |
large_block_mask rd 1 |
mem_used.fd rd 1 |
mem_used.bk rd 1 |
mem_block_arr rd 1 |
mem_block_start rd 1 |
mem_block_end rd 1 |
heap_mutex rd 1 |
heap_size rd 1 |
heap_free rd 1 |
heap_blocks rd 1 |
free_blocks rd 1 |
mst MEM_STATE |
page_start rd 1 |
page_end rd 1 |
sys_page_map rd 1 |
os_stack_seg rd 1 |
srv.fd rd 1 |
srv.bk rd 1 |
align 16 |
_display display_t |
_WinMapAddress rd 1 |
_WinMapSize rd 1 |
def_cursor rd 1 |
current_cursor rd 1 |
hw_cursor rd 1 |
cur_saved_base rd 1 |
cur.lock rd 1 ;1 - lock update, 2- hide |
cur.left rd 1 ;cursor clip box |
cur.top rd 1 |
cur.right rd 1 |
cur.bottom rd 1 |
cur.w rd 1 |
cur.h rd 1 |
ipc_tmp rd 1 |
ipc_pdir rd 1 |
ipc_ptab rd 1 |
proc_mem_map rd 1 |
proc_mem_pdir rd 1 |
proc_mem_tab rd 1 |
tmp_task_pdir rd 1 |
tmp_task_ptab rd 1 |
default_io_map rd 1 |
LFBSize rd 1 |
stall_mcs rd 1 |
current_slot rd 1 |
; status |
hd1_status rd 1 ; 0 - free : other - pid |
application_table_status rd 1 ; 0 - free : other - pid |
; device addresses |
mididp rd 1 |
midisp rd 1 |
cdbase rd 1 |
cdid rd 1 |
hdbase rd 1 ; for boot 0x1f0 |
hdid rd 1 |
hdpos rd 1 ; for boot 0x1 |
fat32part rd 1 ; for boot 0x1 |
cdpos rd 1 |
;CPUID information |
cpu_vendor rd 3 |
cpu_sign rd 1 |
cpu_info rd 1 |
cpu_caps rd 4 |
pg_data PG_DATA |
heap_test rd 1 |
buttontype rd 1 |
windowtypechanged rd 1 |
hd_entries rd 1 ;unused ? 0xfe10 |
;* start code - Mario79 |
mouse_active rd 1 |
mouse_pause rd 1 |
MouseTickCounter rd 1 |
;* end code - Mario79 |
img_background rd 1 |
mem_BACKGROUND rd 1 |
static_background_data rd 1 |
cache_ide0: |
cache_ide0_pointer rd 1 |
cache_ide0_size rd 1 ; not use |
cache_ide0_data_pointer rd 1 |
cache_ide0_system_data_size rd 1 ; not use |
cache_ide0_appl_data_size rd 1 ; not use |
cache_ide0_system_data rd 1 |
cache_ide0_appl_data rd 1 |
cache_ide0_system_sad_size rd 1 |
cache_ide0_appl_sad_size rd 1 |
cache_ide0_search_start rd 1 |
cache_ide0_appl_search_start rd 1 |
cache_ide1: |
cache_ide1_pointer rd 1 |
cache_ide1_size rd 1 ; not use |
cache_ide1_data_pointer rd 1 |
cache_ide1_system_data_size rd 1 ; not use |
cache_ide1_appl_data_size rd 1 ; not use |
cache_ide1_system_data rd 1 |
cache_ide1_appl_data rd 1 |
cache_ide1_system_sad_size rd 1 |
cache_ide1_appl_sad_size rd 1 |
cache_ide1_search_start rd 1 |
cache_ide1_appl_search_start rd 1 |
cache_ide2: |
cache_ide2_pointer rd 1 |
cache_ide2_size rd 1 ; not use |
cache_ide2_data_pointer rd 1 |
cache_ide2_system_data_size rd 1 ; not use |
cache_ide2_appl_data_size rd 1 ; not use |
cache_ide2_system_data rd 1 |
cache_ide2_appl_data rd 1 |
cache_ide2_system_sad_size rd 1 |
cache_ide2_appl_sad_size rd 1 |
cache_ide2_search_start rd 1 |
cache_ide2_appl_search_start rd 1 |
cache_ide3: |
cache_ide3_pointer rd 1 |
cache_ide3_size rd 1 ; not use |
cache_ide3_data_pointer rd 1 |
cache_ide3_system_data_size rd 1 ; not use |
cache_ide3_appl_data_size rd 1 ; not use |
cache_ide3_system_data rd 1 |
cache_ide3_appl_data rd 1 |
cache_ide3_system_sad_size rd 1 |
cache_ide3_appl_sad_size rd 1 |
cache_ide3_search_start rd 1 |
cache_ide3_appl_search_start rd 1 |
debug_step_pointer rd 1 |
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache |
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache |
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled |
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled |
timer_ticks_enable rb 1 ; for cd driver |
NumBiosDisks rd 1 |
BiosDisksData rb 200h |
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0) |
BiosDiskPartitions rd 80h |
IncludeUGlobals |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/com_mouse.asm |
---|
0,0 → 1,382 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Includes source code by Kulakov Vladimir Gennadievich. ;; |
;; Modified by Mario79 and Rus. ;; |
;; 02.12.2009 <Lrz> ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;driver sceletone |
format MS COFF |
DEBUG equ 0 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 5 ;debug |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
public START |
public version |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
STRIDE equ 4 ;size of row in devices table |
SRV_GETVERSION equ 0 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
.entry: |
;Detect_COM_Mouse: |
if DEBUG |
mov esi, msgInit |
call Boot_Log |
end if |
mov bx, 0x3f8 |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
;mov [com1_mouse_detected],1 |
;mov [irq_owner+4*4], 1 ; IRQ4 owner is System |
mov dx, bx |
inc dx ; 0x3f8 + 1 |
mov al, 1 |
out dx, al |
stdcall AttachIntHandler, 4, irq4_handler, dword 0 |
if DEBUG |
test eax, eax |
jne .label1 |
mov esi, msg_error_attach_int_handler |
call Boot_Log |
end if |
.label1: |
; mov eax, 0 |
; mov ebx, 0x3F8 |
; mov ecx, 0x3FF |
xor ebx,ebx |
mov ecx, 0x3F8 |
mov edx, 0x3FF |
call ReservePortArea |
if DEBUG |
cmp eax, 1 |
jne .go |
mov esi, msg_error_reserve_ports |
call Boot_Log |
.go: |
mov esi,boot_setmouse_type |
call Boot_Log |
end if |
@@: |
mov bx, 0x2f8 |
call MSMouseSearch |
cmp AL,'M' |
jne .resume |
;mov [com2_mouse_detected],1 |
;mov [irq_owner+3*4], 1 ; IRQ3 owner is System |
stdcall AttachIntHandler, 3, irq3_handler, dword 0 |
; mov eax, 0 |
; mov ebx, 0x2F8 |
; mov ecx, 0x3F8 |
xor ebx,ebx |
mov ecx, 0x2F8 |
mov edx, 0x3F8 |
call ReservePortArea |
if DEBUG |
cmp eax, 1 |
jne @f |
mov esi, msg_error_reserve_ports |
call Boot_Log |
@@: |
mov esi,boot_setmouse_type + 22 |
call Boot_Log |
end if |
.resume: |
stdcall RegService, my_service, service_proc |
if DEBUG |
test eax, eax |
jne @f |
mov esi, msg_exit |
call Boot_Log |
end if |
@@: |
ret |
.fail: |
.exit: |
if DEBUG |
mov esi, msg_exit |
call Boot_Log |
end if |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
align 4 |
MSMouseSearch: |
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ |
MouseSearch: |
; Óñòàíàâëèâàåì ñêîðîñòü |
; ïðèåìà/ïåðåäà÷è 1200 áîä |
; in bx COM Port Base Address |
mov DX, bx |
add DX,3 |
in AL,DX |
or AL,80h ;óñòàíîâèòü áèò DLAB |
out DX,AL |
mov DX, bx |
mov AL,60h ;1200 áîä |
out DX,AL |
inc DX |
mov AL,0 |
out DX,AL |
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò, |
; ÷åòíîñòü íå êîíòðîëèðîâàòü |
mov DX, bx |
add DX,3 |
mov AL,00000010b |
out DX,AL |
; Çàïðåòèòü âñå ïðåðûâàíè |
mov dx, bx |
inc dx |
mov AL,0 |
out DX,AL |
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ |
; ìûøüþ òèïà MSMouse |
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè |
mov DX, bx |
add EDX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì |
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2 |
out DX,AL |
; Îæèäàòü 5 "òèêîâ" (0,2 ñ) |
mov ecx, 0xFFFF |
loop $ |
; Âêëþ÷èòü ïèòàíèå ìûøè |
mov al, 1 |
out dx, al |
mov ecx, 0xFFFF |
loop $ |
; Î÷èñòèòü ðåãèñòð äàííûõ |
mov dx, bx |
in AL,DX |
add edx, 4 |
mov AL, 1011b ;óñòàíîâèòü DTR è RTS è OUT2 |
out DX,AL |
mov ecx, 0x1FFFF |
; Öèêë îïðîñà ïîðòà |
WaitData: |
; Îæèäàòü åùå 10 "òèêîâ" |
dec ecx |
; cmp ecx,0 |
jz NoMouse |
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà |
mov DX, bx |
add DX,5 |
in AL,DX |
test AL,1 ;Äàííûå ãîòîâû? |
jz WaitData |
; Ââåñòè äàííûå |
mov DX, bx |
in AL,DX |
NoMouse: |
ret |
align 4 |
irq3_handler: |
mov dx, 0x2f8 |
mov esi, com2_mouse |
jmp irq_handler |
align 4 |
irq4_handler: |
mov dx, 0x3f8 |
mov esi, com1_mouse |
irq_handler: |
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h) |
add edx, 5 ; xFDh |
in al, dx |
test al, 1 ; Äàííûå ãîòîâû? |
jz .Error |
; Ââåñòè äàííûå |
sub edx, 5 |
in al, dx |
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò |
and al, 01111111b |
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2 |
ja .Error |
jz .ThirdByte |
jp .SecondByte |
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ |
.FirstByte: |
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè? |
jz .Error |
mov [esi+COM_MOUSE_DATA.FirstByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Ñîõðàíèòü âòîðîé áàéò äàííûõ |
.SecondByte: |
test al, 1000000b |
jnz .Error |
mov [esi+COM_MOUSE_DATA.SecondByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Ñîõðàíèòü òðåòèé áàéò äàííûõ |
.ThirdByte: |
test al, 1000000b |
jnz .Error |
mov [esi+COM_MOUSE_DATA.ThirdByte], al |
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 |
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ). |
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
mov ah, al |
shr al, 3 |
and al, 2 |
shr ah, 5 |
and ah, 1 |
add al, ah |
movzx eax, al |
mov [BTN_DOWN], eax |
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
shl al, 6 |
or al, [esi+COM_MOUSE_DATA.SecondByte] |
cbw |
movzx eax, ax |
mov [MOUSE_X], eax |
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
and al, 00001100b |
shl al, 4 |
or al, [esi+COM_MOUSE_DATA.ThirdByte] |
cbw |
movzx eax, ax |
neg eax |
mov [MOUSE_Y], eax |
stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0 |
jmp .EndMouseInterrupt |
.Error: |
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò |
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ |
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0 |
.EndMouseInterrupt: |
ret |
;all initialized data place here |
align 4 |
struc COM_MOUSE_DATA { |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
.MouseByteNumber db ? |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
.FirstByte db ? |
.SecondByte db ? |
.ThirdByte db ? |
;.timer_ticks_com dd ? |
} |
virtual at 0 |
COM_MOUSE_DATA COM_MOUSE_DATA |
end virtual |
com1_mouse COM_MOUSE_DATA |
com2_mouse COM_MOUSE_DATA |
MOUSE_X dd 0 |
MOUSE_Y dd 0 |
BTN_DOWN dd 0 |
COMPortBaseAddr dw 3F8h |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
my_service db 'COM_Mouse',0 ;max 16 chars include zero |
if DEBUG |
msgInit db 'Preved bugoga!',13,10,0 |
boot_setmouse_type db 'Detected - COM1 mouse',13,10,0 |
db 'Detected - COM2 mouse',13,10,0 |
msg_error_reserve_ports db 'Error reserving ports!',13,10,0 |
msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0 |
msg_exit db 'Exit!',13,10,0 |
end if |
section '.data' data readable writable align 16 |
;all uninitialized data place here |
/kernel/tags/kolibri0.7.7.0/drivers/sb16/sb16.asm |
---|
0,0 → 1,393 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
include 'config.inc' |
;structs---------------------------------------------------------- |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
;something-------------------------------------------------------- |
public START |
public service_proc |
public version |
include '..\proc32.inc' |
include '..\imports.inc' |
section '.flat' code readable align 16 |
include 'sb16.inc' |
;------------------------------------------------------------------------------- |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
.entry: |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect ;returns DSP version or zero if |
test eax,eax ;SB card not found |
jz .exit |
if DEBUG |
movzx eax,al ;major version |
mov esi,sb_DSP_description |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi],'2.x ' |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi],'Pro ' |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi],'16 ' |
.sb_say_about_found_dsp: |
mov esi,msgDSPFound |
call SysMsgBoardStr |
end if |
; xor eax,eax |
; mov ebx,[sb_base_port] |
; lea ecx,[ebx+0xF] |
xor ebx,ebx |
mov ecx,[sb_base_port] |
lea edx,[ebx+0xF] |
call ReservePortArea ;these ports must be my! |
if DEBUG |
dec eax |
jnz @f |
mov esi,msgErrRsrvPorts |
call SysMsgBoardStr |
@@: |
end if |
call sb_setup ;clock it, etc |
stdcall AttachIntHandler, sb_irq_num, sb_irq, 0 |
if DEBUG |
test eax,eax |
jnz @f |
mov esi,msgErrAtchIRQ |
call SysMsgBoardStr |
stdcall GetIntHandler, sb_irq_num |
call SysMsgBoardNum |
jmp .stop |
@@: |
mov esi,msgSucAtchIRQ |
call SysMsgBoardStr |
end if |
stdcall RegService, my_service, service_proc |
ret |
.stop: |
call sb_reset |
.exit: |
if DEBUG |
mov esi,msgExit |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
endp |
;------------------------------------------------------------------------------- |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi,[ioctl] |
mov eax,[edi+io_code] |
cmp eax,SRV_GETVERSION |
jne @F |
mov eax,[edi+output] |
cmp [edi+out_size],4 |
jne .fail |
mov [eax],dword API_VERSION |
xor eax,eax |
ret |
@@: |
cmp eax,DEV_PLAY |
jne @f |
if DEBUG |
mov esi,msgPlay |
call SysMsgBoardStr |
end if |
call sb_stop ;to play smth new we must stop smth old |
call pre_fill_data ;fill first and second half of the buffer |
call pre_fill_data ; |
call sb_set_dma ;is it really needed here? Paranoia. |
call sb_play |
xor eax,eax ;set maximum volume |
call sb_set_master_vol |
xor eax,eax |
ret |
;@@: ;all this commented stuff in service proc |
; cmp eax,DEV_STOP ;is never used. Mixer do this virtually, |
; jne @f ;e.g. instead of stopping driver it |
;if DEBUG ;outputs silence |
; mov esi,msgStop |
; call SysMsgBoardStr |
;end if |
; call sb_stop |
; xor eax,eax |
; ret |
@@: |
cmp eax,DEV_CALLBACK |
jne @f |
if DEBUG |
mov esi,msgCallback |
call SysMsgBoardStr |
end if |
mov edi,[edi+input] |
mov eax,[edi] |
mov [callback],eax |
if DEBUG |
call SysMsgBoardNum |
end if |
xor eax,eax |
ret |
@@: |
cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock |
jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it. |
;It doesn't use it _in current version_ - but in the future... |
if DEBUG |
mov esi,msgSetVol |
call SysMsgBoardStr |
end if |
mov eax,[edi+input] |
mov eax,[eax] |
call sb_set_master_vol |
xor eax,eax |
ret |
@@: |
cmp eax,DEV_GET_MASTERVOL |
jne @F |
if DEBUG |
mov esi,msgGetVol |
call SysMsgBoardStr |
end if |
mov eax,[edi+output] |
mov edx,[sb_master_vol] |
mov [eax],edx |
xor eax,eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
;------------------------------------------------------------------------------- |
align 4 |
proc sb_irq |
mov edx,[sb_base_port] ;tell the DSP that we have processed IRQ |
add dl,0xF ;0xF for 16 bit sound, 0xE for 8 bit sound |
in al,dx ;for non-stop sound |
pre_fill_data: |
mov eax,int_flip_flop |
not dword[eax] |
mov eax,[eax] |
test eax,eax |
jns .fill_second_half |
if sb_buffer_size eq small_buffer |
stdcall [callback],SB16Buffer0 ;for 32k buffer |
else if sb_buffer_size eq full_buffer |
stdcall [callback],SB16Buffer0 ;for 64k buffer |
stdcall [callback],SB16Buffer1 ;for 64k buffer |
end if |
xor eax,eax |
ret |
.fill_second_half: |
if sb_buffer_size eq small_buffer |
stdcall [callback],SB16Buffer1 ;for 32k buffer |
else if sb_buffer_size eq full_buffer |
stdcall [callback],SB16Buffer2 ;for 64k buffer |
stdcall [callback],SB16Buffer3 ;for 64k buffer |
end if |
xor eax,eax |
ret |
endp |
;------------------------------------------------------------------------------- |
align 4 |
proc detect |
.sb_detect_next_port: |
if DEBUG |
inc dword[port_second_digit_num] |
end if |
mov edx,sb_base_port |
add byte[edx],10h |
cmp byte[edx],80h |
jbe .sb_try_to_detect_at_specified_port |
;error - no SB card detected |
.sb_not_found_err: |
xor eax, eax |
ret |
.sb_try_to_detect_at_specified_port: |
call sb_reset |
add dl,8 |
mov ecx,100 |
.sb_check_port: |
in al,dx |
test al,al ;is DSP port ready to be read? |
jns .sb_port_not_ready |
sub dl,4 |
in al,dx ;check for AAh response |
add dl,4 |
cmp al,0xAA |
jne .sb_port_not_ready |
.sb_card_found: |
and dl,0xF0 |
add dl,0xC |
sb_out 0xE1 ;get DSP version |
add dl,2 |
@@: |
in al,dx |
test al,al ;is DSP port ready to be read? |
jns @b |
sub dl,4 |
in al,dx ;get major version |
ror eax,16 |
add dl,4 |
@@: |
in al,dx |
test al,al ;is DSP port ready to be read? |
jns @b |
sub dl,4 |
in al,dx ;get minor version |
xor edx,edx |
mov dl,10 |
div dl |
ror eax,16 |
xor ah,ah |
mov [sb_DSP_version_int],eax ;for internal usage |
if DEBUG |
add [sb_DSP_version],eax |
end if |
ret |
.sb_port_not_ready: |
loop .sb_check_port ;100 retries (~100 microsec.) |
jmp .sb_detect_next_port |
endp |
;------------------------------------------------------------------------------- |
if DEBUG |
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi |
mov ebx,eax |
mov ecx,8 |
mov esi,(number_to_out+1) |
.1: |
mov eax,ebx |
and eax,0xF |
add al,'0' |
cmp al,(10+'0') |
jb @f |
add al,('A'-'0'-10) |
@@: |
mov [esi+ecx],al |
shr ebx,4 |
loop .1 |
dec esi |
call SysMsgBoardStr |
ret |
endp |
end if |
;all initialized data place here |
align 4 |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
sb_base_port: dd 200h ;don't ask me why - see the code&docs |
sound_dma dd sb_dma_num |
;note that 4th DMA channel doesn't exist, it is used for cascade |
;plugging the first DMA controler to the second |
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A |
my_service db 'SOUND',0 ;max 16 chars include zero |
if DEBUG |
number_to_out db '0x00000000',13,10,0 |
msgInit db 'detecting hardware...',13,10,0 |
msgExit db 'exiting... May be some problems found?',13,10,0 |
msgPlay db 'start play',13,10,0 |
;msgStop db 'stop play',13,10,0 |
msgCallback db 'set_callback received from the mixer!',13,10 |
db 'callback handler is: ',0 |
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10 |
db 'owner',39,'s handler: ',0 |
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0') |
db ' as hardcoded',13,10,0 |
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10 |
db 'Driver may work unstable',13,10,0 |
msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0 |
msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0 |
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0 |
;------------------------------------------------------------------------------- |
msgDSPFound db 'DSP found at port 2' |
label port_second_digit_num dword at $ |
db '00h',13,10,'DSP version ' |
sb_DSP_version: db '0.00 - SB' |
sb_DSP_description: db 32,32,32,32,13,10,0 |
;------------------------------------------------------------------------------- |
end if |
section '.data' data readable writable align 16 |
;all uninitialized data place here |
;pTempBuf rd 1 |
callback rd 1 |
int_flip_flop rd 1 |
sb_master_vol rd 1 |
sb_DSP_version_int rd 1 |
/kernel/tags/kolibri0.7.7.0/drivers/sb16/CONFIG.INC |
---|
0,0 → 1,50 |
;flags------------------------------------------------------------ |
DEBUG equ 1 ;show messages at debug board |
use_cli_sti equ 1 ;driver become more stable (theoretically) |
;constants-------------------------------------------------------- |
API_VERSION equ 0 ;debug |
OS_BASE equ 0x80000000 |
new_app_base equ 0x0 |
PROC_BASE equ (OS_BASE+0x080000) |
SB16Buffer equ (OS_BASE+0x2A0000) |
SB16_Status equ (OS_BASE+0x2B0000) |
DMAPage equ ((SB16Buffer-OS_BASE) shr 16) |
SB16Buffer0 equ SB16Buffer |
SB16Buffer1 equ (SB16Buffer+16384) |
SB16Buffer2 equ (SB16Buffer+(2*16384)) |
SB16Buffer3 equ (SB16Buffer+(3*16384)) |
sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect |
sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect |
small_buffer equ 32768 |
full_buffer equ 65536 |
sb_buffer_size equ small_buffer ; FIX ring buffer overlapped events issue; full_buffer |
__supported_buffer_sizes fix <small_buffer, full_buffer> |
if ~(sb_buffer_size in __supported_buffer_sizes) |
display 13,10,'unsupported buffer size was selected, check config.inc',13,10 |
stop |
end if |
sb_out_rate equ 48000 |
;time constant for cards older than SB16 |
sb_tc equ (256-(1000000/(sb_out_rate*2))) |
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
/kernel/tags/kolibri0.7.7.0/drivers/sb16/README.TXT |
---|
0,0 → 1,72 |
Nable 21.05.2008. |
This driver is my contribution (or donation) to KolibriOS. This is provided |
AS IS in hope it'll be useful, but WITHOUT ANY WARRANTY! No responcibility |
for any hardware damage or data loss. Use at your own risk! |
;------------------------------------------------------------------------------- |
;Changelog: |
;------------------------------------------------------------------------------- |
v0.2 - DEV_SET(GET)_MASTERVOL functions are unlocked and implemented. |
v0.1 - first release. |
;------------------------------------------------------------------------------- |
;Tiny FAQ for sound driver by Nable for SB16 sound card. |
;------------------------------------------------------------------------------- |
;What is it?-------------------------------------------------------------------- |
As you may know there is a sound subsystem ('INFINITY') in KolibriOS. |
This subsystem includes mixer and separate interface for soundplayer |
program and driver, so player application don't need to know what soundcard |
is installed and how to cope with it, all work with card do the driver. |
Before this time there were drivers only for AC97 integrated sound, but I |
don't have such at home and if I would upgrade my computer with a newest |
hardware, with 100% probability integrated sound will be HD Codec, nowadays |
AC97 is not actual (2008 year is at calendar). But I'm not planning to upgrade |
my computer so much now (and in next 5-6 years), writing the driver for my PCI |
ESS Maestro1 card is difficult for me (may be some time later), so I decided |
to write a driver for SB16. At first it is easy, there are many working |
examples for DOS, there are heaps of good documentation and as an ISA device |
SB16 can be programmed through I/O ports (about 5 ports are used), that is |
more easy than PCI access. Now, enough lirics, lets go to physics :-) |
If you still don't understand what stuff is it, I'll tell this in brief: |
with this driver you can play MP3 and WAV music (using AC97SND player) and |
sounds (some games and DOSBOX can produce sound output through sound |
subsystem) in KolibriOS. |
;Yeah! I need sound in Kolibri and I have SB16 card. Whats then?---------------- |
At first copy my SOUND.OBJ to /sys/drivers at your Kolibri system. Note, |
that if you have AC97 card and it's driver started - then new driver won't |
run until reboot. Then run BOARD and go to 'user' tab. Then try to run |
AC97SND player. At BOARD you will see the following (if you had a proper |
card): |
|----------------------------| |
|detecting hardware... | <- detector startup message |
|DSP found at port 220h | <- if you have a proper card, it'll be |
|DSP version 4.13 - SB16 | autodetected. Numbers may be different. |
|failed to attach IRQ5 | <- don't mention. Old kernels reserve IRQ5 |
|owner's handler: 0x80D74284 | see below how to fix it. |
|----------------------------| |
At first, note that DSP version must be 4.xx or higher. Older cards are not |
supported in this first release, maybe some time later. If nothing detected |
but PNP/BIOS or some other OS detects your card - I'm sorry, it's perverted |
PNP card like OPTi16, that is like HD Codec - until you init it through |
PCI->ISA bridge (HD Codec of course through PCI->PCI bridge), map it, etc, |
you can't use it in any way. I'd rather write a PCI device driver, than |
for this extreme perversion. If your card detected and has a proper version |
but you see 'failed to attach IRQ' - delete stroke 'mov [irq_owner+4*5],1' from the |
file kernel.asm of your kernel source, save it, rebuild kernel, copy new |
kernel to /sys/ (did you rename 'kernel' to 'kernel.mnt'? You should do it), |
restart kernel (Ctrl+Alt+F12, Home). THE EASIER WAY IS TO USE A NEWER KERNEL, |
since SVN802 it's fixed. |
Now everything should be OK. |
;It works for a part of the second and then stops, but system doesn't hang------ |
Go to 'config.inc' of my driver and change 'sb_irq_num' value from 5 to 7. |
Then save, rebuild driver (compile 'sound.asm'), put 'sound' to /sys/drivers/ |
(you need to rename file 'sound' to 'sound.obj'), restart kernel and try again |
to produce sound. |
;------------------------------------------------------------------------------- |
Ask your questions at KolibriOS forum: board.kolibrios.org |
I'll try to answer you if possible. |
/kernel/tags/kolibri0.7.7.0/drivers/sb16/SB16.INC |
---|
0,0 → 1,297 |
;-------------------------------- |
; program dma |
;-------------------------------- |
sb_set_dma: |
mov ebx,[sound_dma] |
lea eax,[ebx+4] ;mask required channel |
cmp bl,4 |
ja .use_second_dma_controller |
jb @f |
.dma_setup_error: |
if DEBUG |
mov esi,msgErrDMAsetup |
call SysMsgBoardStr |
end if |
mov dword[esp],START.stop |
ret |
@@: |
if use_cli_sti |
cli ;here to minimize time with disabled ints |
end if |
out 0xA,al ;mask required channel |
xor eax,eax |
out 0xC,al ;clear byte pointer flip-flop register |
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx) |
out 0xB,al ;DMA channel 0-3 mode register |
movzx edx,byte[ebx+dma_table] ;page register |
mov al,DMAPage |
out dx,al |
lea edx,[ebx*2] ;DMA channel 0-3 base address |
mov al,0 ;LSB is 0 |
out dx,al |
; mov al,0 ;MSB is 0 too |
out dx,al |
inc edx ;DMA channel 0-3 byte count |
mov al,((sb_buffer_size-1) and 0xff) |
out dx,al |
mov al,((sb_buffer_size-1) shr 8) ;it is the same |
out dx,al |
mov eax,ebx ;unmask DMA channel |
out 0xA,al |
if use_cli_sti |
sti |
end if |
ret |
.use_second_dma_controller: |
cmp bl,7 |
ja .dma_setup_error |
sub bl,4 |
sub al,4 |
if use_cli_sti |
cli ;here to minimize time with disabled ints |
end if |
out 0xD4,al ;mask required channel |
xor eax,eax |
out 0xD8,al ;clear byte pointer flip-flop register |
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx+4) |
out 0xD6,al ;DMA channel 4-7 mode register |
movzx edx,byte[ebx+dma_table+4] ;page register |
mov al,DMAPage |
out dx,al |
lea edx,[ebx*4+0xC0] ;DMA channel 4-7 base address |
mov al,0 ;LSB is 0 ;for 16bit DMA this contains |
out dx,al ;A1-A8 lines of address bus, A0 is zero |
; mov al,0 ;MSB is 0 too ;for 16bit DMA this contains |
out dx,al ;A9-A16 lines of address bus |
inc edx |
inc edx ;DMA channel 4-7 16bit word count |
mov al,(((sb_buffer_size/2)-1) and 0xff) |
out dx,al |
mov al,(((sb_buffer_size/2)-1) shr 8) |
out dx,al |
mov eax,ebx ;unmask DMA channel |
out 0xD4,al |
if use_cli_sti |
sti |
end if |
ret |
;------------------------------------------------------------------------------- |
; out byte to SB DSP's write port |
;------------------------------------------------------------------------------- |
macro sb_out data_to_out { |
@@: |
in al,dx |
test al,al ;is DSP busy? |
js @b ;it's busy |
mov al,data_to_out ;it's free |
out dx,al |
} |
;------------------------------------------------------------------------------- |
; stop playing |
;------------------------------------------------------------------------------- |
proc sb_stop |
mov edx,[sb_base_port] |
add dl,0xC |
sb_out 0xD3 ;turn the speaker off |
sb_out 0xDA ;exit 8bit DMA |
sb_out 0xD9 ;exit 16bit DMA |
ret |
endp |
;------------------------------------------------------------------------------- |
; start playing |
;------------------------------------------------------------------------------- |
proc sb_play |
and [int_flip_flop],0 |
mov edx,[sb_base_port] |
add dl,0xC |
sb_out 0xD1 ;turn speaker on |
; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported |
; ;in this version |
; mov ax,32767 ;(64k)/2-1 |
;@@: ;out the low byte... |
; in al,dx |
; test al,al ;is DSP busy? |
; js @b ;it's busy |
; out dx,al |
; mov al,ah ;...then the high byte |
;@@: |
; in al,dx |
; test al,al ;is DSP busy? |
; js @b ;it's busy |
; out dx,al |
; sb_out 0x1C ;auto-init 8bit playback |
; 0xBXh - 16 bit DMA mode |
; |||| |
sb_out 10110110b ;bCommand |
; |||| |
; |||+-reserved |
; ||+--turn FIFO on (0 for off) |
; |+---auto-init mode on (0 for off) |
; +----A/D: 0-output, 1-input |
; +------stereo on |
; |+-----unsigned (1 for signed) |
; || |
sb_out 00110000b ;bMode |
; || |||| |
; ---------reserved |
;wSize is a number of 16bit samples less 1. For auto-init mode each half |
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples |
sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte |
sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte |
ret |
endp |
;------------------------------------------------------------------------------- |
; reset DSP |
;------------------------------------------------------------------------------- |
proc sb_reset |
and [int_flip_flop],0 |
mov edx,[sb_base_port] |
add dl,6 |
mov al,1 ;start DSP reset |
if use_cli_sti |
cli ;here to minimize time with disabled ints |
end if |
out dx,al |
mov ecx,40 ;wait at least 3 microsec. |
@@: |
in al,dx |
loop @b |
xor eax,eax ;stop DSP reset |
if use_cli_sti |
sti |
end if |
out dx,al |
ret |
endp |
;------------------------------------------------------------------------------- |
; set the rate for playing, enable stereo |
;------------------------------------------------------------------------------- |
proc sb_setup |
mov edx,[sb_base_port] |
add dl,0xC |
sb_out 40h ;set time constant, this is for old cards |
sb_out sb_tc |
sb_out 41h ;set sound rate, this can only SB16 |
sb_out (sb_out_rate shr 8) ;first high byte (MSB) |
sb_out (sb_out_rate and 0xff) ;then low byte (LSB) |
; mov al,0xE ;for older cards, not supported in this version |
; sub dl,(0xC-4) ;talk to SB's mixer |
; out dx,al ;select this register of the mixer |
; mov ecx,6 ;wait for the chip |
;@@: |
; in al,dx |
; loop @b |
; inc edx ;now read the data port |
; in al,dx |
; or al,22h ;turn on stereo |
; mov ah,al |
; mov al,0xE |
; dec edx ;talk to SB's mixer |
; out dx,al ;select this register of the mixer |
; mov ecx,6 ;wait for the chip |
;@@: |
; in al,dx |
; loop @b |
; inc edx ;now send data to the data port |
; mov al,ah |
; out dx,al |
; dec edx |
; mov ecx,35 ;wait for the chip |
;@@: |
; in al,dx |
; loop @b |
ret |
endp |
;------------------------------------------------------------------------------- |
; set master volume of SB mixer, note, not only SB16 but SBPro and older |
; this is the first step to more full support for hardware |
;------------------------------------------------------------------------------- |
;in: eax in range [-10000;0] - master volume for _both_ channels |
;note that x*3*17/2000 and x*3/2000*17 are not the same numbers, |
;because we count in integers |
proc sb_set_master_vol |
mov [sb_master_vol],eax |
add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL |
lea eax,[eax+eax*2] ;*3 |
mov ebx,2000 ;divisor |
xor edx,edx |
cmp byte[sb_DSP_version_int],4 |
jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because |
;volume byte looks like that: 0xLR, where L - left |
;channel volume, R - right, 0<=R,L<=15 |
div ebx |
imul eax,17 |
mov edx,[sb_base_port] |
push eax ;here for optimisation |
add dl,4 |
mov al,0x22 ;write mixer register 0x22 |
out dx,al |
in al,dx ;wait for the chip ;6 |
in al,dx ;wait for the chip ;5 |
in al,dx ;wait for the chip ;4 |
in al,dx ;wait for the chip ;3 |
in al,dx ;wait for the chip ;2 |
in al,dx ;wait for the chip ;1 |
pop eax ;go! |
inc edx |
out dx,al |
ret |
@@: ;SB16's MAX_LEVEL is 255 |
imul eax,17 |
div ebx |
mov edx,[sb_base_port] |
push eax ;here for optimisation |
add dl,4 |
mov al,0x30 ;left speaker |
out dx,al |
pop eax ;<--+ |
inc edx ; \/ |
push eax ;here for optimisation |
out dx,al ;write |
dec edx |
mov al,0x31 ;right speaker |
out dx,al |
pop eax |
inc edx |
out dx,al ;write |
ret |
endp |
;------------------------------------------------------------------------------- |
/kernel/tags/kolibri0.7.7.0/drivers/infinity.asm |
---|
0,0 → 1,1306 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Serge 2006-2008 |
; email: infinity_sound@mail.ru |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'main.inc' |
include 'imports.inc' |
CURRENT_API equ 0x0101 ;1.01 |
COMPATIBLE_API equ 0x0100 ;1.00 |
API_VERSION equ (COMPATIBLE_API shl 16) or CURRENT_API |
SOUND_VERSION equ CURRENT_API |
FORCE_MMX equ 0 ;set to 1 to force use mmx or |
FORCE_MMX_128 equ 0 ;integer sse2 extensions |
;and reduce driver size |
;USE_SSE equ 0 |
USE_SSE2_MIXER equ 0 ;floating point mixer. Disabled by default |
OS_BASE equ 0x80000000 |
CAPS_SSE2 equ 26 |
PG_SW equ 0x003 |
public START |
public service_proc |
public version |
RT_INP_EMPTY equ 0xFF000001 |
RT_OUT_EMPTY equ 0xFF000002 |
RT_INP_FULL equ 0xFF000003 |
RT_OUT_FULL equ 0xFF000004 |
EVENT_WATCHED equ 0x10000000 |
EVENT_SIGNALED equ 0x20000000 |
MANUAL_RESET equ 0x40000000 |
MANUAL_DESTROY equ 0x80000000 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
stdcall GetService, szSound |
test eax, eax |
jz .fail |
mov [hSound], eax |
stdcall KernelAlloc, 16*512 |
test eax, eax |
jz .out_of_mem |
mov [mix_buff], eax |
mov eax, str.fd-FD_OFFSET |
mov [str.fd], eax |
mov [str.bk], eax |
if FORCE_MMX |
if FORCE_MMX_128 |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
end if |
if FORCE_MMX_128 |
if FORCE_MMX |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
end if |
if 0 |
if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect |
mov eax, 1 |
cpuid |
bt edx, CAPS_SSE2 |
jc .mmx128 |
;old 64-bit mmx |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
jmp @F |
.mmx128: ;128-bit integer sse2 extensions |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
@@: |
end if |
end if |
stdcall set_handler, [hSound], new_mix |
mov [eng_state], SND_STOP |
stdcall RegService, szInfinity, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
.exit: |
xor eax, eax |
ret |
.out_of_mem: |
if DEBUG |
mov esi, msgMem |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov eax, [eax] |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, SND_CREATE_BUFF |
jne @F |
mov ebx, [edi+input] |
stdcall CreateBuffer,[ebx],[ebx+4] |
mov edi, [ioctl] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
@@: |
mov ebx, [edi+input] |
mov edx, [ebx] |
cmp [edx+STREAM.magic], 'WAVE' |
jne .fail |
cmp [edx+STREAM.size], STREAM_SIZE |
jne .fail |
cmp eax, SND_DESTROY_BUFF |
jne @F |
mov eax, edx |
call DestroyBuffer ;edx= stream |
ret |
@@: |
cmp eax, SND_SETFORMAT |
jne @F |
stdcall SetFormat,edx,[ebx+4] |
ret |
@@: |
cmp eax, SND_GETFORMAT |
jne @F |
movzx eax, word [edx+STREAM.format] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
@@: |
cmp eax, SND_RESET |
jne @F |
stdcall ResetBuffer,edx,[ebx+4] |
ret |
@@: |
cmp eax, SND_SETPOS |
jne @F |
stdcall SetBufferPos,edx,[ebx+4] |
ret |
@@: |
cmp eax, SND_GETPOS |
jne @F |
stdcall GetBufferPos, edx |
mov edi, [ioctl] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
@@: |
cmp eax, SND_SETBUFF |
jne @F |
mov eax, [ebx+4] |
stdcall set_buffer, edx,eax,[ebx+8],[ebx+12] |
ret |
@@: |
cmp eax, SND_SETVOLUME |
jne @F |
stdcall SetBufferVol,edx,[ebx+4],[ebx+8] |
ret |
@@: |
cmp eax, SND_GETVOLUME |
jne @F |
mov eax, [edi+output] |
mov ecx, [eax] |
mov eax, [eax+4] |
stdcall GetBufferVol,edx,ecx,eax |
ret |
@@: |
cmp eax, SND_SETPAN |
jne @F |
stdcall SetBufferPan,edx,[ebx+4] |
ret |
@@: |
cmp eax, SND_GETPAN |
jne @F |
mov eax, [edx+STREAM.pan] |
mov ebx, [edi+output] |
mov ebx, [ebx] |
mov [ebx], eax |
xor eax, eax |
ret |
@@: |
cmp eax, SND_OUT |
jne @F |
mov eax, [ebx+4] |
stdcall wave_out, edx,eax,[ebx+8] |
ret |
@@: |
cmp eax, SND_PLAY |
jne @F |
stdcall play_buffer, edx,[ebx+4] |
ret |
@@: |
cmp eax, SND_STOP |
jne @F |
stdcall stop_buffer, edx |
ret |
@@: |
cmp eax, SND_GETBUFFSIZE |
jne @F |
mov eax, [edx+STREAM.in_size] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
@@: |
cmp eax, SND_GETFREESPACE |
jne @F |
test [edx+STREAM.format], PCM_OUT |
jz .fail |
mov ebx, [edx+STREAM.in_free] |
mov ecx, [edi+output] |
mov [ecx], ebx |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc CreateBuffer stdcall, format:dword, size:dword |
locals |
str dd ? |
ring_size dd ? |
ring_pages dd ? |
endl |
mov eax, [format] |
cmp ax, PCM_1_8_8 |
ja .fail |
test eax, PCM_OUT |
jnz .test_out |
test eax, PCM_RING |
jnz .test_ring |
;staic |
test eax, PCM_STATIC |
jz .test_out ;use PCM_OUT as default format |
jmp .test_ok |
.test_out: |
test eax, PCM_RING+PCM_STATIC |
jnz .fail |
or [format], PCM_OUT ;force set |
jmp .test_ok |
.test_ring: |
test eax, PCM_OUT+PCM_STATIC |
jnz .fail |
.test_ok: |
call GetPid |
mov ebx, eax |
mov eax, STREAM_SIZE |
call CreateObject |
test eax, eax |
jz .fail |
mov [str], eax |
mov ebx, [format] |
mov [eax+STREAM.format], ebx |
xor ecx, ecx |
movzx ebx, bx |
cmp ebx, 19 |
jb @f |
mov ecx, 0x80808080 |
@@: |
mov [eax+STREAM.r_silence], ecx |
shl ebx, 2 |
lea ebx, [ebx+ebx*2] ;ebx*=12 |
mov ecx, [resampler_params+ebx] |
mov edx, [resampler_params+ebx+4] |
mov esi, [resampler_params+ebx+8] |
mov [eax+STREAM.r_size],ecx |
mov [eax+STREAM.r_dt], edx |
mov [eax+STREAM.resample], esi |
xor ecx, ecx |
mov [eax+STREAM.l_vol], ecx |
mov [eax+STREAM.r_vol], ecx |
mov dword [eax+STREAM.l_amp], 0x7FFF7FFF |
mov [eax+STREAM.pan], ecx |
test [format], PCM_STATIC |
jnz .static |
; ring and waveout |
mov ebx, 0x10000 |
test [format], PCM_RING |
jz .waveout |
mov ebx, [eax+STREAM.r_size] |
add ebx, 4095 |
and ebx, -4096 |
add ebx, ebx |
.waveout: |
mov [ring_size], ebx |
mov eax, ebx |
shr ebx, 12 |
mov [ring_pages], ebx |
stdcall CreateRingBuffer, eax, PG_SW |
mov edi, [str] |
mov ecx, [ring_size] |
mov [edi+STREAM.in_base], eax |
mov [edi+STREAM.in_size], ecx |
add eax, 128 |
; sub ecx, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov [edi+STREAM.in_count], 0 |
mov [edi+STREAM.in_free], ecx |
add eax, ecx |
mov [edi+STREAM.in_top], eax |
jmp .out_buff |
.static: |
mov ecx, [size] |
add ecx, 128 ;resampler required |
mov [eax+STREAM.in_size], ecx |
stdcall KernelAlloc, ecx |
mov edi, [str] |
mov [edi+STREAM.in_base], eax |
add eax, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov ebx, [size] |
mov [edi+STREAM.in_count], ebx |
mov [edi+STREAM.in_free], ebx |
add eax, ebx |
mov [edi+STREAM.in_top], eax |
.out_buff: |
stdcall AllocKernelSpace, dword 128*1024 |
mov edi, [str] |
mov [edi+STREAM.out_base], eax |
mov [edi+STREAM.out_wp], eax |
mov [edi+STREAM.out_rp], eax |
mov [edi+STREAM.out_count], 0 |
add eax, 64*1024 |
mov [edi+STREAM.out_top], eax |
stdcall AllocPages, dword 64/4 |
mov edi, [str] |
mov ebx, [edi+STREAM.out_base] |
mov ecx, 16 |
or eax, PG_SW |
push eax |
push ebx |
call CommitPages ;eax, ebx, ecx |
mov ecx, 16 |
pop ebx |
pop eax |
add ebx, 64*1024 |
call CommitPages ;double mapped |
mov edi, [str] |
mov ecx, [edi+STREAM.in_top] |
mov edi, [edi+STREAM.in_base] |
sub ecx, edi |
xor eax, eax |
shr ecx, 2 |
cld |
rep stosd |
mov edi, [str] |
mov edi, [edi+STREAM.out_base] |
mov ecx, (64*1024)/4 |
rep stosd |
xor esi, esi |
mov ecx, MANUAL_DESTROY |
call CreateEvent |
mov ebx, [str] |
mov [ebx+STREAM.notify_event], eax |
mov [ebx+STREAM.notify_id], edx |
mov [ebx+STREAM.magic], 'WAVE' |
mov [ebx+STREAM.destroy], DestroyBuffer.destroy |
mov [ebx+STREAM.size], STREAM_SIZE |
mov [ebx+STREAM.flags], SND_STOP |
pushf |
cli |
mov eax, str.fd-FD_OFFSET |
mov edx, [eax+STREAM.str_fd] |
mov [ebx+STREAM.str_fd], edx |
mov [ebx+STREAM.str_bk], eax |
mov [eax+STREAM.str_fd], ebx |
mov [edx+STREAM.str_bk], ebx |
popf |
xor eax, eax |
ret |
.fail: |
xor ebx, ebx |
or eax, -1 |
ret |
endp |
;param |
; eax= buffer handle |
align 4 |
DestroyBuffer: |
.handle equ esp ;local |
mov [eax+STREAM.flags], SND_STOP |
.destroy: |
push eax |
pushfd |
cli |
mov ebx, [eax+STREAM.str_fd] |
mov ecx, [eax+STREAM.str_bk] |
mov [ebx+STREAM.str_bk], ecx |
mov [ecx+STREAM.str_fd], ebx |
popf |
stdcall KernelFree, [eax+STREAM.in_base] |
mov eax, [.handle] |
stdcall KernelFree, [eax+STREAM.out_base] |
pop eax ;restore stack |
call DestroyObject ;eax= stream |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
restore .handle |
align 4 |
proc SetFormat stdcall, str:dword, format:dword |
cmp word [format], PCM_1_8_8 |
ja .fail |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
test [edx+STREAM.format], PCM_RING |
jnz .fail |
; mov eax,[edx+STREAM.out_base] |
; mov [edx+STREAM.out_wp], eax |
; mov [edx+STREAM.out_rp], eax |
; mov [edx+STREAM.out_count], 0 |
movzx eax, word [format] |
mov word [edx+STREAM.format], ax |
xor ebx, ebx |
cmp eax, 19 |
jb @f |
mov ebx, 0x80808080 |
@@: |
mov [edx+STREAM.r_silence], ebx |
shl eax, 2 |
lea eax, [eax+eax*2] ;eax*=12 |
mov edi, [resampler_params+eax] |
mov ecx, [resampler_params+eax+4] |
mov ebx, [resampler_params+eax+8] |
mov [edx+STREAM.r_size],edi |
mov [edx+STREAM.r_dt], ecx |
mov [edx+STREAM.resample], ebx |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
; use waveout for streams |
align 4 |
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_OUT |
jnz .fail |
mov esi, [src] |
mov edi, [offs] |
add edi, [edx+STREAM.in_base] |
add edi, 128 |
cmp edi, [edx+STREAM.in_top] |
jae .fail |
mov ecx, [size] |
lea ebx, [ecx+edi] |
sub ebx, [edx+STREAM.in_top] |
jb @F |
sub ecx, ebx |
@@: |
shr ecx, 2 |
cld |
rep movsd |
xor eax,eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for stream buffers only |
align 4 |
proc wave_out stdcall, str:dword,src:dword,size:dword |
locals |
state_saved dd ? |
fpu_state rb 528 |
endl |
mov edx, [str] |
mov eax, [edx+STREAM.format] |
test eax, PCM_OUT |
jz .fail |
cmp ax, PCM_ALL |
je .fail |
mov esi,[src] |
test esi, esi |
jz .fail |
cmp esi, OS_BASE |
jae .fail |
mov [state_saved], 0 |
.main_loop: |
mov edx, [str] |
mov ebx, [size] |
test ebx, ebx |
jz .done |
cmp [edx+STREAM.flags], SND_STOP |
jne .fill |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov ecx, [edx+STREAM.in_size] |
sub ecx, 128 |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
mov [edx+STREAM.in_count], 0 |
mov [edx+STREAM.in_free], ecx |
mov eax,[edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], eax |
mov [edx+STREAM.out_rp], eax |
mov [edx+STREAM.out_count], 0 |
.fill: |
cli |
mov ecx, [edx+STREAM.in_free] |
test ecx, ecx |
jz .wait |
cmp ecx, ebx |
jbe @F |
mov ecx, ebx |
@@: |
sub [size], ecx |
add [edx+STREAM.in_count], ecx |
sub [edx+STREAM.in_free], ecx |
shr ecx, 2 |
mov edi, [edx+STREAM.in_wp] |
mov esi, [src] |
cld |
rep movsd |
mov [src], esi |
cmp edi, [edx+STREAM.in_top] |
jb @F |
sub edi, [edx+STREAM.in_size] |
@@: |
mov [edx+STREAM.in_wp], edi |
cmp [edx+STREAM.out_count], 32768 |
jae .skip |
cmp [state_saved], 0 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
call FpuSave |
mov [state_saved], 1 |
@@: |
stdcall refill, edx |
.skip: |
sti |
mov edx, [str] |
mov [edx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .main_loop |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
jmp .main_loop |
.wait: |
sti |
mov edx, [str] |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call WaitEvent ;eax ebx |
jmp .main_loop |
.done: |
cmp [state_saved], 1 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
call FpuRestore |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; both static and stream |
; reset all but not clear buffers |
; flags reserved |
; RESET_INPUT equ 1 ;reserved reset and clear input buffer |
; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer |
; RESET_ALL equ 3 |
align 4 |
proc ResetBuffer stdcall, str:dword, flags:dword |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
test [edx+STREAM.flags], PCM_STATIC |
jnz .static |
mov [edx+STREAM.in_count], 0 |
jmp @F |
.static: |
mov eax, [edx+STREAM.in_size] |
mov [edx+STREAM.in_count], eax |
@@: |
mov eax, [edx+STREAM.in_size] |
sub eax, 128 |
mov [edx+STREAM.in_free], eax |
xor eax, eax |
mov ebx,[edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], ebx |
mov [edx+STREAM.out_rp], ebx |
mov [edx+STREAM.out_count], eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
align 4 |
proc SetBufferPos stdcall, str:dword, pos:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC |
jz .fail |
mov [edx+STREAM.flags], SND_STOP |
mov eax, [pos] |
add eax, [edx+STREAM.in_base] |
mov ebx, [edx+STREAM.in_top] |
add eax, 128 |
cmp eax, ebx |
jae .fail |
mov [edx+STREAM.in_rp], eax |
sub ebx, eax |
mov [edx+STREAM.in_count], ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
align 4 |
proc GetBufferPos stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC |
jz .fail |
mov ebx, [edx+STREAM.in_rp] |
sub ebx, [edx+STREAM.in_base] |
sub ebx, 128 |
xor eax, eax |
ret |
.fail: |
xor ebx,ebx |
or eax, -1 |
ret |
endp |
; both |
align 4 |
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword |
mov edx, [str] |
stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan] |
ret |
endp |
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword |
locals |
_600 dd ? |
_32767 dd ? |
state rb 108 |
endl |
mov [_600], 0x44160000 ;600.0 |
mov [_32767], 32767 |
lea ebx, [state] |
fnsave [ebx] |
movq mm0, qword [l_vol] |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movq qword [l_vol], mm0 |
movq qword [edx+STREAM.l_vol], mm0 |
movd mm1,[pan] |
pminsw mm1, qword [pan_max] |
pmaxsw mm1, qword [vol_min] |
movd [edx+STREAM.pan], mm1 |
cmp word [edx+STREAM.pan], 0 |
jl @F |
psubsw mm0,mm1 |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movd [l_vol],mm0 |
jmp .calc_amp |
@@: |
punpckhdq mm0,mm0 |
paddsw mm0,mm1 |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movd [r_vol], mm0 |
.calc_amp: |
emms |
fild word [l_vol] |
call .calc |
fistp word [edx+STREAM.l_amp] |
fstp dword [edx+STREAM.l_amp_f] |
fstp st0 |
fild word [r_vol] |
call .calc |
fistp word [edx+STREAM.r_amp] |
fstp dword [edx+STREAM.r_amp_f] |
fstp st0 |
fnclex |
lea ebx, [state] |
frstor [ebx] |
xor eax, eax |
inc eax |
ret |
.calc: |
fdiv dword [_600] |
fld st0 |
frndint |
fxch st1 |
fsub st, st1 |
f2xm1 |
fld1 |
faddp st1, st0 |
fscale |
fld st0 |
fimul dword [_32767] |
ret 0 |
endp |
align 4 |
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword |
mov edx, [str] |
mov eax, [p_lvol] |
movsx ecx, word [edx+STREAM.l_vol] |
mov [eax], ecx |
mov eax, [p_rvol] |
movsx ecx, word [edx+STREAM.r_vol] |
mov [eax], ecx |
xor eax, eax |
ret |
endp |
align 4 |
proc SetBufferPan stdcall, str:dword,pan:dword |
mov edx, [str] |
stdcall set_vol_param,[edx+STREAM.l_vol],\ |
[edx+STREAM.r_vol],[pan] |
ret |
endp |
; for static and ring buffers only |
align 4 |
proc play_buffer stdcall, str:dword, flags:dword |
mov ebx, [str] |
mov eax, [ebx+STREAM.format] |
test eax, PCM_OUT |
jnz .fail |
cmp ax, PCM_ALL |
je .fail |
mov [ebx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .done |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
.done: |
test [flags], PLAY_SYNC |
jz @F |
mov edx, [str] |
.wait: |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call WaitEvent ;eax ebx |
mov edx, [str] |
cmp [edx+STREAM.flags], SND_STOP |
jne .wait |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static and ring buffers only |
align 4 |
proc stop_buffer stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC+PCM_RING |
jz .fail |
mov [edx+STREAM.flags], SND_STOP |
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call ClearEvent ;eax ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; param |
; eax= mix_list |
align 4 |
do_mix_list: |
xor edx, edx |
mov esi, str.fd-FD_OFFSET |
mov ebx, [esi+STREAM.str_fd] |
@@: |
cmp ebx, esi |
je .done |
cmp [ebx+STREAM.magic], 'WAVE' |
jne .next |
cmp [ebx+STREAM.size], STREAM_SIZE |
jne .next |
cmp [ebx+STREAM.flags], SND_PLAY; |
jne .next |
mov ecx, [ebx+STREAM.out_count] |
test ecx, ecx |
jnz .l1 |
test [ebx+STREAM.format], PCM_RING |
jnz .next |
mov [ebx+STREAM.flags], SND_STOP |
jmp .next |
.l1: |
cmp ecx, 512 |
jae .add_buff |
mov edi, [ebx+STREAM.out_rp] |
add edi, ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
cld |
rep stosb |
pop eax |
mov [ebx+STREAM.out_count], 512 |
.add_buff: |
mov ecx, [ebx+STREAM.out_rp] |
mov [eax],ecx |
if USE_SSE2_MIXER |
mov edi, dword [ebx+STREAM.l_amp_f] |
mov [eax+4], edi |
mov edi, dword [ebx+STREAM.r_amp_f] |
mov [eax+8], edi |
else |
mov edi, dword [ebx+STREAM.l_amp] |
mov [eax+4], edi |
end if |
add [ebx+STREAM.out_rp], 512 |
sub [ebx+STREAM.out_count], 512 |
add eax, 12 |
inc edx |
.next: |
mov ebx, [ebx+STREAM.str_fd] |
jmp @B |
.done: |
mov eax, edx |
ret |
align 4 |
prepare_playlist: |
xor edx, edx |
mov [play_count], edx |
mov esi, str.fd-FD_OFFSET |
mov edi, [esi+STREAM.str_fd] |
@@: |
cmp edi, esi |
je .done |
cmp [edi+STREAM.magic], 'WAVE' |
jne .next |
cmp [edi+STREAM.size], STREAM_SIZE |
jne .next |
cmp [edi+STREAM.flags], SND_PLAY; |
jne .next |
mov [play_list+edx], edi |
inc [play_count] |
add edx, 4 |
.next: |
mov edi, [edi+STREAM.str_fd] |
jmp @B |
.done: |
ret |
align 4 |
proc set_handler stdcall, hsrv:dword, handler_proc:dword |
locals |
handler dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
lea ecx, [handler_proc] |
xor ebx, ebx |
mov [handler], eax |
mov [io_code], DEV_CALLBACK |
mov [input], ecx |
mov [inp_size], 4 |
mov [output], ebx |
mov [out_size], 0 |
lea eax, [handler] |
stdcall ServiceHandler, eax |
ret |
endp |
align 4 |
proc dev_play stdcall, hsrv:dword |
locals |
handle dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
xor ebx, ebx |
mov [handle], eax |
mov [io_code], DEV_PLAY |
mov [input], ebx |
mov [inp_size], ebx |
mov [output], ebx |
mov [out_size], ebx |
lea eax, [handle] |
stdcall ServiceHandler, eax |
ret |
endp |
if 0 |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
end if |
include 'mixer.asm' |
include 'mix_mmx.inc' |
include 'mix_sse2.inc' |
;if USE_SSE |
; include 'mix_sse.inc' |
;end if |
align 16 |
resampler_params: |
;r_size r_dt resampler_func |
dd 0,0,0 ; 0 PCM_ALL |
dd 16384, 0, copy_stream ; 1 PCM_2_16_48 |
dd 8192, 0, m16_stereo ; 2 PCM_1_16_48 |
dd 16384, 30109, resample_2 ; 3 PCM_2_16_44 |
dd 8192, 30109, resample_1 ; 4 PCM_1_16_44 |
dd 16384, 21846, resample_2 ; 5 PCM_2_16_32 |
dd 8192, 21846, resample_1 ; 6 PCM_1_16_32 |
dd 16384, 16384, resample_2 ; 7 PCM_2_16_24 |
dd 8192, 16384, resample_1 ; 8 PCM_1_16_24 |
dd 8192, 15052, resample_2 ; 9 PCM_2_16_22 |
dd 4096, 15052, resample_1 ;10 PCM_1_16_22 |
dd 8192, 10923, resample_2 ;11 PCM_2_16_16 |
dd 4096, 10923, resample_1 ;12 PCM_1_16_16 |
dd 8192, 8192, resample_2 ;13 PCM_2_16_12 |
dd 4096, 8192, resample_1 ;14 PCM_1_16_12 |
dd 4096, 7527, resample_2 ;15 PCM_2_16_11 |
dd 2048, 7527, resample_1 ;16 PCM_1_16_11 |
dd 4096, 5462, resample_2 ;17 PCM_2_16_8 |
dd 2048, 5462, resample_1 ;18 PCM_1_16_8 |
dd 16384, 0, s8_stereo ;19 PCM_2_8_48 |
dd 8192, 0, m8_stereo ;20 PCM_1_8_48 |
dd 8192, 30109, resample_28 ;21 PCM_2_8_44 |
dd 4096, 30109, resample_18 ;22 PCM_1_8_44 |
dd 8192, 21846, resample_28 ;23 PCM_2_8_32 |
dd 4096, 21846, resample_18 ;24 PCM_1_8_32 |
dd 8192, 16384, resample_28 ;25 PCM_2_8_24 |
dd 4096, 16384, resample_18 ;26 PCM_1_8_24 |
dd 4096, 15052, resample_28 ;27 PCM_2_8_22 |
dd 2048, 15052, resample_18 ;28 PCM_1_8_22 |
dd 4096, 10923, resample_28 ;29 PCM_2_8_16 |
dd 2048, 10923, resample_18 ;30 PCM_1_8_16 |
dd 4096, 8192, resample_28 ;31 PCM_2_8_12 |
dd 2048, 8192, resample_18 ;32 PCM_1_8_12 |
dd 2048, 7527, resample_28 ;33 PCM_2_8_11 |
dd 1024, 7527, resample_18 ;34 PCM_1_8_11 |
dd 2048, 5462, resample_28 ;35 PCM_2_8_8 |
dd 1024, 5462, resample_18 ;36 PCM_1_8_8 |
m7 dw 0x8000,0x8000,0x8000,0x8000 |
mm80 dq 0x8080808080808080 |
mm_mask dq 0xFF00FF00FF00FF00 |
vol_max dd 0x00000000,0x00000000 |
vol_min dd 0x0000D8F0,0x0000D8F0 |
pan_max dd 0x00002710,0x00002710 |
;stream_map dd 0xFFFF ; 16 |
version dd (5 shl 16) or SOUND_VERSION |
szInfinity db 'INFINITY',0 |
szSound db 'SOUND',0 |
if DEBUG |
msgFail db 'Sound service not loaded',13,10,0 |
msgPlay db 'Play buffer',13,10,0 |
msgStop db 'Stop',13,10,0 |
msgUser db 'User callback',13,10,0 |
msgMem db 'Not enough memory',13,10,0 |
msgDestroy db 'Destroy sound buffer', 13,10,0 |
msgWaveout db 'Play waveout', 13,10,0 |
msgSetVolume db 'Set volume',13,10,0 |
end if |
section '.data' data readable writable align 16 |
play_list rd 16 |
mix_input rd 16 |
play_count rd 1 |
hSound rd 1 |
eng_state rd 1 |
mix_buff rd 1 |
mix_buff_map rd 1 |
str.fd rd 1 |
str.bk rd 1 |
mix_2_core rd 1 |
mix_3_core rd 1 |
mix_4_core rd 1 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/mixer.asm |
---|
0,0 → 1,1262 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; (C) copyright Serge 2006 |
; email: infinity_sound@mail.ru |
align 4 |
mix_list rd 32*3 |
align 4 |
proc new_mix stdcall, output:dword |
locals |
main_count rd 1 |
fpu_state rb 528 ;512+16 |
endl |
mov [main_count], 32 |
call prepare_playlist |
cmp [play_count], 0 |
je .clear |
lea eax, [fpu_state+16] |
and eax, -16 ;must be 16b aligned |
call FpuSave |
call update_stream |
.mix: |
lea eax, [mix_list] |
call do_mix_list |
test eax, eax |
je .done |
if USE_SSE2_MIXER |
cmp eax, 1 |
ja @F |
;use fast path |
mov edi, [output] |
lea edx, [mix_list] |
call mix_fast |
jmp .next |
@@: |
cmp eax, 2 |
ja @F |
mov edi, [output] |
lea edx, [mix_list] |
call mix_fast_2_stream |
jmp .next |
@@: |
end if |
lea ebx, [mix_list] |
stdcall mix_all, [output], ebx, eax |
.next: |
add [output], 512 |
dec [main_count] |
jnz .mix |
.exit: |
lea eax, [fpu_state+16] |
and eax, -16 |
call FpuRestore |
ret |
.done: |
mov ecx, [main_count] |
shl ecx, 7 ;ecx*= 512/4 |
mov edi, [output] |
xor eax, eax |
cld |
rep stosd |
jmp .exit |
.clear: |
mov edi, [output] |
mov ecx, 4096 |
xor eax, eax |
cld |
rep stosd |
ret |
endp |
align 4 |
proc update_stream |
locals |
stream_index dd ? |
event rd 6 |
endl |
mov [stream_index], 0 |
.l1: |
mov edx, [stream_index] |
mov esi, [play_list+edx*4] |
mov eax, [esi+STREAM.out_rp] |
cmp eax, [esi+STREAM.out_top] |
jb @f |
sub eax, 64*1024 |
@@: |
mov [esi+STREAM.out_rp], eax |
cmp [esi+STREAM.out_count], 16384 |
ja .skip |
test [esi+STREAM.format], PCM_RING |
jnz .ring |
stdcall refill, esi |
.skip: |
inc [stream_index] |
dec [play_count] |
jnz .l1 |
ret |
.ring: |
stdcall refill_ring, esi |
jmp .skip |
endp |
align 4 |
proc refill stdcall, str:dword |
locals |
r_size rd 1 |
endl |
mov ebx, [str] |
mov edi, [ebx+STREAM.out_wp] |
cmp edi, [ebx+STREAM.out_top] |
jb @F |
sub edi, 0x10000 |
mov [ebx+STREAM.out_wp], edi |
@@: |
mov eax, [ebx+STREAM.in_count] |
test eax, eax |
jz .done |
mov ecx, [ebx+STREAM.r_size] |
cmp eax, ecx |
jle @F |
mov eax, ecx |
@@: |
mov ecx, eax |
cmp word [ebx+STREAM.format], PCM_1_16_8 |
ja @F |
shr eax, 1 ;two channles |
@@: |
test [ebx+STREAM.format], 1 ;even formats mono |
jz @F |
shr eax, 1 ;eax= samples |
@@: |
shl eax, 15 ;eax*=32768 =r_end |
mov [r_size], ecx |
mov esi, [ebx+STREAM.in_rp] |
mov edi, [ebx+STREAM.out_wp] |
stdcall [ebx+STREAM.resample], edi, esi, \ |
[ebx+STREAM.r_dt], ecx, eax |
mov ebx, [str] |
add [ebx+STREAM.out_count], eax; |
add [ebx+STREAM.out_wp], eax; |
mov eax, [ebx+STREAM.in_rp] |
mov ecx, [r_size] |
add eax, ecx |
add [ebx+STREAM.in_free], ecx |
sub [ebx+STREAM.in_count], ecx |
cmp eax, [ebx+STREAM.in_top] |
jb @f |
sub eax, [ebx+STREAM.in_size] |
@@: |
mov [ebx+STREAM.in_rp], eax |
.done: |
mov eax, [ebx+STREAM.notify_event] |
test eax, eax |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
mov edx, EVENT_WATCHED |
xor esi, esi |
call RaiseEvent ;eax, ebx, edx, esi |
.exit: |
ret |
endp |
align 4 |
proc refill_ring stdcall, str:dword |
locals |
event rd 6 |
endl |
mov ebx, [str] |
mov edi, [ebx+STREAM.out_wp] |
cmp edi, [ebx+STREAM.out_top] |
jb @F |
sub edi, 0x10000 |
mov [ebx+STREAM.out_wp], edi |
@@: |
mov ecx, [ebx+STREAM.r_size] |
mov eax, ecx |
cmp word [ebx+STREAM.format], PCM_1_16_8 |
ja @F |
shr eax, 1 ;two channles |
@@: |
test [ebx+STREAM.format], 1 ;even formats mono |
jz @F |
shr eax, 1 ;eax= samples |
@@: |
shl eax, 15 ;eax*=32768 =r_end |
mov esi, [ebx+STREAM.in_rp] |
mov edi, [ebx+STREAM.out_wp] |
stdcall [ebx+STREAM.resample], edi, esi, \ |
[ebx+STREAM.r_dt], ecx, eax |
mov ebx, [str] |
add [ebx+STREAM.out_count], eax; |
add [ebx+STREAM.out_wp], eax; |
mov eax, [ebx+STREAM.in_rp] |
mov ecx, [ebx+STREAM.r_size] |
add eax, ecx |
add [ebx+STREAM.in_free], ecx |
sub [ebx+STREAM.in_count], ecx |
cmp eax, [ebx+STREAM.in_top] |
jb @f |
sub eax, [ebx+STREAM.in_size] |
@@: |
mov [ebx+STREAM.in_rp], eax |
sub eax, [ebx+STREAM.in_base] |
sub eax, 128 |
lea esi, [event] |
mov dword [esi], RT_INP_EMPTY |
mov dword [esi+4], 0 |
mov dword [esi+8], ebx |
mov dword [esi+12], eax |
mov eax, [ebx+STREAM.notify_event] |
test eax, eax |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
xor edx, edx |
call RaiseEvent ;eax, ebx, edx, esi |
.exit: |
ret |
endp |
if USE_SSE2_MIXER |
align 4 |
proc mix_all stdcall, dest:dword, list:dword, count:dword |
mov edi, [dest] |
mov ebx, 32 |
.mix: |
mov edx, [list] |
mov ecx, [count] |
mov eax, [edx] |
movdqa xmm1, [eax] |
movss xmm2, [edx+4] |
movss xmm3, [edx+8] |
punpcklwd xmm0, xmm1 |
punpckhwd xmm1, xmm1 |
shufps xmm2, xmm3, 0 |
shufps xmm2, xmm2, 0x88 |
psrad xmm0, 16 |
psrad xmm1, 16 |
cvtdq2ps xmm0, xmm0 |
cvtdq2ps xmm1, xmm1 |
mulps xmm0, xmm2 |
mulps xmm1, xmm2 |
.mix_loop: |
add dword [edx], 16 |
add edx, 12 |
dec ecx |
jz @F |
mov eax, [edx] |
movdqa xmm3, [eax] |
movss xmm4, [edx+4] |
movss xmm5, [edx+8] |
punpcklwd xmm2, xmm3 |
punpckhwd xmm3, xmm3 |
shufps xmm4, xmm5, 0 |
shufps xmm4, xmm4, 0x88 |
psrad xmm2, 16 |
psrad xmm3, 16 |
cvtdq2ps xmm2, xmm2 |
cvtdq2ps xmm3, xmm3 |
mulps xmm2, xmm4 |
mulps xmm3, xmm4 |
addps xmm0, xmm2 |
addps xmm1, xmm3 |
jmp .mix_loop |
@@: |
cvtps2dq xmm0, xmm0 |
cvtps2dq xmm1, xmm1 |
packssdw xmm0, xmm0 |
packssdw xmm1, xmm1 |
punpcklqdq xmm0, xmm1 |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
endp |
; param |
; edi = dest |
; edx = mix_list |
align 4 |
mix_fast: |
mov ebx, 32 |
mov eax, [edx] |
movss xmm2, [edx+4] ; vol Lf |
movss xmm3, [edx+8] ; vol Rf |
shufps xmm2, xmm3, 0 ; Rf Rf Lf Lf |
shufps xmm2, xmm2, 0x88 ; volume level Rf Lf Rf Lf |
.mix: |
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w |
add eax, 16 |
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm0, 16 ; R1d L1d R0d L0d |
psrad xmm1, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm0, xmm0 ; time to use all power |
cvtdq2ps xmm1, xmm1 ; of the dark side |
mulps xmm0, xmm2 ; R1f' L1f' R0f' L0f' |
mulps xmm1, xmm2 ; R3f' L3f' R2f' L2f' |
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' |
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' |
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' |
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' |
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
align 4 |
mix_fast_2_stream: |
mov ebx, 32 |
mov eax, [edx] |
movss xmm4, [edx+4] ; vol Lf |
movss xmm5, [edx+8] ; vol Rf |
mov ecx, [edx+12] |
movss xmm6, [edx+16] ; vol Lf |
movss xmm7, [edx+20] ; vol Rf |
shufps xmm4, xmm5, 0 ; Rf Rf Lf Lf |
shufps xmm4, xmm4, 0x88 ; volume level Rf Lf Rf Lf |
shufps xmm6, xmm7, 0 ; Rf Rf Lf Lf |
shufps xmm6, xmm6, 0x88 ; volume level Rf Lf Rf Lf |
.mix: |
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w |
movdqa xmm3, [ecx] ; R3w L3w R2w L2w R1w L1w R0w L0w |
add eax, 16 |
add ecx, 16 |
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm0, 16 ; R1d L1d R0d L0d |
psrad xmm1, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm0, xmm0 ; time to use all power |
cvtdq2ps xmm1, xmm1 ; of the dark side |
mulps xmm0, xmm4 ; R1f' L1f' R0f' L0f' |
mulps xmm1, xmm4 ; R3f' L3f' R2f' L2f' |
punpcklwd xmm2, xmm3 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm3, xmm3 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm2, 16 ; R1d L1d R0d L0d |
psrad xmm3, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm2, xmm2 ; time to use all power |
cvtdq2ps xmm3, xmm3 ; of the dark side |
mulps xmm2, xmm6 ; R1f' L1f' R0f' L0f' |
mulps xmm3, xmm6 ; R3f' L3f' R2f' L2f' |
addps xmm0, xmm2 |
addps xmm1, xmm3 |
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' |
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' |
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' |
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' |
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
else ; fixed point mmx version |
align 4 |
proc mix_all stdcall, dest:dword, list:dword, count:dword |
mov edi, [dest] |
mov ebx, 64 |
.mix: |
mov edx, [list] |
mov ecx, [count] |
mov eax, [edx] |
movq mm0, [eax] |
movd mm1, [edx+4] |
punpckldq mm1,mm1 |
pmulhw mm0, mm1 |
psllw mm0, 1 |
.mix_loop: |
add dword [edx], 8 |
add edx, 12 |
dec ecx |
jz @F |
mov eax, [edx] |
movq mm1, [eax] |
movd mm2, [edx+4] |
punpckldq mm2,mm2 |
pmulhw mm1, mm2 |
psllw mm1, 1 |
paddsw mm0, mm1 |
jmp .mix_loop |
@@: |
movq [edi], mm0 |
add edi, 8 |
dec ebx |
jnz .mix |
ret |
endp |
end if |
align 4 |
proc resample_1 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
; dest equ esp+8 |
; src equ esp+12 |
; r_dt equ esp+16 |
; r_size equ esp+20 |
; r_end equ esp+24 |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32*2 |
mov eax, 16 |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movsx ebp, word [esi] |
movsx esi, word [esi+2] |
mov ebx, 32768 |
imul esi, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+esi+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add eax, [esp+16] |
cmp eax, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_18 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32 |
mov esi, 16 |
align 4 |
.l1: |
mov ecx, esi |
mov eax, esi |
and ecx, 0x7FFF |
shr eax, 15 |
lea eax, [edx+eax] |
mov bx, word [eax] |
sub bh, 0x80 |
sub bl, 0x80 |
movsx eax, bh |
shl eax,8 |
movsx ebp, bl |
shl ebp,8 |
mov ebx, 32768 |
imul eax, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+eax+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add esi, [esp+16] |
cmp esi, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc copy_stream stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov ecx, [r_size] |
mov eax, ecx |
shr ecx, 2 |
mov esi, [src] |
mov edi, [dest] |
cld |
rep movsd |
ret |
endp |
align 4 |
proc resample_2 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*4 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*4] |
movq mm0, [esi] |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ;0x8000 |
psubw mm3, mm2 ; ;0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_28 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*2 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
movq mm7,[mm80] |
movq mm6,[mm_mask] |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movq mm0, [esi] |
psubb mm0,mm7 |
punpcklbw mm0,mm0 |
pand mm0,mm6 |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ; // 0x8000 |
psubw mm3, mm2 ; // 0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
proc m16_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx,8 |
@@: |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
align 4 |
proc s8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 7 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
proc m8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 6 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
add eax, eax |
ret |
endp |
align 4 |
proc alloc_mix_buff |
bsf eax, [mix_buff_map] |
jnz .find |
xor eax, eax |
ret |
.find: |
btr [mix_buff_map], eax |
shl eax, 9 |
add eax, [mix_buff] |
ret |
endp |
align 4 |
proc m16_s_mmx |
movq mm0, [esi] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
movq mm0, [esi+32] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+64], mm0 |
movq [edi+72], mm1 |
movq mm0, [esi+40] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+80], mm0 |
movq [edi+88], mm1 |
movq mm0, [esi+48] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+96], mm0 |
movq [edi+104], mm1 |
movq mm0, [esi+56] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+112], mm0 |
movq [edi+120], mm1 |
ret |
endp |
align 4 |
proc s8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
ret |
endp |
align 4 |
proc m8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi], mm0 |
movq [edi+8], mm2 |
movq [edi+16], mm1 |
movq [edi+24], mm3 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi+32], mm0 |
movq [edi+40], mm2 |
movq [edi+48], mm1 |
movq [edi+56], mm3 |
ret |
endp |
align 4 |
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov esi, 128 |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
ret |
endp |
align 4 |
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov esi, 128 |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
ret |
endp |
align 4 |
proc mix_4_1 stdcall, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
local output:DWORD |
call alloc_mix_buff |
and eax, eax |
jz .err |
mov [output], eax |
mov edi, eax |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
mov eax, [output] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
ret |
endp |
align 4 |
proc copy_mem stdcall, output:dword, input:dword |
mov edi, [output] |
mov esi, [input] |
mov ecx, 0x80 |
.l1: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
loop .l1 |
ret |
endp |
proc memcpy |
@@: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
dec ecx |
jnz @B |
ret |
endp |
if 0 |
align 4 |
proc new_mix stdcall, output:dword |
locals |
mixCounter dd ? |
mixIndex dd ? |
streamIndex dd ? |
inputCount dd ? |
main_count dd ? |
blockCount dd ? |
mix_out dd ? |
endl |
call prepare_playlist |
cmp [play_count], 0 |
je .exit |
call FpuSave |
mov [main_count], 32; |
.l00: |
mov [mix_buff_map], 0x0000FFFF; |
xor eax, eax |
mov [mixCounter], eax |
mov [mixIndex],eax |
mov [streamIndex], eax; |
mov ebx, [play_count] |
mov [inputCount], ebx |
.l0: |
mov ecx, 4 |
.l1: |
mov ebx, [streamIndex] |
mov esi, [play_list+ebx*4] |
mov eax, [esi+STREAM.work_read] |
add [esi+STREAM.work_read], 512 |
mov ebx, [mixIndex] |
mov [mix_input+ebx*4], eax |
inc [mixCounter] |
inc [mixIndex] |
inc [streamIndex] |
dec [inputCount] |
jz .m2 |
dec ecx |
jnz .l1 |
cmp [mixCounter], 4 |
jnz .m2 |
stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12] |
sub [mixIndex],4 |
mov ebx, [mixIndex] |
mov [mix_input+ebx*4], eax |
inc [mixIndex] |
mov [mixCounter], 0 |
cmp [inputCount], 0 |
jnz .l0 |
.m2: |
cmp [mixIndex], 1 |
jne @f |
stdcall copy_mem, [output], [mix_input] |
jmp .m3 |
@@: |
cmp [mixIndex], 2 |
jne @f |
stdcall mix_2_1, [output], [mix_input], [mix_input+4] |
jmp .m3 |
@@: |
cmp [mixIndex], 3 |
jne @f |
stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8] |
jmp .m3 |
@@: |
stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12] |
.m3: |
add [output],512 |
dec [main_count] |
jnz .l00 |
call update_stream |
emms |
call FpuRestore |
ret |
.exit: |
mov edi, [output] |
mov ecx, 0x1000 |
xor eax, eax |
cld |
rep stosd |
ret |
endp |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/uart.asm |
---|
0,0 → 1,976 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0 |
UART_VERSION equ API_VERSION |
PG_SW equ 0x003 |
page_tabs equ 0xFDC00000 ;hack |
OS_BASE equ 0x80000000 |
SLOT_BASE equ (OS_BASE+0x0080000) |
TASK_COUNT equ (OS_BASE+0x0003004) |
CURRENT_TASK equ (OS_BASE+0x0003000) |
struc APPOBJ ;common object header |
{ |
.magic dd ? ; |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
}; |
virtual at 0 |
APPOBJ APPOBJ |
end virtual |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
DEBUG equ 1 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
THR_REG equ 0; x3f8 ;transtitter/reciever |
IER_REG equ 1; x3f9 ;interrupt enable |
IIR_REG equ 2; x3fA ;interrupt info |
LCR_REG equ 3; x3FB ;line control |
MCR_REG equ 4; x3FC ;modem control |
LSR_REG equ 5; x3FD ;line status |
MSR_REG equ 6; x3FE ;modem status |
LCR_5BIT equ 0x00 |
LCR_6BIT equ 0x01 |
LCR_7BIT equ 0x02 |
LCR_8BIT equ 0x03 |
LCR_STOP_1 equ 0x00 |
LCR_STOP_2 equ 0x04 |
LCR_PARITY equ 0x08 |
LCR_EVEN equ 0x10 |
LCR_STICK equ 0x20 |
LCR_BREAK equ 0x40 |
LCR_DLAB equ 0x80 |
LSR_DR equ 0x01 ;data ready |
LSR_OE equ 0x02 ;overrun error |
LSR_PE equ 0x04 ;parity error |
LSR_FE equ 0x08 ;framing error |
LSR_BI equ 0x10 ;break interrupt |
LSR_THRE equ 0x20 ;transmitter holding empty |
LSR_TEMT equ 0x40 ;transmitter empty |
LSR_FER equ 0x80 ;FIFO error |
FCR_EFIFO equ 0x01 ;enable FIFO |
FCR_CRB equ 0x02 ;clear reciever FIFO |
FCR_CXMIT equ 0x04 ;clear transmitter FIFO |
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins |
FCR_FIFO_1 equ 0x00 ;1 byte trigger |
FCR_FIFO_4 equ 0x40 ;4 bytes trigger |
FCR_FIFO_8 equ 0x80 ;8 bytes trigger |
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger |
IIR_INTR equ 0x01 ;1= no interrupts |
IER_RDAI equ 0x01 ;reciever data interrupt |
IER_THRI equ 0x02 ;transmitter empty interrupt |
IER_LSI equ 0x04 ;line status interrupt |
IER_MSI equ 0x08 ;modem status interrupt |
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0 |
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0 |
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0 |
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr |
MCR_LOOP equ 0x10 ;lopback mode |
MSR_DCTS equ 0x01 ;delta clear to send |
MSR_DDSR equ 0x02 ;delta data set redy |
MSR_TERI equ 0x04 ;trailinh edge of ring |
MSR_DDCD equ 0x08 ;delta carrier detect |
RATE_50 equ 0 |
RATE_75 equ 1 |
RATE_110 equ 2 |
RATE_134 equ 3 |
RATE_150 equ 4 |
RATE_300 equ 5 |
RATE_600 equ 6 |
RATE_1200 equ 7 |
RATE_1800 equ 8 |
RATE_2000 equ 9 |
RATE_2400 equ 10 |
RATE_3600 equ 11 |
RATE_4800 equ 12 |
RATE_7200 equ 13 |
RATE_9600 equ 14 |
RATE_19200 equ 15 |
RATE_38400 equ 16 |
RATE_57600 equ 17 |
RATE_115200 equ 18 |
COM_1 equ 1 |
COM_2 equ 2 |
COM_3 equ 3 |
COM_4 equ 4 |
COM_MAX equ 2 ;only two port supported |
COM_1_BASE equ 0x3F8 |
COM_2_BASE equ 0x2F8 |
COM_1_IRQ equ 4 |
COM_2_IRQ equ 3 |
UART_CLOSED equ 0 |
UART_TRANSMIT equ 1 |
UART_STOP equ 2 |
struc UART |
{ |
.lock dd ? |
.base dd ? |
.lcr_reg dd ? |
.mcr_reg dd ? |
.rate dd ? |
.mode dd ? |
.state dd ? |
.rcvr_buff dd ? |
.rcvr_rp dd ? |
.rcvr_wp dd ? |
.rcvr_count dd ? |
.rcvr_top dd ? |
.xmit_buff dd ? |
.xmit_rp dd ? |
.xmit_wp dd ? |
.xmit_count dd ? |
.xmit_free dd ? |
.xmit_top dd ? |
} |
virtual at 0 |
UART UART |
end virtual |
UART_SIZE equ 18*4 |
struc CONNECTION |
{ |
.magic dd ? ;'CNCT' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.id dd ? ;reserved |
.uart dd ? ;uart pointer |
} |
virtual at 0 |
CONNECTION CONNECTION |
end virtual |
CONNECTION_SIZE equ 7*4 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
mov eax, UART_SIZE |
call Kmalloc |
test eax, eax |
jz .fail |
mov [com1], eax |
mov edi, eax |
mov ecx, UART_SIZE/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [com1] |
mov [eax+UART.base], COM_1_BASE |
stdcall AllocKernelSpace, 32768 |
mov edi, [com1] |
mov edx, eax |
mov [edi+UART.rcvr_buff], eax |
add eax, 8192 |
mov [edi+UART.rcvr_top], eax |
add eax, 8192 |
mov [edi+UART.xmit_buff], eax |
add eax, 8192 |
mov [edi+UART.xmit_top], eax |
call AllocPage |
test eax, eax |
jz .fail |
shr edx, 12 |
or eax, PG_SW |
mov [page_tabs+edx*4], eax |
mov [page_tabs+edx*4+8], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+4], eax |
mov [page_tabs+edx*4+12], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+16], eax |
mov [page_tabs+edx*4+24], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+20], eax |
mov [page_tabs+edx*4+28], eax |
mov eax, [edi+UART.rcvr_buff] |
invlpg [eax] |
invlpg [eax+0x1000] |
invlpg [eax+0x2000] |
invlpg [eax+0x3000] |
invlpg [eax+0x4000] |
invlpg [eax+0x5000] |
invlpg [eax+0x6000] |
invlpg [eax+0x7000] |
mov eax, edi |
call uart_reset.internal ;eax= uart |
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0 |
stdcall RegService, sz_uart_srv, service_proc |
ret |
.fail: |
.stop: |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
SRV_GETVERSION equ 0 |
PORT_OPEN equ 1 |
PORT_CLOSE equ 2 |
PORT_RESET equ 3 |
PORT_SETMODE equ 4 |
PORT_GETMODE equ 5 |
PORT_SETMCR equ 6 |
PORT_GETMCR equ 7 |
PORT_READ equ 8 |
PORT_WRITE equ 9 |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, PORT_WRITE |
ja .fail |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword UART_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, PORT_OPEN |
jne @F |
cmp [ebx+out_size], 4 |
jne .fail |
mov ebx, [ebx+input] |
mov eax, [ebx] |
call uart_open |
mov ebx, [ioctl] |
mov ebx, [ebx+output] |
mov [ebx], ecx |
ret |
@@: |
mov esi, [ebx+input] ;input buffer |
mov edi, [ebx+output] |
call [uart_func+eax*4] |
ret |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
; param |
; esi= input buffer |
; +0 connection |
; |
; retval |
; eax= error code |
align 4 |
uart_reset: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
; set mode 2400 bod 8-bit |
; disable DTR & RTS |
; clear FIFO |
; clear pending interrupts |
; |
; param |
; eax= uart |
align 4 |
.internal: |
mov esi, eax |
mov [eax+UART.state], UART_CLOSED |
mov edx, [eax+UART.base] |
add edx, MCR_REG |
xor eax, eax |
out dx, al ;clear DTR & RTS |
mov eax, esi |
mov ebx, RATE_2400 |
mov ecx, LCR_8BIT+LCR_STOP_1 |
call uart_set_mode.internal |
mov edx, [esi+UART.base] |
add edx, IIR_REG |
mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14 |
out dx, al |
.clear_RB: |
mov edx, [esi+UART.base] |
add edx, LSR_REG |
in al, dx |
test eax, LSR_DR |
jz @F |
mov edx, [esi+UART.base] |
in al, dx |
jmp .clear_RB |
@@: |
mov edx, [esi+UART.base] |
add edx, IER_REG |
mov eax,IER_RDAI+IER_THRI+IER_LSI |
out dx, al |
.clear_IIR: |
mov edx, [esi+UART.base] |
add edx, IIR_REG |
in al, dx |
test al, IIR_INTR |
jnz .done |
shr eax, 1 |
and eax, 3 |
jnz @F |
mov edx, [esi+UART.base] |
add edx, MSR_REG |
in al, dx |
jmp .clear_IIR |
@@: |
cmp eax, 1 |
je .clear_IIR |
cmp eax, 2 |
jne @F |
mov edx, [esi+UART.base] |
in al, dx |
jmp .clear_IIR |
@@: |
mov edx, [esi+UART.base] |
add edx, LSR_REG |
in al, dx |
jmp .clear_IIR |
.done: |
mov edi, [esi+UART.rcvr_buff] |
mov ecx, 8192/4 |
xor eax, eax |
mov [esi+UART.rcvr_rp], edi |
mov [esi+UART.rcvr_wp], edi |
mov [esi+UART.rcvr_count], eax |
cld |
rep stosd |
mov edi, [esi+UART.xmit_buff] |
mov ecx, 8192/4 |
mov [esi+UART.xmit_rp], edi |
mov [esi+UART.xmit_wp], edi |
mov [esi+UART.xmit_count], eax |
mov [esi+UART.xmit_free], 8192 |
rep stosd |
ret ;eax= 0 |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 rate |
; +8 mode |
; |
; retval |
; eax= error code |
align 4 |
uart_set_mode: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov ecx, [esi+8] |
; param |
; eax= uart |
; ebx= baud rate |
; ecx= mode |
align 4 |
.internal: |
cmp ebx, RATE_115200 |
ja .fail |
cmp ecx, LCR_BREAK |
jae .fail |
mov [eax+UART.rate], ebx |
mov [eax+UART.mode], ecx |
mov esi, eax |
mov bx, [divisor+ebx*2] |
mov edx, [esi+UART.base] |
push edx |
add edx, LCR_REG |
in al, dx |
or al, 0x80 |
out dx, al |
pop edx |
mov al, bl |
out dx, al |
inc dx |
mov al, bh |
out dx, al |
add edx, LCR_REG-1 |
mov eax, ecx |
out dx, al |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 modem control reg valie |
; |
; retval |
; eax= error code |
align 4 |
uart_set_mcr: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov [eax+UART.mcr_reg], ebx |
mov edx, [eax+UART.base] |
add edx, MCR_REG |
mov al, bl |
out dx, al |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; eax= port |
; |
; retval |
; ecx= connection |
; eax= error code |
align 4 |
uart_open: |
dec eax |
cmp eax, COM_MAX |
jae .fail |
mov esi, [com1+eax*4] ;uart |
push esi |
.do_wait: |
cmp dword [esi+UART.lock],0 |
je .get_lock |
; call change_task |
jmp .do_wait |
.get_lock: |
mov eax, 1 |
xchg eax, [esi+UART.lock] |
test eax, eax |
jnz .do_wait |
mov eax, esi ;uart |
call uart_reset.internal |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
mov eax, CONNECTION_SIZE |
call CreateObject |
pop esi ;uart |
test eax, eax |
jz .fail |
mov [eax+APPOBJ.magic], 'CNCT' |
mov [eax+APPOBJ.destroy], uart_close.destroy |
mov [eax+CONNECTION.uart], esi |
mov ecx, eax |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
restore .uart |
; param |
; esi= input buffer |
align 4 |
uart_close: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
.destroy: |
push [eax+CONNECTION.uart] |
call DestroyObject ;eax= object |
pop eax ;eax= uart |
test eax, eax |
jz .fail |
mov [eax+UART.state], UART_CLOSED |
mov [eax+UART.lock], 0 ;release port |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; eax= uart |
; ebx= baud rate |
align 4 |
set_rate: |
cmp ebx, RATE_115200 |
ja .fail |
mov [eax+UART.rate], ebx |
mov bx, [divisor+ebx*2] |
mov edx, [eax+UART.base] |
add edx, LCR_REG |
in al, dx |
push eax |
or al, 0x80 |
out dx, al |
sub edx, LCR_REG |
mov al, bl |
out dx, al |
inc edx |
mov al, bh |
out dx, al |
pop eax |
add edx, LCR_REG-1 |
out dx, al |
.fail: |
ret |
; param |
; ebx= uart |
align 4 |
transmit: |
push esi |
push edi |
mov edx, [ebx+UART.base] |
pushfd |
cli |
mov esi, [ebx+UART.xmit_rp] |
mov ecx, [ebx+UART.xmit_count] |
test ecx, ecx |
je .stop |
cmp ecx, 16 |
jbe @F |
mov ecx, 16 |
@@: |
sub [ebx+UART.xmit_count], ecx |
add [ebx+UART.xmit_free], ecx |
cld |
@@: |
lodsb |
out dx, al |
dec ecx |
jnz @B |
cmp esi,[ebx+UART.xmit_top] |
jb @F |
sub esi, 8192 |
@@: |
mov [ebx+UART.xmit_rp], esi |
cmp [ebx+UART.xmit_count], 0 |
je .stop |
mov [ebx+UART.state], UART_TRANSMIT |
jmp @F |
.stop: |
mov [ebx+UART.state], UART_STOP |
@@: |
popfd |
pop edi |
pop esi |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 dst buffer |
; +8 dst size |
; edi= output buffer |
; +0 bytes read |
; retval |
; eax= error code |
align 4 |
uart_read: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+8] ;dst size |
mov ecx, [eax+UART.rcvr_count] |
cmp ecx, ebx |
jbe @F |
mov ecx, ebx |
@@: |
mov [edi], ecx ;bytes read |
test ecx, ecx |
jz .done |
push ecx |
mov edi, [esi+4] ;dst |
mov esi, [eax+UART.rcvr_rp] |
cld |
rep movsb |
pop ecx |
cmp esi, [eax+UART.rcvr_top] |
jb @F |
sub esi, 8192 |
@@: |
mov [eax+UART.rcvr_rp], esi |
sub [eax+UART.rcvr_count], ecx |
.done: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 src buffer |
; +8 src size |
; |
; retval |
; eax= error code |
align 4 |
uart_write: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov edx, [esi+8] |
; param |
; eax= uart |
; ebx= src |
; edx= count |
align 4 |
.internal: |
mov esi, ebx |
mov edi, [eax+UART.xmit_wp] |
.write: |
test edx, edx |
jz .fail |
.wait: |
cmp [eax+UART.xmit_free], 0 |
jne .fill |
cmp [eax+UART.state], UART_TRANSMIT |
je .wait |
mov ebx, eax |
push edx |
call transmit |
pop edx |
mov eax, ebx |
jmp .write |
.fill: |
mov ecx, [eax+UART.xmit_free] |
cmp ecx, edx |
jbe @F |
mov ecx, edx |
@@: |
push ecx |
cld |
rep movsb |
pop ecx |
sub [eax+UART.xmit_free], ecx |
add [eax+UART.xmit_count], ecx |
sub edx, ecx |
jnz .wait |
.done: |
cmp edi, [eax+UART.xmit_top] |
jb @F |
sub edi, 8192 |
@@: |
mov [eax+UART.xmit_wp], edi |
cmp [eax+UART.state], UART_TRANSMIT |
je @F |
mov ebx, eax |
call transmit |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
align 4 |
com_2_isr: |
mov ebx, [com2] |
jmp com_1_isr.get_info |
align 4 |
com_1_isr: |
mov ebx, [com1] |
.get_info: |
mov edx, [ebx+UART.base] |
add edx, IIR_REG |
in al, dx |
test al, IIR_INTR |
jnz .done |
shr eax, 1 |
and eax, 3 |
call [isr_action+eax*4] |
jmp .get_info |
.done: |
ret |
align 4 |
isr_line: |
mov edx, [ebx+UART.base] |
add edx, LSR_REG |
in al, dx |
ret |
align 4 |
isr_recieve: |
mov esi, [ebx+UART.base] |
add esi, LSR_REG |
mov edi, [ebx+UART.rcvr_wp] |
xor ecx, ecx |
cld |
.read: |
mov edx, esi |
in al, dx |
test eax, LSR_DR |
jz .done |
mov edx, [ebx+UART.base] |
in al, dx |
stosb |
inc ecx |
jmp .read |
.done: |
cmp edi, [ebx+UART.rcvr_top] |
jb @F |
sub edi, 8192 |
@@: |
mov [ebx+UART.rcvr_wp], edi |
add [ebx+UART.rcvr_count], ecx |
ret |
align 4 |
isr_modem: |
mov edx, [ebx+UART.base] |
add edx, MSR_REG |
in al, dx |
ret |
align 4 |
divisor dw 2304, 1536, 1047, 857, 768, 384 |
dw 192, 96, 64, 58, 48, 32 |
dw 24, 16, 12, 6, 3, 2, 1 |
align 4 |
uart_func dd 0 ;SRV_GETVERSION |
dd 0 ;PORT_OPEN |
dd uart_close ;PORT_CLOSE |
dd uart_reset ;PORT_RESET |
dd uart_set_mode ;PORT_SETMODE |
dd 0 ;PORT_GETMODE |
dd uart_set_mcr ;PORT_SETMODEM |
dd 0 ;PORT_GETMODEM |
dd uart_read ;PORT_READ |
dd uart_write ;PORT_WRITE |
isr_action dd isr_modem |
dd transmit |
dd isr_recieve |
dd isr_line |
version dd (5 shl 16) or (UART_VERSION and 0xFFFF) |
sz_uart_srv db 'UART',0 |
align 4 |
com1 rd 1 |
com2 rd 1 |
/kernel/tags/kolibri0.7.7.0/drivers/ensoniq.asm |
---|
0,0 → 1,1177 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;alpha version |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'imports.inc' |
REMAP_IRQ equ 0 |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010101000b |
IRQ_LINE equ 0 |
CPU_FREQ equ 2600d |
BIT0 EQU 0x00000001 |
BIT1 EQU 0x00000002 |
BIT2 EQU 0x00000004 |
BIT3 EQU 0x00000008 |
BIT4 EQU 0x00000010 |
BIT5 EQU 0x00000020 |
BIT6 EQU 0x00000040 |
BIT7 EQU 0x00000080 |
BIT8 EQU 0x00000100 |
BIT9 EQU 0x00000200 |
BIT10 EQU 0x00000400 |
BIT11 EQU 0x00000800 |
BIT12 EQU 0x00001000 |
BIT13 EQU 0x00002000 |
BIT14 EQU 0x00004000 |
BIT15 EQU 0x00008000 |
BIT16 EQU 0x00010000 |
BIT17 EQU 0x00020000 |
BIT18 EQU 0x00040000 |
BIT19 EQU 0x00080000 |
BIT20 EQU 0x00100000 |
BIT21 EQU 0x00200000 |
BIT22 EQU 0x00400000 |
BIT23 EQU 0x00800000 |
BIT24 EQU 0x00100000 |
BIT25 EQU 0x02000000 |
BIT26 EQU 0x04000000 |
BIT27 EQU 0x08000000 |
BIT28 EQU 0x10000000 |
BIT29 EQU 0x20000000 |
BIT30 EQU 0x40000000 |
BIT31 EQU 0x80000000 |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 18h ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 28h ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
OS_BASE equ 0x80000000 |
SLOT_BASE equ OS_BASE+0x0080000 |
new_app_base equ 0 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgDetect |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
jmp .fail ;force fail |
if DEBUG |
mov esi, msgInitCodec |
call SysMsgBoardStr |
end if |
call init_codec |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, [codec.ac_vendor_ids] |
call SysMsgBoardStr |
mov esi, [codec.chip_ids] |
call SysMsgBoardStr |
end if |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov eax, VALID_IRQ |
mov ebx, [ctrl.int_line] |
mov esi, msgInvIRQ |
bt eax, ebx |
jnc .fail |
mov eax, ATTCH_IRQ |
mov esi, msgAttchIRQ |
bt eax, ebx |
jnc .fail |
stdcall AttachIntHandler, ebx, ac97_irq, dword 0 |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
; if DEBUG |
; mov esi, msgIRQ |
; call SysMsgBoardStr |
; end if |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp ebx, 0x1274 |
jne @F |
mov [ctrl.vendor_ids], msgEnsoniq |
ret |
@@: |
mov [ctrl.vendor_ids], 0 ;something wrong ? |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_controller |
mov esi, msgPCIcmd |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
call dword2str |
call SysMsgBoardStr |
mov esi, msgIObase |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
; and eax, -16 |
mov [ctrl.ctrl_io_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgIRQline |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
mov [ctrl.int_line], eax |
call dword2str |
call SysMsgBoardStr |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_ICH |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
and eax, eax |
jz .err |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .ready |
mov eax, 5000 ; wait 5 ms |
call StallExec |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.ready: |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
xor eax, eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 1000000 ; wait 1 s |
call StallExec |
mov eax, 2 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax,eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax,eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx,edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
codec_io_r16: |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
align 4 |
codec_io_w16: |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
align 4 |
ctrl_io_r8: |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
align 4 |
ctrl_io_r16: |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
align 4 |
ctrl_io_r32: |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
align 4 |
ctrl_io_w8: |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
align 4 |
ctrl_io_w16: |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
align 4 |
ctrl_io_w32: |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH |
dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH |
dd 0 ;terminator |
version dd 0x00040004 |
msgEnsoniq db 'Ensonic 1371',13,10,0 |
msgVibra128 db 'Sound Blaster AudioPCI Vibra 128',13,10,0 |
sz_sound_srv db 'SOUND',0 |
msgDetect db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer',13,10,0 |
msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPCIcmd db 'PCI command ',0 |
msgIObase db 'IO base ',0 |
msgIRQline db 'IRQ line ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/imports.inc |
---|
0,0 → 1,89 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
macro kernel_export [name]{ |
forward |
if used name |
if DEBUG |
display 'uses: ',`name,#13,#10 |
end if |
extrn name |
end if |
} |
; all exported kernel functions and data |
kernel_export \ |
RegService,\ |
GetService,\ |
ServiceHandler,\ |
AttachIntHandler,\ |
GetIntHandler,\ |
FpuSave,\ |
FpuRestore,\ |
ReservePortArea,\ |
Boot_Log,\ |
\ |
PciApi,\ |
PciRead32,\ |
PciRead16,\ |
PciRead8,\ |
PciWrite8,\ |
PciWrite16,\ |
PciWrite32,\ |
\ |
AllocPage,\ |
AllocPages,\ |
FreePage,\ |
MapPage,\ |
MapSpace,\ |
MapIoMem,\ |
GetPgAddr,\ |
CommitPages,\ |
ReleasePages,\ |
\ |
AllocKernelSpace,\ |
FreeKernelSpace,\ |
KernelAlloc,\ |
KernelFree,\ |
UserAlloc,\ |
UserFree,\ |
Kmalloc,\ |
Kfree,\ |
CreateRingBuffer,\ |
\ |
GetPid,\ |
CreateObject,\ |
DestroyObject,\ |
CreateEvent,\ |
RaiseEvent,\ |
WaitEvent,\ |
DestroyEvent,\ |
ClearEvent,\ |
\ |
LoadCursor,\ |
SelectHwCursor,\ |
SetHwCursor,\ |
HwCursorRestore,\ |
HwCursorCreate,\ |
\ |
SysMsgBoardStr,\ |
SysMsgBoardChar,\ |
GetCurrentTask,\ |
LoadFile,\ |
SendEvent,\ |
SetMouseData,\ |
Sleep,\ |
GetTimerTicks,\ |
\ |
strncat,\ |
strncpy,\ |
strncmp,\ |
strnlen,\ |
strchr,\ |
strrchr,\ |
\ |
LFBAddress |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/proc32.inc |
---|
0,0 → 1,268 |
; Macroinstructions for defining and calling procedures |
macro stdcall proc,[arg] ; directly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call proc } |
macro invoke proc,[arg] ; indirectly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call [proc] } |
macro ccall proc,[arg] ; directly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call proc |
if size@ccall |
add esp,size@ccall |
end if } |
macro cinvoke proc,[arg] ; indirectly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call [proc] |
if size@ccall |
add esp,size@ccall |
end if } |
macro proc [args] ; define procedure |
{ common |
match name params, args> |
\{ define@proc name,<params \} } |
prologue@proc equ prologuedef |
macro prologuedef procname,flag,parmbytes,localbytes,reglist |
{ if parmbytes | localbytes |
push ebp |
mov ebp,esp |
if localbytes |
sub esp,localbytes |
end if |
end if |
irps reg, reglist \{ push reg \} } |
epilogue@proc equ epiloguedef |
macro epiloguedef procname,flag,parmbytes,localbytes,reglist |
{ irps reg, reglist \{ reverse pop reg \} |
if parmbytes | localbytes |
leave |
end if |
if flag and 10000b |
retn |
else |
retn parmbytes |
end if } |
macro define@proc name,statement |
{ local params,flag,regs,parmbytes,localbytes,current |
if used name |
name: |
match =stdcall args, statement \{ params equ args |
flag = 11b \} |
match =stdcall, statement \{ params equ |
flag = 11b \} |
match =c args, statement \{ params equ args |
flag = 10001b \} |
match =c, statement \{ params equ |
flag = 10001b \} |
match =params, params \{ params equ statement |
flag = 0 \} |
virtual at ebp+8 |
match =uses reglist=,args, params \{ regs equ reglist |
params equ args \} |
match =regs =uses reglist, regs params \{ regs equ reglist |
params equ \} |
match =regs, regs \{ regs equ \} |
match =,args, params \{ defargs@proc args \} |
match =args@proc args, args@proc params \{ defargs@proc args \} |
parmbytes = $ - (ebp+8) |
end virtual |
name # % = parmbytes/4 |
all@vars equ |
current = 0 |
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \} |
macro locals |
\{ virtual at ebp-localbytes+current |
macro label . \\{ deflocal@proc .,:, \\} |
struc db [val] \\{ \common deflocal@proc .,db,val \\} |
struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
macro endl |
\{ purge label |
restruc db,dw,dp,dd,dt,dq |
restruc rb,rw,rp,rd,rt,rq |
restruc byte,word,dword,pword,tword,qword |
current = $-(ebp-localbytes) |
end virtual \} |
macro ret operand |
\{ match any, operand \\{ retn operand \\} |
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> |
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
end if \} } |
macro defargs@proc [arg] |
{ common |
if ~ arg eq |
forward |
local ..arg,current@arg |
match argname:type, arg |
\{ current@arg equ argname |
label ..arg type |
argname equ ..arg |
if dqword eq type |
dd ?,?,?,? |
else if tbyte eq type |
dd ?,?,? |
else if qword eq type | pword eq type |
dd ?,? |
else |
dd ? |
end if \} |
match =current@arg,current@arg |
\{ current@arg equ arg |
arg equ ..arg |
..arg dd ? \} |
common |
args@proc equ current@arg |
forward |
restore current@arg |
common |
end if } |
macro deflocal@proc name,def,[val] |
{ common |
match vars, all@vars \{ all@vars equ all@vars, \} |
all@vars equ all@vars name |
forward |
local ..var,..tmp |
..var def val |
match =?, val \{ ..tmp equ \} |
match any =dup (=?), val \{ ..tmp equ \} |
match tmp : value, ..tmp : val |
\{ tmp: end virtual |
initlocal@proc ..var,def value |
virtual at tmp\} |
common |
match first rest, ..var, \{ name equ first \} } |
macro initlocal@proc name,def |
{ virtual at name |
def |
size@initlocal = $ - name |
end virtual |
position@initlocal = 0 |
while size@initlocal > position@initlocal |
virtual at name |
def |
if size@initlocal - position@initlocal < 2 |
current@initlocal = 1 |
load byte@initlocal byte from name+position@initlocal |
else if size@initlocal - position@initlocal < 4 |
current@initlocal = 2 |
load word@initlocal word from name+position@initlocal |
else |
current@initlocal = 4 |
load dword@initlocal dword from name+position@initlocal |
end if |
end virtual |
if current@initlocal = 1 |
mov byte [name+position@initlocal],byte@initlocal |
else if current@initlocal = 2 |
mov word [name+position@initlocal],word@initlocal |
else |
mov dword [name+position@initlocal],dword@initlocal |
end if |
position@initlocal = position@initlocal + current@initlocal |
end while } |
macro endp |
{ purge ret,locals,endl |
finish@proc |
purge finish@proc |
restore regs@proc |
match all,args@proc \{ restore all \} |
restore args@proc |
match all,all@vars \{ restore all \} } |
macro local [var] |
{ common |
locals |
forward done@local equ |
match varname[count]:vartype, var |
\{ match =BYTE, vartype \\{ varname rb count |
restore done@local \\} |
match =WORD, vartype \\{ varname rw count |
restore done@local \\} |
match =DWORD, vartype \\{ varname rd count |
restore done@local \\} |
match =PWORD, vartype \\{ varname rp count |
restore done@local \\} |
match =QWORD, vartype \\{ varname rq count |
restore done@local \\} |
match =TBYTE, vartype \\{ varname rt count |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
rq count+count |
restore done@local \\} |
match , done@local \\{ virtual |
varname vartype |
end virtual |
rb count*sizeof.\#vartype |
restore done@local \\} \} |
match :varname:vartype, done@local:var |
\{ match =BYTE, vartype \\{ varname db ? |
restore done@local \\} |
match =WORD, vartype \\{ varname dw ? |
restore done@local \\} |
match =DWORD, vartype \\{ varname dd ? |
restore done@local \\} |
match =PWORD, vartype \\{ varname dp ? |
restore done@local \\} |
match =QWORD, vartype \\{ varname dq ? |
restore done@local \\} |
match =TBYTE, vartype \\{ varname dt ? |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
dq ?,? |
restore done@local \\} |
match , done@local \\{ varname vartype |
restore done@local \\} \} |
match ,done@local |
\{ var |
restore done@local \} |
common |
endl } |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/sceletone.asm |
---|
0,0 → 1,177 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;driver sceletone |
format MS COFF |
DEBUG equ 1 |
API_VERSION equ 0 ;debug |
include 'proc32.inc' |
include 'imports.inc' |
OS_BASE equ 0; |
new_app_base equ 0x60400000 |
PROC_BASE equ OS_BASE+0x0080000 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
public START |
public service_proc |
public version |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
STRIDE equ 4 ;size of row in devices table |
SRV_GETVERSION equ 0 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
.entry: |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
stdcall RegService, my_service, service_proc |
ret |
.fail: |
.exit: |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc detect |
locals |
last_bus dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, STRIDE |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
DEVICE_ID equ 1234; pci device id |
VENDOR_ID equ 5678; device vendor id |
;all initialized data place here |
align 4 |
devices dd (DEVICE_ID shl 16)+VENDOR_ID |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
my_service db 'MY_SERVICE',0 ;max 16 chars include zero |
msgInit db 'detect hardware...',13,10,0 |
msgPCI db 'PCI accsess not supported',13,10,0 |
msgFail db 'device not found',13,10,0 |
section '.data' data readable writable align 16 |
;all uninitialized data place here |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/sis.asm |
---|
0,0 → 1,1307 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
DEBUG_IRQ equ 0 |
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices |
IRQ_REMAP equ 0 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
if USE_COM_IRQ |
ATTCH_IRQ equ 0000111010111000b |
end if |
CPU_FREQ equ 2600d |
BIT0 EQU 0x00000001 |
BIT1 EQU 0x00000002 |
BIT2 EQU 0x00000004 |
BIT3 EQU 0x00000008 |
BIT4 EQU 0x00000010 |
BIT5 EQU 0x00000020 |
BIT6 EQU 0x00000040 |
BIT7 EQU 0x00000080 |
BIT8 EQU 0x00000100 |
BIT9 EQU 0x00000200 |
BIT10 EQU 0x00000400 |
BIT11 EQU 0x00000800 |
BIT12 EQU 0x00001000 |
BIT13 EQU 0x00002000 |
BIT14 EQU 0x00004000 |
BIT15 EQU 0x00008000 |
BIT16 EQU 0x00010000 |
BIT17 EQU 0x00020000 |
BIT18 EQU 0x00040000 |
BIT19 EQU 0x00080000 |
BIT20 EQU 0x00100000 |
BIT21 EQU 0x00200000 |
BIT22 EQU 0x00400000 |
BIT23 EQU 0x00800000 |
BIT24 EQU 0x00100000 |
BIT25 EQU 0x02000000 |
BIT26 EQU 0x04000000 |
BIT27 EQU 0x08000000 |
BIT28 EQU 0x10000000 |
BIT29 EQU 0x20000000 |
BIT30 EQU 0x40000000 |
BIT31 EQU 0x80000000 |
VID_SIS equ 0x1039 |
CTRL_SIS equ 0x7012 |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x18 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
call init_codec |
test eax, eax |
jz .fail |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov esi, msgDone |
call SysMsgBoardStr |
if IRQ_REMAP |
pushf |
cli |
mov ebx, [ctrl.int_line] |
in al, 0xA1 |
mov ah, al |
in al, 0x21 |
test ebx, ebx |
jz .skip |
bts ax, bx ;mask old line |
.skip |
bts ax, IRQ_LINE ;mask new ine |
out 0x21, al |
mov al, ah |
out 0xA1, al |
;remap IRQ |
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE |
mov dx, 0x4d0 ;8259 ELCR1 |
in al, dx |
bts ax, IRQ_LINE |
out dx, al ;set level-triggered mode |
mov [ctrl.int_line], IRQ_LINE |
popf |
mov esi, msgRemap |
call SysMsgBoardStr |
end if |
mov eax, VALID_IRQ |
mov ebx, [ctrl.int_line] |
mov esi, msgInvIRQ |
bt eax, ebx |
jnc .fail_msg |
mov eax, ATTCH_IRQ |
mov esi, msgAttchIRQ |
bt eax, ebx |
jnc .fail_msg |
stdcall AttachIntHandler, ebx, ac97_irq, dword 0 |
.reg: |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.fail_msg: |
call SysMsgBoardStr |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
if DEBUG_IRQ |
mov esi, msgIRQ |
call SysMsgBoardStr |
end if |
mov edx, PCM_OUT_CR_REG |
mov al, 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0004000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
and eax, not 0x000000C0 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov [ctrl.vendor_ids], msg_SIS |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_controller |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
mov esi, msgPciCmd |
call SysMsgBoardStr |
call dword2str |
call SysMsgBoardStr |
mov esi, msgPciStat |
call SysMsgBoardStr |
mov eax, [ctrl.pci_stat] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgMixIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
call dword2str |
call SysMsgBoardStr |
and eax,0xFFFE |
mov [ctrl.codec_io_base], eax |
mov esi, msgCtrlIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFC0 |
mov [ctrl.ctrl_io_base], eax |
mov esi, msgMixMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 |
mov [ctrl.codec_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgCtrlMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C |
mov [ctrl.ctrl_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
.default: |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
@@: |
mov [ctrl.int_line], eax |
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 |
and eax, 0xFF |
mov [ctrl.cfg_reg], eax |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_SIS |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
cmp eax, 0xFFFFFFFF |
je .err |
test eax, CTRL_ST_CREADY |
jnz .done ;;;;;.ready |
call reset_codec |
test eax, eax |
jz .err |
.ready: |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov eax, 5000 ; wait 5 ms |
call StallExec |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
je .done |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.done: |
mov eax, 2 ;force set 16-bit 2-channel PCM |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov eax, 5000 ; wait 5 ms |
call StallExec |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
clc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
mov eax, 0x02 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 400000 ; wait 400 ms |
call StallExec |
mov [counter], 16 ; total 20*100 ms = 2s |
.wait: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
mov eax, 100000 ; wait 100 ms |
call StallExec |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
test eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
endp |
align 4 |
play: |
xor eax, eax |
mov [civ_val], eax |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_write8] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax,eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax,eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx, edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS |
dd 0 |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_AC db '7012 AC97 controller',13,10, 0 |
msg_SIS db 'Silicon Integrated Systems',13,10, 0 |
sz_sound_srv db 'SOUND',0 |
msgInit db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
;msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
;msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer ...',0 |
msgDone db 'done',13,10,0 |
msgRemap db 'Remap IRQ',13,10,0 |
;msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPciCmd db 'PCI command ',0 |
msgPciStat db 'PCI status ',0 |
msgCtrlIsaIo db 'controller io base ',0 |
msgMixIsaIo db 'codec io base ',0 |
msgCtrlMMIo db 'controller mmio base ',0 |
msgMixMMIo db 'codec mmio base ',0 |
msgIrqMap db 'AC97 irq map as ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
/kernel/tags/kolibri0.7.7.0/drivers/sound.asm |
---|
0,0 → 1,1473 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
DEBUG_IRQ equ 0 |
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices |
IRQ_REMAP equ 0 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
if USE_COM_IRQ |
ATTCH_IRQ equ 0000111010111000b |
end if |
CPU_FREQ equ 2600d |
BIT0 EQU 0x00000001 |
BIT1 EQU 0x00000002 |
BIT2 EQU 0x00000004 |
BIT3 EQU 0x00000008 |
BIT4 EQU 0x00000010 |
BIT5 EQU 0x00000020 |
BIT6 EQU 0x00000040 |
BIT7 EQU 0x00000080 |
BIT8 EQU 0x00000100 |
BIT9 EQU 0x00000200 |
BIT10 EQU 0x00000400 |
BIT11 EQU 0x00000800 |
BIT12 EQU 0x00001000 |
BIT13 EQU 0x00002000 |
BIT14 EQU 0x00004000 |
BIT15 EQU 0x00008000 |
BIT16 EQU 0x00010000 |
BIT17 EQU 0x00020000 |
BIT18 EQU 0x00040000 |
BIT19 EQU 0x00080000 |
BIT20 EQU 0x00100000 |
BIT21 EQU 0x00200000 |
BIT22 EQU 0x00400000 |
BIT23 EQU 0x00800000 |
BIT24 EQU 0x00100000 |
BIT25 EQU 0x02000000 |
BIT26 EQU 0x04000000 |
BIT27 EQU 0x08000000 |
BIT28 EQU 0x10000000 |
BIT29 EQU 0x20000000 |
BIT30 EQU 0x40000000 |
BIT31 EQU 0x80000000 |
PCM_4 equ BIT20 |
PCM_6 equ BIT21 |
VID_INTEL equ 0x8086 |
VID_NVIDIA equ 0x10DE |
CTRL_ICH equ 0x2415 |
CTRL_ICH0 equ 0x2425 |
CTRL_ICH2 equ 0x2435 |
CTRL_ICH3 equ 0x2445 |
CTRL_ICH4 equ 0x24C5 |
CTRL_ICH5 equ 0x24D5 |
CTRL_ICH6 equ 0x266E |
CTRL_ICH7 equ 0x27DE |
CTRL_NFORCE equ 0x01B1 |
CTRL_NFORCE2 equ 0x006A |
CTRL_NFORCE3 equ 0x00DA |
CTRL_MCP04 equ 0x003A |
CTRL_CK804 equ 0x0059 |
CTRL_CK8 equ 0x008A |
CTRL_CK8S equ 0x00EA |
CTRL_MCP51 equ 0x026B |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
call init_codec |
test eax, eax |
jz .fail |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov esi, msgDone |
call SysMsgBoardStr |
if IRQ_REMAP |
pushf |
cli |
mov ebx, [ctrl.int_line] |
in al, 0xA1 |
mov ah, al |
in al, 0x21 |
test ebx, ebx |
jz .skip |
bts ax, bx ;mask old line |
.skip |
bts ax, IRQ_LINE ;mask new ine |
out 0x21, al |
mov al, ah |
out 0xA1, al |
;remap IRQ |
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE |
mov dx, 0x4d0 ;8259 ELCR1 |
in al, dx |
bts ax, IRQ_LINE |
out dx, al ;set level-triggered mode |
mov [ctrl.int_line], IRQ_LINE |
popf |
mov esi, msgRemap |
call SysMsgBoardStr |
end if |
mov eax, VALID_IRQ |
mov ebx, [ctrl.int_line] |
mov esi, msgInvIRQ |
bt eax, ebx |
jnc .fail_msg |
mov eax, ATTCH_IRQ |
mov esi, msgAttchIRQ |
bt eax, ebx |
jnc .fail_msg |
stdcall AttachIntHandler, ebx, ac97_irq, dword 0 |
.reg: |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.fail_msg: |
call SysMsgBoardStr |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
if DEBUG_IRQ |
mov esi, msgIRQ |
call SysMsgBoardStr |
end if |
mov edx, PCM_OUT_CR_REG |
mov al, 0x10; 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp edx, VID_INTEL |
jne @F |
mov [ctrl.vendor_ids], msg_Intel |
ret |
@@: |
cmp edx, VID_NVIDIA |
jne @F |
mov [ctrl.vendor_ids], msg_NVidia |
ret |
@@: |
.err: |
xor eax, eax |
mov [ctrl.vendor_ids], eax ;something wrong ? |
ret |
endp |
align 4 |
proc init_controller |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
mov esi, msgPciCmd |
call SysMsgBoardStr |
call dword2str |
call SysMsgBoardStr |
mov esi, msgPciStat |
call SysMsgBoardStr |
mov eax, [ctrl.pci_stat] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgMixIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
call dword2str |
call SysMsgBoardStr |
and eax,0xFFFE |
mov [ctrl.codec_io_base], eax |
mov esi, msgCtrlIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFC0 |
mov [ctrl.ctrl_io_base], eax |
mov esi, msgMixMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 |
mov [ctrl.codec_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgCtrlMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C |
mov [ctrl.ctrl_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
if 0 |
;;patch for some ugly BIOS ICH-ICH5 compatible |
cmp [ctrl.vendor], VID_INTEL |
jne .default |
mov esi, msgIrqMap |
call SysMsgBoardStr |
stdcall PciRead8, 0, 0xF8, 0x61 |
and eax, 0xFF |
call dword2str |
call SysMsgBoardStr |
btr eax, 7 ;when bit 7 set remap disabled |
jnc @F |
xor eax, eax |
jmp @F |
end if |
.default: |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
@@: |
mov [ctrl.int_line], eax |
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 |
and eax, 0xFF |
mov [ctrl.cfg_reg], eax |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_ICH |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
PG_SW equ 0x003 |
PG_NOCACHE equ 0x018 |
align 4 |
proc set_ICH4 |
stdcall MapIoMem,[ctrl.codec_mem_base],0x1000,PG_SW+PG_NOCACHE |
mov [ctrl.codec_mem_base], eax |
stdcall MapIoMem,[ctrl.ctrl_mem_base],0x1000,PG_SW+PG_NOCACHE |
mov [ctrl.ctrl_mem_base], eax |
mov [ctrl.codec_read16], codec_mem_r16 ;virtual |
mov [ctrl.codec_write16], codec_mem_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
cmp eax, 0xFFFFFFFF |
je .err |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
test eax, eax |
jz .err |
.ready: |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov eax, 5000 ; wait 5 ms |
call StallExec |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .done |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.done: |
mov eax, 2 ;force set 16-bit 2-channel PCM |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov eax, 5000 ; wait 5 ms |
call StallExec |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
clc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
mov eax, 0x02 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 400000 ; wait 400 ms |
call StallExec |
mov [counter], 16 ; total 20*100 ms = 2s |
.wait: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
mov eax, 100000 ; wait 100 ms |
call StallExec |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
test eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax,eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax,eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx,edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; MEMORY MAPPED IO (os depended) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_mem_r16 |
add edx, [ctrl.codec_mem_base] |
mov ax, word [edx] |
ret |
endp |
align 4 |
proc codec_mem_w16 |
add edx, [ctrl.codec_mem_base] |
mov word [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_r8 |
add edx, [ctrl.ctrl_mem_base] |
mov al, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r16 |
add edx, [ctrl.ctrl_mem_base] |
mov ax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r32 |
add edx, [ctrl.ctrl_mem_base] |
mov eax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_w8 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], al |
ret |
endp |
align 4 |
proc ctrl_mem_w16 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_w32 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH |
dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH |
dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH |
dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH |
dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 |
dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 |
dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 |
dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 |
dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH |
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH |
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH |
dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH |
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH |
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH |
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH |
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_ICH db '802801AA (ICH)', 13,10, 0 |
msg_ICH0 db '802801AB (ICH0)', 13,10, 0 |
msg_ICH2 db '802801BA (ICH2)', 13,10, 0 |
msg_ICH3 db '802801CA (ICH3)', 13,10, 0 |
msg_ICH4 db '802801DB (ICH4)', 13,10, 0 |
msg_ICH5 db '802801EB (ICH5)', 13,10, 0 |
msg_ICH6 db '802801FB (ICH6)', 13,10, 0 |
msg_ICH7 db '802801GB (ICH7)', 13,10, 0 |
msg_Intel db 'Intel ', 0 |
msg_NForce db 'NForce', 13,10, 0 |
msg_NForce2 db 'NForce 2', 13,10, 0 |
msg_NForce3 db 'NForce 3', 13,10, 0 |
msg_MCP04 db 'NForce MCP04',13,10, 0 |
msg_CK804 db 'NForce CK804',13,10, 0 |
msg_CK8 db 'NForce CK8', 13,10, 0 |
msg_CK8S db 'NForce CK8S', 13,10, 0 |
msg_MCP51 db 'NForce MCP51',13,10, 0 |
msg_NVidia db 'NVidia', 0 |
szKernel db 'KERNEL', 0 |
sz_sound_srv db 'SOUND',0 |
msgInit db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
;msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
;msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer ...',0 |
msgDone db 'done',13,10,0 |
msgRemap db 'Remap IRQ',13,10,0 |
;msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPciCmd db 'PCI command ',0 |
msgPciStat db 'PCI status ',0 |
msgCtrlIsaIo db 'controller io base ',0 |
msgMixIsaIo db 'codec io base ',0 |
msgCtrlMMIo db 'controller mmio base ',0 |
msgMixMMIo db 'codec mmio base ',0 |
msgIrqMap db 'AC97 irq map as ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
/kernel/tags/kolibri0.7.7.0/drivers/main.inc |
---|
0,0 → 1,164 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Serge 2006-2008 |
; email: infinity_sound@mail.ru |
PLAY_SYNC equ 0x80000000 |
PCM_ALL equ 0 |
PCM_OUT equ 0x08000000 |
PCM_RING equ 0x10000000 |
PCM_STATIC equ 0x20000000 |
PCM_FLOAT equ 0x40000000 ;reserved |
PCM_FILTER equ 0x80000000 ;reserved |
PCM_2_16_48 equ 1 |
PCM_1_16_48 equ 2 |
PCM_2_16_44 equ 3 |
PCM_1_16_44 equ 4 |
PCM_2_16_32 equ 5 |
PCM_1_16_32 equ 6 |
PCM_2_16_24 equ 7 |
PCM_1_16_24 equ 8 |
PCM_2_16_22 equ 9 |
PCM_1_16_22 equ 10 |
PCM_2_16_16 equ 11 |
PCM_1_16_16 equ 12 |
PCM_2_16_12 equ 13 |
PCM_1_16_12 equ 14 |
PCM_2_16_11 equ 15 |
PCM_1_16_11 equ 16 |
PCM_2_16_8 equ 17 |
PCM_1_16_8 equ 18 |
PCM_2_8_48 equ 19 |
PCM_1_8_48 equ 20 |
PCM_2_8_44 equ 21 |
PCM_1_8_44 equ 22 |
PCM_2_8_32 equ 23 |
PCM_1_8_32 equ 24 |
PCM_2_8_24 equ 25 |
PCM_1_8_24 equ 26 |
PCM_2_8_22 equ 27 |
PCM_1_8_22 equ 28 |
PCM_2_8_16 equ 29 |
PCM_1_8_16 equ 30 |
PCM_2_8_12 equ 31 |
PCM_1_8_12 equ 32 |
PCM_2_8_11 equ 33 |
PCM_1_8_11 equ 34 |
PCM_2_8_8 equ 35 |
PCM_1_8_8 equ 36 |
SRV_GETVERSION equ 0 |
SND_CREATE_BUFF equ 1 |
SND_DESTROY_BUFF equ 2 |
SND_SETFORMAT equ 3 |
SND_GETFORMAT equ 4 |
SND_RESET equ 5 |
SND_SETPOS equ 6 |
SND_GETPOS equ 7 |
SND_SETBUFF equ 8 |
SND_OUT equ 9 |
SND_PLAY equ 10 |
SND_STOP equ 11 |
SND_SETVOLUME equ 12 |
SND_GETVOLUME equ 13 |
SND_SETPAN equ 14 |
SND_GETPAN equ 15 |
SND_GETBUFFSIZE equ 16 |
SND_GETFREESPACE equ 17 |
struc STREAM |
{ |
.magic dd ? ;'WAVE' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.size dd ? |
.str_fd dd ? |
.str_bk dd ? |
.device dd ? |
.format dd ? |
.flags dd ? |
.out_base dd ? |
.out_wp dd ? |
.out_rp dd ? |
.out_count dd ? |
.out_top dd ? ;16*4 |
.r_size dd ? |
.r_dt dd ? |
.r_silence dd ? |
.resample dd ? |
.l_vol dd ? |
.r_vol dd ? |
.l_amp dw ? |
.r_amp dw ? |
.pan dd ? |
.l_amp_f dd ? ;float point left |
.r_amp_f dd ? ;float point right |
.in_base dd ? |
.in_size dd ? |
.in_wp dd ? |
.in_rp dd ? |
.in_count dd ? |
.in_free dd ? |
.in_top dd ? |
.notify_event dd ? |
.notify_id dd ? |
} |
STREAM_SIZE equ 36*4 |
FD_OFFSET equ 24 |
virtual at 0 |
STREAM STREAM |
end virtual |
struc WAVE_HEADER |
{ .riff_id dd ? |
.riff_size dd ? |
.riff_format dd ? |
.fmt_id dd ? |
.fmt_size dd ? |
.format_tag dw ? |
.channels dw ? |
.freq dd ? |
.bytes_sec dd ? |
.block_align dw ? |
.bits_sample dw ? |
.data_id dd ? |
.data_size dd ? |
} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/vmode.asm |
---|
0,0 → 1,736 |
; |
; MenuetOS Driver (vmode.mdr) |
; Target: Vertical Refresh Rate programming and videomode changing |
; |
; Author: Trans <<<<<13>>>>> |
; Date: 20.07.2003 |
; |
; Version: 1.0 |
; OS: MenuetOS |
; Compiler: FASM |
; |
OS_BASE equ 0x80000000 |
use32 |
macro align value { rb (value-1) - ($ + value-1) mod value } |
org OS_BASE+0x0328000 |
headerstart=$ |
mdid db 'MDAZ' ; 4 byte id |
mdhver dd 0x00 ; header version |
mdcode dd MDSTART ; start of code |
mdver dd 0x00000001 ; driver version (subversion*65536+version) |
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name |
times (32-($-mdname)) db ' ' ; |
headerlen=$-headerstart |
times (256-headerlen) db 0 ; reserved area for future |
MDSTART: ; start of driver code ( base_adr+256 bytes) |
; ebx(=ecx in program): |
; 1 - Get DriverInfo and Driver Initial Set |
; 2 - Get Current Video Mode With Vertical Refresh Rate |
; 3 - Change Video Mode |
; 4 - Return at Start System Video Mode |
; 5 - Change vertical and horizontal size of visible screen area |
; 6 - Change Vert/Hor position visible area on screen (not complete yet) |
; |
; MAXF - ... |
MAXF=5 |
;-------Main Manager------------- |
pushad |
cmp ebx,1 |
jb mdvm_00 |
cmp ebx,MAXF |
ja mdvm_00 |
shl ebx,2 |
add ebx,mdvm_func_table |
call dword [ebx] |
mov [esp+28],eax |
mov [esp+24],ecx |
mov [esp+20],edx |
mov [esp+16],ebx |
popad |
retn |
mdvm_00: |
popad |
xor eax,eax |
dec eax |
retn |
; ------Drivers Functions---------- |
align 4 |
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
; |
vm_info_init: |
push ecx |
cmp [mdrvm],dword 0 |
jnz .vmii_00 |
call vm_safe_reg |
call vm_get_initial_videomode |
mov eax,[initvm] |
mov [currvm],eax |
call vm_search_sys_func_table |
call vm_get_cur_vert_rate |
mov [initrr],eax |
call vm_calc_pixelclock |
call vm_calc_refrate |
inc [mdrvm] |
.vmii_00: |
pop ecx |
call vm_transfer_drv_info |
mov ebx,dword [refrate] |
mov eax,dword [mdid] ;dword [systlb] |
retn |
align 4 |
; EBX=2 (in applications ECX=2)- Get Current Video Mode |
; |
; OUT: eax = X_screen*65536+Y_screen |
; ebx = current vertical rate |
; ecx = current video mode (number) |
vm_get_cur_mode: |
cmp [mdrvm],dword 0 |
jz .vmgcm_00 |
call vm_get_cur_vert_rate |
mov eax,[OS_BASE+0FE00h] |
mov ebx,[OS_BASE+0FE04h] |
shl eax,16 |
add eax,ebx |
add eax,00010001h |
mov ebx,[refrate] |
mov ecx,[currvm] |
retn |
.vmgcm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=3 (in applications ECX=3)- Change Video Mode |
; |
; IN: ecx = VertRate*65536+VideoMode |
; OUT: eax = 0 if no error |
; |
vm_set_video_mode: |
cmp [mdrvm],dword 0 |
jz .vmsvm_00 |
call vm_set_selected_mode |
; xor eax,eax |
retn |
.vmsvm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode |
; |
; IN: |
; OUT: eax = = 0 if no error |
; |
vm_restore_init_video_mode: |
cmp [mdrvm],dword 0 |
jz .vmrivm_00 |
call vm_restore_reg |
xor eax,eax |
retn |
.vmrivm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size |
; of visible screen area |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position |
; = 2/3 - -/+ vertical size on 1 position (8 pixels) |
; ^-^----- not complete yet |
; OUT: eax = = 0 if no error |
; |
vm_change_screen_size: |
cmp [mdrvm],dword 0 |
jz .vmcss_00 |
cmp cl,1 |
ja .vmcss_01 |
mov eax,ecx |
call vm_inc_dec_width |
xor eax,eax |
retn |
.vmcss_01: |
and ecx,01h |
mov eax,ecx |
; call vm_inc_dec_high ; not complete yet |
xor eax,eax |
retn |
.vmcss_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen |
; |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point |
; = 2/3 - -/+ vertical position on 1 pixel |
; ^-^----- not complete yet |
; OUT: eax = 0 if no error |
; |
vm_change_position_screen: |
cmp [mdrvm],dword 0 |
jz .vmcps_00 |
; ... |
xor eax,eax |
retn |
.vmcps_00: |
xor eax,eax |
dec eax |
retn |
;-----Drivers Subfunctions--------- |
; |
; Searching i40 system functions pointer table in kernel area location |
; |
vm_search_sys_func_table: |
push eax ; eax - current value |
push ecx ; ecx - will be counter of equevalent value |
push edx ; edx - last value |
push esi ; esi - current address |
xor ecx,ecx |
mov esi,OS_BASE+010000h ; Start address of kernel location |
lodsd |
mov edx,eax |
cld |
.vmssft_00: |
cmp esi,OS_BASE+30000h |
ja .vmssft_03 |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
je .vmssft_00 |
cmp ecx,128 |
ja .vmssft_02 |
.vmssft_01: |
xor ecx,ecx |
jmp .vmssft_00 |
.vmssft_02: |
cmp edx,0 |
je .vmssft_01 |
sub esi,256*4-1 |
mov [systlb],esi |
xor ecx,ecx |
.vmssft_03_0: |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
jne .vmssft_03_0 |
mov esi,dword [systlb] |
cmp cx,60 |
jae .vmssft_03 |
add esi,256*4-4 |
lodsb |
mov edx,eax |
jmp .vmssft_01 |
.vmssft_03: |
mov [systlb],esi |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
; IN: |
; OUT: eax= vertical rate in Hz |
vm_get_cur_vert_rate: |
push edx |
push ebx |
xor eax,eax |
mov edx,eax |
mov ebx,eax |
mov dx,03DAh |
.vmgcvt_00: |
in al,dx |
test al,8 |
jz .vmgcvt_00 |
.vmgcvt_01: |
in al,dx |
test al,8 |
jnz .vmgcvt_01 |
mov ebx,edx |
rdtsc |
mov edx,ebx |
mov ebx,eax |
.vmgcvt_02: |
in al,dx |
test al,8 |
jz .vmgcvt_02 |
.vmgcvt_03: |
in al,dx |
test al,8 |
jnz .vmgcvt_03 |
rdtsc |
sub eax,ebx |
mov ebx,eax |
mov eax,[OS_BASE+0F600h] |
xor edx,edx |
div ebx |
inc eax |
mov [refrate],eax |
pop ebx |
pop edx |
retn |
vm_calc_pixelclock: |
push ebx |
push edx |
xor eax,eax |
mov al,[_00] |
add ax,5 |
shl eax,3 |
xor ebx,ebx |
mov bl,[_06] |
mov bh,[_07] |
and bh,00100001b |
btr bx,13 |
jnc .vmcpc_00 |
or bh,2 |
.vmcpc_00: |
xor edx,edx |
mul ebx |
xor edx,edx |
mul [initrr] |
mov [pclock],eax |
pop edx |
pop ebx |
retn |
; |
; Safe of initial CRTC state |
; |
vm_safe_reg: |
push edx |
push ebx |
push ecx |
push edi |
cli |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al ; Clear protection bit |
dec dx |
xor ecx,ecx |
mov cl,19h |
xor bl,bl |
mov edi,CRTCreg |
.vmsr_00: |
mov al,bl |
out dx,al |
inc dx |
in al,dx |
dec dx |
stosb |
inc bl |
loop .vmsr_00 |
sti |
pop edi |
pop ecx |
pop ebx |
pop edx |
retn |
; |
; Restore of initial CRTC state |
; |
vm_restore_reg: |
push eax |
push ebx |
push edx |
push esi |
mov eax,[oldX] |
mov [OS_BASE+0FE00h],eax |
mov eax,[oldY] |
mov [OS_BASE+0FE04h],eax |
mov dx,03dah |
.vmrr_00: |
in al,dx |
test al,8 |
jnz .vmrr_00 |
.vmrr_01: |
in al,dx |
test al,8 |
jnz .vmrr_01 |
cli |
mov dx,03c4h |
mov ax,0101h |
out dx,ax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor ecx,ecx |
mov cl,19h |
mov esi,CRTCreg |
xor bl,bl |
.vmrr_02: |
lodsb |
mov ah,al |
mov al,bl |
out dx,ax |
inc bl |
loop .vmrr_02 |
sti |
; call ref_screen |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
; Calculate of possible vertical refrash rate |
; (light version of function) |
vm_calc_refrate: |
push ebx |
push ecx |
push edx |
push edi |
push esi |
mov eax,[pclock] |
xor edx,edx |
mov edi,_m1 |
mov ebx,eax |
mov ecx,(1696*1065) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1344*804) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1056*636) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(800*524) |
div ecx |
xor edx,edx |
stosw |
mov edi,_m1 |
mov esi,edi |
mov ecx,5*4 |
.vmcrr_00: |
lodsw |
cmp ax,55 |
jb .vmcrr_01 |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
.vmcrr_01: |
xor ax,ax |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
vm_get_initial_videomode: |
push eax |
mov eax,dword [OS_BASE+0FE00h] |
mov [oldX],eax |
mov eax,dword [OS_BASE+0FE04h] |
mov [oldY],eax |
mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode |
and ax,01FFh |
mov dword [initvm],eax |
pop eax |
retn |
; IN: eax = 0/1 - -/+ 1 position of width |
vm_inc_dec_width: |
push ebx |
push edx |
mov ebx,eax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor al,al |
out dx,al |
inc dx |
in al,dx |
dec al |
cmp bl,0 |
jnz .vmidr_00 |
inc al |
inc al |
.vmidr_00: |
out dx,al |
pop edx |
pop ebx |
retn |
; |
; Copy driver info to application area |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
vm_transfer_drv_info: |
push ecx |
push edi |
push esi |
mov eax,ecx |
xor ecx,ecx |
mov cl,32/4 |
mov esi,mdname |
mov edi,drvname |
rep movsd |
mov ecx,eax |
mov eax,[mdver] |
mov [drvver],eax |
mov edi,[OS_BASE+3010h] |
mov edi,[edi+10h] |
add edi,ecx |
mov esi,drvinfo |
xor ecx,ecx |
mov cx,512 |
rep movsb |
pop esi |
pop edi |
pop ecx |
retn |
; |
; Set selected video mode |
; (light version) |
; |
; IN: ecx = VertRate*65536+VideoMode |
; |
vm_set_selected_mode: |
push edx |
push ecx |
push esi |
ror ecx,16 |
cmp cx,00h |
je .vmssm_03 |
rol ecx,16 |
mov eax,ecx |
shl eax,16 |
shr eax,16 |
mov [currvm],eax |
cmp cx,112h |
jne .vmssm_00 |
mov esi,mode0 |
mov ecx,639 |
mov edx,479 |
jmp .vmssm_st00 |
.vmssm_00: |
cmp cx,115h |
jne .vmssm_01 |
mov esi,mode1 |
mov ecx,799 |
mov edx,599 |
jmp .vmssm_st00 |
.vmssm_01: |
cmp cx,118h |
jne .vmssm_02 |
mov esi,mode2 |
mov ecx,1023 |
mov edx,767 |
jmp .vmssm_st00 |
.vmssm_02: |
cmp cx,11Bh |
jne .vmssm_03 |
mov esi,mode2 |
mov ecx,1279 |
mov edx,1023 |
jmp .vmssm_st00 |
.vmssm_03: |
xor eax,eax |
dec eax |
pop esi |
pop ecx |
pop edx |
retn |
.vmssm_st00: |
mov [OS_BASE+0FE00h],ecx |
mov [OS_BASE+0FE04h],edx |
cli |
mov dx,03c4h |
lodsw |
out dx,ax |
mov dx,03d4h |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al |
dec dx |
mov ecx,13 |
.vmssm_st01: |
lodsw |
out dx,ax |
loop .vmssm_st01 |
sti |
xor eax,eax |
pop esi |
pop ecx |
pop edx |
retn |
;------------DATA AREA--------------- |
align 4 |
mdvm_func_table: |
dd MDSTART |
dd vm_info_init, vm_get_cur_mode |
dd vm_set_video_mode, vm_restore_init_video_mode |
dd vm_change_screen_size, vm_change_position_screen |
CRTCreg: |
_00 db ? |
_01 db ? |
_02 db ? |
_03 db ? |
_04 db ? |
_05 db ? |
_06 db ? |
_07 db ? |
_08 db ? |
_09 db ? |
_0a db ? |
_0b db ? |
_0c db ? |
_0d db ? |
_0e db ? |
_0f db ? |
_10 db ? |
_11 db ? |
_12 db ? |
_13 db ? |
_14 db ? |
_15 db ? |
_16 db ? |
_17 db ? |
_18 db ? |
_19 db ? |
align 4 |
oldX dd ? |
oldY dd ? |
initvm dd ? |
currvm dd 0 |
refrate dd 0 |
initrr dd 0 |
systlb dd 0 |
pclock dd ? |
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init |
drvinfo: |
drvname: times 32 db ' ' |
drvver dd 0 |
times (32-($-drvver))/4 dd 0 |
drvmode dw 011Bh,0118h,0115h,0112h |
times (64-($-drvmode))/2 dw 00h |
_m1 dw 0,0,0,0,0 |
_m2 dw 0,0,0,0,0 |
_m3 dw 0,0,0,0,0 |
_m4 dw 0,0,0,0,0 |
_m5 dw 0,0,0,0,0 |
times (512-($-drvinfo)) db 0 |
drvinfoend: |
;1280x1024 - 11Bh |
mode3: |
dw 0101h |
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h |
dw 0110h,8411h,0ff12h,0ff15h,2916h |
;1024x768 - 118h |
mode2: |
dw 0101h |
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h |
dw 0310h,8911h,0ff12h,0ff15h,2516h |
;800x600 - 115h |
mode1: |
dw 0101h |
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h |
dw 5910h,8d11h,5712h,5715h,7316h |
;640x480 - 112h, 12h |
mode0: |
dw 0101h |
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h |
dw 0ea10h,8c11h,0df12h,0df15h,0c16h |
; 640x400 |
;mymode0: |
; dw 0101h |
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h |
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h |
; 640x800 |
;mymode1: |
; dw 0101h |
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h |
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h |
DRVM_END: |
/kernel/tags/kolibri0.7.7.0/drivers/codec.inc |
---|
0,0 → 1,283 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
AD_LOSEL equ BIT5 |
AD_HPSEL equ BIT10 |
align 4 |
proc detect_codec |
locals |
codec_id dd ? |
endl |
stdcall codec_read, dword 0x7C |
shl eax, 16 |
mov [codec_id], eax |
stdcall codec_read, dword 0x7E |
or eax, [codec_id] |
mov [codec.chip_id], eax |
and eax, 0xFFFFFF00 |
mov edi, codecs |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .unknown |
cmp eax, ebx |
jne .next |
mov eax, [edi+4] |
mov [codec.ac_vendor_ids], eax |
mov esi, eax |
call SysMsgBoardStr |
stdcall detect_chip, [edi+8] |
ret |
.next: |
add edi, 12 |
jmp @B |
.unknown: |
mov [codec.ac_vendor_ids], ac_unknown |
mov [codec.chip_ids], chip_unknown |
mov esi, chip_unknown |
call SysMsgBoardStr |
mov eax, [codec.chip_id] |
call dword2str |
call SysMsgBoardStr |
ret |
endp |
align 4 |
proc detect_chip stdcall, chip_tab:dword |
mov eax, [codec.chip_id] |
and eax, 0xFF |
mov edi, [chip_tab] |
@@: |
mov ebx, [edi] |
cmp ebx, 0xFF |
je .unknown |
cmp eax,ebx |
jne .next |
mov eax, [edi+4] |
mov [codec.chip_ids], eax |
mov esi, eax |
call SysMsgBoardStr |
ret |
.next: |
add edi, 8 |
jmp @b |
.unknown: |
mov [codec.chip_ids], chip_unknown |
mov esi, chip_unknown |
call SysMsgBoardStr |
mov eax, [codec.chip_id] |
call dword2str |
call SysMsgBoardStr |
ret |
endp |
align 4 |
proc setup_codec |
xor eax, eax |
stdcall codec_write, dword CODEC_AUX_VOL |
mov eax, 0x0B0B |
stdcall codec_write, dword CODEC_MASTER_VOL_REG |
mov ax, 0x08 |
stdcall codec_write, dword 0x0C |
mov ax, 0x0808 |
stdcall codec_write, dword CODEC_PCM_OUT_REG |
mov ax, 0x0808 |
stdcall codec_write, dword 0x10 |
mov ax, 0x0808 |
stdcall codec_write, dword 0x12 |
mov ax, 0x0808 |
stdcall codec_write, dword 0x16 |
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG |
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1) |
or eax, BIT0 ; set VRA (BIT0) |
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG |
stdcall set_sample_rate, dword 48000 |
.init_error: |
xor eax, eax ; exit with error |
ret |
endp |
; param |
; eax= volume -10000 - 0 for both channels |
align 4 |
set_master_vol: |
cmp eax, 0 |
jl @F |
xor eax, eax |
jmp .set |
@@: |
cmp eax, -9450 |
jg .set |
mov eax, -9450 ;clamp into 6 bits |
.set: |
cdq |
mov ebx, -150 |
idiv ebx |
mov ah, al |
stdcall codec_write, dword CODEC_MASTER_VOL_REG |
xor eax, eax |
ret |
align 4 |
proc get_master_vol stdcall, pvol:dword |
stdcall codec_read, dword CODEC_MASTER_VOL_REG |
and eax, 0x3F |
imul eax, -150 |
mov ebx, [pvol] |
mov [ebx], eax |
xor eax, eax |
ret |
endp |
align 4 |
proc set_sample_rate stdcall, rate:dword |
mov eax, [rate] |
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG |
ret |
endp |
patch_AD: |
stdcall codec_read, 0x76 |
or ax, BIT5+BIT10 |
stdcall codec_write, 0x76 |
ret |
align 16 |
ac_unknown db 'unknown manufacturer',13,10,0 |
ac_Realtek db 'Realtek Semiconductor',13,10,0 |
ac_Analog db 'Analog Devices',13,10,0 |
ac_CMedia db 'C-Media Electronics',13,10,0 |
ac_Cirrus db 'Cirrus Logic',13,10,0 |
chip_unknown db 'unknown codec id ', 0 |
CHIP_ANALOG equ 0x41445300 |
CHIP_REALTEK equ 0x414C4700 |
CHIP_CMEDIA equ 0x434D4900 |
CHIP_CIRRUS equ 0x43525900 |
align 16 |
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog |
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia |
dd CHIP_REALTEK,ac_Realtek, chips_Realtek |
dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus |
dd 0 |
align 16 |
chips_Analog dd 0x03, chip_AD1819 |
dd 0x40, chip_AD1881 |
dd 0x48, chip_AD1881A |
dd 0x60, chip_AD1884 |
dd 0x61, chip_AD1886 |
dd 0x62, chip_AD1887 |
dd 0x63, chip_AD1886A |
dd 0x70, chip_AD1980 |
dd 0x75, chip_AD1985 |
dd 0xFF |
chips_Realtek: |
dd 0x20, chip_ALC650 |
dd 0x21, chip_ALC650D |
dd 0x22, chip_ALC650E |
dd 0x23, chip_ALC650F |
dd 0x60, chip_ALC655 |
dd 0x80, chip_ALC658 |
dd 0x81, chip_ALC658D |
dd 0x90, chip_ALC850 |
dd 0xFF |
chips_CMedia dd 0x41, chip_CM9738 |
dd 0x61, chip_CM9739 |
dd 0x69, chip_CM9780 |
dd 0x78, chip_CM9761 |
dd 0x82, chip_CM9761 |
dd 0x83, chip_CM9761 |
dd 0xFF |
chips_Cirrus dd 0x00, chip_CS4297 |
dd 0x10, chip_CS4297A |
dd 0x20, chip_CS4298 |
dd 0x28, chip_CS4294 |
dd 0x30, chip_CS4299 |
dd 0x34, chip_CS4299D |
dd 0x48, chip_CS4201 |
dd 0x58, chip_CS4205 |
dd 0x60, chip_CS4291 |
dd 0x70, chip_CS4202 |
dd 0xFF |
align 16 |
;Analog Devices |
chip_AD1819 db 'AD1819 ',0dh,0ah,00h |
chip_AD1881 db 'AD1881 ',0dh,0ah,00h |
chip_AD1881A db 'AD1881A',0dh,0ah,00h |
chip_AD1884 db 'AD1885 ',0dh,0ah,00h |
chip_AD1885 db 'AD1885 ',0dh,0ah,00h |
chip_AD1886 db 'AD1886 ',0dh,0ah,00h |
chip_AD1886A db 'AD1886A',0dh,0ah,00h |
chip_AD1887 db 'AD1887 ',0dh,0ah,00h |
chip_AD1980 db 'AD1980 ',0dh,0ah,00h |
chip_AD1985 db 'AD1985 ',0dh,0ah,00h |
;Realtek |
chip_ALC650 db 'ALC650 ',0dh,0ah,00h |
chip_ALC650D db 'ALC650D',0dh,0ah,00h |
chip_ALC650E db 'ALC650E',0dh,0ah,00h |
chip_ALC650F db 'ALC650F',0dh,0ah,00h |
chip_ALC655 db 'ALC655 ',0dh,0ah,00h |
chip_ALC658 db 'ALC658 ',0dh,0ah,00h |
chip_ALC658D db 'ALC658D',0dh,0ah,00h |
chip_ALC850 db 'ALC850 ',0dh,0ah,00h |
;CMedia |
chip_CM9738 db 'CMI9738', 0dh,0ah,0 |
chip_CM9739 db 'CMI9739', 0dh,0ah,0 |
chip_CM9780 db 'CMI9780', 0dh,0ah,0 |
chip_CM9761 db 'CMI9761', 0dh,0ah,0 |
;Cirrus |
chip_CS4297 db 'CS4297',13,10,0 |
chip_CS4297A db 'CS4297A',13,10,0 |
chip_CS4298 db 'CS4298',13,10,0 |
chip_CS4294 db 'CS4294',13,10,0 |
chip_CS4299 db 'CS4299',13,10,0 |
chip_CS4299D db 'CS4299D',13,10,0 |
chip_CS4201 db 'CS4201',13,10,0 |
chip_CS4205 db 'CS4205',13,10,0 |
chip_CS4291 db 'CS4291',13,10,0 |
chip_CS4202 db 'CS4202',13,10,0 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/usb/urb.inc |
---|
0,0 → 1,115 |
struc URB |
{ |
.fd dd ? |
.bk dd ? |
.dev dd ? ; pointer to associated device |
.pipe dd ? ; pipe information |
.status dd ? ; non-ISO status |
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ... |
.transfer_buffer dd ? ; associated data buffer |
.transfer_dma dd ? ; dma addr for transfer_buffer |
.transfer_buffer_length dd ? ; data buffer length |
.actual_length dd ? ; actual transfer length |
.setup_packet dd ? ; setup packet (control only) |
.setup_dma dd ? ; dma addr for setup_packet |
.start_frame dd ? ; start frame (ISO) |
.number_of_packets dd ? ; number of ISO packets |
.interval dd ? ; transfer interval |
.error_count dd ? ; number of ISO errors |
.context dd ? ; context for completion |
.complete dd ? ; (in) completion routine |
.iso_frame_desc: |
} |
virtual at 0 |
URB URB |
end virtual |
struc REQ ;usb request |
{ |
.request_type db ? |
.request db ? |
.value dw ? |
.index dw ? |
.length dw ? |
} |
virtual at 0 |
REQ REQ |
end virtual |
align 4 |
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\ |
requesttype:dword, value:dword, index:dword,\ |
data:dword, size:dword, timeout:dword |
locals |
req REQ |
endl |
lea eax, [req] |
mov ecx, [request] |
mov ebx, [requesttupe] |
mov edx, [value] |
mov esi, [index] |
mov edi, [size] |
mov [eax+REQ.request_type], bl |
mov [eax+REQ.request], cl |
mov [eax+REQ.value], dx |
mov [eax+REQ.index], si |
mov [eax+REQ.length], di |
stdcall usb_internal_control_msg, [dev], [pipe],\ |
eax, [data], [size], [timeout] |
ret |
endp |
; returns status (negative) or length (positive) |
static int usb_internal_control_msg(struct usb_device *usb_dev, |
unsigned int pipe, |
struct usb_ctrlrequest *cmd, |
void *data, int len, int timeout) |
{ |
struct urb *urb; |
int retv; |
int length; |
urb = usb_alloc_urb(0, GFP_NOIO); |
if (!urb) |
return -ENOMEM; |
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, |
len, usb_api_blocking_completion, NULL); |
retv = usb_start_wait_urb(urb, timeout, &length); |
if (retv < 0) |
return retv; |
else |
return length; |
} |
void usb_fill_control_urb (struct urb *urb, |
struct usb_device *dev, |
unsigned int pipe, |
unsigned char *setup_packet, |
void *transfer_buffer, |
int buffer_length, |
usb_complete_t complete_fn, |
void *context) |
{ |
urb->dev = dev; |
urb->pipe = pipe; |
urb->setup_packet = setup_packet; |
urb->transfer_buffer = transfer_buffer; |
urb->transfer_buffer_length = buffer_length; |
urb->complete = complete_fn; |
urb->context = context; |
} |
/kernel/tags/kolibri0.7.7.0/drivers/usb/usb.asm |
---|
0,0 → 1,435 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;driver sceletone |
format MS COFF |
API_VERSION equ 0 ;debug |
include '../proc32.inc' |
include '../imports.inc' |
include 'urb.inc' |
struc UHCI |
{ |
.bus dd ? |
.devfn dd ? |
.io_base dd ? |
.mm_base dd ? |
.irq dd ? |
.flags dd ? |
.reset dd ? |
.start dd ? |
.stop dd ? |
.port_c_suspend dd ? |
.resuming_ports dd ? |
.rh_state dd ? |
.rh_numports dd ? |
.is_stopped dd ? |
.dead dd ? |
.sizeof: |
} |
virtual at 0 |
UHCI UHCI |
end virtual |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
struc TD ;transfer descriptor |
{ |
.link dd ? |
.status dd ? |
.token dd ? |
.buffer dd ? |
.addr dd ? |
.frame dd ? |
.fd dd ? |
.bk dd ? |
.sizeof: |
} |
virtual at 0 |
TD TD |
end virtual |
public START |
public service_proc |
public version |
DEBUG equ 1 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
STRIDE equ 4 ;size of row in devices table |
SRV_GETVERSION equ 0 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
.entry: |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call init |
stdcall RegService, my_service, service_proc |
ret |
.fail: |
.exit: |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc detect |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, STRIDE |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov eax, UHCI.sizeof |
call Kmalloc |
test eax, eax |
jz .mem_fail |
mov ebx, [bus] |
mov [eax+UHCI.bus], ebx |
mov ecx, [devfn] |
mov [eax+UHCI.devfn], ecx |
ret |
.mem_fail: |
if DEBUG |
mov esi, msgMemFail |
call SysMsgBoardStr |
end if |
.err: |
xor eax, eax |
ret |
endp |
PCI_BASE equ 0x20 |
USB_LEGKEY equ 0xC0 |
align 4 |
proc init |
locals |
uhci dd ? |
endl |
call detect |
test eax, eax |
jz .fail |
mov [uhci], eax |
stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE |
and eax, 0xFFC0 |
mov esi, [uhci] |
mov [esi+UHCI.io_base], eax |
stdcall uhci_reset, esi |
stdcall finish_reset, [uhci] |
.fail: |
if DEBUG |
mov esi, msgDevNotFound |
call SysMsgBoardStr |
end if |
ret |
endp |
UHCI_USBINTR equ 4 ; interrupt register |
UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits |
UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits |
UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit |
UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset |
UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode |
UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag |
UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable |
PORTSC0 equ 0x10 |
PORTSC1 equ 0x12 |
UHCI_RH_RESET equ 0 |
UHCI_RH_SUSPENDED equ 1 |
UHCI_RH_AUTO_STOPPED equ 2 |
UHCI_RH_RESUMING equ 3 |
; In this state the HC changes from running to halted |
; so it can legally appear either way. |
UHCI_RH_SUSPENDING equ 4 |
; In the following states it's an error if the HC is halted. |
; These two must come last. |
UHCI_RH_RUNNING equ 5 ; The normal state |
UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices |
UHCI_IS_STOPPED equ 9999 |
align 4 |
proc uhci_reset stdcall, uhci:dword |
mov esi, [uhci] |
stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY |
test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC) |
jnz .reset |
mov edx, [esi+UHCI.io_base] |
in ax, dx |
test ax, UHCI_USBCMD_RUN |
jnz .reset |
test ax, UHCI_USBCMD_CONFIGURE |
jz .reset |
test ax, UHCI_USBCMD_EGSM |
jz .reset |
add edx, UHCI_USBINTR |
in ax, dx |
test ax, not UHCI_USBINTR_RESUME |
jnz .reset |
ret |
.reset: |
stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC |
mov edx, [esi+UHCI.io_base] |
mov ax, UHCI_USBCMD_HCRESET |
out dx, ax |
xor eax, eax |
out dx, ax |
add edx, UHCI_USBINTR |
out dx, ax |
ret |
endp |
proc finish_reset stdcall, uhci:dword |
mov esi, [uhci] |
mov edx, [esi+UHCI.io_base] |
add edx, PORTSC0 |
xor eax, eax |
out dx, ax |
add edx, (PORTSC1-PORTSC0) |
out dx, ax |
mov [esi+UHCI.port_c_suspend], eax |
mov [esi+UHCI.resuming_ports], eax |
mov [esi+UHCI.rh_state], UHCI_RH_RESET |
mov [esi+UHCI.rh_numports], 2 |
mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED |
; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT; |
; uhci_to_hcd(uhci)->poll_rh = 0; |
mov [esi+UHCI.dead], eax ; Full reset resurrects the controller |
ret |
endp |
proc insert_td stdcall, td:dword, frame:dword |
mov edi, [td] |
mov eax, [frame] |
and eax, -1024 |
mov [edi+TD.frame], eax |
mov ebx, [framelist] |
mov edx, [dma_framelist] |
shl eax, 5 |
mov ecx, [eax+ebx] |
test ecx, ecx |
jz .empty |
mov ecx, [ecx+TD.bk] ;last TD |
mov edx, [ecx+TD.fd] |
mov [edi+TD.fd], edx |
mov [edi+TD.bk], ecx |
mov [ecx+TD.fd], edi |
mov [edx+TD.bk], edi |
mov eax, [ecx+TD.link] |
mov [edi+TD.link], eax |
mov ebx, [edi+TD.addr] |
mov [ecx+TD.link], ebx |
ret |
.empty: |
mov ecx, [eax+edx] |
mov [edi+TD.link], ecx |
mov [ebx+eax], edi |
mov ecx, [edi+TD.addr] |
mov [eax+edx], ecx |
ret |
endp |
align 4 |
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\ |
buf:dword, size:dword |
locals |
count dd ? |
endl |
mov esi, [buf] |
mov ecx, [size] |
xor eax, eax |
cld |
rep stosb |
mov [count], 3 |
@@: |
mov eax, [type] |
shl eax, 8 |
add eax, [index] |
stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\ |
USB_DIR_IN, eax,0,[buf], [size],\ |
USB_CTRL_GET_TIMEOUT |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
jmp. ok |
.next: |
dec [count] |
jnz @B |
mov eax, -1 |
.ok: |
ret |
endp |
DEVICE_ID equ 0x24D2 ; pci device id |
VENDOR_ID equ 0x8086 ; device vendor id |
QEMU_USB equ 0x7020 |
;all initialized data place here |
align 4 |
devices dd (DEVICE_ID shl 16)+VENDOR_ID |
dd (QEMU_USB shl 16)+VENDOR_ID |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
my_service db 'UHCI',0 ;max 16 chars include zero |
msgInit db 'detect hardware...',13,10,0 |
msgPCI db 'PCI accsess not supported',13,10,0 |
msgDevNotFound db 'device not found',13,10,0 |
msgMemFail db 'Kmalloc failed', 10,10,0 |
;msgFail db 'device not found',13,10,0 |
section '.data' data readable writable align 16 |
;all uninitialized data place here |
/kernel/tags/kolibri0.7.7.0/drivers/usb |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/drivers/mix_mmx.inc |
---|
0,0 → 1,247 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; params |
; edi= output |
; eax= input stream 1 |
; ebx= input stream 2 |
if used mmx_mix_2 |
align 4 |
mmx_mix_2: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
movq [edi], mm0 |
paddsw mm1,[ebx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ebx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ebx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ebx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ebx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ebx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ebx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ebx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ebx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ebx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ebx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edx+104], mm5 |
paddsw mm6, [ebx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ebx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_3: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
paddsw mm1, [ebx+8] |
paddsw mm2, [ebx+16] |
paddsw mm3, [ebx+24] |
paddsw mm4, [ebx+32] |
paddsw mm5, [ebx+40] |
paddsw mm6, [ebx+48] |
paddsw mm7, [ebx+56] |
paddsw mm0, [ecx] |
movq [edi], mm0 |
paddsw mm1,[ecx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ecx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ecx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ecx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ecx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ecx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ecx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
paddsw mm1, [ebx+72] |
paddsw mm2, [ebx+80] |
paddsw mm3, [ebx+88] |
paddsw mm4, [ebx+96] |
paddsw mm5, [ebx+104] |
paddsw mm6, [ebx+112] |
paddsw mm7, [ebx+120] |
paddsw mm0, [ecx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ecx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ecx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ecx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ecx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edi+104], mm5 |
paddsw mm6, [ecx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ecx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_4: |
movq mm0, [eax] |
movq mm2, [eax+8] |
movq mm4, [eax+16] |
movq mm6, [eax+24] |
movq mm1, [ebx] |
movq mm3, [ebx+8] |
movq mm5, [ebx+16] |
movq mm7, [ebx+24] |
paddsw mm0, [ecx] |
paddsw mm2, [ecx+8] |
paddsw mm4, [ecx+16] |
paddsw mm6, [ecx+24] |
paddsw mm1, [edx] |
paddsw mm3, [edx+8] |
paddsw mm5, [edx+16] |
paddsw mm7, [edx+24] |
paddsw mm0, mm1 |
movq [edi], mm0 |
paddsw mm2, mm3 |
movq [edi+8], mm2 |
paddsw mm4, mm5 |
movq [edi+16], mm4 |
paddsw mm5, mm6 |
movq [edi+24], mm6 |
movq mm0, [eax+32] |
movq mm2, [eax+40] |
movq mm4, [eax+48] |
movq mm6, [eax+56] |
movq mm1, [ebx+32] |
movq mm3, [ebx+40] |
movq mm5, [ebx+48] |
movq mm7, [ebx+56] |
paddsw mm0, [ecx+32] |
paddsw mm2, [ecx+40] |
paddsw mm4, [ecx+48] |
paddsw mm6, [ecx+56] |
paddsw mm1, [edx+32] |
paddsw mm3, [edx+40] |
paddsw mm5, [edx+48] |
paddsw mm7, [edx+56] |
paddsw mm0, mm1 |
movq [edi+32], mm0 |
paddsw mm2, mm2 |
movq [edi+40], mm2 |
paddsw mm4, mm5 |
movq [edi+48], mm4 |
paddsw mm6, mm7 |
movq [edi+56], mm6 |
movq mm0, [eax+64] |
movq mm2, [eax+72] |
movq mm4, [eax+80] |
movq mm6, [eax+88] |
movq mm1, [ebx+64] |
movq mm3, [ebx+72] |
movq mm5, [ebx+80] |
movq mm7, [ebx+88] |
paddsw mm0, [ecx+64] |
paddsw mm2, [ecx+72] |
paddsw mm4, [ecx+80] |
paddsw mm6, [ecx+88] |
paddsw mm1, [edx+64] |
paddsw mm3, [edx+72] |
paddsw mm5, [edx+80] |
paddsw mm7, [edx+88] |
paddsw mm0, mm1 |
movq [edi+64], mm0 |
paddsw mm2, mm3 |
movq [edi+72], mm2 |
paddsw mm4, mm5 |
movq [edi+80], mm4 |
paddsw mm6, mm5 |
movq [edi+88], mm7 |
movq mm0, [eax+96] |
movq mm2, [eax+104] |
movq mm4, [eax+112] |
movq mm6, [eax+120] |
movq mm1, [ebx+96] |
movq mm3, [ebx+104] |
movq mm5, [ebx+112] |
movq mm7, [ebx+120] |
paddsw mm0, [ecx+96] |
paddsw mm2, [ecx+104] |
paddsw mm4, [ecx+112] |
paddsw mm6, [ecx+120] |
paddsw mm1, [edx+96] |
paddsw mm3, [edx+104] |
paddsw mm5, [edx+112] |
paddsw mm7, [edx+120] |
paddsw mm0, mm1 |
movq [eax+96], mm0 |
paddsw mm2, mm3 |
movq [edi+104], mm2 |
paddsw mm4, mm5 |
movq [edi+112], mm4 |
paddsw mm6, mm7 |
movq [edi+120], mm6 |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers/mix_sse2.inc |
---|
0,0 → 1,145 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used mmx128_mix_2 |
align 4 |
mmx128_mix_2: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
movaps [edi], xmm0 |
paddsw xmm1,[ebx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ebx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ebx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ebx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ebx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ebx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ebx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_3: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
paddsw xmm1, [ebx+16] |
paddsw xmm2, [ebx+32] |
paddsw xmm3, [ebx+48] |
paddsw xmm4, [ebx+64] |
paddsw xmm5, [ebx+80] |
paddsw xmm6, [ebx+96] |
paddsw xmm7, [ebx+112] |
paddsw xmm0, [ecx] |
movaps [edi], xmm0 |
paddsw xmm1, [ecx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ecx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ecx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ecx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ecx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ecx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ecx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_4: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
prefetcht1 [edx+128] |
movaps xmm0, [eax] |
movaps xmm2, [eax+16] |
movaps xmm4, [eax+32] |
movaps xmm6, [eax+48] |
movaps xmm1, [ebx] |
movaps xmm3, [ebx+16] |
movaps xmm5, [ebx+32] |
movaps xmm7, [ebx+48] |
paddsw xmm0, [ecx] |
paddsw xmm2, [ecx+16] |
paddsw xmm4, [ecx+32] |
paddsw xmm6, [ecx+48] |
paddsw xmm1, [edx] |
paddsw xmm3, [edx+16] |
paddsw xmm5, [edx+32] |
paddsw xmm7, [edx+48] |
paddsw xmm0, xmm1 |
movaps [edi], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+16], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+32], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+48], xmm6 |
movaps xmm0, [eax+64] |
movaps xmm2, [eax+80] |
movaps xmm4, [eax+96] |
movaps xmm6, [eax+112] |
movaps xmm1, [ebx+64] |
movaps xmm3, [ebx+80] |
movaps xmm5, [ebx+96] |
movaps xmm7, [ebx+112] |
paddsw xmm0, [ecx+64] |
paddsw xmm2, [ecx+80] |
paddsw xmm4, [ecx+96] |
paddsw xmm6, [ecx+112] |
paddsw xmm1, [edx+64] |
paddsw xmm3, [edx+80] |
paddsw xmm5, [edx+96] |
paddsw xmm7, [edx+112] |
paddsw xmm0, xmm1 |
movaps [edi+64], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+80], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+96], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+112], xmm6 |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/drivers |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc |
---|
0,0 → 1,456 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; check mouse |
; |
; |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
; FB30 color temp |
; FB28 high bits temp |
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
uglobal |
mousecount dd 0x0 |
mousedata dd 0x0 |
endg |
iglobal |
mouse_delay dd 10 |
mouse_speed_factor: dd 3 |
mouse_timer_ticks dd 0 |
endg |
;include 'm_com.inc' |
;test_mario79: |
; push esi |
; push eax |
; mov [write_error_to],process_test_m79+43 |
; movzx eax,al ;[DevErrorCode] |
; call writehex |
; mov esi,process_test_m79 |
; call sys_msg_board_str |
; pop eax |
; pop esi |
; ret |
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0 |
draw_mouse_under: |
; return old picture |
cmp [_display.restore_cursor], 0 |
je @F |
pushad |
movzx eax,word [X_UNDER] |
movzx ebx,word [Y_UNDER] |
stdcall [_display.restore_cursor], eax, ebx |
popad |
ret |
@@: |
pushad |
xor ecx,ecx |
xor edx,edx |
align 4 |
mres: |
movzx eax,word [X_UNDER] |
movzx ebx,word [Y_UNDER] |
add eax,ecx |
add ebx,edx |
push ecx |
push edx |
push eax |
push ebx |
mov eax,edx |
shl eax,6 |
shl ecx,2 |
add eax,ecx |
add eax,mouseunder |
mov ecx,[eax] |
pop ebx |
pop eax |
mov edi, 1 ;force |
call [putpixel] |
pop edx |
pop ecx |
inc ecx |
cmp ecx, 16 |
jnz mres |
xor ecx, ecx |
inc edx |
cmp edx, 24 |
jnz mres |
popad |
ret |
save_draw_mouse: |
cmp [_display.move_cursor], 0 |
je .no_hw_cursor |
pushad |
mov [X_UNDER],ax |
mov [Y_UNDER],bx |
movzx eax,word [MOUSE_Y] |
movzx ebx,word [MOUSE_X] |
push eax |
push ebx |
mov ecx, [Screen_Max_X] |
inc ecx |
mul ecx |
add eax, [_WinMapAddress] |
movzx edx, byte [ebx+eax] |
shl edx, 8 |
mov esi, [edx+SLOT_BASE+APPDATA.cursor] |
cmp esi, [current_cursor] |
je .draw |
push esi |
call [_display.select_cursor] |
mov [current_cursor], esi |
.draw: |
stdcall [_display.move_cursor], esi |
popad |
ret |
.fail: |
mov ecx, [def_cursor] |
mov [edx+SLOT_BASE+APPDATA.cursor], ecx |
stdcall [_display.move_cursor], ecx ; stdcall: [esp]=ebx,eax |
popad |
ret |
.no_hw_cursor: |
pushad |
; save & draw |
mov [X_UNDER],ax |
mov [Y_UNDER],bx |
push eax |
push ebx |
mov ecx,0 |
mov edx,0 |
align 4 |
drm: |
push eax |
push ebx |
push ecx |
push edx |
; helloworld |
push ecx |
add eax,ecx ; save picture under mouse |
add ebx,edx |
push ecx |
call getpixel |
mov [COLOR_TEMP],ecx |
pop ecx |
mov eax,edx |
shl eax,6 |
shl ecx,2 |
add eax,ecx |
add eax,mouseunder |
mov ebx,[COLOR_TEMP] |
mov [eax],ebx |
pop ecx |
mov edi,edx ; y cycle |
shl edi,4 ; *16 bytes per row |
add edi,ecx ; x cycle |
mov esi, edi |
add edi, esi |
add edi, esi ; *3 |
add edi,[MOUSE_PICTURE] ; we have our str address |
mov esi, edi |
add esi, 16*24*3 |
push ecx |
mov ecx, [COLOR_TEMP] |
call combine_colors |
mov [MOUSE_COLOR_MEM], ecx |
pop ecx |
pop edx |
pop ecx |
pop ebx |
pop eax |
add eax,ecx ; we have x coord+cycle |
add ebx,edx ; and y coord+cycle |
push ecx |
mov ecx, [MOUSE_COLOR_MEM] |
mov edi, 1 |
call [putpixel] |
pop ecx |
mov ebx,[esp+0] ; pure y coord again |
mov eax,[esp+4] ; and x |
inc ecx ; +1 cycle |
cmp ecx,16 ; if more than 16 |
jnz drm |
xor ecx, ecx |
inc edx |
cmp edx,24 |
jnz drm |
add esp,8 |
popad |
ret |
combine_colors: |
; in |
; ecx - color ( 00 RR GG BB ) |
; edi - ref to new color byte |
; esi - ref to alpha byte |
; |
; out |
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) |
push eax |
push ebx |
push edx |
push ecx |
xor ecx, ecx |
; byte 2 |
mov eax, 0xff |
sub al, [esi+0] |
mov ebx, [esp] |
shr ebx, 16 |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+0] |
mov bl, [esi+0] |
mul ebx |
shr eax, 8 |
add ecx, eax |
shl ecx, 8 |
; byte 1 |
mov eax, 0xff |
sub al, [esi+1] |
mov ebx, [esp] |
shr ebx, 8 |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+1] |
mov bl, [esi+1] |
mul ebx |
shr eax, 8 |
add ecx, eax |
shl ecx, 8 |
; byte 2 |
mov eax, 0xff |
sub al, [esi+2] |
mov ebx, [esp] |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+2] |
mov bl, [esi+2] |
mul ebx |
shr eax, 8 |
add ecx, eax |
pop eax |
pop edx |
pop ebx |
pop eax |
ret |
__sys_disable_mouse: |
cmp dword [MOUSE_VISIBLE],dword 0 |
je @f |
ret |
@@: |
pushad |
cmp [CURRENT_TASK],dword 1 |
je disable_m |
mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx eax, word [MOUSE_X] |
movzx ebx, word [MOUSE_Y] |
mov ecx,[Screen_Max_X] |
inc ecx |
imul ecx,ebx |
add ecx,eax |
add ecx, [_WinMapAddress] |
mov eax, [CURRENT_TASK] |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
je yes_mouse_disable |
mov ebx,[Screen_Max_X] |
inc ebx |
imul ebx,10 |
add ecx,ebx |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
je yes_mouse_disable |
jmp no_mouse_disable |
yes_mouse_disable: |
mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx eax, word [MOUSE_X] |
movzx ebx, word [MOUSE_Y] |
mov ecx,[edx+0] ; mouse inside the area ? |
add eax,10 |
cmp eax,ecx |
jb no_mouse_disable |
sub eax,10 |
add ecx,[edx+8] |
cmp eax,ecx |
jg no_mouse_disable |
mov ecx,[edx+4] |
add ebx,14 |
cmp ebx,ecx |
jb no_mouse_disable |
sub ebx,14 |
add ecx,[edx+12] |
cmp ebx,ecx |
jg no_mouse_disable |
disable_m: |
cmp dword [MOUSE_VISIBLE],dword 0 |
jne no_mouse_disable |
pushf |
cli |
call draw_mouse_under |
popf |
mov [MOUSE_VISIBLE],dword 1 |
no_mouse_disable: |
popad |
ret |
__sys_draw_pointer: |
cmp [mouse_pause],0 |
je @f |
ret |
@@: |
push eax |
mov eax,[timer_ticks] |
sub eax,[MouseTickCounter] |
cmp eax,1 |
ja @f |
pop eax |
ret |
@@: |
mov eax,[timer_ticks] |
mov [MouseTickCounter],eax |
pop eax |
pushad |
cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ? |
je chms00 |
mov [MOUSE_VISIBLE], dword 0 |
movzx ebx,word [MOUSE_Y] |
movzx eax,word [MOUSE_X] |
pushfd |
cli |
call save_draw_mouse |
popfd |
nodmu2: |
popad |
ret |
chms00: |
movzx ecx,word [X_UNDER] |
movzx edx,word [Y_UNDER] |
movzx ebx,word [MOUSE_Y] |
movzx eax,word [MOUSE_X] |
cmp eax,ecx |
jne redrawmouse |
cmp ebx,edx |
jne redrawmouse |
jmp nodmp |
redrawmouse: |
pushfd |
cli |
call draw_mouse_under |
call save_draw_mouse |
popfd |
nodmp: |
popad |
ret |
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword |
mov eax,[BtnState] |
mov [BTN_DOWN],eax |
mov eax,[XMoving] |
call mouse_acceleration |
add ax,[MOUSE_X] ;[XCoordinate] |
cmp ax,0 |
jge @@M1 |
mov eax,0 |
jmp @@M2 |
@@M1: |
cmp ax,[Screen_Max_X] ;ScreenLength |
jl @@M2 |
mov ax,[Screen_Max_X] ;ScreenLength-1 |
@@M2: |
mov [MOUSE_X],ax ;[XCoordinate] |
mov eax,[YMoving] |
neg eax |
call mouse_acceleration |
add ax,[MOUSE_Y] ;[YCoordinate] |
cmp ax,0 |
jge @@M3 |
mov ax,0 |
jmp @@M4 |
@@M3: |
cmp ax,[Screen_Max_Y] ;ScreenHeigth |
jl @@M4 |
mov ax,[Screen_Max_Y] ;ScreenHeigth-1 |
@@M4: |
mov [MOUSE_Y],ax ;[YCoordinate] |
mov eax,[VScroll] |
add [MOUSE_SCROLL_V],ax |
mov eax,[HScroll] |
add [MOUSE_SCROLL_H],ax |
mov [mouse_active],1 |
mov eax,[timer_ticks] |
mov [mouse_timer_ticks],eax |
ret |
endp |
mouse_acceleration: |
push eax |
mov eax,[timer_ticks] |
sub eax,[mouse_timer_ticks] |
cmp eax,[mouse_delay] |
pop eax |
ja @f |
;push edx |
imul eax,[mouse_speed_factor] |
;pop edx |
@@: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc |
---|
0,0 → 1,203 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;setting date,time,clock and alarm-clock |
;add sys_settime at servetable as for ex. 22 fcn: |
; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK |
; ebx =0 - set time ecx - 00SSMMHH |
; ebx =1 - set date ecx=00DDMMYY |
; ebx =2 - set day of week ecx- 1-7 |
; ebx =3 - set alarm-clock ecx - 00SSMMHH |
; out: 0 -Ok 1 -wrong format 2 -battery low |
sys_settime: |
cli |
mov al,0x0d |
out 0x70,al |
in al,0x71 |
bt ax,7 |
jnc bat_low |
cmp ebx,2 ;day of week |
jne nosetweek |
test ecx,ecx ;test day of week |
je wrongtime |
cmp ecx,7 |
ja wrongtime |
mov edx,0x70 |
call startstopclk |
dec edx |
mov al,6 |
out dx,al |
inc edx |
mov al,cl |
out dx,al |
jmp endsettime |
nosetweek: ;set date |
cmp ebx,1 |
jne nosetdate |
cmp cl,0x99 ;test year |
ja wrongtime |
shl ecx,4 |
cmp cl,0x90 |
ja wrongtime |
cmp ch,0x99 ;test month |
ja wrongtime |
shr ecx,4 |
test ch,ch |
je wrongtime |
cmp ch,0x12 |
ja wrongtime |
shl ecx,8 |
bswap ecx ;ebx=00YYMMDD |
test cl,cl ;test day |
je wrongtime |
shl ecx,4 |
cmp cl,0x90 |
ja wrongtime |
shr ecx,4 |
cmp ch,2 ;February |
jne testday |
cmp cl,0x29 |
ja wrongtime |
jmp setdate |
testday: |
cmp ch,8 |
jb testday1 ;Aug-Dec |
bt cx,8 |
jnc days31 |
jmp days30 |
testday1: |
bt cx,8 ;Jan-Jul ex.Feb |
jnc days30 |
days31: |
cmp cl,0x31 |
ja wrongtime |
jmp setdate |
days30: |
cmp cl,0x30 |
ja wrongtime |
setdate: |
mov edx,0x70 |
call startstopclk |
dec edx |
mov al,7 ;set days |
out dx,al |
inc edx |
mov al,cl |
out dx,al |
dec edx |
mov al,8 ;set months |
out dx,al |
inc edx |
mov al,ch |
out dx,al |
dec edx |
mov al,9 ;set years |
out dx,al |
inc edx |
shr ecx,8 |
mov al,ch |
out dx,al |
jmp endsettime |
nosetdate: ;set time or alarm-clock |
cmp ebx,3 |
ja wrongtime |
cmp cl,0x23 |
ja wrongtime |
cmp ch,0x59 |
ja wrongtime |
shl ecx,4 |
cmp cl,0x90 |
ja wrongtime |
cmp ch,0x92 |
ja wrongtime |
shl ecx,4 |
bswap ecx ;00HHMMSS |
cmp cl,0x59 |
ja wrongtime |
shl ecx,4 |
cmp cl,0x90 |
ja wrongtime |
shr ecx,4 |
mov edx,0x70 |
call startstopclk |
dec edx |
cmp ebx,3 |
je setalarm |
xor eax,eax ;al=0-set seconds |
out dx,al |
inc edx |
mov al,cl |
out dx,al |
dec edx |
mov al,2 ;set minutes |
out dx,al |
inc edx |
mov al,ch |
out dx,al |
dec edx |
mov al,4 ;set hours |
out dx,al |
inc edx |
shr ecx,8 |
mov al,ch |
out dx,al |
jmp endsettime |
setalarm: |
mov al,1 ;set seconds for al. |
out dx,al |
inc edx |
mov al,cl |
out dx,al |
dec edx |
mov al,3 ;set minutes for al. |
out dx,al |
inc edx |
mov al,ch |
out dx,al |
dec edx |
mov al,5 ;set hours for al. |
out dx,al |
inc edx |
shr ecx,8 |
mov al,ch |
out dx,al |
dec edx |
mov al,0x0b ;enable irq's |
out dx,al |
inc dx |
in al,dx |
bts ax,5 ;set bit 5 |
out dx,al |
endsettime: |
dec edx |
call startstopclk |
sti |
and [esp+36-4],dword 0 |
ret |
bat_low: |
sti |
mov [esp+36-4],dword 2 |
ret |
wrongtime: |
sti |
mov [esp+36-4],dword 1 |
ret |
startstopclk: |
mov al,0x0b |
out dx,al |
inc dx |
in al,dx |
btc ax,7 |
out dx,al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/hid/keyboard.inc |
---|
0,0 → 1,343 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;// mike.dld [ |
VKEY_LSHIFT = 0000000000000001b |
VKEY_RSHIFT = 0000000000000010b |
VKEY_LCONTROL = 0000000000000100b |
VKEY_RCONTROL = 0000000000001000b |
VKEY_LALT = 0000000000010000b |
VKEY_RALT = 0000000000100000b |
VKEY_CAPSLOCK = 0000000001000000b |
VKEY_NUMLOCK = 0000000010000000b |
VKEY_SCRLOCK = 0000000100000000b |
VKEY_SHIFT = 0000000000000011b |
VKEY_CONTROL = 0000000000001100b |
VKEY_ALT = 0000000000110000b |
uglobal |
align 4 |
kb_state dd 0 |
ext_code db 0 |
keyboard_mode db 0 |
keyboard_data db 0 |
altmouseb db 0 |
ctrl_alt_del db 0 |
kb_lights db 0 |
align 4 |
hotkey_scancodes rd 256 ; we have 256 scancodes |
hotkey_list rd 256*4 ; max 256 defined hotkeys |
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys |
endg |
iglobal |
hotkey_tests dd hotkey_test0 |
dd hotkey_test1 |
dd hotkey_test2 |
dd hotkey_test3 |
dd hotkey_test4 |
hotkey_tests_num = 5 |
endg |
hotkey_test0: |
test al, al |
setz al |
ret |
hotkey_test1: |
test al, al |
setnp al |
ret |
hotkey_test2: |
cmp al, 3 |
setz al |
ret |
hotkey_test3: |
cmp al, 1 |
setz al |
ret |
hotkey_test4: |
cmp al, 2 |
setz al |
ret |
hotkey_do_test: |
push eax |
mov edx, [kb_state] |
shr edx, cl |
add cl, cl |
mov eax, [eax+4] |
shr eax, cl |
and eax, 15 |
cmp al, hotkey_tests_num |
jae .fail |
xchg eax, edx |
and al, 3 |
call [hotkey_tests + edx*4] |
cmp al, 1 |
pop eax |
ret |
.fail: |
stc |
pop eax |
ret |
align 4 |
irq1: |
; save_ring3_context |
; mov ax, os_data |
; mov ds, ax |
; mov es, ax |
movzx eax,word[TASK_COUNT] ; top window process |
movzx eax,word[WIN_POS+eax*2] |
shl eax,8 |
mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode] |
mov [keyboard_mode],al |
in al,0x60 |
mov [keyboard_data],al |
; ch = scancode |
; cl = ext_code |
; bh = 0 - normal key |
; bh = 1 - modifier (Shift/Ctrl/Alt) |
; bh = 2 - extended code |
mov ch,al |
cmp al,0xE0 |
je @f |
cmp al,0xE1 |
jne .normal_code |
@@: |
mov bh, 2 |
mov [ext_code], al |
jmp .writekey |
.normal_code: |
mov cl, 0 |
xchg cl, [ext_code] |
and al,0x7F |
mov bh, 1 |
@@: cmp al,0x2A |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_LSHIFT |
jmp .modifier |
@@: cmp al,0x36 |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_RSHIFT |
jmp .modifier |
@@: cmp al,0x38 |
jne @f |
mov eax, VKEY_LALT |
test cl, cl |
jz .modifier |
mov al, VKEY_RALT |
jmp .modifier |
@@: cmp al,0x1D |
jne @f |
mov eax, VKEY_LCONTROL |
test cl, cl |
jz .modifier |
mov al, VKEY_RCONTROL |
cmp cl, 0xE0 |
jz .modifier |
mov [ext_code], cl |
jmp .writekey |
@@: cmp al,0x3A |
jne @f |
mov bl,4 |
mov eax,VKEY_CAPSLOCK |
jmp .no_key.xor |
@@: cmp al,0x45 |
jne @f |
test cl, cl |
jnz .writekey |
mov bl,2 |
mov eax,VKEY_NUMLOCK |
jmp .no_key.xor |
@@: cmp al,0x46 |
jne @f |
mov bl,1 |
mov eax,VKEY_SCRLOCK |
jmp .no_key.xor |
@@: |
test ch,ch |
js .writekey |
movzx eax,ch ; plain key |
mov bl,[keymap+eax] |
mov edx,[kb_state] |
test dl,VKEY_CONTROL ; ctrl alt del |
jz .noctrlaltdel |
test dl,VKEY_ALT |
jz .noctrlaltdel |
cmp ch,53h |
jne .noctrlaltdel |
mov [ctrl_alt_del],1 |
.noctrlaltdel: |
test dl,VKEY_CONTROL ; ctrl on ? |
jz @f |
sub bl,0x60 |
@@: test dl,VKEY_SHIFT ; shift on ? |
jz @f |
mov bl,[keymap_shift+eax] |
@@: test dl,VKEY_ALT ; alt on ? |
jz @f |
mov bl,[keymap_alt+eax] |
@@: |
mov bh, 0 |
jmp .writekey |
.modifier: |
test ch, ch |
js .modifier.up |
or [kb_state], eax |
jmp .writekey |
.modifier.up: |
not eax |
and [kb_state], eax |
jmp .writekey |
.no_key.xor: |
mov bh, 0 |
test ch, ch |
js .writekey |
xor [kb_state], eax |
xor [kb_lights], bl |
call set_lights |
.writekey: |
; test for system hotkeys |
movzx eax, ch |
cmp bh, 1 |
ja .nohotkey |
jb @f |
xor eax, eax |
@@: |
mov eax, [hotkey_scancodes + eax*4] |
.hotkey_loop: |
test eax, eax |
jz .nohotkey |
mov cl, 0 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 2 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 4 |
call hotkey_do_test |
jnc .hotkey_found |
.hotkey_cont: |
mov eax, [eax] |
jmp .hotkey_loop |
.hotkey_found: |
mov eax, [eax+8] |
; put key in buffer for process in slot eax |
mov edi, hotkey_buffer |
@@: |
cmp dword [edi], 0 |
jz .found_free |
add edi, 8 |
cmp edi, hotkey_buffer+120*8 |
jb @b |
; no free space - replace first entry |
mov edi, hotkey_buffer |
.found_free: |
mov [edi], eax |
movzx eax, ch |
cmp bh, 1 |
jnz @f |
xor eax, eax |
@@: |
mov [edi+4], ax |
mov eax, [kb_state] |
mov [edi+6], ax |
jmp .exit.irq1 |
.nohotkey: |
cmp [keyboard_mode],0 ; return from keymap |
jne .scancode |
test bh, bh |
jnz .exit.irq1 |
test bl, bl |
jz .exit.irq1 |
;.........................Part1 Start.......Code by Rus, optimize by Ghost................................... |
test [kb_state], VKEY_NUMLOCK |
jz .dowrite |
cmp cl, 0xE0 |
jz .dowrite |
cmp ch, 55 |
jnz @f |
mov bl, 0x2A ;* |
jmp .dowrite |
@@: |
cmp ch, 71 |
jb .dowrite |
cmp ch, 83 |
ja .dowrite |
;push eax |
movzx eax, ch |
mov bl, [numlock_map + eax - 71] |
;pop eax |
;.........................Part1 End................................................. |
jmp .dowrite |
.scancode: |
mov bl, ch |
.dowrite: |
movzx eax,byte[KEY_COUNT] |
cmp al,120 |
jae .exit.irq1 |
inc eax |
mov [KEY_COUNT],al |
mov [KEY_COUNT+eax],bl |
.exit.irq1: |
mov [check_idle_semaphore],5 |
; mov al,0x20 ; ready for next irq |
; out 0x20,al |
; restore_ring3_context |
; iret |
ret |
set_lights: |
mov al,0xED |
call kb_write |
mov al,[kb_lights] |
call kb_write |
ret |
;// mike.dld ] |
;..........................Part2 Start.......Code by Rus....................................... |
numlock_map: |
db 0x37 ;Num 7 |
db 0x38 ;Num 8 |
db 0x39 ;Num 9 |
db 0x2D ;Num - |
db 0x34 ;Num 4 |
db 0x35 ;Num 5 |
db 0x36 ;Num 6 |
db 0x2B ;Num + |
db 0x31 ;Num 1 |
db 0x32 ;Num 2 |
db 0x33 ;Num 3 |
db 0x30 ;Num 0 |
db 0x2E ;Num . |
;..........................Part2 End................................................ |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/hid |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/video/cursors.inc |
---|
0,0 → 1,806 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
LOAD_FROM_FILE equ 0 |
LOAD_FROM_MEM equ 1 |
LOAD_INDIRECT equ 2 |
LOAD_SYSTEM equ 3 |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
virtual at 0 |
BI BITMAPINFOHEADER |
end virtual |
align 4 |
proc init_cursor stdcall, dst:dword, src:dword |
locals |
rBase dd ? |
pQuad dd ? |
pBits dd ? |
pAnd dd ? |
width dd ? |
height dd ? |
counter dd ? |
endl |
mov esi, [src] |
add esi,[esi+18] |
mov eax,esi |
cmp [esi+BI.biBitCount], 24 |
je .img_24 |
cmp [esi+BI.biBitCount], 8 |
je .img_8 |
cmp [esi+BI.biBitCount], 4 |
je .img_4 |
.img_2: |
add eax, [esi] |
mov [pQuad],eax |
add eax,8 |
mov [pBits],eax |
add eax, 128 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
.l21: |
mov ebx, [pBits] |
mov ebx, [ebx] |
bswap ebx |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
xor ecx, ecx |
shl ebx,1 |
setc cl |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pBits], 4 |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l21 |
ret |
.img_4: |
add eax, [esi] |
mov [pQuad],eax |
add eax,64 |
mov [pBits],eax |
add eax, 0x200 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l4: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 16 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0xF0 |
shr ecx, 2 |
mov ecx, [esi+ecx] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0x0F |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi+4], edx |
inc ebx |
add edi, 8 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l4 |
ret |
.img_8: |
add eax, [esi] |
mov [pQuad],eax |
add eax,1024 |
mov [pBits],eax |
add eax, 1024 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l81: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
inc ebx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l81 |
ret |
.img_24: |
add eax, [esi] |
mov [pQuad],eax |
add eax, 0xC00 |
mov [pAnd],eax |
mov eax,[esi+BI.biWidth] |
mov [width],eax |
mov ebx,[esi+BI.biHeight] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pAnd] |
mov ebx, [pQuad] |
.row_24: |
mov eax, [esi] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
mov ecx, [ebx] |
and ecx, 0x00FFFFFF |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add ebx, 3 |
add edi, 4 |
dec [counter] |
jnz @B |
add esi, 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .row_24 |
ret |
endp |
align 4 |
proc set_cursor stdcall, hcursor:dword |
mov eax, [hcursor] |
cmp [eax+CURSOR.magic], 'CURS' |
jne .fail |
; cmp [eax+CURSOR.size], CURSOR_SIZE |
; jne .fail |
mov ebx, [current_slot] |
xchg eax, [ebx+APPDATA.cursor] |
ret |
.fail: |
mov eax, [def_cursor] |
mov ebx, [current_slot] |
xchg eax, [ebx+APPDATA.cursor] |
ret |
endp |
; param |
; eax= pid |
; ebx= src |
; ecx= flags |
create_cursor: |
.src equ esp |
.flags equ esp+4 |
.hcursor equ esp+8 |
sub esp, 4 ;space for .hcursor |
push ecx |
push ebx |
mov ebx, eax |
mov eax, CURSOR.sizeof |
call create_kernel_object |
test eax, eax |
jz .fail |
mov [.hcursor],eax |
xor ebx, ebx |
mov [eax+CURSOR.magic], 'CURS' |
mov [eax+CURSOR.destroy], destroy_cursor |
mov [eax+CURSOR.hot_x], ebx |
mov [eax+CURSOR.hot_y], ebx |
stdcall kernel_alloc, 0x1000 |
test eax, eax |
jz .fail |
mov edi, [.hcursor] |
mov [edi+CURSOR.base], eax |
mov esi, [.src] |
mov ebx, [.flags] |
cmp bx, LOAD_INDIRECT |
je .indirect |
movzx ecx, word [esi+10] |
movzx edx, word [esi+12] |
mov [edi+CURSOR.hot_x], ecx |
mov [edi+CURSOR.hot_y], edx |
stdcall init_cursor, eax, esi |
mov eax, [.hcursor] |
lea eax, [eax+CURSOR.list_next] |
lea edx, [_display.cr_list.next] |
pushfd |
cli |
mov ecx, [edx] |
mov [eax], ecx |
mov [eax+4], edx |
mov [ecx+4], eax |
mov [edx], eax |
popfd |
mov eax, [.hcursor] |
.check_hw: |
cmp [_display.init_cursor], 0 |
je .fail |
push eax |
call [_display.init_cursor] |
add esp, 4 |
mov eax, [.hcursor] |
.fail: |
add esp, 12 |
ret |
.indirect: |
shr ebx, 16 |
movzx ecx, bh |
movzx edx, bl |
mov [eax+CURSOR.hot_x], ecx |
mov [eax+CURSOR.hot_y], edx |
xchg edi, eax |
mov ecx, 1024 |
cld |
rep movsd |
jmp .check_hw |
align 4 |
proc load_cursor stdcall, src:dword, flags:dword |
locals |
handle dd ? |
endl |
xor eax, eax |
cmp [create_cursor], eax |
je .fail2 |
mov [handle], eax |
cmp word [flags], LOAD_FROM_FILE |
jne @F |
stdcall load_file, [src] |
test eax, eax |
jz .fail |
mov [src], eax |
@@: |
push ebx |
push esi |
push edi |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
mov eax, [CURRENT_TASK+eax+4] |
mov ebx, [src] |
mov ecx, [flags] |
call create_cursor ;eax, ebx, ecx |
mov [handle], eax |
cmp word [flags], LOAD_FROM_FILE |
jne .exit |
stdcall kernel_free, [src] |
.exit: |
pop edi |
pop esi |
pop ebx |
.fail: |
mov eax, [handle] |
.fail2: |
ret |
endp |
align 4 |
proc delete_cursor stdcall, hcursor:dword |
locals |
hsrv dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
endl |
mov esi, [hcursor] |
cmp [esi+CURSOR.magic], 'CURS' |
jne .fail |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
cmp ebx, [esi+CURSOR.pid] |
jne .fail |
mov ebx, [current_slot] |
cmp esi, [ebx+APPDATA.cursor] |
jne @F |
mov eax, [def_cursor] |
mov [ebx+APPDATA.cursor], eax |
@@: |
mov eax, [hcursor] |
call [eax+APPOBJ.destroy] |
.fail: |
ret |
endp |
; param |
; eax= cursor |
align 4 |
destroy_cursor: |
push eax |
stdcall kernel_free, [eax+CURSOR.base] |
pop eax |
call destroy_kernel_object |
ret |
align 4 |
select_cursor: |
mov eax, [esp+4] |
mov [_display.cursor], eax |
ret 4 |
align 4 |
proc restore_24 stdcall, x:dword, y:dword |
push ebx |
mov ebx, [cur_saved_base] |
mov edx, [cur.h] |
test edx, edx |
jz .ret |
push esi |
push edi |
mov esi, cur_saved_data |
mov ecx, [cur.w] |
lea ecx, [ecx+ecx*2] |
push ecx |
@@: |
mov edi, ebx |
add ebx, [BytesPerScanLine] |
mov ecx, [esp] |
rep movsb |
dec edx |
jnz @B |
pop ecx |
pop edi |
pop esi |
.ret: |
pop ebx |
ret |
endp |
align 4 |
proc restore_32 stdcall, x:dword, y:dword |
push ebx |
mov ebx, [cur_saved_base] |
mov edx, [cur.h] |
test edx, edx |
jz .ret |
push esi |
push edi |
mov esi, cur_saved_data |
@@: |
mov edi, ebx |
add ebx, [BytesPerScanLine] |
mov ecx, [cur.w] |
rep movsd |
dec edx |
jnz @B |
pop edi |
.ret: |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc move_cursor_24 stdcall, hcursor:dword, x:dword, y:dword |
locals |
h dd ? |
_dx dd ? |
_dy dd ? |
endl |
mov esi, [hcursor] |
mov ecx, [x] |
mov eax, [y] |
mov ebx, [BytesPerScanLine] |
xor edx, edx |
sub ecx, [esi+CURSOR.hot_x] |
lea ebx, [ecx+32-1] |
mov [x], ecx |
sets dl |
dec edx |
and ecx, edx ;clip x to 0<=x |
mov [cur.left], ecx |
mov edi, ecx |
sub edi, [x] |
mov [_dx], edi |
xor edx, edx |
sub eax, [esi+CURSOR.hot_y] |
lea edi, [eax+32-1] |
mov [y], eax |
sets dl |
dec edx |
and eax, edx ;clip y to 0<=y |
mov [cur.top], eax |
mov edx, eax |
sub edx, [y] |
mov [_dy], edx |
mul dword [BytesPerScanLine] |
lea edx, [LFB_BASE+ecx*3] |
add edx, eax |
mov [cur_saved_base],edx |
cmp ebx, [Screen_Max_X] |
jbe @F |
mov ebx, [Screen_Max_X] |
@@: |
cmp edi, [Screen_Max_Y] |
jbe @F |
mov edi, [Screen_Max_Y] |
@@: |
mov [cur.right], ebx |
mov [cur.bottom], edi |
sub ebx, [x] |
sub edi, [y] |
inc ebx |
inc edi |
mov [cur.w], ebx |
mov [cur.h], edi |
mov [h], edi |
mov eax, edi |
mov edi, cur_saved_data |
@@: |
mov esi, edx |
add edx, [BytesPerScanLine] |
mov ecx, [cur.w] |
lea ecx, [ecx+ecx*2] |
rep movsb |
dec eax |
jnz @B |
;draw cursor |
mov ebx, [cur_saved_base] |
mov eax, [_dy] |
shl eax, 5 |
add eax, [_dx] |
mov esi, [hcursor] |
mov esi, [esi+CURSOR.base] |
lea edx, [esi+eax*4] |
.row: |
mov ecx, [cur.w] |
mov esi, edx |
mov edi, ebx |
add edx, 32*4 |
add ebx, [BytesPerScanLine] |
.pix: |
lodsd |
test eax, 0xFF000000 |
jz @F |
mov [edi], ax |
shr eax, 16 |
mov [edi+2],al |
@@: |
add edi, 3 |
dec ecx |
jnz .pix |
dec [h] |
jnz .row |
ret |
endp |
align 4 |
proc move_cursor_32 stdcall, hcursor:dword, x:dword, y:dword |
locals |
h dd ? |
_dx dd ? |
_dy dd ? |
endl |
mov esi, [hcursor] |
mov ecx, [x] |
mov eax, [y] |
xor edx, edx |
sub ecx, [esi+CURSOR.hot_x] |
lea ebx, [ecx+32-1] |
mov [x], ecx |
sets dl |
dec edx |
and ecx, edx ;clip x to 0<=x |
mov [cur.left], ecx |
mov edi, ecx |
sub edi, [x] |
mov [_dx], edi |
xor edx, edx |
sub eax, [esi+CURSOR.hot_y] |
lea edi, [eax+32-1] |
mov [y], eax |
sets dl |
dec edx |
and eax, edx ;clip y to 0<=y |
mov [cur.top], eax |
mov edx, eax |
sub edx, [y] |
mov [_dy], edx |
mul dword [BytesPerScanLine] |
lea edx, [LFB_BASE+eax+ecx*4] |
mov [cur_saved_base],edx |
cmp ebx, [Screen_Max_X] |
jbe @F |
mov ebx, [Screen_Max_X] |
@@: |
cmp edi, [Screen_Max_Y] |
jbe @F |
mov edi, [Screen_Max_Y] |
@@: |
mov [cur.right], ebx |
mov [cur.bottom], edi |
sub ebx, [x] |
sub edi, [y] |
inc ebx |
inc edi |
mov [cur.w], ebx |
mov [cur.h], edi |
mov [h], edi |
mov eax, edi |
mov edi, cur_saved_data |
@@: |
mov esi, edx |
add edx, [BytesPerScanLine] |
mov ecx, [cur.w] |
rep movsd |
dec eax |
jnz @B |
;draw cursor |
mov ebx, [cur_saved_base] |
mov eax, [_dy] |
shl eax, 5 |
add eax, [_dx] |
mov esi, [hcursor] |
mov esi, [esi+CURSOR.base] |
lea edx, [esi+eax*4] |
.row: |
mov ecx, [cur.w] |
mov esi, edx |
mov edi, ebx |
add edx, 32*4 |
add ebx, [BytesPerScanLine] |
.pix: |
lodsd |
test eax, 0xFF000000 |
jz @F |
mov [edi], eax |
@@: |
add edi, 4 |
dec ecx |
jnz .pix |
dec [h] |
jnz .row |
ret |
endp |
align 4 |
get_display: |
mov eax, _display |
ret |
align 4 |
init_display: |
xor eax, eax |
mov edi, _display |
mov [edi+display_t.init_cursor], eax |
mov [edi+display_t.select_cursor], eax |
mov [edi+display_t.show_cursor], eax |
mov [edi+display_t.move_cursor], eax |
mov [edi+display_t.restore_cursor], eax |
lea ecx, [edi+display_t.cr_list.next] |
mov [edi+display_t.cr_list.next], ecx |
mov [edi+display_t.cr_list.prev], ecx |
cmp [SCR_MODE],word 0x13 |
jbe .fail |
test word [SCR_MODE], 0x4000 |
jz .fail |
mov ebx, restore_32 |
mov ecx, move_cursor_32 |
movzx eax, byte [ScreenBPP] |
cmp eax, 32 |
je @F |
mov ebx, restore_24 |
mov ecx, move_cursor_24 |
cmp eax, 24 |
jne .fail |
@@: |
mov [_display.select_cursor], select_cursor |
mov [_display.move_cursor], ecx |
mov [_display.restore_cursor], ebx |
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM |
mov [def_cursor], eax |
ret |
.fail: |
xor eax, eax |
mov [_display.select_cursor], eax |
mov [_display.move_cursor], eax |
ret |
align 4 |
def_arrow: |
file 'arrow.cur' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/video/vesa12.inc |
---|
0,0 → 1,1004 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VESA12.INC ;; |
;; ;; |
;; Vesa 1.2 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; ;; |
;; quickcode@mail.ru - bankswitch for S3 cards ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
TRIDENT equ 0 |
S3_VIDEO equ 0 |
INTEL_VIDEO equ 0 |
if TRIDENT |
if S3_VIDEO or INTEL_VIDEO |
stop |
end if |
end if |
if S3_VIDEO |
if TRIDENT or INTEL_VIDEO |
stop |
end if |
end if |
if INTEL_VIDEO |
if S3_VIDEO or TRIDENT |
stop |
end if |
end if |
; A complete video driver should include the following types of function |
; |
; Putpixel |
; Getpixel |
; |
; Drawimage |
; Drawbar |
; |
; Drawbackground |
; |
; |
; Modifying the set_bank -function is mostly enough |
; for different Vesa 1.2 setups. |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
; set_bank for Trident videocards, work on Trident 9440 |
; modified by Mario79 |
if TRIDENT |
set_bank: |
pushfd |
cli |
cmp al,[BANK_RW] |
je .retsb |
mov [BANK_RW],al |
push dx |
mov dx,3D8h |
out dx,al |
pop dx |
.retsb: |
popfd |
ret |
end if |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
; set_bank for S3 videocards, work on S3 ViRGE PCI (325) |
; modified by kmeaw |
if S3_VIDEO |
set_bank: |
pushfd |
cli |
cmp al,[BANK_RW] |
je .retsb |
mov [BANK_RW],al |
push ax |
push dx |
push cx |
mov cl, al |
mov dx, 0x3D4 |
mov al, 0x38 |
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to |
;unlock and 00h to lock |
inc dx |
mov al, 0x48 |
out dx, al ;3d5 -? |
dec dx |
mov al, 0x31 |
out dx, al ;CR31 Memory Configuration Register |
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear. |
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h, |
;for the 864/964 see index 69h. |
inc dx |
in al, dx |
dec dx |
mov ah, al |
mov al, 0x31 |
out dx, ax |
mov al, ah |
or al, 9 |
inc dx |
out dx, al |
dec dx |
mov al, 0x35 |
out dx, al ;CR35 CRT Register Lock |
inc dx |
in al, dx |
dec dx |
and al, 0xF0 |
mov ch, cl |
and ch, 0x0F |
or ch, al |
mov al, 0x35 |
out dx, al |
inc dx |
mov al, ch |
out dx, ax |
dec dx |
mov al, 0x51 ;Extended System Control 2 Register |
out dx, al |
inc dx |
in al, dx |
dec dx |
and al, 0xF3 |
shr cl, 2 |
and cl, 0x0C |
or cl, al |
mov al, 0x51 |
out dx, al |
inc dx |
mov al, cl |
out dx, al |
dec dx |
mov al, 0x38 |
out dx, al |
inc dx |
xor al, al |
out dx, al |
dec dx |
pop cx |
pop dx |
pop ax |
.retsb: |
popfd |
ret |
end if |
;Set bank function for Intel 810/815 chipsets |
; *****Modified by Protopopius, Russia.***** |
; ********* http://menuetos.hut.ru ************** |
; ************************************************ |
if INTEL_VIDEO |
set_bank: |
pushfd |
cli |
cmp al,[BANK_RW] |
je .retsb |
mov [BANK_RW],al |
push ax |
push dx |
mov dx,3CEh |
mov ah,al ; Save value for later use |
mov al,10h ; Index GR10 (Address Mapping) |
out dx,al ; Select GR10 |
inc dl |
mov al,3 ; Set bits 0 and 1 (Enable linear page mapping) |
out dx,al ; Write value |
dec dl |
mov al,11h ; Index GR11 (Page Selector) |
out dx,al ; Select GR11 |
inc dl |
mov al,ah ; Write address |
out dx,al ; Write the value |
pop dx |
pop ax |
.retsb: |
popfd |
ret |
end if |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} |
if (TRIDENT or S3_VIDEO or INTEL_VIDEO) |
else |
set_bank: |
pushfd |
cli |
cmp al,[BANK_RW] |
je .retsb |
mov [BANK_RW],al |
push ax |
push dx |
mov ah,al |
mov dx,0x03D4 |
mov al,0x39 |
out dx,al |
inc dl |
mov al,0xA5 |
out dx,al |
dec dl |
mov al,6Ah |
out dx,al |
inc dl |
mov al,ah |
out dx,al |
dec dl |
mov al,0x39 |
out dx,al |
inc dl |
mov al,0x5A |
out dx,al |
dec dl |
pop dx |
pop ax |
.retsb: |
popfd |
ret |
end if |
vesa12_drawbackground: |
call [_display.disable_mouse] |
push eax |
push ebx |
push ecx |
push edx |
xor edx,edx |
mov eax,dword[BgrDataWidth] |
mov ebx,dword[BgrDataHeight] |
mul ebx |
mov ebx,3 |
mul ebx |
mov [imax],eax |
mov eax,[draw_data+32+RECT.left] |
mov ebx,[draw_data+32+RECT.top] |
mov edi,0 ;no force |
v12dp3: |
push eax |
push ebx |
cmp [BgrDrawMode],dword 1 ; tiled background |
jne no_vesa12_tiled_bgr |
push edx |
xor edx,edx |
div dword [BgrDataWidth] |
push edx |
mov eax,ebx |
xor edx,edx |
div dword [BgrDataHeight] |
mov ebx,edx |
pop eax |
pop edx |
no_vesa12_tiled_bgr: |
cmp [BgrDrawMode],dword 2 ; stretched background |
jne no_vesa12_stretched_bgr |
push edx |
mul dword [BgrDataWidth] |
mov ecx,[Screen_Max_X] |
inc ecx |
div ecx |
push eax |
mov eax,ebx |
mul dword [BgrDataHeight] |
mov ecx,[Screen_Max_Y] |
inc ecx |
div ecx |
mov ebx,eax |
pop eax |
pop edx |
no_vesa12_stretched_bgr: |
mov esi,ebx |
imul esi, dword [BgrDataWidth] |
add esi,eax |
lea esi,[esi*3] |
add esi,[img_background] ;IMG_BACKGROUND |
pop ebx |
pop eax |
v12di4: |
mov cl,[esi+2] |
shl ecx,16 |
mov cx,[esi] |
pusha |
mov esi,eax |
mov edi,ebx |
mov eax,[Screen_Max_X] |
add eax,1 |
mul ebx |
add eax, [_WinMapAddress] |
cmp [eax+esi],byte 1 |
jnz v12nbgp |
mov eax,[BytesPerScanLine] |
mov ebx,edi |
mul ebx |
add eax, esi |
lea eax, [VGABasePtr+eax+esi*2] |
cmp [ScreenBPP],byte 24 |
jz v12bgl3 |
add eax,esi |
v12bgl3: |
push ebx |
push eax |
sub eax,VGABasePtr |
shr eax,16 |
call set_bank |
pop eax |
and eax,65535 |
add eax,VGABasePtr |
pop ebx |
mov [eax],cx |
add eax,2 |
shr ecx,16 |
mov [eax],cl |
sti |
v12nbgp: |
popa |
add esi,3 |
inc eax |
cmp eax,[draw_data+32+RECT.right] |
jg v12nodp31 |
jmp v12dp3 |
v12nodp31: |
mov eax,[draw_data+32+RECT.left] |
inc ebx |
cmp ebx,[draw_data+32+RECT.bottom] |
jg v12dp4 |
jmp v12dp3 |
v12dp4: |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
vesa12_drawbar: |
call [_display.disable_mouse] |
;; mov [novesachecksum],dword 0 |
sub edx,ebx |
sub ecx,eax |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
mov ecx,[TASK_BASE] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mov ebx,[BytesPerScanLine] |
mul ebx |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start |
jz dbpi2412 |
add eax,ecx |
dbpi2412: |
add eax,VGABasePtr |
mov edi,eax |
; x size |
mov eax,[esp+4] ; [esp+6] |
mov ecx,eax |
add ecx,eax |
add ecx,eax |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz dbpi24312 |
add ecx,eax |
dbpi24312: |
mov ebx,[esp+0] |
; check limits ? |
push eax |
push ecx |
mov eax,[TASK_BASE] |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.left] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.top] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] |
cmp ecx,[Screen_Max_X] |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] |
cmp ecx,[Screen_Max_Y] |
jnz dbcblimitlset12 |
pop ecx |
pop eax |
push dword 0 |
jmp dbcblimitlno12 |
dbcblimitlset12: |
pop ecx |
pop eax |
push dword 1 |
dbcblimitlno12: |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jz dbpi24bit12 |
jmp dbpi32bit12 |
; DRAWBAR 24 BBP |
dbpi24bit12: |
push eax |
push ebx |
push edx |
mov eax,ecx |
mov ebx,3 |
div ebx |
mov ecx,eax |
pop edx |
pop ebx |
pop eax |
cld |
dbnewpi12: |
push ebx |
push edi |
push ecx |
xor edx,edx |
mov eax,edi |
sub eax,VGABasePtr |
mov ebx,3 |
div ebx |
add eax, [_WinMapAddress] |
mov ebx,[CURRENT_TASK] |
cld |
dbnp2412: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp24no12 |
cmp [esp+5*4],dword 0 |
jz dbimp24yes12 |
; call dbcplimit |
; jnz dbimp24no12 |
dbimp24yes12: |
push edi |
mov eax,edi |
sub eax,VGABasePtr |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,VGABasePtr |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,3 |
pop ecx |
pop eax |
inc eax |
loop dbnp2412 |
jmp dbnp24d12 |
dbimp24no12: |
pop ecx |
pop eax |
cld |
add edi,3 |
inc eax |
loop dbnp2412 |
dbnp24d12: |
mov eax,[esp+3*4+16+4] |
test eax,0x80000000 |
jz nodbgl2412 |
cmp al,0 |
jz nodbgl2412 |
dec eax |
mov [esp+3*4+16+4],eax |
nodbgl2412: |
pop ecx |
pop edi |
pop ebx |
add edi,[BytesPerScanLine] |
dec ebx |
jz dbnonewpi12 |
jmp dbnewpi12 |
dbnonewpi12: |
add esp,7*4 |
ret |
; DRAWBAR 32 BBP |
dbpi32bit12: |
cld |
shr ecx,2 |
dbnewpi3212: |
push ebx |
push edi |
push ecx |
mov eax,edi |
sub eax,VGABasePtr |
shr eax,2 |
add eax, [_WinMapAddress] |
mov ebx,[CURRENT_TASK] |
cld |
dbnp3212: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp32no12 |
cmp [esp+5*4],dword 0 |
jz dbimp32yes12 |
; call dbcplimit |
; jnz dbimp32no12 |
dbimp32yes12: |
push edi |
mov eax,edi |
sub eax,VGABasePtr |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,VGABasePtr |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,4 |
inc ebp |
pop ecx |
pop eax |
inc eax |
loop dbnp3212 |
jmp dbnp32d12 |
dbimp32no12: |
pop ecx |
pop eax |
inc eax |
add edi,4 |
inc ebp |
loop dbnp3212 |
dbnp32d12: |
mov eax,[esp+12+16+4] |
test eax,0x80000000 |
jz nodbgl3212 |
cmp al,0 |
jz nodbgl3212 |
dec eax |
mov [esp+12+16+4],eax |
nodbgl3212: |
pop ecx |
pop edi |
pop ebx |
add edi,[BytesPerScanLine] |
dec ebx |
jz nodbnewpi3212 |
jmp dbnewpi3212 |
nodbnewpi3212: |
add esp,7*4 |
ret |
Vesa12_putpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[esp+28] |
stosw |
shr eax,16 |
mov [edi],al |
sti |
ret |
Vesa12_putpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[esp+28] |
mov [edi],ecx |
sti |
ret |
Vesa12_getpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
Vesa12_getpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[BytesPerScanLine] |
xor edx,edx |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
vesa12_putimage: |
; ebx = pointer to image |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
; ebp = pointer to 'get' function |
; esi = pointer to 'init' function |
; edi = parameter for 'get' function |
; mov ebx,image |
; mov ecx,320*65536+240 |
; mov edx,20*65536+20 |
call [_display.disable_mouse] |
mov [novesachecksum],dword 0 |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
movzx eax,word [esp+2] |
movzx ebx,word [esp+0] |
mov ecx,[TASK_BASE] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mul dword [BytesPerScanLine] |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start |
jz pi2412 |
add eax,ecx |
pi2412: |
add eax,VGABasePtr |
mov edi,eax |
; x size |
movzx ecx,word [esp+6] |
mov esi,[esp+8] |
movzx ebx,word [esp+4] |
; check limits while draw ? |
push ecx |
mov eax,[TASK_BASE] |
cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0 |
jnz dbcblimitlset212 |
cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0 |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] |
cmp ecx,[Screen_Max_X] |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] |
cmp ecx,[Screen_Max_Y] |
jnz dbcblimitlset212 |
pop ecx |
push 0 |
jmp dbcblimitlno212 |
dbcblimitlset212: |
pop ecx |
push 1 |
dbcblimitlno212: |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jnz pi32bit12 |
pi24bit12: |
newpi12: |
push edi |
push ecx |
push ebx |
mov edx,edi |
sub edx,VGABasePtr |
mov ebx,3 |
div ebx |
add edx, [_WinMapAddress] |
mov ebx,[CURRENT_TASK] |
mov bh,[esp+4*3] |
np2412: |
cmp bl,[edx] |
jnz imp24no12 |
; mov eax,[esi] |
push dword [esp+4*3+20] |
call ebp |
; cmp bh,0 |
; jz imp24yes12 |
; call dbcplimit |
; jnz imp24no12 |
imp24yes12: |
push edi |
push eax |
mov eax,edi |
sub eax,VGABasePtr |
shr eax,16 |
call set_bank |
pop eax |
and edi,0xffff |
add edi,VGABasePtr |
mov [edi],ax |
shr eax,16 |
mov [edi+2],al |
pop edi |
imp24no12: |
inc edx |
; add esi,3 |
add edi,3 |
dec ecx |
jnz np2412 |
np24d12: |
pop ebx |
pop ecx |
pop edi |
add edi,[BytesPerScanLine] |
add esi,[esp+32] |
cmp ebp,putimage_get1bpp |
jz .correct |
cmp ebp,putimage_get2bpp |
jz .correct |
cmp ebp,putimage_get4bpp |
jnz @f |
.correct: |
mov eax,[esp+20] |
mov byte[eax],80h |
@@: |
dec ebx |
jnz newpi12 |
nonewpi12: |
pop eax edx ecx ebx eax edi esi |
xor eax, eax |
ret |
pi32bit12: |
newpi3212: |
push edi |
push ecx |
push ebx |
mov edx,edi |
sub edx,VGABasePtr |
shr edx,2 |
add edx, [_WinMapAddress] |
mov ebx,[CURRENT_TASK] |
mov bh,[esp+4*3] |
np3212: |
cmp bl,[edx] |
jnz imp32no12 |
; mov eax,[esi] |
push dword [esp+4*3+20] |
call ebp |
; cmp bh,0 |
; jz imp32yes12 |
; call dbcplimit |
; jnz imp32no12 |
imp32yes12: |
push edi |
push eax |
mov eax,edi |
sub eax,VGABasePtr |
shr eax,16 |
call set_bank |
pop eax |
and edi,0xffff |
mov [edi+VGABasePtr],eax |
pop edi |
imp32no12: |
inc edx |
; add esi,3 |
add edi,4 |
dec ecx |
jnz np3212 |
np32d12: |
pop ebx |
pop ecx |
pop edi |
add edi,[BytesPerScanLine] |
cmp ebp,putimage_get1bpp |
jz .correct |
cmp ebp,putimage_get2bpp |
jz .correct |
cmp ebp,putimage_get4bpp |
jnz @f |
.correct: |
mov eax,[esp+20] |
mov byte[eax],80h |
@@: |
dec ebx |
jnz newpi3212 |
nonewpi3212: |
pop eax edx ecx ebx eax edi esi |
xor eax, eax |
ret |
vesa12_read_screen_pixel: |
and eax,0x3FFFFF |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jz v12rsp24 |
mov edi,eax |
shl edi,2 |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
v12rsp24: |
imul eax,3 |
mov edi,eax |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/video/vesa20.inc |
---|
0,0 → 1,1150 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VESA20.INC ;; |
;; ;; |
;; Vesa 2.0 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; Alexey, kgaz@crosswindws.net ;; |
;; - Voodoo compatible graphics ;; |
;; Juan M. Caravaca ;; |
;; - Graphics optimimizations eg. drawline ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; If you're planning to write your own video driver I suggest |
; you replace the VESA12.INC file and see those instructions. |
;Screen_Max_X equ 0xfe00 |
;Screen_Max_Y equ 0xfe04 |
;BytesPerScanLine equ 0xfe08 |
;LFBAddress equ 0xfe80 |
;ScreenBPP equ 0xfbf1 |
;************************************************* |
; getpixel |
; |
; in: |
; eax = x coordinate |
; ebx = y coordinate |
; |
; ret: |
; ecx = 00 RR GG BB |
getpixel: |
push eax ebx edx edi |
call dword [GETPIXEL] |
pop edi edx ebx eax |
ret |
Vesa20_getpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
add edi, ebx ; edi = x*3+(y*y multiplier) |
mov ecx, [LFB_BASE+edi] |
and ecx, 0xffffff |
ret |
Vesa20_getpixel32: |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) |
mov ecx, [LFB_BASE+edi] |
and ecx, 0xffffff |
ret |
;************************************************* |
virtual at esp |
putimg: |
.real_sx dd ? |
.real_sy dd ? |
.image_sx dd ? |
.image_sy dd ? |
.image_cx dd ? |
.image_cy dd ? |
.pti dd ? |
.abs_cx dd ? |
.abs_cy dd ? |
.line_increment dd ? |
.winmap_newline dd ? |
.screen_newline dd ? |
.stack_data = 4*12 |
.edi dd ? |
.esi dd ? |
.ebp dd ? |
.esp dd ? |
.ebx dd ? |
.edx dd ? |
.ecx dd ? |
.eax dd ? |
.ret_addr dd ? |
.arg_0 dd ? |
end virtual |
align 16 |
; ebx = pointer |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
; ebp = pointer to 'get' function |
; esi = pointer to 'init' function |
; edi = parameter for 'get' function |
vesa20_putimage: |
pushad |
call [_display.disable_mouse] |
sub esp, putimg.stack_data |
; save pointer to image |
mov [putimg.pti], ebx |
; unpack the size |
mov eax, ecx |
and ecx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_sx], eax |
mov [putimg.image_sy], ecx |
; unpack the coordinates |
mov eax, edx |
and edx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_cx], eax |
mov [putimg.image_cy], edx |
; calculate absolute (i.e. screen) coordinates |
mov eax, [TASK_BASE] |
mov ebx, [eax-twdw + WDATA.box.left] |
add ebx, [putimg.image_cx] |
mov [putimg.abs_cx], ebx |
mov ebx, [eax-twdw + WDATA.box.top] |
add ebx, [putimg.image_cy] |
mov [putimg.abs_cy], ebx |
; real_sx = MIN(wnd_sx-image_cx, image_sx); |
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx |
; \begin{diamond}[20.08.2006] |
; note that WDATA.box.width is one pixel less than real window x-size |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [putimg.image_cx] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sx] |
jbe .end_x |
mov ebx, [putimg.image_sx] |
.end_x: |
mov [putimg.real_sx], ebx |
; init real_sy |
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy |
; \begin{diamond}[20.08.2006] |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [putimg.image_cy] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sy] |
jbe .end_y |
mov ebx, [putimg.image_sy] |
.end_y: |
mov [putimg.real_sy], ebx |
; line increment |
mov eax, [putimg.image_sx] |
mov ecx, [putimg.real_sx] |
sub eax, ecx |
;; imul eax, [putimg.source_bpp] |
; lea eax, [eax + eax * 2] |
call esi |
add eax, [putimg.arg_0] |
mov [putimg.line_increment], eax |
; winmap new line increment |
mov eax, [Screen_Max_X] |
inc eax |
sub eax, [putimg.real_sx] |
mov [putimg.winmap_newline], eax |
; screen new line increment |
mov eax, [BytesPerScanLine] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul ecx, ebx |
sub eax, ecx |
mov [putimg.screen_newline], eax |
; pointer to image |
mov esi, [putimg.pti] |
; pointer to screen |
mov edx, [putimg.abs_cy] |
imul edx, [BytesPerScanLine] |
mov eax, [putimg.abs_cx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul eax, ebx |
add edx, eax |
; pointer to pixel map |
mov eax, [putimg.abs_cy] |
imul eax, [Screen_Max_X] |
add eax, [putimg.abs_cy] |
add eax, [putimg.abs_cx] |
add eax, [_WinMapAddress] |
xchg eax, ebp |
; get process number |
mov ebx, [CURRENT_TASK] |
cmp byte [ScreenBPP], 32 |
je put_image_end_32 |
;put_image_end_24: |
mov edi, [putimg.real_sy] |
align 4 |
.new_line: |
mov ecx, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
push [putimg.edi] |
mov eax, [putimg.ebp+4] |
call eax |
cmp [ebp], bl |
jne .skip |
; mov eax, [esi] ; eax = RRBBGGRR |
mov [LFB_BASE+edx], ax |
shr eax, 16 |
mov [LFB_BASE+edx+2], al |
.skip: |
; add esi, 3 ;[putimg.source_bpp] |
add edx, 3 |
inc ebp |
dec ecx |
jnz .new_x |
; pop edx ebp |
add esi, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[Screen_Max_X] |
; inc ebp |
cmp [putimg.ebp], putimage_get1bpp |
jz .correct |
cmp [putimg.ebp], putimage_get2bpp |
jz .correct |
cmp [putimg.ebp], putimage_get4bpp |
jnz @f |
.correct: |
mov eax, [putimg.edi] |
mov byte [eax], 80h |
@@: |
dec edi |
jnz .new_line |
.finish: |
add esp, putimg.stack_data |
popad |
ret |
put_image_end_32: |
mov edi, [putimg.real_sy] |
align 4 |
.new_line: |
mov ecx, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
push [putimg.edi] |
mov eax, [putimg.ebp+4] |
call eax |
cmp [ebp], bl |
jne .skip |
; mov eax, [esi] ; ecx = RRBBGGRR |
mov [LFB_BASE+edx], eax |
.skip: |
; add esi, [putimg.source_bpp] |
add edx, 4 |
inc ebp |
dec ecx |
jnz .new_x |
; pop edx ebp |
add esi, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[Screen_Max_X] |
; inc ebp |
cmp [putimg.ebp], putimage_get1bpp |
jz .correct |
cmp [putimg.ebp], putimage_get2bpp |
jz .correct |
cmp [putimg.ebp], putimage_get4bpp |
jnz @f |
.correct: |
mov eax, [putimg.edi] |
mov byte [eax], 80h |
@@: |
dec edi |
jnz .new_line |
.finish: |
add esp, putimg.stack_data |
popad |
call VGA__putimage |
mov [EGA_counter],1 |
ret |
;************************************************* |
align 4 |
__sys_putpixel: |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;;; mov [novesachecksum], dword 0 |
pushad |
cmp [Screen_Max_X], eax |
jb .exit |
cmp [Screen_Max_Y], ebx |
jb .exit |
test edi,1 ; force ? |
jnz .forced |
; not forced: |
push eax |
mov edx,[_display.width] ; screen x size |
imul edx, ebx |
add eax, [_WinMapAddress] |
movzx edx, byte [eax+edx] |
cmp edx, [CURRENT_TASK] |
pop eax |
jne .exit |
.forced: |
; check if negation |
test ecx,0x01000000 |
jz .noneg |
call getpixel |
not ecx |
mov [esp+32-8],ecx |
.noneg: |
; OK to set pixel |
call dword [PUTPIXEL] ; call the real put_pixel function |
.exit: |
popad |
ret |
align 4 |
Vesa20_putpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
mov eax, [esp+32-8+4] |
mov [LFB_BASE+ebx+edi], ax |
shr eax, 16 |
mov [LFB_BASE+ebx+edi+2], al |
ret |
align 4 |
Vesa20_putpixel32: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) |
mov eax, [esp+32-8+4] ; eax = color |
mov [LFB_BASE+edi], eax |
ret |
;************************************************* |
;align 4 |
calculate_edi: |
mov edi, ebx |
imul edi, [Screen_Max_X] |
add edi, ebx |
add edi, eax |
ret |
;************************************************* |
; DRAWLINE |
align 4 |
__sys_draw_line: |
; inc [mouse_pause] |
call [_display.disable_mouse] |
; draw a line |
; eax = HIWORD = x1 |
; LOWORD = x2 |
; ebx = HIWORD = y1 |
; LOWORD = y2 |
; ecx = color |
; edi = force ? |
pusha |
dl_x1 equ esp+20 |
dl_y1 equ esp+16 |
dl_x2 equ esp+12 |
dl_y2 equ esp+8 |
dl_dx equ esp+4 |
dl_dy equ esp+0 |
xor edx, edx ; clear edx |
xor esi, esi ; unpack arguments |
xor ebp, ebp |
mov si, ax ; esi = x2 |
mov bp, bx ; ebp = y2 |
shr eax, 16 ; eax = x1 |
shr ebx, 16 ; ebx = y1 |
push eax ; save x1 |
push ebx ; save y1 |
push esi ; save x2 |
push ebp ; save y2 |
; checking x-axis... |
sub esi, eax ; esi = x2-x1 |
push esi ; save y2-y1 |
jl .x2lx1 ; is x2 less than x1 ? |
jg .no_vline ; x1 > x2 ? |
mov edx, ebp ; else (if x1=x2) |
call vline |
push edx ; necessary to rightly restore stack frame at .exit |
jmp .exit |
.x2lx1: |
neg esi ; get esi absolute value |
.no_vline: |
; checking y-axis... |
sub ebp, ebx ; ebp = y2-y1 |
push ebp ; save y2-y1 |
jl .y2ly1 ; is y2 less than y1 ? |
jg .no_hline ; y1 > y2 ? |
mov edx, [dl_x2] ; else (if y1=y2) |
call hline |
jmp .exit |
.y2ly1: |
neg ebp ; get ebp absolute value |
.no_hline: |
cmp ebp, esi |
jle .x_rules ; |y2-y1| < |x2-x1| ? |
cmp [dl_y2], ebx ; make sure y1 is at the begining |
jge .no_reverse1 |
neg dword [dl_dx] |
mov edx, [dl_x2] |
mov [dl_x2], eax |
mov [dl_x1], edx |
mov edx, [dl_y2] |
mov [dl_y2], ebx |
mov [dl_y1], edx |
.no_reverse1: |
mov eax, [dl_dx] |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) |
mov edx, ebp ; edx = counter (number of pixels to draw) |
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0 |
mov esi, eax ; esi = dx |
jmp .y_rules |
.x_rules: |
cmp [dl_x2], eax ; make sure x1 is at the begining |
jge .no_reverse2 |
neg dword [dl_dy] |
mov edx, [dl_x2] |
mov [dl_x2], eax |
mov [dl_x1], edx |
mov edx, [dl_y2] |
mov [dl_y2], ebx |
mov [dl_y1], edx |
.no_reverse2: |
xor edx, edx |
mov eax, [dl_dy] |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) |
mov edx, esi ; edx = counter (number of pixels to draw) |
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0 |
mov ebp, eax ; ebp = dy |
.y_rules: |
mov eax, [dl_x1] |
mov ebx, [dl_y1] |
shl eax, 16 |
shl ebx, 16 |
align 4 |
.draw: |
push eax ebx |
shr eax, 16 |
shr ebx, 16 |
call [putpixel] |
pop ebx eax |
add ebx, ebp ; y = y+dy |
add eax, esi ; x = x+dx |
dec edx |
jnz .draw |
; force last drawn pixel to be at (x2,y2) |
mov eax, [dl_x2] |
mov ebx, [dl_y2] |
call [putpixel] |
.exit: |
add esp, 6*4 |
popa |
; dec [mouse_pause] |
call [draw_pointer] |
ret |
hline: |
; draw an horizontal line |
; eax = x1 |
; edx = x2 |
; ebx = y |
; ecx = color |
; edi = force ? |
push eax edx |
cmp edx, eax ; make sure x2 is above x1 |
jge @f |
xchg eax, edx |
align 4 |
@@: |
call [putpixel] |
inc eax |
cmp eax, edx |
jle @b |
pop edx eax |
ret |
vline: |
; draw a vertical line |
; eax = x |
; ebx = y1 |
; edx = y2 |
; ecx = color |
; edi = force ? |
push ebx edx |
cmp edx, ebx ; make sure y2 is above y1 |
jge @f |
xchg ebx, edx |
align 4 |
@@: |
call [putpixel] |
inc ebx |
cmp ebx, edx |
jle @b |
pop edx ebx |
ret |
;************************************************* |
virtual at esp |
drbar: |
.bar_sx dd ? |
.bar_sy dd ? |
.bar_cx dd ? |
.bar_cy dd ? |
.abs_cx dd ? |
.abs_cy dd ? |
.real_sx dd ? |
.real_sy dd ? |
.color dd ? |
.line_inc_scr dd ? |
.line_inc_map dd ? |
.stack_data = 4*11 |
end virtual |
align 4 |
; eax cx |
; ebx cy |
; ecx xe |
; edx ye |
; edi color |
vesa20_drawbar: |
pushad |
call [_display.disable_mouse] |
sub esp, drbar.stack_data |
mov [drbar.color], edi |
sub edx, ebx |
jle .exit ;// mike.dld, 2005-01-29 |
sub ecx, eax |
jle .exit ;// mike.dld, 2005-01-29 |
mov [drbar.bar_sy], edx |
mov [drbar.bar_sx], ecx |
mov [drbar.bar_cx], eax |
mov [drbar.bar_cy], ebx |
mov edi, [TASK_BASE] |
add eax, [edi-twdw + WDATA.box.left] ; win_cx |
add ebx, [edi-twdw + WDATA.box.top] ; win_cy |
mov [drbar.abs_cx], eax |
mov [drbar.abs_cy], ebx |
; real_sx = MIN(wnd_sx-bar_cx, bar_sx); |
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx |
; \begin{diamond}[20.08.2006] |
; note that WDATA.box.width is one pixel less than real window x-size |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [drbar.bar_cx] |
ja @f |
.exit: ;// mike.dld, 2005-01-29 |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sx] |
jbe .end_x |
mov ebx, [drbar.bar_sx] |
.end_x: |
mov [drbar.real_sx], ebx |
; real_sy = MIN(wnd_sy-bar_cy, bar_sy); |
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy |
; \begin{diamond}[20.08.2006] |
inc ebx |
; \end{diamond} |
sub ebx, [drbar.bar_cy] |
ja @f |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sy] |
jbe .end_y |
mov ebx, [drbar.bar_sy] |
.end_y: |
mov [drbar.real_sy], ebx |
; line_inc_map |
mov eax, [Screen_Max_X] |
sub eax, [drbar.real_sx] |
inc eax |
mov [drbar.line_inc_map], eax |
; line_inc_scr |
mov eax, [drbar.real_sx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul eax, ebx |
neg eax |
add eax, [BytesPerScanLine] |
mov [drbar.line_inc_scr], eax |
; pointer to screen |
mov edx, [drbar.abs_cy] |
imul edx, [BytesPerScanLine] |
mov eax, [drbar.abs_cx] |
; movzx ebx, byte [ScreenBPP] |
; shr ebx, 3 |
imul eax, ebx |
add edx, eax |
; pointer to pixel map |
mov eax, [drbar.abs_cy] |
imul eax, [Screen_Max_X] |
add eax, [drbar.abs_cy] |
add eax, [drbar.abs_cx] |
add eax, [_WinMapAddress] |
xchg eax, ebp |
; get process number |
mov ebx, [CURRENT_TASK] |
cmp byte [ScreenBPP], 24 |
jne draw_bar_end_32 |
draw_bar_end_24: |
mov eax, [drbar.color] ;; BBGGRR00 |
mov bh, al ;; bh = BB |
shr eax, 8 ;; eax = RRGG |
; eax - color high RRGG |
; bl - process num |
; bh - color low BB |
; ecx - temp |
; edx - pointer to screen |
; esi - counter |
; edi - counter |
mov esi, [drbar.real_sy] |
align 4 |
.new_y: |
mov edi, [drbar.real_sx] |
align 4 |
.new_x: |
cmp byte [ebp], bl |
jne .skip |
mov [LFB_BASE+edx], bh |
mov [LFB_BASE+edx + 1], ax |
.skip: |
; add pixel |
add edx, 3 |
inc ebp |
dec edi |
jnz .new_x |
; add line |
add edx, [drbar.line_inc_scr] |
add ebp, [drbar.line_inc_map] |
; <Ivan 15.10.04> drawing gradient bars |
test eax, 0x00800000 |
jz @f |
test bh, bh |
jz @f |
dec bh |
@@: |
; </Ivan 15.10.04> |
dec esi |
jnz .new_y |
add esp, drbar.stack_data |
popad |
xor eax, eax |
ret |
draw_bar_end_32: |
mov eax, [drbar.color] ;; BBGGRR00 |
mov esi, [drbar.real_sy] |
align 4 |
.new_y: |
mov edi, [drbar.real_sx] |
align 4 |
.new_x: |
cmp byte [ebp], bl |
jne .skip |
mov [LFB_BASE+edx], eax |
.skip: |
; add pixel |
add edx, 4 |
inc ebp |
dec edi |
jnz .new_x |
; add line |
add edx, [drbar.line_inc_scr] |
add ebp, [drbar.line_inc_map] |
; <Ivan 15.10.04> drawing gradient bars |
test eax, 0x80000000 |
jz @f |
test al, al |
jz @f |
dec al |
@@: |
; </Ivan 15.10.04> |
dec esi |
jnz .new_y |
add esp, drbar.stack_data |
popad |
call VGA_draw_bar |
xor eax, eax |
mov [EGA_counter],1 |
ret |
align 4 |
vesa20_drawbackground_tiled: |
call [_display.disable_mouse] |
pushad |
; External loop for all y from start to end |
mov ebx, [draw_data+32+RECT.top] ; y start |
dp2: |
mov ebp, [draw_data+32+RECT.left] ; x start |
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] |
; and LFB data (output for our function) [edi] |
mov eax, [BytesPerScanLine] |
mul ebx |
xchg ebp, eax |
add ebp, eax |
add ebp, eax |
add ebp, eax |
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp, eax |
@@: |
add ebp, LFB_BASE |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
xchg edi, ebp |
add ebp, [_WinMapAddress] |
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress |
; 2) Calculate offset in background memory block |
push eax |
xor edx, edx |
mov eax, ebx |
div dword [BgrDataHeight] ; edx := y mod BgrDataHeight |
pop eax |
push eax |
mov ecx, [BgrDataWidth] |
mov esi, edx |
imul esi, ecx ; esi := (y mod BgrDataHeight) * BgrDataWidth |
xor edx, edx |
div ecx ; edx := x mod BgrDataWidth |
sub ecx, edx |
add esi, edx ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth) |
pop eax |
lea esi, [esi*3] |
add esi, [img_background] |
xor edx, edx |
inc edx |
; 3) Loop through redraw rectangle and copy background data |
; Registers meaning: |
; eax = x, ebx = y (screen coordinates) |
; ecx = deltax - number of pixels left in current tile block |
; edx = 1 |
; esi -> bgr memory, edi -> output |
; ebp = offset in WinMapAddress |
dp3: |
cmp [ebp], dl |
jnz nbgp |
movsb |
movsb |
movsb |
jmp @f |
nbgp: |
add esi, 3 |
add edi, 3 |
@@: |
cmp [ScreenBPP], byte 25 ; 24 or 32 bpp? |
sbb edi, -1 ; +1 for 32 bpp |
; I do not use 'inc eax' because this is slightly slower then 'add eax,1' |
add ebp, edx |
add eax, edx |
cmp eax, [draw_data+32+RECT.right] |
ja dp4 |
sub ecx, edx |
jnz dp3 |
; next tile block on x-axis |
mov ecx, [BgrDataWidth] |
sub esi, ecx |
sub esi, ecx |
sub esi, ecx |
jmp dp3 |
dp4: |
; next scan line |
inc ebx |
cmp ebx, [draw_data+32+RECT.bottom] |
jbe dp2 |
popad |
mov [EGA_counter], 1 |
call VGA_drawbackground |
ret |
; ---------- |
vesa20_drawbackground_stretch: |
call [_display.disable_mouse] |
pushad |
; Helper variables |
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1) |
mov eax, [BgrDataWidth] |
dec eax |
xor edx, edx |
div dword [Screen_Max_X] |
push eax ; high |
xor eax, eax |
div dword [Screen_Max_X] |
push eax ; low |
; the same for height |
mov eax, [BgrDataHeight] |
dec eax |
xor edx, edx |
div dword [Screen_Max_Y] |
push eax ; high |
xor eax, eax |
div dword [Screen_Max_Y] |
push eax ; low |
; External loop for all y from start to end |
mov ebx, [draw_data+32+RECT.top] ; y start |
mov ebp, [draw_data+32+RECT.left] ; x start |
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] |
; and LFB data (output for our function) [edi] |
mov eax, [BytesPerScanLine] |
mul ebx |
xchg ebp, eax |
add ebp, eax |
add ebp, eax |
add ebp, eax |
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp, eax |
@@: |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
xchg edi, ebp |
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress |
push ebx |
push eax |
; 2) Calculate offset in background memory block |
mov eax, ebx |
imul ebx, dword [esp+12] |
mul dword [esp+8] |
add edx, ebx ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1) |
mov esi, edx |
imul esi, [BgrDataWidth] |
push edx |
push eax |
mov eax, [esp+8] |
mul dword [esp+28] |
push eax |
mov eax, [esp+12] |
mul dword [esp+28] |
add [esp], edx |
pop edx ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1) |
add esi, edx |
lea esi, [esi*3] |
add esi, [img_background] |
push eax |
push edx |
push esi |
; 3) Smooth horizontal |
bgr_resmooth0: |
mov ecx, [esp+8] |
mov edx, [esp+4] |
mov esi, [esp] |
push edi |
mov edi, bgr_cur_line |
call smooth_line |
bgr_resmooth1: |
mov eax, [esp+16+4] |
inc eax |
cmp eax, [BgrDataHeight] |
jae bgr.no2nd |
mov ecx, [esp+8+4] |
mov edx, [esp+4+4] |
mov esi, [esp+4] |
add esi, [BgrDataWidth] |
add esi, [BgrDataWidth] |
add esi, [BgrDataWidth] |
mov edi, bgr_next_line |
call smooth_line |
bgr.no2nd: |
pop edi |
sdp3: |
xor esi, esi |
mov ecx, [esp+12] |
; 4) Loop through redraw rectangle and copy background data |
; Registers meaning: |
; esi = offset in current line, edi -> output |
; ebp = offset in WinMapAddress |
; dword [esp] = offset in bgr data |
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1) |
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1) |
; dword [esp+20] = x |
; dword [esp+24] = y |
; precalculated constants: |
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1) |
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1) |
sdp3a: |
mov eax, [_WinMapAddress] |
cmp [ebp+eax], byte 1 |
jnz snbgp |
mov eax, [bgr_cur_line+esi] |
test ecx, ecx |
jz .novert |
mov ebx, [bgr_next_line+esi] |
call [overlapping_of_points_ptr] |
.novert: |
mov [LFB_BASE+edi], ax |
shr eax, 16 |
mov [LFB_BASE+edi+2], al |
snbgp: |
cmp [ScreenBPP], byte 25 |
sbb edi, -4 |
add ebp, 1 |
mov eax, [esp+20] |
add eax, 1 |
mov [esp+20], eax |
add esi, 4 |
cmp eax, [draw_data+32+RECT.right] |
jbe sdp3a |
sdp4: |
; next y |
mov ebx, [esp+24] |
add ebx, 1 |
mov [esp+24], ebx |
cmp ebx, [draw_data+32+RECT.bottom] |
ja sdpdone |
; advance edi, ebp to next scan line |
sub eax, [draw_data+32+RECT.left] |
sub ebp, eax |
add ebp, [Screen_Max_X] |
add ebp, 1 |
sub edi, eax |
sub edi, eax |
sub edi, eax |
cmp [ScreenBPP], byte 24 |
jz @f |
sub edi, eax |
@@: |
add edi, [BytesPerScanLine] |
; restore ecx,edx; advance esi to next background line |
mov eax, [esp+28] |
mov ebx, [esp+32] |
add [esp+12], eax |
mov eax, [esp+16] |
adc [esp+16], ebx |
sub eax, [esp+16] |
mov ebx, eax |
lea eax, [eax*3] |
imul eax, [BgrDataWidth] |
sub [esp], eax |
mov eax, [draw_data+32+RECT.left] |
mov [esp+20], eax |
test ebx, ebx |
jz sdp3 |
cmp ebx, -1 |
jnz bgr_resmooth0 |
push edi |
mov esi, bgr_next_line |
mov edi, bgr_cur_line |
mov ecx, [Screen_Max_X] |
inc ecx |
rep movsd |
jmp bgr_resmooth1 |
sdpdone: |
add esp, 44 |
popad |
mov [EGA_counter],1 |
call VGA_drawbackground |
ret |
uglobal |
align 4 |
bgr_cur_line rd 1280 ; maximum width of screen |
bgr_next_line rd 1280 |
endg |
smooth_line: |
mov al, [esi+2] |
shl eax, 16 |
mov ax, [esi] |
test ecx, ecx |
jz @f |
mov ebx, [esi+2] |
shr ebx, 8 |
call [overlapping_of_points_ptr] |
@@: |
stosd |
mov eax, [esp+20+8] |
add eax, 1 |
mov [esp+20+8], eax |
cmp eax, [draw_data+32+RECT.right] |
ja @f |
add ecx, [esp+36+8] |
mov eax, edx |
adc edx, [esp+40+8] |
sub eax, edx |
lea eax, [eax*3] |
sub esi, eax |
jmp smooth_line |
@@: |
mov eax, [draw_data+32+RECT.left] |
mov [esp+20+8], eax |
ret |
align 16 |
overlapping_of_points: |
if 0 |
; this version of procedure works, but is slower than next version |
push ecx edx |
mov edx, eax |
push esi |
shr ecx, 24 |
mov esi, ecx |
mov ecx, ebx |
movzx ebx, dl |
movzx eax, cl |
sub eax, ebx |
movzx ebx, dh |
imul eax, esi |
add dl, ah |
movzx eax, ch |
sub eax, ebx |
imul eax, esi |
add dh, ah |
ror ecx, 16 |
ror edx, 16 |
movzx eax, cl |
movzx ebx, dl |
sub eax, ebx |
imul eax, esi |
pop esi |
add dl, ah |
mov eax, edx |
pop edx |
ror eax, 16 |
pop ecx |
ret |
else |
push ecx edx |
mov edx, eax |
push esi |
shr ecx, 26 |
mov esi, ecx |
mov ecx, ebx |
shl esi, 9 |
movzx ebx, dl |
movzx eax, cl |
sub eax, ebx |
movzx ebx, dh |
add dl, [BgrAuxTable+(eax+0x100)+esi] |
movzx eax, ch |
sub eax, ebx |
add dh, [BgrAuxTable+(eax+0x100)+esi] |
ror ecx, 16 |
ror edx, 16 |
movzx eax, cl |
movzx ebx, dl |
sub eax, ebx |
add dl, [BgrAuxTable+(eax+0x100)+esi] |
pop esi |
mov eax, edx |
pop edx |
ror eax, 16 |
pop ecx |
ret |
end if |
iglobal |
align 4 |
overlapping_of_points_ptr dd overlapping_of_points |
endg |
init_background: |
mov edi, BgrAuxTable |
xor edx, edx |
.loop2: |
mov eax, edx |
shl eax, 8 |
neg eax |
mov ecx, 0x200 |
.loop1: |
mov byte [edi], ah |
inc edi |
add eax, edx |
loop .loop1 |
add dl, 4 |
jnz .loop2 |
test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8) |
jz @f |
mov [overlapping_of_points_ptr], overlapping_of_points_mmx |
@@: |
ret |
align 16 |
overlapping_of_points_mmx: |
movd mm0, eax |
movd mm4, eax |
movd mm1, ebx |
pxor mm2, mm2 |
punpcklbw mm0, mm2 |
punpcklbw mm1, mm2 |
psubw mm1, mm0 |
movd mm3, ecx |
psrld mm3, 24 |
packuswb mm3, mm3 |
packuswb mm3, mm3 |
pmullw mm1, mm3 |
psrlw mm1, 8 |
packuswb mm1, mm2 |
paddb mm4, mm1 |
movd eax, mm4 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/video/vga.inc |
---|
0,0 → 1,450 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VGA.INC ;; |
;; ;; |
;; 640x480 mode 0x12 VGA functions for MenuetOS ;; |
;; ;; |
;; Paul Butcher, paul.butcher@asa.co.uk ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
paletteVGA: |
;16 colour palette |
mov dx,0x3c8 |
mov al,0 |
out dx,al |
mov ecx,16 |
mov dx,0x3c9 |
xor eax,eax |
palvganew: |
mov al,0 |
test ah,4 |
jz palvgalbl1 |
add al,31 |
test ah,8 |
jz palvgalbl1 |
add al,32 |
palvgalbl1: |
out dx,al ; red 0,31 or 63 |
mov al,0 |
test ah,2 |
jz palvgalbl2 |
add al,31 |
test ah,8 |
jz palvgalbl2 |
add al,32 |
palvgalbl2: |
out dx,al ; blue 0,31 or 63 |
mov al,0 |
test ah,1 |
jz palvgalbl3 |
add al,31 |
test ah,8 |
jz palvgalbl3 |
add al,32 |
palvgalbl3: |
out dx,al ; green 0,31 or 63 |
add ah,1 |
loop palvganew |
; mov dx, 3ceh |
; mov ax, 0005h |
; out dx, ax |
ret |
palette320x200: |
mov edx,0x3c8 |
xor eax, eax |
out dx,al |
mov ecx,256 |
mov edx,0x3c9 |
xor eax,eax |
palnew: |
mov al,0 |
test ah,64 |
jz pallbl1 |
add al,21 |
pallbl1: |
test ah,128 |
jz pallbl2 |
add al,42 |
pallbl2: |
out dx,al |
mov al,0 |
test ah,8 |
jz pallbl3 |
add al,8 |
pallbl3: |
test ah,16 |
jz pallbl4 |
add al,15 |
pallbl4: |
test ah,32 |
jz pallbl5 |
add al,40 |
pallbl5: |
out dx,al |
mov al,0 |
test ah,1 |
jz pallbl6 |
add al,8 |
pallbl6: |
test ah,2 |
jz pallbl7 |
add al,15 |
pallbl7: |
test ah,4 |
jz pallbl8 |
add al,40 |
pallbl8: |
out dx,al |
add ah,1 |
loop palnew |
ret |
align 4 |
uglobal |
novesachecksum dd 0x0 |
EGA_counter db 0 |
VGA_drawing_screen db 0 |
VGA_8_pixels: |
rb 16 |
temp: |
.cx dd 0 |
endg |
align 4 |
checkVga_N13: |
cmp [SCR_MODE],dword 0x13 |
jne @f |
; cnvl: |
pushad |
cmp [EGA_counter],1 |
je novesal |
mov ecx,[MOUSE_X] |
cmp ecx,[novesachecksum] |
jne novesal |
popad |
@@: |
ret |
novesal: |
mov [novesachecksum],ecx |
mov ecx,0 |
movzx eax,word [MOUSE_Y] |
cmp eax,100 |
jge m13l3 |
mov eax,100 |
m13l3: |
cmp eax,480-100 |
jbe m13l4 |
mov eax,480-100 |
m13l4: |
sub eax,100 |
imul eax,640*4 |
add ecx,eax |
movzx eax,word [MOUSE_X] |
cmp eax,160 |
jge m13l1 |
mov eax,160 |
m13l1: |
cmp eax,640-160 |
jbe m13l2 |
mov eax,640-160 |
m13l2: |
sub eax,160 |
shl eax,2 |
add ecx,eax |
mov esi,[LFBAddress] |
add esi,ecx |
mov edi,VGABasePtr |
mov edx,200 |
mov ecx,320 |
cld |
m13pix: |
lodsd |
test eax,eax |
jz .save_pixel |
push eax |
mov ebx,eax |
and eax,(128+64+32) ; blue |
shr eax,5 |
and ebx,(128+64+32)*256 ; green |
shr ebx,8+2 |
add eax,ebx |
pop ebx |
and ebx,(128+64)*256*256 ; red |
shr ebx,8+8 |
add eax,ebx |
.save_pixel: |
stosb |
loop m13pix |
mov ecx,320 |
add esi,4*(640-320) |
dec edx |
jnz m13pix |
mov [EGA_counter],0 |
popad |
ret |
VGA_drawbackground: |
; draw all |
cmp [SCR_MODE],dword 0x12 |
jne .end |
pushad |
mov esi,[LFBAddress] |
mov edi,VGABasePtr |
mov ebx,640/32 ; 640*480/(8*4) |
mov edx,480 |
@@: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
dec edx |
jnz @r |
call VGA_draw_long_line_1 |
popad |
.end: |
ret |
VGA_draw_long_line: |
mov dx,3ceh |
mov ax,0ff08h |
cli |
out dx, ax |
mov ax,0005h |
out dx, ax |
m12pix: |
call VGA_draw_32_pixels |
dec ebx |
jnz m12pix |
mov dx,3c4h |
mov ax,0ff02h |
out dx,ax |
mov dx,3ceh |
mov ax,0205h |
out dx,ax |
mov dx,3ceh |
mov al,08h |
out dx,al |
sti |
ret |
VGA_draw_32_pixels: |
xor eax,eax |
mov ebp,VGA_8_pixels |
mov [ebp],eax |
mov [ebp+4],eax |
mov [ebp+8],eax |
mov [ebp+12],eax |
mov ch,4 |
.main_loop: |
mov cl,8 |
.convert_pixels_to_VGA: |
lodsd ; eax = 24bit colour |
test eax,eax |
jz .end |
rol eax,8 |
mov al,ch |
ror eax,8 |
mov ch,1 |
dec cl |
shl ch,cl |
cmp al,85 |
jbe .p13green |
or [ebp],ch |
cmp al,170 |
jbe .p13green |
or [ebp+12],ch |
.p13green: |
cmp ah,85 |
jbe .p13red |
or [ebp+4],ch |
cmp ah,170 |
jbe .p13red |
or [ebp+12],ch |
.p13red: |
shr eax,8 |
cmp ah,85 |
jbe .p13cont |
or [ebp+8],ch |
cmp ah,170 |
jbe .p13cont |
or [ebp+12],ch |
.p13cont: |
ror eax,8 |
mov ch,ah |
inc cl |
.end: |
dec cl |
jnz .convert_pixels_to_VGA |
inc ebp |
dec ch |
jnz .main_loop |
push esi |
sub ebp,4 |
mov esi,ebp |
mov dx, 3c4h |
mov ah, 1h |
@@: |
mov al, 02h |
out dx,ax |
xchg ax,bp |
lodsd |
mov [edi],eax |
xchg ax,bp |
shl ah, 1 |
cmp ah, 10h |
jnz @r |
add edi,4 |
pop esi |
ret |
VGA_putpixel: |
; eax = x |
; ebx = y |
mov ecx,eax |
mov eax, [esp+32-8+4] ; color |
shl ebx,9 |
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov edi,edx |
add edi, [LFBAddress] ; + LFB address |
mov [edi], eax ; write to LFB for Vesa2.0 |
shr edx,5 ; change BytesPerPixel to 1/8 |
mov edi,edx |
add edi, VGABasePtr ; address of pixel in VGA area |
and ecx,0x07 ; bit no. (modulo 8) |
pushfd |
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) |
xor edx,edx |
test eax,eax |
jz .p13cont |
cmp al,85 |
jbe .p13green |
or dl,0x01 |
cmp al,170 |
jbe .p13green |
or dl,0x08 |
.p13green: |
cmp ah,85 |
jbe .p13red |
or dl,0x02 |
cmp ah,170 |
jbe .p13red |
or dl,0x08 |
.p13red: |
shr eax,8 |
cmp ah,85 |
jbe .p13cont |
or dl,0x04 |
cmp ah,170 |
jbe .p13cont |
or dl,0x08 |
.p13cont: |
ror edx,8 |
inc cl |
xor eax,eax |
inc ah |
shr ax,cl |
mov dx,3cfh |
cli |
out dx,al |
mov al,[edi] ; dummy read |
rol edx,8 |
mov [edi],dl |
popfd |
;.end: |
ret |
VGA__putimage: |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
cmp [SCR_MODE],dword 0x12 |
jne @f |
pushad |
rol edx,16 |
movzx eax,dx |
rol edx,16 |
movzx ebx,dx |
movzx edx,cx |
rol ecx,16 |
movzx ecx,cx |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar: |
; eax cx |
; ebx cy |
; ecx xe |
; edx ye |
cmp [SCR_MODE],dword 0x12 |
jne @f |
pushad |
sub ecx,eax |
sub edx,ebx |
and eax,0xffff |
and ebx,0xffff |
and ecx,0xffff |
and edx,0xffff |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar_1: |
mov [temp.cx],eax |
mov eax, [TASK_BASE] |
add ebx, [eax-twdw + 4] |
mov eax, [eax-twdw + 0] |
add eax, [temp.cx] |
and eax,0xfff8 |
shl ebx,9 |
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov esi,ebx |
add esi, [LFBAddress] ; + LFB address |
shr ebx,5 ; change BytesPerPixel to 1/8 |
mov edi,ebx |
add edi, VGABasePtr ; address of pixel in VGA area |
mov ebx,ecx |
shr ebx,5 |
inc ebx |
.main_loop: |
call VGA_draw_long_line_1 |
dec edx |
jnz .main_loop |
call VGA_draw_long_line_1 |
ret |
VGA_draw_long_line_1: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/video/arrow.cur |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/video |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/fdo.inc |
---|
0,0 → 1,439 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
_esp equ esp |
; |
; Formatted Debug Output (FDO) |
; Copyright (c) 2005-2006, mike.dld |
; Created: 2005-01-29, Changed: 2006-11-10 |
; |
; For questions and bug reports, mail to mike.dld@gmail.com |
; |
; Available format specifiers are: %s, %d, %u, %x (with partial width support) |
; |
; to be defined: |
; __DEBUG__ equ 1 |
; __DEBUG_LEVEL__ equ 5 |
macro debug_func name { |
if used name |
name@of@func equ name |
} |
macro debug_beginf { |
align 4 |
name@of@func: |
} |
debug_endf fix end if |
macro DEBUGS _sign,[_str] { |
common |
local tp |
tp equ 0 |
match _arg:_num,_str \{ |
DEBUGS_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _str \{ |
DEBUGS_N _sign,,_arg |
\} |
} |
macro DEBUGS_N _sign,_num,[_str] { |
common |
pushf |
pushad |
local ..str,..label,is_str |
is_str = 0 |
forward |
if _str eqtype '' |
is_str = 1 |
end if |
common |
if is_str = 1 |
jmp ..label |
..str db _str,0 |
..label: |
; add esp,4*8+4 |
esp equ esp+4*8+4 |
mov edx,..str |
esp equ _esp |
; sub esp,4*8+4 |
else |
mov edx,_str |
end if |
if ~_num eq |
if _num eqtype eax |
if _num in <eax,ebx,ecx,edx,edi,ebp,esp> |
mov esi,_num |
else if ~_num eq esi |
movzx esi,_num |
end if |
else if _num eqtype 0 |
mov esi,_num |
else |
local tp |
tp equ 0 |
match [_arg],_num \{ |
mov esi,dword[_arg] |
tp equ 1 |
\} |
match =0 =dword[_arg],tp _num \{ |
mov esi,dword[_arg] |
tp equ 1 |
\} |
match =0 =word[_arg],tp _num \{ |
movzx esi,word[_arg] |
tp equ 1 |
\} |
match =0 =byte[_arg],tp _num \{ |
movzx esi,byte[_arg] |
tp equ 1 |
\} |
match =0,tp \{ |
'Error: specified string width is incorrect' |
\} |
end if |
else |
mov esi,0x7FFFFFFF |
end if |
call fdo_debug_outstr |
popad |
popf |
} |
macro DEBUGD _sign,_dec { |
local tp |
tp equ 0 |
match _arg:_num,_dec \{ |
DEBUGD_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _dec \{ |
DEBUGD_N _sign,,_arg |
\} |
} |
macro DEBUGD_N _sign,_num,_dec { |
pushf |
pushad |
if (~_num eq) |
if (_dec eqtype eax | _dec eqtype 0) |
'Error: precision allowed only for in-memory variables' |
end if |
if (~_num in <1,2,4>) |
if _sign |
'Error: 1, 2 and 4 are only allowed for precision in %d' |
else |
'Error: 1, 2 and 4 are only allowed for precision in %u' |
end if |
end if |
end if |
if _dec eqtype eax |
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp> |
mov eax,_dec |
else if ~_dec eq eax |
if _sign = 1 |
movsx eax,_dec |
else |
movzx eax,_dec |
end if |
end if |
else if _dec eqtype 0 |
mov eax,_dec |
else |
; add esp,4*8+4 |
esp equ esp+4*8+4 |
if _num eq |
mov eax,dword _dec |
else if _num = 1 |
if _sign = 1 |
movsx eax,byte _dec |
else |
movzx eax,byte _dec |
end if |
else if _num = 2 |
if _sign = 1 |
movsx eax,word _dec |
else |
movzx eax,word _dec |
end if |
else |
mov eax,dword _dec |
end if |
esp equ _esp |
; sub esp,4*8+4 |
end if |
mov cl,_sign |
call fdo_debug_outdec |
popad |
popf |
} |
macro DEBUGH _sign,_hex { |
local tp |
tp equ 0 |
match _arg:_num,_hex \{ |
DEBUGH_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _hex \{ |
DEBUGH_N _sign,,_arg |
\} |
} |
macro DEBUGH_N _sign,_num,_hex { |
pushf |
pushad |
if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>) |
'Error: 1..8 are only allowed for precision in %x' |
end if |
if _hex eqtype eax |
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp> |
if ~_hex eq eax |
mov eax,_hex |
end if |
mov edx,8 |
else if _hex in <ax,bx,cx,dx,si,di,bp,sp> |
if ~_hex eq ax |
movzx eax,_hex |
end if |
if (_num eq) |
mov edx,4 |
end if |
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh> |
if ~_hex eq al |
movzx eax,_hex |
end if |
if (_num eq) |
mov edx,2 |
end if |
end if |
else if _hex eqtype 0 |
mov eax,_hex |
else |
; add esp,4*8+4 |
esp equ esp+4*8+4 |
mov eax,dword _hex |
esp equ _esp |
; sub esp,4*8+4 |
end if |
if ~_num eq |
mov edx,_num |
else |
if ~_hex eqtype eax |
mov edx,8 |
end if |
end if |
call fdo_debug_outhex |
popad |
popf |
} |
;----------------------------------------------------------------------------- |
debug_func fdo_debug_outchar |
debug_beginf |
pushad |
movzx ebx,al |
mov eax,1 |
mov ecx,sys_msg_board |
call ecx ; sys_msg_board |
popad |
ret |
debug_endf |
debug_func fdo_debug_outstr |
debug_beginf |
mov eax,1 |
.l1: dec esi |
js .l2 |
movzx ebx,byte[edx] |
or bl,bl |
jz .l2 |
mov ecx,sys_msg_board |
call ecx ; sys_msg_board |
inc edx |
jmp .l1 |
.l2: ret |
debug_endf |
debug_func fdo_debug_outdec |
debug_beginf |
or cl,cl |
jz @f |
or eax,eax |
jns @f |
neg eax |
push eax |
mov al,'-' |
call fdo_debug_outchar |
pop eax |
@@: push 10 |
pop ecx |
push -'0' |
.l1: xor edx,edx |
div ecx |
push edx |
test eax,eax |
jnz .l1 |
.l2: pop eax |
add al,'0' |
jz .l3 |
call fdo_debug_outchar |
jmp .l2 |
.l3: ret |
debug_endf |
debug_func fdo_debug_outhex |
__fdo_hexdigits db '0123456789ABCDEF' |
debug_beginf |
mov cl,dl |
neg cl |
add cl,8 |
shl cl,2 |
rol eax,cl |
.l1: rol eax,4 |
push eax |
and eax,0x0000000F |
mov al,[__fdo_hexdigits+eax] |
call fdo_debug_outchar |
pop eax |
dec edx |
jnz .l1 |
ret |
debug_endf |
;----------------------------------------------------------------------------- |
macro DEBUGF _level,_format,[_arg] { |
common |
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__ |
local ..f1,f2,a1,a2,c1,c2,c3,..lbl |
_debug_str_ equ __debug_str_ # a1 |
a1 = 0 |
c2 = 0 |
c3 = 0 |
f2 = 0 |
repeat ..lbl-..f1 |
virtual at 0 |
db _format,0,0 |
load c1 word from %-1 |
end virtual |
if c1 = '%s' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER S,a1,0,_arg |
else if c1 = '%x' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER H,a1,0,_arg |
else if c1 = '%d' | c1 = '%u' |
local c4 |
if c1 = '%d' |
c4 = 1 |
else |
c4 = 0 |
end if |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER D,a1,c4,_arg |
else if c1 = '\n' |
c3 = c3 + 1 |
end if |
end repeat |
virtual at 0 |
db _format,0,0 |
load c1 from f2-c2 |
end virtual |
if (c1<>0)&(f2<>..lbl-..f1-1) |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
virtual at 0 |
..f1 db _format,0 |
..lbl: |
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3 |
end virtual |
end if |
} |
macro __include_debug_strings dummy,[_id,_fmt,_len] { |
common |
local c1,a1,a2 |
forward |
if defined _len & ~_len eq |
_id: |
a1 = 0 |
a2 = 0 |
repeat _len |
virtual at 0 |
db _fmt,0,0 |
load c1 word from %+a2-1 |
end virtual |
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u') |
db 0 |
a2 = a2 + 1 |
else if (c1='\n') |
dw $0A0D |
a1 = a1 + 1 |
a2 = a2 + 1 |
else |
db c1 and 0x0FF |
end if |
end repeat |
db 0 |
end if |
} |
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] { |
common |
local num |
num = 0 |
forward |
if num = _num |
DEBUG#_letter _sign,_arg |
end if |
num = num+1 |
common |
_num = _num+1 |
} |
macro include_debug_strings { |
if __DEBUG__ = 1 |
match dbg_str,__debug_strings \{ |
__include_debug_strings dbg_str |
\} |
end if |
} |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/const.inc |
---|
0,0 → 1,767 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
dpl0 equ 10010000b ; data read dpl0 |
drw0 equ 10010010b ; data read/write dpl0 |
drw3 equ 11110010b ; data read/write dpl3 |
cpl0 equ 10011010b ; code read dpl0 |
cpl3 equ 11111010b ; code read dpl3 |
D32 equ 01000000b ; 32bit segment |
G32 equ 10000000b ; page gran |
;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; |
CPU_386 equ 3 |
CPU_486 equ 4 |
CPU_PENTIUM equ 5 |
CPU_P6 equ 6 |
CPU_PENTIUM4 equ 0x0F |
CAPS_FPU equ 00 ;on-chip x87 floating point unit |
CAPS_VME equ 01 ;virtual-mode enhancements |
CAPS_DE equ 02 ;debugging extensions |
CAPS_PSE equ 03 ;page-size extensions |
CAPS_TSC equ 04 ;time stamp counter |
CAPS_MSR equ 05 ;model-specific registers |
CAPS_PAE equ 06 ;physical-address extensions |
CAPS_MCE equ 07 ;machine check exception |
CAPS_CX8 equ 08 ;CMPXCHG8B instruction |
CAPS_APIC equ 09 ;on-chip advanced programmable |
; interrupt controller |
; 10 ;unused |
CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions |
CAPS_MTRR equ 12 ;memory-type range registers |
CAPS_PGE equ 13 ;page global extension |
CAPS_MCA equ 14 ;machine check architecture |
CAPS_CMOV equ 15 ;conditional move instructions |
CAPS_PAT equ 16 ;page attribute table |
CAPS_PSE36 equ 17 ;page-size extensions |
CAPS_PSN equ 18 ;processor serial number |
CAPS_CLFLUSH equ 19 ;CLFUSH instruction |
CAPS_DS equ 21 ;debug store |
CAPS_ACPI equ 22 ;thermal monitor and software |
;controlled clock supported |
CAPS_MMX equ 23 ;MMX instructions |
CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions |
CAPS_SSE equ 25 ;SSE instructions |
CAPS_SSE2 equ 26 ;SSE2 instructions |
CAPS_SS equ 27 ;self-snoop |
CAPS_HTT equ 28 ;hyper-threading technology |
CAPS_TM equ 29 ;thermal monitor supported |
CAPS_IA64 equ 30 ;IA64 capabilities |
CAPS_PBE equ 31 ;pending break enable |
;ecx |
CAPS_SSE3 equ 32 ;SSE3 instructions |
; 33 |
; 34 |
CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions |
CAPS_DS_CPL equ 36 ; |
CAPS_VMX equ 37 ;virtual mode extensions |
; 38 ; |
CAPS_EST equ 39 ;enhansed speed step |
CAPS_TM2 equ 40 ;thermal monitor2 supported |
; 41 |
CAPS_CID equ 42 ; |
; 43 |
; 44 |
CAPS_CX16 equ 45 ;CMPXCHG16B instruction |
CAPS_xTPR equ 46 ; |
; |
;reserved |
; |
;ext edx /ecx |
CAPS_SYSCAL equ 64 ; |
CAPS_XD equ 65 ;execution disable |
CAPS_FFXSR equ 66 ; |
CAPS_RDTSCP equ 67 ; |
CAPS_X64 equ 68 ; |
CAPS_3DNOW equ 69 ; |
CAPS_3DNOWEXT equ 70 ; |
CAPS_LAHF equ 71 ; |
CAPS_CMP_LEG equ 72 ; |
CAPS_SVM equ 73 ;secure virual machine |
CAPS_ALTMOVCR8 equ 74 ; |
; CPU MSR names |
MSR_SYSENTER_CS equ 0x174 |
MSR_SYSENTER_ESP equ 0x175 |
MSR_SYSENTER_EIP equ 0x176 |
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register |
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register |
CR0_PE equ 0x00000001 ;protected mode |
CR0_MP equ 0x00000002 ;monitor fpu |
CR0_EM equ 0x00000004 ;fpu emulation |
CR0_TS equ 0x00000008 ;task switch |
CR0_ET equ 0x00000010 ;extension type hardcoded to 1 |
CR0_NE equ 0x00000020 ;numeric error |
CR0_WP equ 0x00010000 ;write protect |
CR0_AM equ 0x00040000 ;alignment check |
CR0_NW equ 0x20000000 ;not write-through |
CR0_CD equ 0x40000000 ;cache disable |
CR0_PG equ 0x80000000 ;paging |
CR4_VME equ 0x0001 |
CR4_PVI equ 0x0002 |
CR4_TSD equ 0x0004 |
CR4_DE equ 0x0008 |
CR4_PSE equ 0x0010 |
CR4_PAE equ 0x0020 |
CR4_MCE equ 0x0040 |
CR4_PGE equ 0x0080 |
CR4_PCE equ 0x0100 |
CR4_OSFXSR equ 0x0200 |
CR4_OSXMMEXPT equ 0x0400 |
SSE_IE equ 0x0001 |
SSE_DE equ 0x0002 |
SSE_ZE equ 0x0004 |
SSE_OE equ 0x0008 |
SSE_UE equ 0x0010 |
SSE_PE equ 0x0020 |
SSE_DAZ equ 0x0040 |
SSE_IM equ 0x0080 |
SSE_DM equ 0x0100 |
SSE_ZM equ 0x0200 |
SSE_OM equ 0x0400 |
SSE_UM equ 0x0800 |
SSE_PM equ 0x1000 |
SSE_FZ equ 0x8000 |
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) |
struc TSS |
{ |
._back rw 2 |
._esp0 rd 1 |
._ss0 rw 2 |
._esp1 rd 1 |
._ss1 rw 2 |
._esp2 rd 1 |
._ss2 rw 2 |
._cr3 rd 1 |
._eip rd 1 |
._eflags rd 1 |
._eax rd 1 |
._ecx rd 1 |
._edx rd 1 |
._ebx rd 1 |
._esp rd 1 |
._ebp rd 1 |
._esi rd 1 |
._edi rd 1 |
._es rw 2 |
._cs rw 2 |
._ss rw 2 |
._ds rw 2 |
._fs rw 2 |
._gs rw 2 |
._ldt rw 2 |
._trap rw 1 |
._io rw 1 |
rb 24 |
._io_map_0 rb 4096 |
._io_map_1 rb 4096 |
} |
virtual at 0 |
TSS TSS |
end virtual |
TSS_SIZE equ (128+8192) |
OS_BASE equ 0x80000000 |
window_data equ (OS_BASE+0x0001000) |
CURRENT_TASK equ (OS_BASE+0x0003000) |
TASK_COUNT equ (OS_BASE+0x0003004) |
TASK_BASE equ (OS_BASE+0x0003010) |
TASK_DATA equ (OS_BASE+0x0003020) |
TASK_EVENT equ (OS_BASE+0x0003020) |
mouseunder equ (OS_BASE+0x0006900) |
CDDataBuf equ (OS_BASE+0x0007000) |
FLOPPY_BUFF equ (OS_BASE+0x0008000) |
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused |
idts equ (OS_BASE+0x000B100) |
WIN_STACK equ (OS_BASE+0x000C000) |
WIN_POS equ (OS_BASE+0x000C400) |
FDD_BUFF equ (OS_BASE+0x000D000) |
;unused ? only one reference |
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000) |
PUTPIXEL equ (OS_BASE+0x000E020) |
GETPIXEL equ (OS_BASE+0x000E024) |
;unused ? only one reference |
BANK_SWITCH equ (OS_BASE+0x000E030) |
;unused ? store mousepointer |
MOUSE_PICTURE equ (OS_BASE+0x000F200) |
MOUSE_VISIBLE equ (OS_BASE+0x000F204) |
WIN_TEMP_XY equ (OS_BASE+0x000F300) |
KEY_COUNT equ (OS_BASE+0x000F400) |
KEY_BUFF equ (OS_BASE+0x000F401) |
BTN_COUNT equ (OS_BASE+0x000F500) |
BTN_BUFF equ (OS_BASE+0x000F501) |
CPU_FREQ equ (OS_BASE+0x000F600) |
;unused ? no active references |
MOUSE_PORT equ (OS_BASE+0x000F604) |
;unused |
PS2_CHUNK equ (OS_BASE+0x000FB00) |
MOUSE_SCROLL_H equ (OS_BASE+0x000FB08) |
MOUSE_X equ (OS_BASE+0x000FB0A) |
MOUSE_Y equ (OS_BASE+0x000FB0C) |
MOUSE_SCROLL_V equ (OS_BASE+0x000FB0E) |
MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10) |
COLOR_TEMP equ (OS_BASE+0x000FB30) |
BTN_DOWN equ (OS_BASE+0x000FB40) |
MOUSE_DOWN equ (OS_BASE+0x000FB44) |
X_UNDER equ (OS_BASE+0x000FB4A) |
Y_UNDER equ (OS_BASE+0x000FB4C) |
ScreenBPP equ (OS_BASE+0x000FBF1) |
;unused ? only one reference |
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) |
LFBAddress equ (OS_BASE+0x000FE80) |
MEM_AMOUNT equ (OS_BASE+0x000FE8C) |
Screen_Max_X equ (OS_BASE+0x000FE00) |
Screen_Max_Y equ (OS_BASE+0x000FE04) |
BytesPerScanLine equ (OS_BASE+0x000FE08) |
SCR_MODE equ (OS_BASE+0x000FE0C) |
BTN_ADDR equ (OS_BASE+0x000FE88) |
SYS_SHUTDOWN equ (OS_BASE+0x000FF00) |
TASK_ACTIVATE equ (OS_BASE+0x000FF01) |
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0) |
BANK_RW equ (OS_BASE+0x000FFF2) |
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) |
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) |
DONT_SWITCH equ (OS_BASE+0x000FFFF) |
TMP_STACK_TOP equ 0x006CC00 |
FONT_II equ (OS_BASE+0x006DC00) |
FONT_I equ (OS_BASE+0x006E600) |
sys_pgdir equ (OS_BASE+0x006F000) |
DRIVE_DATA equ (OS_BASE+0x0070000) |
SLOT_BASE equ (OS_BASE+0x0080000) |
;unused |
TMP_BUFF equ (OS_BASE+0x0090000) |
VGABasePtr equ (OS_BASE+0x00A0000) |
RAMDISK equ (OS_BASE+0x0100000) |
RAMDISK_FAT equ (OS_BASE+0x0280000) |
FLOPPY_FAT equ (OS_BASE+0x0282000) |
IDE_DMA equ 0x284000 |
BgrAuxTable equ (OS_BASE+0x0298000) |
; unused? |
SB16Buffer equ (OS_BASE+0x2A0000) |
SB16_Status equ (OS_BASE+0x02B0000) |
BUTTON_INFO equ (OS_BASE+0x02C0000) |
RESERVED_PORTS equ (OS_BASE+0x02D0000) |
IRQ_SAVE equ (OS_BASE+0x02E0000) |
BOOT_VAR equ (OS_BASE+0x02f0000) |
stack_data_start equ (OS_BASE+0x0300000) |
eth_data_start equ (OS_BASE+0x0300000) |
stack_data equ (OS_BASE+0x0304000) |
stack_data_end equ (OS_BASE+0x031ffff) |
resendQ equ (OS_BASE+0x0320000) |
VMODE_BASE equ (OS_BASE+0x0328000) |
skin_data equ (OS_BASE+0x0330000) |
draw_data equ (OS_BASE+0x0338000); |
BgrDrawMode equ (OS_BASE+0x033BFF4) |
BgrDataWidth equ (OS_BASE+0x033BFF8) |
BgrDataHeight equ (OS_BASE+0x033BFFC) |
sys_pgmap equ (OS_BASE+0x033C000) |
virtual at (OS_BASE+0x05FFF80) |
tss TSS |
end virtual |
HEAP_BASE equ (OS_BASE+0x0800000) |
HEAP_MIN_SIZE equ 0x01000000 |
page_tabs equ 0xFDC00000 |
app_page_tabs equ 0xFDC00000 |
kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000 |
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000 |
LFB_BASE equ 0xFE000000 |
new_app_base equ 0; |
twdw equ 0x2000 ;(CURRENT_TASK-window_data) |
std_application_base_address equ new_app_base |
RING0_STACK_SIZE equ (0x2000 - 512) ;512 áàéò äëÿ êîíòåêñòà FPU |
REG_SS equ (RING0_STACK_SIZE-4) |
REG_APP_ESP equ (RING0_STACK_SIZE-8) |
REG_EFLAGS equ (RING0_STACK_SIZE-12) |
REG_CS equ (RING0_STACK_SIZE-16) |
REG_EIP equ (RING0_STACK_SIZE-20) |
REG_EAX equ (RING0_STACK_SIZE-24) |
REG_ECX equ (RING0_STACK_SIZE-28) |
REG_EDX equ (RING0_STACK_SIZE-32) |
REG_EBX equ (RING0_STACK_SIZE-36) |
REG_ESP equ (RING0_STACK_SIZE-40) ;RING0_STACK_SIZE-20 |
REG_EBP equ (RING0_STACK_SIZE-44) |
REG_ESI equ (RING0_STACK_SIZE-48) |
REG_EDI equ (RING0_STACK_SIZE-52) |
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return |
PG_UNMAP equ 0x000 |
PG_MAP equ 0x001 |
PG_WRITE equ 0x002 |
PG_SW equ 0x003 |
PG_USER equ 0x005 |
PG_UW equ 0x007 |
PG_NOCACHE equ 0x018 |
PG_LARGE equ 0x080 |
PG_GLOBAL equ 0x100 |
PG_SHARED equ 0x200 |
;;;;;;;;;;;boot time variables |
;BOOT_BPP equ 0x9000 ;byte bits per pixel |
BOOT_SCANLINE equ 0x9001 ;word scanline length |
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode |
;;BOOT_X_RES equ 0x900A ;word X res |
;;BOOT_Y_RES equ 0x900C ;word Y res |
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used |
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch |
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address |
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration |
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) |
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled |
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data |
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no |
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr |
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount |
TMP_FILE_NAME equ 0 |
TMP_CMD_LINE equ 1024 |
TMP_ICON_OFFS equ 1280 |
EVENT_REDRAW equ 0x00000001 |
EVENT_KEY equ 0x00000002 |
EVENT_BUTTON equ 0x00000004 |
EVENT_BACKGROUND equ 0x00000010 |
EVENT_MOUSE equ 0x00000020 |
EVENT_IPC equ 0x00000040 |
EVENT_NETWORK equ 0x00000080 |
EVENT_DEBUG equ 0x00000100 |
EVENT_EXTENDED equ 0x00000200 |
EV_INTR equ 1 |
struc THR_DATA |
{ |
rb (8192-512) |
.pl0_stack: |
.fpu_state rb 512 |
.tls_page rb 4096 |
.pdbr rb 4096 |
} |
THR_DATA_SIZE equ 4096*4 |
virtual at (OS_BASE-THR_DATA_SIZE) |
thr_data THR_DATA |
end virtual |
struc SYS_VARS |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
} |
struc APPOBJ ;common object header |
{ |
.magic dd ? ; |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
}; |
virtual at 0 |
APPOBJ APPOBJ |
end virtual |
APP_OBJ_OFFSET equ 48 |
APP_EV_OFFSET equ 40 |
struc CURSOR |
{ |
;common object header |
.magic dd ? ;'CURS' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
;cursor data |
.base dd ? ;allocated memory |
.hot_x dd ? ;hotspot coords |
.hot_y dd ? |
.list_next dd ? ;next cursor in cursor list |
.list_prev dd ? ;prev cursor in cursor list |
.dev_obj dd ? ;device depended data |
.sizeof: |
} |
virtual at 0 |
CURSOR CURSOR |
end virtual |
struc EVENT |
{ |
.magic dd ? ;'EVNT' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.id dd ? ;event uid |
.state dd ? ;internal flags |
.code dd ? |
rd 5 |
.size = $ - .magic |
.codesize = $ - .code |
} |
virtual at 0 |
EVENT EVENT |
end virtual |
struc SMEM |
{ |
.bk dd ? |
.fd dd ? ;+4 |
.base dd ? ;+8 |
.size dd ? ;+12 |
.access dd ? ;+16 |
.refcount dd ? ;+20 |
.name rb 32 ;+24 |
.sizeof: |
} |
struc SMAP |
{ |
.magic dd ? ; SMAP |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.base dd ? ;mapped base |
.parent dd ? ;SMEM |
.sizeof: |
} |
virtual at 0 |
SMEM SMEM |
end virtual |
virtual at 0 |
SMAP SMAP |
end virtual |
struc DLLDESCR |
{ |
.bk dd ? |
.fd dd ? ;+4 |
.data dd ? ;+8 |
.size dd ? ;+12 |
.timestamp dq ? |
.refcount dd ? |
.defaultbase dd ? |
.coff_hdr dd ? |
.symbols_ptr dd ? |
.symbols_num dd ? |
.symbols_lim dd ? |
.exports dd ? ;export table |
.name: |
.sizeof: |
} |
struc HDLL |
{ |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.base dd ? ;mapped base |
.size dd ? ;mapped size |
.refcount dd ? ;reference counter for this process and this lib |
.parent dd ? ;DLLDESCR |
.sizeof: |
} |
virtual at 0 |
DLLDESCR DLLDESCR |
end virtual |
virtual at 0 |
HDLL HDLL |
end virtual |
struc display_t |
{ |
.x dd ? |
.y dd ? |
.width dd ? |
.height dd ? |
.bpp dd ? |
.vrefresh dd ? |
.pitch dd ? |
.lfb dd ? |
.modes dd ? |
.ddev dd ? |
.connector dd ? |
.crtc dd ? |
.cr_list.next dd ? |
.cr_list.prev dd ? |
.cursor dd ? |
.init_cursor dd ? |
.select_cursor dd ? |
.show_cursor dd ? |
.move_cursor dd ? |
.restore_cursor dd ? |
.disable_mouse dd ? |
} |
virtual at 0 |
display_t display_t |
end virtual |
struc HEAP_DATA |
{ |
.mutex rd 1 |
.refcount rd 1 |
.heap_base rd 1 |
.heap_top rd 1 |
.app_mem rd 1 |
} |
HEAP_DATA_SIZE equ 20 |
virtual at 0 |
HEAP_DATA HEAP_DATA |
end virtual |
struc BOOT_DATA |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
.mouse_port dd ? |
.bank_switch dd ? |
.lfb dd ? |
.vesa_mem dd ? |
.log dd ? |
.direct_lfb dd ? |
.pci_data dd ? |
; dd ? |
.vrr dd ? |
.ide_base dd ? |
.mem_amount dd ? |
.pages_count dd ? |
.pagemap_size dd ? |
.kernel_max dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.cpu_vendor dd ? |
dd ? |
dd ? |
.cpu_sign dd ? |
.cpu_info dd ? |
.cpu_caps dd ? |
dd ? |
dd ? |
} |
virtual at 0 |
BOOT_DATA BOOT_DATA |
end virtual |
struc MEM_STATE |
{ .mutex rd 1 |
.smallmap rd 1 |
.treemap rd 1 |
.topsize rd 1 |
.top rd 1 |
.smallbins rd 4*32 |
.treebins rd 32 |
} |
struc PG_DATA |
{ .mem_amount dd ? |
.vesa_mem dd ? |
.pages_count dd ? |
.pages_free dd ? |
.pages_faults dd ? |
.pagemap_size dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.sys_page_dir dd ? |
.pg_mutex dd ? |
} |
;struc LIB |
;{ .lib_name rb 16 |
; .lib_base dd ? |
; .lib_start dd ? |
; .export dd ? |
; .import dd ? |
;} |
struc SRV |
{ |
.srv_name rb 16 ;ASCIIZ string |
.magic dd ? ;+0x10 ;'SRV ' |
.size dd ? ;+0x14 ;size of structure SRV |
.fd dd ? ;+0x18 ;next SRV descriptor |
.bk dd ? ;+0x1C ;prev SRV descriptor |
.base dd ? ;+0x20 ;service base address |
.entry dd ? ;+0x24 ;service START function |
.srv_proc dd ? ;+0x28 ;user mode service handler |
.srv_proc_ex dd ? ;+0x2C ;kernel mode service handler |
.sizeof: |
} |
SRV_FD_OFFSET equ 0x18 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
struc COFF_HEADER |
{ .machine dw ? |
.nSections dw ? |
.DataTime dd ? |
.pSymTable dd ? |
.nSymbols dd ? |
.optHeader dw ? |
.flags dw ? |
}; |
struc COFF_SECTION |
{ .Name rb 8 |
.VirtualSize dd ? |
.VirtualAddress dd ? |
.SizeOfRawData dd ? |
.PtrRawData dd ? |
.PtrReloc dd ? |
.PtrLinenumbers dd ? |
.NumReloc dw ? |
.NumLinenum dw ? |
.Characteristics dd ? |
} |
COFF_SECTION_SIZE equ 40 |
struc COFF_RELOC |
{ .VirtualAddress dd ? |
.SymIndex dd ? |
.Type dw ? |
} |
struc COFF_SYM |
{ .Name rb 8 |
.Value dd ? |
.SectionNumber dw ? |
.Type dw ? |
.StorageClass db ? |
.NumAuxSymbols db ? |
} |
CSYM_SIZE equ 18 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
;virtual at 0 |
; LIB LIB |
;end virtual |
virtual at 0 |
SRV SRV |
end virtual |
virtual at 0 |
CFH COFF_HEADER |
end virtual |
virtual at 0 |
CFS COFF_SECTION |
end virtual |
virtual at 0 |
CRELOC COFF_RELOC |
end virtual |
virtual at 0 |
CSYM COFF_SYM |
end virtual |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/kernel32.inc |
---|
0,0 → 1,279 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; KERNEL32.INC ;; |
;; ;; |
;; Included 32 bit kernel files for MenuetOS ;; |
;; ;; |
;; This file is kept separate as it will be easier to ;; |
;; maintain and compile with an automated SETUP program ;; |
;; in the future. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;struc db [a] { common . db a |
; if ~used . |
; display 'not used db: ',`.,13,10 |
; end if } |
;struc dw [a] { common . dw a |
; if ~used . |
; display 'not used dw: ',`.,13,10 |
; end if } |
;struc dd [a] { common . dd a |
; if ~used . |
; display 'not used dd: ',`.,13,10 |
; end if } |
;struc dp [a] { common . dp a |
; if ~used . |
; display 'not used dp: ',`.,13,10 |
; end if } |
;struc dq [a] { common . dq a |
; if ~used . |
; display 'not used dq: ',`.,13,10 |
; end if } |
;struc dt [a] { common . dt a |
; if ~used . |
; display 'not used dt: ',`.,13,10 |
; end if } |
struc RECT { |
.left dd ? |
.top dd ? |
.right dd ? |
.bottom dd ? |
} |
virtual at 0 |
RECT RECT |
end virtual |
struc BOX { |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
} |
virtual at 0 |
BOX BOX |
end virtual |
struc DISPMODE { |
.width rw 1 |
.height rw 1 |
.bpp rw 1 |
.freq rw 1 |
} |
; constants definition |
WSTATE_NORMAL = 00000000b |
WSTATE_MAXIMIZED = 00000001b |
WSTATE_MINIMIZED = 00000010b |
WSTATE_ROLLEDUP = 00000100b |
WSTATE_REDRAW = 00000001b |
WSTATE_WNDDRAWN = 00000010b |
WSTYLE_HASCAPTION = 00010000b |
WSTYLE_CLIENTRELATIVE = 00100000b |
struc TASKDATA |
{ |
.event_mask dd ? |
.pid dd ? |
dw ? |
.state db ? |
db ? |
dw ? |
.wnd_number db ? |
db ? |
.mem_start dd ? |
.counter_sum dd ? |
.counter_add dd ? |
.cpu_usage dd ? |
} |
virtual at 0 |
TASKDATA TASKDATA |
end virtual |
; structures definition |
struc WDATA { |
.box BOX |
.cl_workarea dd ? |
.cl_titlebar dd ? |
.cl_frames dd ? |
.reserved db ? |
.fl_wstate db ? |
.fl_wdrawn db ? |
.fl_redraw db ? |
} |
virtual at 0 |
WDATA WDATA |
end virtual |
label WDATA.fl_wstyle byte at 0x13 |
struc APPDATA |
{ |
.app_name db 11 dup(?) |
db 5 dup(?) |
.fpu_state dd ? ;+16 |
.ev_count_ dd ? ;unused ;+20 |
.exc_handler dd ? ;+24 |
.except_mask dd ? ;+28 |
.pl0_stack dd ? ;unused ;+32 |
.heap_base dd ? ;+36 |
.heap_top dd ? ;+40 |
.cursor dd ? ;+44 |
.fd_ev dd ? ;+48 |
.bk_ev dd ? ;+52 |
.fd_obj dd ? ;+56 |
.bk_obj dd ? ;+60 |
.saved_esp dd ? ;+64 |
.io_map rd 2 ;+68 |
.dbg_state dd ? ;+76 |
.cur_dir dd ? ;+80 |
.wait_timeout dd ? ;+84 |
.saved_esp0 dd ? ;+88 |
.wait_begin dd ? ;+92 +++ |
.wait_test dd ? ;+96 +++ |
.wait_param dd ? ;+100 +++ |
.tls_base dd ? ;+104 |
.dlls_list_ptr dd ? ;+108 |
db 16 dup(?) ;+112 |
.wnd_shape dd ? ;+128 |
.wnd_shape_scale dd ? ;+132 |
dd ? ;+136 |
.mem_size dd ? ;+140 |
.saved_box BOX |
.ipc_start dd ? |
.ipc_size dd ? |
.event_mask dd ? |
.debugger_slot dd ? |
dd ? |
.keyboard_mode db ? |
db 3 dup(?) |
.dir_table dd ? |
.dbg_event_mem dd ? |
.dbg_regs: |
.dbg_regs.dr0 dd ? |
.dbg_regs.dr1 dd ? |
.dbg_regs.dr2 dd ? |
.dbg_regs.dr3 dd ? |
.dbg_regs.dr7 dd ? |
.wnd_caption dd ? |
.wnd_clientbox BOX |
} |
virtual at 0 |
APPDATA APPDATA |
end virtual |
;// mike.dld, 2006-29-01 ] |
; Core functions |
include "core/sync.inc" ; macros for synhronization objects |
include "core/sys32.inc" ; process management |
include "core/sched.inc" ; process scheduling |
include "core/syscall.inc" ; system call |
include "core/fpu.inc" ; all fpu/sse support |
include "core/memory.inc" |
include "core/heap.inc" ; kernel and app heap |
include "core/malloc.inc" ; small kernel heap |
include "core/taskman.inc" |
include "core/dll.inc" |
include "core/peload.inc" ; |
include "core/exports.inc" |
include "core/string.inc" |
include "core/v86.inc" ; virtual-8086 manager |
; GUI stuff |
include "gui/window.inc" |
include "gui/event.inc" |
include "gui/font.inc" |
include "gui/button.inc" |
; shutdown |
; file system |
include "fs/fs.inc" ; syscall |
include "fs/fat32.inc" ; read / write for fat32 filesystem |
include "fs/ntfs.inc" ; read / write for ntfs filesystem |
include "fs/fat12.inc" ; read / write for fat12 filesystem |
include "blkdev/rd.inc" ; ramdisk read /write |
include "fs/fs_lfn.inc" ; syscall, version 2 |
include "fs/iso9660.inc" ; read for iso9660 filesystem CD |
; sound |
include "sound/playnote.inc" ; player Note for Speaker PC |
; display |
include "video/vesa12.inc" ; Vesa 1.2 functions |
include "video/vesa20.inc" ; Vesa 2.0 functions |
include "video/vga.inc" ; VGA 16 color functions |
include "video/cursors.inc" ; cursors functions |
; Network Interface & TCPIP Stack |
include "network/stack.inc" |
;include "drivers/uart.inc" |
; Mouse pointer |
include "gui/mouse.inc" |
; Window skinning |
include "gui/skincode.inc" |
; Pci functions |
include "bus/pci/pci32.inc" |
; Floppy drive controller |
include "blkdev/fdc.inc" |
include "blkdev/flp_drv.inc" |
; IDE cache |
include "blkdev/ide_cache.inc" |
; HD drive controller |
include "blkdev/hd_drv.inc" |
; CD drive controller |
include "blkdev/cdrom.inc" |
include "blkdev/cd_drv.inc" |
; Character devices |
include "hid/keyboard.inc" |
include "hid/mousedrv.inc" |
; setting date,time,clock and alarm-clock |
include "hid/set_dtc.inc" |
;% -include |
;parser file names |
include "fs/parse_fn.inc" |
; work with conf lib |
include "core/conf_lib.inc" |
; load external lib |
include "core/ext_lib.inc" |
; list of external functions |
include "imports.inc" |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc |
---|
0,0 → 1,1145 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
image_of_eax EQU esp+36 |
image_of_ebx EQU esp+24 |
; System function 70 - files with long names (LFN) |
; diamond, 2006 |
iglobal |
; in this table names must be in lowercase |
rootdirs: |
db 2,'rd' |
dd fs_OnRamdisk |
dd fs_NextRamdisk |
db 7,'ramdisk' |
dd fs_OnRamdisk |
dd fs_NextRamdisk |
db 2,'fd' |
dd fs_OnFloppy |
dd fs_NextFloppy |
db 10,'floppydisk' |
dd fs_OnFloppy |
dd fs_NextFloppy |
db 3,'hd0' |
dd fs_OnHd0 |
dd fs_NextHd0 |
db 3,'hd1' |
dd fs_OnHd1 |
dd fs_NextHd1 |
db 3,'hd2' |
dd fs_OnHd2 |
dd fs_NextHd2 |
db 3,'hd3' |
dd fs_OnHd3 |
dd fs_NextHd3 |
;********************************************** |
db 3,'cd0' |
dd fs_OnCd0 |
dd fs_NextCd |
db 3,'cd1' |
dd fs_OnCd1 |
dd fs_NextCd |
db 3,'cd2' |
dd fs_OnCd2 |
dd fs_NextCd |
db 3,'cd3' |
dd fs_OnCd3 |
dd fs_NextCd |
;*********************************************** |
db 0 |
virtual_root_query: |
dd fs_HasRamdisk |
db 'rd',0 |
dd fs_HasFloppy |
db 'fd',0 |
dd fs_HasHd0 |
db 'hd0',0 |
dd fs_HasHd1 |
db 'hd1',0 |
dd fs_HasHd2 |
db 'hd2',0 |
dd fs_HasHd3 |
db 'hd3',0 |
;********************************************** |
dd fs_HasCd0 |
db 'cd0',0 |
dd fs_HasCd1 |
db 'cd1',0 |
dd fs_HasCd2 |
db 'cd2',0 |
dd fs_HasCd3 |
db 'cd3',0 |
;********************************************** |
dd 0 |
fs_additional_handlers: |
dd biosdisk_handler, biosdisk_enum_root |
; add new handlers here |
dd 0 |
endg |
file_system_lfn: |
; in: eax->fileinfo block |
; operation codes: |
; 0 : read file |
; 1 : read folder |
; 2 : create/rewrite file |
; 3 : write/append to file |
; 4 : set end of file |
; 5 : get file/directory attributes structure |
; 6 : set file/directory attributes structure |
; 7 : start application |
; 8 : delete file |
; 9 : create directory |
; parse file name |
xchg ebx, eax |
lea esi, [ebx+20] |
lodsb |
test al, al |
jnz @f |
mov esi, [esi] |
lodsb |
@@: |
cmp al, '/' |
jz .notcurdir |
dec esi |
mov ebp, esi |
test al, al |
jnz @f |
xor ebp, ebp |
@@: |
mov esi, [current_slot] |
mov esi, [esi+APPDATA.cur_dir] |
jmp .parse_normal |
.notcurdir: |
cmp byte [esi], 0 |
jz .rootdir |
call process_replace_file_name |
.parse_normal: |
cmp dword [ebx], 7 |
jne @F |
mov edx, [ebx+4] |
mov ebx, [ebx+8] |
call fs_execute ; esi+ebp, ebx, edx |
mov [image_of_eax], eax |
ret |
@@: |
mov edi, rootdirs-8 |
xor ecx, ecx |
push esi |
.scan1: |
pop esi |
add edi, ecx |
scasd |
scasd |
mov cl, byte [edi] |
test cl, cl |
jz .notfound_try |
inc edi |
push esi |
@@: |
lodsb |
or al, 20h |
scasb |
loopz @b |
jnz .scan1 |
lodsb |
cmp al, '/' |
jz .found1 |
test al, al |
jnz .scan1 |
pop eax |
; directory /xxx |
.maindir: |
mov esi, [edi+4] |
.maindir_noesi: |
cmp dword [ebx], 1 |
jnz .access_denied |
xor eax, eax |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler |
mov edi, edx |
push ecx |
mov ecx, 32/4 |
rep stosd |
pop ecx |
mov byte [edx], 1 ; version |
.maindir_loop: |
call esi |
jc .maindir_done |
inc dword [edx+8] |
dec dword [esp] |
jns .maindir_loop |
dec ebp |
js .maindir_loop |
inc dword [edx+4] |
mov dword [edi], 0x10 ; attributes: folder |
mov dword [edi+4], 1 ; name type: UNICODE |
push eax |
xor eax, eax |
add edi, 8 |
push ecx |
mov ecx, 40/4-2 |
rep stosd |
pop ecx |
pop eax |
push eax edx |
; convert number in eax to decimal UNICODE string |
push edi |
push ecx |
push -'0' |
mov ecx, 10 |
@@: |
xor edx, edx |
div ecx |
push edx |
test eax, eax |
jnz @b |
@@: |
pop eax |
add al, '0' |
stosb |
test bl, 1 ; UNICODE name? |
jz .ansi2 |
mov byte [edi], 0 |
inc edi |
.ansi2: |
test al, al |
jnz @b |
mov byte [edi-1], 0 |
pop ecx |
pop edi |
; UNICODE name length is 520 bytes, ANSI - 264 |
add edi, 520 |
test bl, 1 |
jnz @f |
sub edi, 520-264 |
@@: |
pop edx eax |
jmp .maindir_loop |
.maindir_done: |
pop eax |
mov ebx, [edx+4] |
xor eax, eax |
dec ebp |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
; directory / |
.rootdir: |
cmp dword [ebx], 1 ; read folder? |
jz .readroot |
.access_denied: |
mov dword [image_of_eax], 10 ; access denied |
ret |
.readroot: |
; virtual root folder - special handler |
mov esi, virtual_root_query |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
xor eax, eax |
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area |
mov edi, edx |
mov ecx, 32/4 |
rep stosd |
mov byte [edx], 1 ; version |
.readroot_loop: |
cmp dword [esi], eax |
jz .readroot_done_static |
call dword [esi] |
add esi, 4 |
test eax, eax |
jnz @f |
.readroot_next: |
or ecx, -1 |
xchg esi, edi |
repnz scasb |
xchg esi, edi |
jmp .readroot_loop |
@@: |
xor eax, eax |
inc dword [edx+8] |
dec dword [esp] |
jns .readroot_next |
dec ebp |
js .readroot_next |
inc dword [edx+4] |
mov dword [edi], 0x10 ; attributes: folder |
mov dword [edi+4], ebx ; name type: UNICODE |
add edi, 8 |
mov ecx, 40/4-2 |
rep stosd |
push edi |
@@: |
lodsb |
stosb |
test bl, 1 |
jz .ansi |
mov byte [edi], 0 |
inc edi |
.ansi: |
test eax, eax |
jnz @b |
pop edi |
add edi, 520 |
test bl, 1 |
jnz .readroot_loop |
sub edi, 520-264 |
jmp .readroot_loop |
.readroot_done_static: |
mov esi, fs_additional_handlers-8 |
sub esp, 16 |
.readroot_ah_loop: |
add esi, 8 |
cmp dword [esi], 0 |
jz .readroot_done |
xor eax, eax |
.readroot_ah_loop2: |
push edi |
lea edi, [esp+4] |
call dword [esi+4] |
pop edi |
test eax, eax |
jz .readroot_ah_loop |
inc dword [edx+8] |
dec dword [esp+16] |
jns .readroot_ah_loop2 |
dec ebp |
js .readroot_ah_loop2 |
push eax |
xor eax, eax |
inc dword [edx+4] |
mov dword [edi], 0x10 ; attributes: folder |
mov dword [edi+4], ebx |
add edi, 8 |
mov ecx, 40/4-2 |
rep stosd |
push esi edi |
lea esi, [esp+12] |
@@: |
lodsb |
stosb |
test bl, 1 |
jz .ansi3 |
mov byte [edi], 0 |
inc edi |
.ansi3: |
test al, al |
jnz @b |
pop edi esi eax |
add edi, 520 |
test bl, 1 |
jnz .readroot_ah_loop2 |
sub edi, 520-264 |
jmp .readroot_ah_loop2 |
.readroot_done: |
add esp, 16 |
pop eax |
mov ebx, [edx+4] |
xor eax, eax |
dec ebp |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.notfound_try: |
mov edi, fs_additional_handlers |
@@: |
cmp dword [edi], 0 |
jz .notfound |
call dword [edi] |
scasd |
scasd |
jmp @b |
.notfound: |
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND |
and dword [image_of_ebx], 0 |
ret |
.notfounda: |
cmp edi, esp |
jnz .notfound |
add esp, 8 |
jmp .notfound |
.found1: |
pop eax |
cmp byte [esi], 0 |
jz .maindir |
.found2: |
; read partition number |
xor ecx, ecx |
xor eax, eax |
@@: |
lodsb |
cmp al, '/' |
jz .done1 |
test al, al |
jz .done1 |
sub al, '0' |
cmp al, 9 |
ja .notfounda |
lea ecx, [ecx*5] |
lea ecx, [ecx*2+eax] |
jmp @b |
.done1: |
jecxz .notfounda |
test al, al |
jnz @f |
dec esi |
@@: |
cmp byte [esi], 0 |
jnz @f |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
@@: |
; now [edi] contains handler address, ecx - partition number, |
; esi points to ASCIIZ string - rest of name |
jmp dword [edi] |
; handlers for devices |
; in: ecx = 0 => query virtual directory /xxx |
; in: ecx = partition number |
; esi -> relative (for device) name |
; ebx -> fileinfo |
; ebp = 0 or pointer to rest of name from folder addressed by esi |
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx |
fs_OnRamdisk: |
cmp ecx, 1 |
jnz file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumRamdiskServices |
jae .not_impl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_RamdiskServices + eax*4] |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_NotImplemented: |
mov eax, 2 |
ret |
fs_RamdiskServices: |
dd fs_RamdiskRead |
dd fs_RamdiskReadFolder |
dd fs_RamdiskRewrite |
dd fs_RamdiskWrite |
dd fs_RamdiskSetFileEnd |
dd fs_RamdiskGetFileInfo |
dd fs_RamdiskSetFileInfo |
dd 0 |
dd fs_RamdiskDelete |
dd fs_RamdiskCreateFolder |
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 |
fs_OnFloppy: |
cmp ecx, 2 |
ja file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumFloppyServices |
jae fs_OnRamdisk.not_impl |
call reserve_flp |
mov [flp_number], cl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_FloppyServices + eax*4] |
and [flp_status], 0 |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
fs_FloppyServices: |
dd fs_FloppyRead |
dd fs_FloppyReadFolder |
dd fs_FloppyRewrite |
dd fs_FloppyWrite |
dd fs_FloppySetFileEnd |
dd fs_FloppyGetFileInfo |
dd fs_FloppySetFileInfo |
dd 0 |
dd fs_FloppyDelete |
dd fs_FloppyCreateFolder |
fs_NumFloppyServices = ($ - fs_FloppyServices)/4 |
fs_OnHd0: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0 |
push 1 |
jmp fs_OnHd |
fs_OnHd1: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0x10 |
push 2 |
jmp fs_OnHd |
fs_OnHd2: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0 |
push 3 |
jmp fs_OnHd |
fs_OnHd3: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0x10 |
push 4 |
fs_OnHd: |
call reserve_hd_channel |
pop eax |
mov [hdpos], eax |
cmp ecx, 0x100 |
jae fs_OnHdAndBd.nf |
cmp cl, [DRIVE_DATA+1+eax] |
fs_OnHdAndBd: |
jbe @f |
.nf: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [image_of_eax], 5 ; not found |
ret |
@@: |
mov [fat32part], ecx |
push ebx esi |
call choice_necessity_partition_1 |
pop esi ebx |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax, fs_NumHdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_HdServices + eax*4] |
call free_hd_channel |
and [hd1_status], 0 |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_HdServices: |
dd fs_HdRead |
dd fs_HdReadFolder |
dd fs_HdRewrite |
dd fs_HdWrite |
dd fs_HdSetFileEnd |
dd fs_HdGetFileInfo |
dd fs_HdSetFileInfo |
dd 0 |
dd fs_HdDelete |
dd fs_HdCreateFolder |
fs_NumHdServices = ($ - fs_HdServices)/4 |
;******************************************************* |
fs_OnCd0: |
call reserve_cd |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
push 6 |
push 1 |
jmp fs_OnCd |
fs_OnCd1: |
call reserve_cd |
mov [ChannelNumber],1 |
mov [DiskNumber],1 |
push 4 |
push 2 |
jmp fs_OnCd |
fs_OnCd2: |
call reserve_cd |
mov [ChannelNumber],2 |
mov [DiskNumber],0 |
push 2 |
push 3 |
jmp fs_OnCd |
fs_OnCd3: |
call reserve_cd |
mov [ChannelNumber],2 |
mov [DiskNumber],1 |
push 0 |
push 4 |
fs_OnCd: |
call reserve_cd_channel |
pop eax |
mov [cdpos], eax |
pop eax |
cmp ecx, 0x100 |
jae .nf |
push ecx ebx |
mov cl,al |
mov bl,[DRIVE_DATA+1] |
shr bl,cl |
test bl,2 |
pop ebx ecx |
jnz @f |
.nf: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [image_of_eax], 5 ; not found |
ret |
@@: |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax,fs_NumCdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_CdServices + eax*4] |
call free_cd_channel |
and [cd_status], 0 |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_CdServices: |
dd fs_CdRead |
dd fs_CdReadFolder |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_CdGetFileInfo |
dd fs_NotImplemented |
dd 0 |
dd fs_NotImplemented |
dd fs_NotImplemented |
fs_NumCdServices = ($ - fs_CdServices)/4 |
;******************************************************* |
fs_HasRamdisk: |
mov al, 1 ; we always have ramdisk |
ret |
fs_HasFloppy: |
cmp byte [DRIVE_DATA], 0 |
setnz al |
ret |
fs_HasHd0: |
mov al, [DRIVE_DATA+1] |
and al, 11000000b |
cmp al, 01000000b |
setz al |
ret |
fs_HasHd1: |
mov al, [DRIVE_DATA+1] |
and al, 00110000b |
cmp al, 00010000b |
setz al |
ret |
fs_HasHd2: |
mov al, [DRIVE_DATA+1] |
and al, 00001100b |
cmp al, 00000100b |
setz al |
ret |
fs_HasHd3: |
mov al, [DRIVE_DATA+1] |
and al, 00000011b |
cmp al, 00000001b |
setz al |
ret |
;******************************************************* |
fs_HasCd0: |
mov al, [DRIVE_DATA+1] |
and al, 11000000b |
cmp al, 10000000b |
setz al |
ret |
fs_HasCd1: |
mov al, [DRIVE_DATA+1] |
and al, 00110000b |
cmp al, 00100000b |
setz al |
ret |
fs_HasCd2: |
mov al, [DRIVE_DATA+1] |
and al, 00001100b |
cmp al, 00001000b |
setz al |
ret |
fs_HasCd3: |
mov al, [DRIVE_DATA+1] |
and al, 00000011b |
cmp al, 00000010b |
setz al |
ret |
;******************************************************* |
; fs_NextXXX functions: |
; in: eax = partition number, from which start to scan |
; out: CF=1 => no more partitions |
; CF=0 => eax=next partition number |
fs_NextRamdisk: |
; we always have /rd/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
fs_NextFloppy: |
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0) |
test byte [DRIVE_DATA], 0xF0 |
jz .no1 |
test eax, eax |
jnz .no1 |
inc eax |
ret ; CF cleared |
.no1: |
test byte [DRIVE_DATA], 0x0F |
jz .no2 |
cmp al, 2 |
jae .no2 |
mov al, 2 |
clc |
ret |
.no2: |
stc |
ret |
; on hdx, we have partitions from 1 to [0x40002+x] |
fs_NextHd0: |
push 0 |
jmp fs_NextHd |
fs_NextHd1: |
push 1 |
jmp fs_NextHd |
fs_NextHd2: |
push 2 |
jmp fs_NextHd |
fs_NextHd3: |
push 3 |
fs_NextHd: |
pop ecx |
movzx ecx, byte [DRIVE_DATA+2+ecx] |
cmp eax, ecx |
jae fs_NextFloppy.no2 |
inc eax |
clc |
ret |
;******************************************************* |
fs_NextCd: |
; we always have /cdX/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
;******************************************************* |
; Additional FS handlers. |
; This handler gets the control each time when fn 70 is called |
; with unknown item of root subdirectory. |
; in: esi -> name |
; ebp = 0 or rest of name relative to esi |
; out: if the handler processes path, he must not return in file_system_lfn, |
; but instead pop return address and return directly to the caller |
; otherwise simply return |
; here we test for /bd<N>/... - BIOS disks |
biosdisk_handler: |
cmp [NumBiosDisks], 0 |
jz .ret |
mov al, [esi] |
or al, 20h |
cmp al, 'b' |
jnz .ret |
mov al, [esi+1] |
or al, 20h |
cmp al, 'd' |
jnz .ret |
push esi |
inc esi |
inc esi |
cmp byte [esi], '0' |
jb .ret2 |
cmp byte [esi], '9' |
ja .ret2 |
xor edx, edx |
@@: |
lodsb |
test al, al |
jz .ok |
cmp al, '/' |
jz .ok |
sub al, '0' |
cmp al, 9 |
ja .ret2 |
lea edx, [edx*5] |
lea edx, [edx*2+eax] |
jmp @b |
.ret2: |
pop esi |
.ret: |
ret |
.ok: |
cmp al, '/' |
jz @f |
dec esi |
@@: |
add dl, 80h |
xor ecx, ecx |
@@: |
cmp dl, [BiosDisksData+ecx*4] |
jz .ok2 |
inc ecx |
cmp ecx, [NumBiosDisks] |
jb @b |
jmp .ret2 |
.ok2: |
add esp, 8 |
test al, al |
jnz @f |
mov esi, fs_BdNext |
jmp file_system_lfn.maindir_noesi |
@@: |
push ecx |
push fs_OnBd |
mov edi, esp |
jmp file_system_lfn.found2 |
fs_BdNext: |
cmp eax, [BiosDiskPartitions+ecx*4] |
inc eax |
cmc |
ret |
fs_OnBd: |
pop edx edx |
; edx = disk number, ecx = partition number |
; esi+ebp = name |
call reserve_hd1 |
add edx, 0x80 |
mov [hdpos], edx |
cmp ecx, [BiosDiskPartitions+(edx-0x80)*4] |
jmp fs_OnHdAndBd |
; This handler is called when virtual root is enumerated |
; and must return all items which can be handled by this. |
; It is called several times, first time with eax=0 |
; in: eax = 0 for first call, previously returned value for subsequent calls |
; out: eax = 0 => no more items |
; eax != 0 => buffer pointed to by edi contains name of item |
; here we enumerate existing BIOS disks /bd<N> |
biosdisk_enum_root: |
cmp eax, [NumBiosDisks] |
jae .end |
push eax |
movzx eax, byte [BiosDisksData+eax*4] |
sub al, 80h |
push eax |
mov al, 'b' |
stosb |
mov al, 'd' |
stosb |
pop eax |
cmp al, 10 |
jae .big |
add al, '0' |
stosb |
mov byte [edi], 0 |
pop eax |
inc eax |
ret |
.end: |
xor eax, eax |
ret |
.big: |
push ecx |
push -'0' |
mov ecx, 10 |
@@: |
xor edx, edx |
div ecx |
push edx |
test eax, eax |
jnz @b |
xchg eax, edx |
@@: |
pop eax |
add al, '0' |
stosb |
jnz @b |
pop ecx |
pop eax |
inc eax |
ret |
process_replace_file_name: |
mov ebp, [full_file_name_table] |
mov edi, [full_file_name_table.size] |
dec edi |
shl edi, 7 |
add edi, ebp |
.loop: |
cmp edi, ebp |
jb .notfound |
push esi edi |
@@: |
cmp byte [edi], 0 |
jz .dest_done |
lodsb |
test al, al |
jz .cont |
or al, 20h |
scasb |
jz @b |
jmp .cont |
.dest_done: |
cmp byte [esi], 0 |
jz .found |
cmp byte [esi], '/' |
jnz .cont |
inc esi |
jmp .found |
.cont: |
pop edi esi |
sub edi, 128 |
jmp .loop |
.found: |
pop edi eax |
mov ebp, esi |
cmp byte [esi], 0 |
lea esi, [edi+64] |
jnz .ret |
.notfound: |
xor ebp, ebp |
.ret: |
ret |
sys_current_directory: |
; mov esi, [current_slot] |
; mov esi, [esi+APPDATA.cur_dir] |
; mov edx, esi |
;get length string of appdata.cur_dir |
mov eax, [current_slot] |
mov edi, [eax+APPDATA.cur_dir] |
dec ebx |
jz .set |
dec ebx |
jz .get |
ret |
.get: |
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len |
; for our code: ebx->buffer,ecx=len |
max_cur_dir equ 0x1000 |
mov ebx,edi |
push ecx |
push edi |
xor eax,eax |
mov ecx,max_cur_dir |
repne scasb ;find zerro at and string |
jnz .error ; no zero in cur_dir: internal error, should not happen |
sub edi,ebx ;lenght for copy |
inc edi |
mov [esp+32+8],edi ;return in eax |
cmp edx, edi |
jbe @f |
mov edx, edi |
@@: |
;source string |
pop esi |
;destination string |
pop edi |
cmp edx, 1 |
jbe .ret |
mov al,'/' ;start string with '/' |
stosb |
mov ecx,edx |
rep movsb ;copy string |
.ret: ret |
.error: add esp,8 |
or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir] |
ret |
.set: |
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string |
; for our code: ebx->string to set |
; use generic resolver with APPDATA.cur_dir as destination |
push max_cur_dir ;0x1000 |
push edi ;destination |
mov ebx,ecx |
call get_full_file_name |
ret |
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination |
; destroys all registers except ebp,esp |
get_full_file_name: |
push ebp |
mov esi, [current_slot] |
mov esi, [esi+APPDATA.cur_dir] |
mov edx, esi |
@@: |
inc esi |
cmp byte [esi-1], 0 |
jnz @b |
dec esi |
cmp byte [ebx], '/' |
jz .set_absolute |
; string gives relative path |
mov edi, [esp+8] ; destination |
.relative: |
cmp byte [ebx], 0 |
jz .set_ok |
cmp word [ebx], '.' |
jz .set_ok |
cmp word [ebx], './' |
jnz @f |
add ebx, 2 |
jmp .relative |
@@: |
cmp word [ebx], '..' |
jnz .doset_relative |
cmp byte [ebx+2], 0 |
jz @f |
cmp byte [ebx+2], '/' |
jnz .doset_relative |
@@: |
dec esi |
cmp byte [esi], '/' |
jnz @b |
add ebx, 3 |
jmp .relative |
.set_ok: |
cmp edx, edi ; is destination equal to APPDATA.cur_dir? |
jz .set_ok.cur_dir |
sub esi, edx |
cmp esi, [esp+12] |
jb .set_ok.copy |
.fail: |
mov byte [edi], 0 |
xor eax, eax ; fail |
pop ebp |
ret 8 |
.set_ok.copy: |
mov ecx, esi |
mov esi, edx |
rep movsb |
mov byte [edi], 0 |
.ret.ok: |
mov al, 1 ; ok |
pop ebp |
ret 8 |
.set_ok.cur_dir: |
mov byte [esi], 0 |
jmp .ret.ok |
.doset_relative: |
cmp edx, edi |
jz .doset_relative.cur_dir |
sub esi, edx |
cmp esi, [esp+12] |
jae .fail |
mov ecx, esi |
mov esi, edx |
mov edx, edi |
rep movsb |
jmp .doset_relative.copy |
.doset_relative.cur_dir: |
mov edi, esi |
.doset_relative.copy: |
add edx, [esp+12] |
mov byte [edi], '/' |
inc edi |
cmp edi, edx |
jae .overflow |
@@: |
mov al, [ebx] |
inc ebx |
stosb |
test al, al |
jz .ret.ok |
cmp edi, edx |
jb @b |
.overflow: |
dec edi |
jmp .fail |
.set_absolute: |
lea esi, [ebx+1] |
call process_replace_file_name |
mov edi, [esp+8] |
mov edx, [esp+12] |
add edx, edi |
.set_copy: |
lodsb |
stosb |
test al, al |
jz .set_part2 |
.set_copy_cont: |
cmp edi, edx |
jb .set_copy |
jmp .overflow |
.set_part2: |
mov esi, ebp |
xor ebp, ebp |
test esi, esi |
jz .ret.ok |
mov byte [edi-1], '/' |
jmp .set_copy_cont |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/fat12.inc |
---|
0,0 → 1,2272 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; FAT12.INC ;; |
;; (C) 2005 Mario79, License: GPL ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
n_sector dd 0 ; temporary save for sector value |
flp_status dd 0 |
clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write |
path_pointer_flp dd 0 |
pointer_file_name_flp dd 0 |
save_root_flag db 0 |
save_flag db 0 |
root_read db 0 ; 0-necessary to load root, 1-not to load root |
flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat |
flp_number db 0 ; 1- Floppy A, 2-Floppy B |
old_track db 0 ; old value track |
flp_label rb 15 ; Label and ID of inserted floppy disk |
reserve_flp: |
cli |
cmp [flp_status],0 |
je reserve_flp_ok |
sti |
call change_task |
jmp reserve_flp |
reserve_flp_ok: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [flp_status],eax |
pop eax |
sti |
ret |
floppy_fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars - for root directory |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X |
; edi pointer to path /fd/1/...... - for all files in nested directories |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; 10 = access denied |
;-------------------------------------------------------------- |
mov [save_flag],0 |
mov [path_pointer_flp],edi |
cmp esi,0 ; return ramdisk root |
jne fr_noroot_1 |
cmp ebx,224/16 |
jbe fr_do_1 |
mov eax,5 |
mov ebx,0 |
mov [flp_status],0 |
ret |
fr_do_1: |
push ebx ecx edx |
call read_flp_root |
pop edx ecx ebx |
cmp [FDC_Status],0 |
jne fdc_status_error_1 |
mov edi,edx |
dec ebx |
shl ebx,9 |
mov esi,FLOPPY_BUFF |
add esi,ebx |
shl ecx,9 |
cld |
rep movsb |
xor eax,eax |
xor ebx,ebx |
; mov eax,0 ; ok read |
; mov ebx,0 |
mov [flp_status],eax |
ret |
fdc_status_error_1: |
xor eax,eax |
mov [flp_status],eax |
mov eax,10 |
or ebx,-1 |
ret |
fr_noroot_1: |
sub esp,32 |
call expand_filename |
frfloppy_1: |
test ebx,ebx |
jnz frfl5_1 |
mov ebx,1 |
frfl5_1: |
test ecx,ecx |
jnz frfl6_1 |
mov ecx,1 |
frfl6_1: |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call read_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_3_1 |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
call SeekTrack |
mov dh,14 |
l.20_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error_3_1 |
mov dl,16 |
mov edi,FDD_BUFF |
inc [FDD_Sector] |
l.21_1: |
mov esi,eax ;Name of file we want |
mov ecx,11 |
cld |
rep cmpsb ;Found the file? |
je fifound_1 ;Yes |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
test dl,dl |
jnz l.21_1 |
dec dh |
test dh,dh |
jnz l.20_1 |
fdc_status_error_3: |
mov eax,5 ; file not found ? |
or ebx,-1 |
add esp,32+28 |
mov [flp_status],0 |
ret |
fdc_status_error_3_2: |
cmp [FDC_Status],0 |
je fdc_status_error_3 |
fdc_status_error_3_1: |
add esp,32+28 |
jmp fdc_status_error_1 |
fifound_1: |
mov eax,[path_pointer_flp] |
cmp [eax+36],byte 0 |
je fifound_2 |
add edi,0xf |
mov eax,[edi] |
and eax,65535 |
mov ebx,[path_pointer_flp] |
add ebx,36 |
call get_cluster_of_a_path_flp |
jc fdc_status_error_3_2 |
mov ebx,[ebx-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
jmp fifound_3 |
fifound_2: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
mov eax,[edi] |
fifound_3: |
and eax,65535 |
mov [n_sector],eax ;eax=cluster |
frnew_1: |
add eax,31 ;bootsector+2*fat+filenames |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7_1 |
call read_chs_sector |
cmp [FDC_Status],0 |
jne fdc_status_error_5 |
mov edi,[esp+8] |
call give_back_application_data_1 |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
cmp [esp+12],dword 0 |
je frnoread_1 |
jmp frfl8_1 |
frfl7_1: |
dec dword [esp+16] |
frfl8_1: |
mov edi,[n_sector] |
shl edi,1 ;find next cluster from FAT |
add edi,FLOPPY_FAT |
mov eax,[edi] |
and eax,4095 |
mov edi,eax |
mov [n_sector],edi |
cmp edi,4095 ;eof - cluster |
jz frnoread2_1 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread_1 |
sub [esp+24],dword 512 |
jmp frnew_1 |
read_chs_sector: |
call calculate_chs |
call ReadSectWithRetr |
ret |
frnoread2_1: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread_1 |
mov [fdc_irq_func],fdc_null |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
mov [flp_status],0 |
ret |
frnoread_1: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax |
mov [flp_status],eax |
ret |
fdc_status_error_5: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
jmp fdc_status_error_1 |
read_flp_root: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_root_read |
cmp [root_read],1 |
je unnecessary_root_read |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov edi,FLOPPY_BUFF |
call SeekTrack |
read_flp_root_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_read |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne read_flp_root_1 |
mov [root_read],1 |
unnecessary_root_read: |
popa |
ret |
read_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
cmp [flp_fat],1 |
je unnecessary_flp_fat |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov edi,FLOPPY_BUFF |
call SeekTrack |
read_flp_fat_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne read_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
call give_back_application_data_1 |
call calculatefatchain_flp |
mov [root_read],0 |
mov [flp_fat],1 |
unnecessary_flp_fat: |
popa |
ret |
calculatefatchain_flp: |
pushad |
mov esi,FLOPPY_BUFF |
mov edi,FLOPPY_FAT |
fcnew_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
add edi,4 |
mov dword [edi],ebx |
add edi,4 |
mov dword [edi],ecx |
add edi,4 |
mov dword [edi],edx |
add edi,4 |
add esi,12 |
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters |
jnz fcnew_1 |
popad |
ret |
check_label: |
pushad |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
call SetUserInterrupts |
call FDDMotorON |
call RecalibrateFDD |
cmp [FDC_Status],0 |
jne fdc_status_error |
call SeekTrack |
cmp [FDC_Status],0 |
jne fdc_status_error |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error |
mov esi,flp_label |
mov edi,FDD_BUFF+39 |
mov ecx,15 |
cld |
rep cmpsb |
je same_label |
mov [root_read],0 |
mov [flp_fat],0 |
same_label: |
mov esi,FDD_BUFF+39 |
mov edi,flp_label |
mov ecx,15 |
cld |
rep movsb |
popad |
ret |
fdc_status_error: |
popad |
ret |
save_flp_root: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
cmp [root_read],0 |
je unnecessary_root_save |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,FLOPPY_BUFF |
call SeekTrack |
save_flp_root_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne save_flp_root_1 |
unnecessary_root_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
save_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
cmp [flp_fat],0 |
je unnecessary_flp_fat_save |
call restorefatchain_flp |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,FLOPPY_BUFF |
call SeekTrack |
save_flp_fat_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call take_data_from_application_1 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
mov [root_read],0 |
unnecessary_flp_fat_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
restorefatchain_flp: ; restore fat chain |
pushad |
mov esi,FLOPPY_FAT |
mov edi,FLOPPY_BUFF |
fcnew2_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
add edi,4 |
mov word [edi],bx |
add edi,2 |
add esi,8 |
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT |
jb fcnew2_1 |
mov esi,FLOPPY_BUFF ; duplicate fat chain |
mov edi,FLOPPY_BUFF+0x1200 |
mov ecx,0x1200/4 |
cld |
rep movsd |
popad |
ret |
save_chs_sector: |
call calculate_chs |
call WriteSectWithRetr |
ret |
calculate_chs: |
mov bl,[FDD_Track] |
mov [old_track],bl |
mov ebx,18 |
xor edx,edx |
div ebx |
inc edx |
mov [FDD_Sector],dl |
xor edx,edx |
mov ebx,2 |
div ebx |
mov [FDD_Track],al |
mov [FDD_Head],0 |
test edx,edx |
jz no_head_2 |
inc [FDD_Head] |
no_head_2: |
mov dl,[old_track] |
cmp dl,[FDD_Track] |
je no_seek_track_1 |
call SeekTrack |
no_seek_track_1: |
ret |
get_cluster_of_a_path_flp: |
;--------------------------------------------------------- |
; input : EBX = pointer to a path string |
; (example: the path "/files/data/document" become |
; "files......data.......document...0" |
; '.' = space char |
; '0' = char(0) (ASCII=0) !!! ) |
; output : if (CARRY=1) -> ERROR in the PATH |
; if (CARRY=0) -> EAX=cluster |
;--------------------------------------------------------- |
push edx |
mov edx,ebx |
search_end_of_path_flp: |
cmp [save_flag],0 |
jne search_end_of_path_flp_1 |
cmp byte [edx],0 |
je found_end_of_path_flp |
jmp search_end_of_path_flp_2 |
search_end_of_path_flp_1: |
cmp byte [edx+12],0 |
je found_end_of_path_flp |
search_end_of_path_flp_2: |
inc edx ; '/' |
call analyze_directory_flp |
jc directory_not_found_flp |
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field |
mov ax,[ebx+26] ; read the LOW 16bit cluster field |
and eax,0xfff ;[fatMASK] |
add edx,11 ; 8+3 (name+extension) |
jmp search_end_of_path_flp |
found_end_of_path_flp: |
inc edx |
mov [pointer_file_name_flp],edx |
pop edx |
clc ; no errors |
ret |
directory_not_found_flp: |
pop edx |
stc ; errors occour |
ret |
analyze_directory_flp: |
;-------------------------------- |
; input : EAX = first cluster of the directory |
; EBX = pointer to filename |
; output : IF CARRY=0 EAX = sector where th file is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,EDI,EDI not changed |
; IF CARRY=1 |
;-------------------------------- |
push ebx ;[esp+16] |
push ecx |
push edx |
push esi |
push edi |
adr56_flp: |
mov [clust_tmp_flp],eax |
add eax,31 |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status],0 |
jne not_found_file_analyze_flp |
mov ecx,512/32 |
mov ebx,FDD_BUFF |
adr1_analyze_flp: |
mov esi,edx ;[esp+16] |
mov edi,ebx |
cld |
push ecx |
mov ecx,11 |
rep cmpsb |
pop ecx |
je found_file_analyze_flp |
add ebx,32 |
loop adr1_analyze_flp |
mov eax,[clust_tmp_flp] |
shl eax,1 ;find next cluster from FAT |
add eax,FLOPPY_FAT |
mov eax,[eax] |
and eax,4095 |
cmp eax,0x0ff8 |
jb adr56_flp |
not_found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
stc ;file not found |
ret |
found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
clc ;file found |
ret |
; \begin{diamond} |
fat_find_lfn: |
; in: esi->name |
; [esp+4] = next |
; [esp+8] = first |
; [esp+C]... - possibly parameters for first and next |
; out: CF=1 - file not found |
; else CF=0, esi->next name component, edi->direntry |
pusha |
lea eax, [esp+0Ch+20h] |
call dword [eax-4] |
jc .reterr |
sub esp, 262*2 ; reserve place for LFN |
mov ebp, esp |
push 0 ; for fat_get_name: read ASCII name |
.l1: |
call fat_get_name |
jc .l2 |
call fat_compare_name |
jz .found |
.l2: |
lea eax, [esp+0Ch+20h+262*2+4] |
call dword [eax-8] |
jnc .l1 |
add esp, 262*2+4 |
.reterr: |
stc |
popa |
ret |
.found: |
add esp, 262*2+4 |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
jnz @f |
lea eax, [esp+0Ch+20h] |
call dword [eax-8] |
jc .reterr |
@@: |
add esp, 8 ; CF=0 |
push esi |
push edi |
popa |
ret |
uglobal |
; this is for delete support |
fd_prev_sector dd ? |
fd_prev_prev_sector dd ? |
endg |
flp_root_next: |
cmp edi, OS_BASE+0xD200-0x20 |
jae @f |
add edi, 0x20 |
ret ; CF=0 |
@@: |
; read next sector |
inc dword [eax] |
cmp dword [eax], 14 |
jae flp_root_first.readerr |
push [fd_prev_sector] |
pop [fd_prev_prev_sector] |
push eax |
mov eax, [eax] |
add eax, 19-1 |
mov [fd_prev_sector], eax |
pop eax |
flp_root_first: |
mov eax, [eax] |
pusha |
add eax, 19 |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .readerr |
mov edi, FDD_BUFF |
ret ; CF=0 |
.readerr: |
stc |
ret |
flp_rootmem_first: |
mov edi, FLOPPY_BUFF |
clc |
ret |
flp_rootmem_next: |
add edi, 0x20 |
cmp edi, FLOPPY_BUFF+14*0x200 |
cmc |
flp_rootmem_next_write: |
flp_rootmem_begin_write: |
flp_rootmem_end_write: |
ret |
flp_rootmem_extend_dir: |
stc |
ret |
flp_notroot_next: |
cmp edi, OS_BASE+0xD200-0x20 |
jae flp_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
flp_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
push [fd_prev_sector] |
pop [fd_prev_prev_sector] |
add ecx, 31 |
mov [fd_prev_sector], ecx |
mov ecx, [(ecx-31)*2+FLOPPY_FAT] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae flp_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
flp_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov edi, FDD_BUFF |
cmp [FDC_Status], 0 |
jnz .err |
ret ; CF=0 |
.err2: |
pop ecx |
.err: |
stc |
ret |
flp_notroot_begin_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call read_chs_sector |
popa |
ret |
flp_notroot_end_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call save_chs_sector |
popa |
ret |
flp_notroot_next_write: |
cmp edi, OS_BASE+0xD200 |
jae @f |
ret |
@@: |
call flp_notroot_end_write |
jmp flp_notroot_next_sector |
flp_notroot_extend_dir: |
; find free cluster in FAT |
pusha |
xor eax, eax |
mov edi, FLOPPY_FAT |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF ; mark as last cluster |
sub edi, FLOPPY_FAT |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [FLOPPY_FAT+ecx*2], di |
mov [eax], edi |
xor eax, eax |
mov edi, FDD_BUFF |
mov ecx, 128 |
rep stosd |
popa |
call flp_notroot_end_write |
mov edi, FDD_BUFF |
clc |
ret |
.notfound: |
popa |
stc |
ret |
fd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=directory cluster (0 for root) |
push esi edi |
push 0 |
push flp_root_first |
push flp_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] ; cluster |
mov [esp+8], eax |
mov dword [esp+4], flp_notroot_first |
mov dword [esp], flp_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
mov eax, [esp+8] |
add eax, 31 |
cmp dword [esp], flp_root_next |
jnz @f |
add eax, -31+19 |
@@: |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRead - LFN variant for reading floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyRead: |
call read_flp_fat |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
sub ebx, 512 |
jae .skip |
lea eax, [edi+31] |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .err |
lea eax, [FDD_BUFF+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+FLOPPY_FAT] |
jmp .new |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
jmp .reteof |
.err: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
mov al, 11 |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyReadFolder - LFN variant for reading floppy folders |
; |
; esi points to filename |
; ebx pointer to structure: 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyReadFolder: |
call read_flp_fat |
push edi |
cmp byte [esi], 0 |
jz .root |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.main_loop: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, FDD_BUFF |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, OS_BASE+0xD200 |
jb .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, FDD_BUFF |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, OS_BASE+0xD200 |
jb .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
jmp .main_loop |
.error: |
add esp, 262*2+4 |
pop ebp ecx edi edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx edi edi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fsfrfe2: |
popad |
fsfrfe: |
mov eax, 11 |
xor ebx, ebx |
ret |
fs_FloppyCreateFolder: |
mov al, 1 |
jmp fs_FloppyRewrite.common |
fs_FloppyRewrite: |
xor eax, eax |
.common: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz fsfrfe |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
call read_flp_root |
cmp [FDC_Status], 0 |
jnz fsfrfe2 |
push flp_rootmem_extend_dir |
push flp_rootmem_end_write |
push flp_rootmem_next_write |
push flp_rootmem_begin_write |
xor ebp, ebp |
push ebp |
push flp_rootmem_first |
push flp_rootmem_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call fd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call fd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push flp_notroot_extend_dir |
push flp_notroot_end_write |
push flp_notroot_next_write |
push flp_notroot_begin_write |
push ebp |
push flp_notroot_first |
push flp_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 28 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+28+28], 0 |
jz @f |
add esp, 28 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [FLOPPY_FAT + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 28 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+28 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 8+8+12+28 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [FDC_Status], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+16] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+28 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+12] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+28+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
lea eax, [esp+8] |
call dword [eax+12] ; flush directory |
push ecx |
push edi |
push 0 |
mov esi, edx |
test ecx, ecx |
jz .done |
mov ecx, 2849 |
mov edi, FLOPPY_FAT |
push 0 ; first cluster |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
mov al, ERROR_DISK_FULL |
jnz .ret |
dec edi |
dec edi |
mov eax, edi |
sub eax, FLOPPY_FAT |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp+4] |
cmp dword [esp], 0 |
jz .first |
stosw |
jmp @f |
.first: |
mov [esp], eax |
@@: |
mov edi, [esp+4] |
inc ecx |
; write data |
push ecx edi |
mov ecx, 512 |
cmp dword [esp+20], ecx |
jae @f |
mov ecx, [esp+20] |
@@: |
mov edi, FDD_BUFF |
cmp byte [esp+24+28+28], 0 |
jnz .writedir |
push ecx |
rep movsb |
pop ecx |
.writedircont: |
push ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
add eax, 31 |
pusha |
call save_chs_sector |
popa |
pop ecx |
cmp [FDC_Status], 0 |
jnz .diskerr |
sub [esp+20], ecx |
pop edi ecx |
jnz .write_loop |
.done: |
xor eax, eax |
.ret: |
pop ebx edi edi ecx |
mov [esp+28+28], eax |
lea eax, [esp+8] |
call dword [eax+4] |
mov [edi+26], bx |
mov ebx, esi |
sub ebx, edx |
mov [edi+28], ebx |
call dword [eax+12] |
mov [esp+28+16], ebx |
test ebp, ebp |
jnz @f |
call save_flp_root |
@@: |
add esp, 28 |
cmp [FDC_Status], 0 |
jnz .err3 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .err3 |
popa |
ret |
.err3: |
popa |
mov al, 11 |
xor ebx, ebx |
ret |
.diskerr: |
sub esi, ecx |
mov eax, 11 |
pop edi ecx |
jmp .ret |
.writedir: |
push ecx |
mov ecx, 32/4 |
push ecx esi |
rep movsd |
pop esi ecx |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov word [edi-32+26], ax |
push esi |
rep movsd |
pop esi |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov ecx, [esp+28+8] |
mov word [edi-32+26], cx |
pop ecx |
jmp .writedircont |
;---------------------------------------------------------------- |
; |
; fs_FloppyWrite - LFN variant for writing to floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_FloppyWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_FloppyWrite.ret11: |
push 11 |
jmp fs_FloppyWrite.ret0 |
fs_FloppyWrite: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz .ret11 |
pushad |
call fd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push eax ; save directory cluster |
push 0 ; return value=0 |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
push dword [edi+28] ; save current file size |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call floppy_extend_file |
jnc .length_ok |
mov [esp+4], eax |
; floppy_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
pop eax |
mov [esp+4+28], eax |
pop eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
pop eax |
mov [esp+4+28], eax ; eax=return value |
pop eax |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; save FAT & directory |
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000 |
mov esi, [edi+28] |
movzx edi, word [edi+26] ; starting cluster |
mov eax, [esp+8] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err |
call save_flp_fat |
cmp [FDC_Status], 0 |
jz @f |
.device_err: |
mov byte [esp+4], 11 |
jmp .ret |
@@: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
call SetUserInterrupts |
.write_loop: |
; skip unmodified sectors |
cmp dword [esp], 0x200 |
jb .modify |
sub ebx, 0x200 |
jae .skip |
add ebx, 0x200 |
.modify: |
lea eax, [edi+31] ; current sector |
; get length of data in current sector |
push ecx |
sub ebx, 0x200 |
jb .hasdata |
neg ebx |
xor ecx, ecx |
jmp @f |
.hasdata: |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
; load sector if needed |
cmp dword [esp+4], 0 ; we don't need to read uninitialized data |
jz .noread |
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten |
jz .noread |
cmp ecx, esi ; (same for the last sector) |
jz .noread |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jz @f |
.device_err2: |
pop ecx |
jmp .device_err |
@@: |
.noread: |
; zero uninitialized data if file was extended (because floppy_extend_file does not this) |
push eax ecx edi |
xor eax, eax |
mov ecx, 0x200 |
sub ecx, [esp+4+12] |
jbe @f |
mov edi, FDD_BUFF |
add edi, [esp+4+12] |
rep stosb |
@@: |
; zero uninitialized data in the last sector |
mov ecx, 0x200 |
sub ecx, esi |
jbe @f |
mov edi, FDD_BUFF |
add edi, esi |
rep stosb |
@@: |
pop edi ecx eax |
; copy new data |
push eax |
mov eax, edx |
neg ebx |
jecxz @f |
add ebx, FDD_BUFF+0x200 |
call memmove |
xor ebx, ebx |
@@: |
pop eax |
; save sector |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err2 |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .done |
.skip: |
.next_cluster: |
movzx edi, word [edi*2+FLOPPY_FAT] |
sub esi, 0x200 |
jae @f |
xor esi, esi |
@@: |
sub dword [esp], 0x200 |
jae .write_loop |
and dword [esp], 0 |
jmp .write_loop |
.done: |
mov [fdc_irq_func], fdc_null |
jmp .ret |
floppy_extend_file.zero_size: |
xor eax, eax |
jmp floppy_extend_file.start_extend |
; extends file on floppy to given size (new data area is undefined) |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
floppy_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+FLOPPY_FAT] |
and eax, 0xFFF |
jz .fat_err |
cmp eax, 0xFF8 |
jb @b |
.fat_err: |
pop ecx |
push ERROR_FAT_TABLE |
pop eax |
stc |
ret |
@@: |
push eax |
mov eax, [eax*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
pop eax |
jb .fat_err |
; set length to full number of sectors |
sub [edi+28], ecx |
.start_extend: |
pop ecx |
; now do extend |
push edx esi |
mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2 |
mov edx, 2847 ; number of clusters to scan |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
push edi |
.scan: |
mov ecx, edx |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, FLOPPY_FAT |
shr edi, 1 |
dec edi ; now edi=new cluster |
test eax, eax |
jz .first_cluster |
mov [FLOPPY_FAT+eax*2], di |
jmp @f |
.first_cluster: |
pop eax ; eax->direntry |
push eax |
mov [eax+26], di |
@@: |
mov eax, edi ; eax=new cluster |
pop edi ; edi->direntry |
pop ecx ; ecx=required size |
add dword [edi+28], 0x200 |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop esi edx |
xor eax, eax ; CF=0 |
ret |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppySetFileEnd - set end of file on floppy |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppySetFileEnd: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call fd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
jmp .doret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4 Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
push eax |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop eax |
pushad |
call save_chs_sector |
popad |
pop edi |
xor eax, eax |
cmp [FDC_Status], 0 |
jz @f |
mov al, 11 |
@@: |
.doret: |
mov [fdc_irq_func], fdc_null |
ret |
.expand: |
push ecx |
push dword [edi+28] ; save old size |
mov ecx, eax |
call floppy_extend_file |
push eax ; return code |
jnc .expand_ok |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax ecx ecx edi edi |
jmp .doret |
.device_err: |
pop eax |
.device_err2: |
pop ecx ecx eax edi |
push 11 |
jmp .ret |
.disk_full: |
.expand_ok: |
; save directory & FAT |
mov eax, [edi+28] |
xchg eax, [esp+12] |
movzx edi, word [edi+26] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .device_err |
call SetUserInterrupts |
; now zero new data |
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code |
.zero_loop: |
sub dword [esp+4], 0x200 |
jae .next_cluster |
cmp dword [esp+4], -0x200 |
jz .noread |
lea eax, [edi+31] |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .err_next |
.noread: |
mov ecx, [esp+4] |
neg ecx |
push edi |
mov edi, FDD_BUFF+0x200 |
add edi, [esp+8] |
xor eax, eax |
mov [esp+8], eax |
rep stosb |
pop edi |
lea eax, [edi+31] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jz .next_cluster |
.err_next: |
mov byte [esp], 11 |
.next_cluster: |
sub dword [esp+12], 0x200 |
jbe .expand_done |
movzx edi, word [FLOPPY_FAT+edi*2] |
jmp .zero_loop |
.expand_done: |
pop eax ecx ecx edi edi |
jmp .doret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [FLOPPY_FAT+ecx*2] |
jmp @b |
@@: |
; we will zero data at the end of last sector - remember it |
push ecx |
; terminate FAT chain |
lea ecx, [FLOPPY_FAT+ecx+ecx] |
push dword [ecx] |
mov word [ecx], 0xFFF |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.zero_size: |
and word [edi+26], 0 |
push 0 |
.delete: |
; delete FAT chain starting with ecx |
; mark all clusters as free |
cmp ecx, 0xFF8 |
jae .deleted |
lea ecx, [FLOPPY_FAT+ecx+ecx] |
push dword [ecx] |
and word [ecx], 0 |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.deleted: |
mov edi, [edi+28] |
; save directory & FAT |
mov eax, [esp+8] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err2 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .device_err2 |
; zero last sector, ignore errors |
pop eax |
add eax, 31 |
and edi, 0x1FF |
jz .truncate_done |
call SetUserInterrupts |
pusha |
call read_chs_sector |
popa |
add edi, FDD_BUFF |
mov ecx, FDD_BUFF+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pusha |
call save_chs_sector |
popa |
.truncate_done: |
pop ecx eax edi |
xor eax, eax |
jmp .doret |
fs_FloppyGetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jmp fs_GetFileInfo_finish |
ret11: |
mov eax, 11 |
ret |
fs_FloppySetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
pusha |
call save_chs_sector |
popa |
pop edi |
xor eax, eax |
cmp [FDC_Status], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyDelete - delete file or empty folder from floppy |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyDelete: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jz @f |
push 11 |
jmp .pop_ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [fd_prev_sector], 0 |
and [fd_prev_prev_sector], 0 |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
push eax |
movzx eax, word [edi+26] |
push ebx |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov ebx, FDD_BUFF + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
cmp ebx, FDD_BUFF + 0x200 |
jb .checkempty |
movzx eax, word [FLOPPY_FAT + eax*2] |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov ebx, FDD_BUFF |
jmp .checkempty |
.notempty: |
pop ebx |
pop eax |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
pop eax |
pusha |
call read_chs_sector |
popa |
.dodel: |
push eax |
movzx eax, word [edi+26] |
xchg eax, [esp] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
cmp edi, FDD_BUFF |
ja @f |
cmp [fd_prev_sector], 0 |
jz .lfndone |
push [fd_prev_sector] |
push [fd_prev_prev_sector] |
pop [fd_prev_sector] |
and [fd_prev_prev_sector], 0 |
pusha |
call save_chs_sector |
popa |
pop eax |
pusha |
call read_chs_sector |
popa |
mov edi, FDD_BUFF+0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
pusha |
call save_chs_sector |
popa |
; delete FAT chain |
pop eax |
test eax, eax |
jz .done |
@@: |
lea eax, [FLOPPY_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jnz @b |
.done: |
call save_flp_fat |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/part_set.inc |
---|
0,0 → 1,481 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;************************************************************* |
;* 12.07.2007 Check all 4 entry of MBR and EMBR |
;* 29.04.2006 Elimination of hangup after the |
;* expiration hd_wait_timeout - Mario79 |
;* 28.01.2006 find all Fat16/32 partition in all input point |
;* to MBR - Mario79 |
;************************************************************* |
uglobal |
align 4 |
;****************************************************** |
; Please do not change this place - variables in text |
; Mario79 |
; START place |
;****************************************************** |
PARTITION_START dd 0x3f |
PARTITION_END dd 0 |
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 |
align 4 |
fs_dependent_data_start: |
; FATxx data |
SECTORS_PER_FAT dd 0x1f3a |
NUMBER_OF_FATS dd 0x2 |
SECTORS_PER_CLUSTER dd 0x8 |
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
ROOT_CLUSTER dd 2 ; first rootdir cluster |
FAT_START dd 0 ; start of fat table |
ROOT_START dd 0 ; start of rootdir (only fat16) |
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
DATA_START dd 0 ; start of data area (=first cluster 2) |
LAST_CLUSTER dd 0 ; last availabe cluster |
ADR_FSINFO dd 0 ; used only by fat32 |
fatRESERVED dd 0x0FFFFFF6 |
fatBAD dd 0x0FFFFFF7 |
fatEND dd 0x0FFFFFF8 |
fatMASK dd 0x0FFFFFFF |
fatStartScan dd 2 |
fs_dependent_data_end: |
file_system_data_size = $ - PARTITION_START |
if file_system_data_size > 96 |
ERROR: sizeof(file system data) too big! |
end if |
virtual at fs_dependent_data_start |
; NTFS data |
ntfs_data: |
.sectors_per_cluster dd ? |
.mft_cluster dd ? |
.mftmirr_cluster dd ? |
.frs_size dd ? ; FRS size in bytes |
.iab_size dd ? ; IndexAllocationBuffer size in bytes |
.frs_buffer dd ? |
.iab_buffer dd ? |
.mft_retrieval dd ? |
.mft_retrieval_size dd ? |
.mft_retrieval_alloc dd ? |
.mft_retrieval_end dd ? |
.cur_index_size dd ? |
.cur_index_buf dd ? |
if $ > fs_dependent_data_end |
ERROR: increase sizeof(fs_dependent_data)! |
end if |
end virtual |
;*************************************************************************** |
; End place |
; Mario79 |
;*************************************************************************** |
endg |
iglobal |
partition_types: ; list of fat16/32 partitions |
db 0x04 ; DOS: fat16 <32M |
db 0x06 ; DOS: fat16 >32M |
db 0x0b ; WIN95: fat32 |
db 0x0c ; WIN95: fat32, LBA-mapped |
db 0x0e ; WIN95: fat16, LBA-mapped |
db 0x14 ; Hidden DOS: fat16 <32M |
db 0x16 ; Hidden DOS: fat16 >32M |
db 0x1b ; Hidden WIN95: fat32 |
db 0x1c ; Hidden WIN95: fat32, LBA-mapped |
db 0x1e ; Hidden WIN95: fat16, LBA-mapped |
db 0xc4 ; DRDOS/secured: fat16 <32M |
db 0xc6 ; DRDOS/secured: fat16 >32M |
db 0xcb ; DRDOS/secured: fat32 |
db 0xcc ; DRDOS/secured: fat32, LBA-mapped |
db 0xce ; DRDOS/secured: fat16, LBA-mapped |
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M |
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M |
db 0x07 ; NTFS |
db 0x27 ; NTFS, hidden |
partition_types_end: |
extended_types: ; list of extended partitions |
db 0x05 ; DOS: extended partition |
db 0x0f ; WIN95: extended partition, LBA-mapped |
db 0xc5 ; DRDOS/secured: extended partition |
db 0xd5 ; Old Multiuser DOS secured: extended partition |
extended_types_end: |
endg |
; Partition chain used: |
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 |
;========================================================== |
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- |
; extended --+ extended --+ extended --+ extended --+ |
; 0 0 0 0 |
; 0 0 0 0 |
; Notes: |
; - extended partition need to be in second entry on table |
; - it will skip over removed partitions |
set_FAT32_variables: |
mov [problem_partition],0 |
call reserve_hd1 |
call reserve_hd_channel |
pushad |
cmp dword [hdpos],0 |
je problem_hd |
xor ecx,ecx ; partition count |
mov edx,-1 ; flag for partition |
xor eax,eax ; read MBR |
xor ebp,ebp ; extended partition start |
new_partition: |
test ebp,ebp ; is there extended partition? |
jnz extended_already_set ; yes |
xchg ebp,eax ; no. set it now |
extended_already_set: |
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne problem_hd |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz end_partition_chain |
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition |
; jz next_partition |
jnz .next_primary_partition |
cmp dword [ebx+0x1be+0xc+16],0 |
jnz next_primary_partition |
cmp dword [ebx+0x1be+0xc+16+16],0 |
jnz next_primary_partition_1 |
cmp dword [ebx+0x1be+0xc+16+16+16],0 |
jnz next_primary_partition_2 |
jmp next_partition |
.next_primary_partition: |
push eax |
mov al,[ebx+0x1be+4] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition ; no |
mov edx, eax ; start sector |
add edx, [ebx+0x1be+8] ; add relative start |
push edx |
add edx, [ebx+0x1be+12] ; add length |
dec edx ; PARTITION_END is inclusive |
mov [PARTITION_END], edx ; note that this can be changed |
; when file system data will be available |
mov dl, [ebx+0x1be+4] |
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) |
pop edx |
next_primary_partition: |
push eax |
mov al,[ebx+0x1be+4+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_1 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_1 ; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16] |
push edx |
add edx, [ebx+0x1be+12+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16] |
mov [fs_type], dl |
pop edx |
next_primary_partition_1: |
push eax |
mov al,[ebx+0x1be+4+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_2 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_2 ; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16] |
mov [fs_type], dl |
pop edx |
next_primary_partition_2: |
push eax |
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_partition ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_partition ; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16+16] |
mov [fs_type], dl |
pop edx |
next_partition: |
push eax |
mov al,[ebx+0x1be+4] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_1 |
mov eax,[ebx+0x1be+8] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_1: |
push eax |
mov al,[ebx+0x1be+4+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_2 |
mov eax,[ebx+0x1be+8+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_2: |
push eax |
mov al,[ebx+0x1be+4+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_3 |
mov eax,[ebx+0x1be+8+16+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_3: |
push eax |
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz end_partition_chain ; no. end chain |
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
end_partition_chain: |
mov [partition_count],ecx |
cmp edx,-1 ; found wanted partition? |
jnz hd_and_partition_ok ; yes. install it |
jmp problem_partition_or_fat |
scan_partition_types: |
push ecx |
mov edi,partition_types |
mov ecx,partition_types_end-partition_types |
cld |
repne scasb ; is partition type ok? |
pop ecx |
ret |
scan_extended_types: |
push ecx |
mov edi,extended_types |
mov ecx,extended_types_end-extended_types |
cld |
repne scasb ; is it extended partition? |
pop ecx |
ret |
problem_fat_dec_count: ; bootsector is missing or another problem |
dec [partition_count] ; remove it from partition_count |
problem_partition_or_fat: |
problem_hd: |
popad |
mov [fs_type],0 |
call free_hd_channel |
mov [hd1_status],0 ; free |
mov [problem_partition],1 |
ret |
hd_and_partition_ok: |
mov eax,edx |
mov [PARTITION_START],eax |
mov edx, [PARTITION_END] |
sub edx, eax |
inc edx ; edx = length of partition |
; mov [hd_setup],1 |
mov ebx,buffer |
call hd_read ; read boot sector of partition |
cmp [hd_error], 0 |
jz boot_read_ok |
cmp [fs_type], 7 |
jnz problem_fat_dec_count |
; NTFS duplicates bootsector: |
; NT4/2k/XP+ saves bootsector copy in the end of disk |
; NT 3.51 saves bootsector copy in the middle of disk |
and [hd_error], 0 |
mov eax, [PARTITION_END] |
call hd_read |
cmp [hd_error], 0 |
jnz @f |
call ntfs_test_bootsec |
jnc boot_read_ok |
@@: |
and [hd_error], 0 |
mov eax, edx |
shr eax, 1 |
add eax, [PARTITION_START] |
call hd_read |
cmp [hd_error], 0 |
jnz problem_fat_dec_count ; ¥ áã¤ì¡ ... |
boot_read_ok: |
; mov [hd_setup], 0 |
; if we are running on NTFS, check bootsector |
; cmp [fs_type], 7 |
; jz ntfs_setup |
call ntfs_test_bootsec |
jnc ntfs_setup |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz problem_fat_dec_count |
movzx eax,word [ebx+0xe] ; sectors reserved |
add eax,[PARTITION_START] |
mov [FAT_START],eax ; fat_start = partition_start + reserved |
movzx eax,byte [ebx+0xd] ; sectors per cluster |
test eax,eax |
jz problem_fat_dec_count |
mov [SECTORS_PER_CLUSTER],eax |
movzx ecx,word [ebx+0xb] ; bytes per sector |
cmp ecx,0x200 |
jnz problem_fat_dec_count |
mov [BYTES_PER_SECTOR],ecx |
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32) |
mov edx,32 |
mul edx |
dec ecx |
add eax,ecx ; round up if not equal count |
inc ecx ; bytes per sector |
div ecx |
mov [ROOT_SECTORS],eax ; count of rootdir sectors |
movzx eax,word [ebx+0x16] ; sectors per fat <65536 |
test eax,eax |
jnz fat16_fatsize |
mov eax,[ebx+0x24] ; sectors per fat |
fat16_fatsize: |
mov [SECTORS_PER_FAT],eax |
movzx eax,byte [ebx+0x10] ; number of fats |
test eax,eax ; if 0 it's not fat partition |
jz problem_fat_dec_count |
mov [NUMBER_OF_FATS],eax |
imul eax,[SECTORS_PER_FAT] |
add eax,[FAT_START] |
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count |
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32 |
mov [DATA_START],eax ; data area = rootdir + rootdir_size |
movzx eax,word [ebx+0x13] ; total sector count <65536 |
test eax,eax |
jnz fat16_total |
mov eax,[ebx+0x20] ; total sector count |
fat16_total: |
add eax,[PARTITION_START] |
dec eax |
mov [PARTITION_END],eax |
inc eax |
sub eax,[DATA_START] ; eax = count of data sectors |
xor edx,edx |
div dword [SECTORS_PER_CLUSTER] |
inc eax |
mov [LAST_CLUSTER],eax |
dec eax ; cluster count |
mov [fatStartScan],2 |
; limits by Microsoft Hardware White Paper v1.03 |
cmp eax,4085 ; 0xff5 |
jb problem_fat_dec_count ; fat12 not supported |
cmp eax,65525 ; 0xfff5 |
jb fat16_partition |
fat32_partition: |
mov eax,[ebx+0x2c] ; rootdir cluster |
mov [ROOT_CLUSTER],eax |
movzx eax,word [ebx+0x30] ; fs info sector |
add eax,[PARTITION_START] |
mov [ADR_FSINFO],eax |
call hd_read |
mov eax,[ebx+0x1ec] |
cmp eax,-1 |
jz @f |
mov [fatStartScan],eax |
@@: |
popad |
mov [fatRESERVED],0x0FFFFFF6 |
mov [fatBAD],0x0FFFFFF7 |
mov [fatEND],0x0FFFFFF8 |
mov [fatMASK],0x0FFFFFFF |
mov [fs_type],32 ; Fat32 |
call free_hd_channel |
mov [hd1_status],0 ; free |
ret |
fat16_partition: |
xor eax,eax |
mov [ROOT_CLUSTER],eax |
popad |
mov [fatRESERVED],0x0000FFF6 |
mov [fatBAD],0x0000FFF7 |
mov [fatEND],0x0000FFF8 |
mov [fatMASK],0x0000FFFF |
mov [fs_type],16 ; Fat16 |
call free_hd_channel |
mov [hd1_status],0 ; free |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/fat32.inc |
---|
0,0 → 1,2917 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; FAT32.INC ;; |
;; ;; |
;; FAT16/32 functions for KolibriOS ;; |
;; ;; |
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
;; ;; |
;; See file COPYING for details ;; |
;; 04.02.2007 LFN create folder - diamond ;; |
;; 08.10.2006 LFN delete file/folder - diamond ;; |
;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;; |
;; 17.08.2006 LFN write/append to file - diamond ;; |
;; 23.06.2006 LFN start application - diamond ;; |
;; 15.06.2006 LFN get/set file/folder info - diamond ;; |
;; 27.05.2006 LFN create/rewrite file - diamond ;; |
;; 04.05.2006 LFN read folder - diamond ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout - Mario79 ;; |
;; 23.04.2006 LFN read file - diamond ;; |
;; 28.01.2006 find all Fat16/32 partition in all input point ;; |
;; to MBR, see file part_set.inc - Mario79 ;; |
;; 15.01.2005 get file size/attr/date, file_append - ATV ;; |
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; |
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; |
;; 23.11.2004 don't allow overwrite dir with file - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; |
;; 10.11.2004 removedir clear whole directory structure - ATV ;; |
;; 08.11.2004 rename - ATV ;; |
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; |
;; 20.10.2004 Makedir/Removedir - ATV ;; |
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; |
;; 06.9.2004 Fix free space by Mario79 added - MH ;; |
;; 24.5.2004 Write back buffer for File_write -VT ;; |
;; 20.5.2004 File_read function to work with syscall 58 - VT ;; |
;; 30.3.2004 Error parameters at function return - VT ;; |
;; 01.5.2002 Bugfix in device write - VT ;; |
;; 20.5.2002 Hd status check - VT ;; |
;; 29.6.2002 Improved fat32 verification - VT ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 |
ERROR_SUCCESS = 0 |
ERROR_DISK_BASE = 1 |
ERROR_UNSUPPORTED_FS = 2 |
ERROR_UNKNOWN_FS = 3 |
ERROR_PARTITION = 4 |
ERROR_FILE_NOT_FOUND = 5 |
ERROR_END_OF_FILE = 6 |
ERROR_MEMORY_POINTER = 7 |
ERROR_DISK_FULL = 8 |
ERROR_FAT_TABLE = 9 |
ERROR_ACCESS_DENIED = 10 |
PUSHAD_EAX equ [esp+28] |
PUSHAD_ECX equ [esp+24] |
PUSHAD_EDX equ [esp+20] |
PUSHAD_EBX equ [esp+16] |
PUSHAD_EBP equ [esp+8] |
PUSHAD_ESI equ [esp+4] |
PUSHAD_EDI equ [esp+0] |
uglobal |
align 4 |
partition_count dd 0 ; partitions found by set_FAT32_variables |
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous |
longname_sec2 dd 0 ; directory sectors for delete long filename |
hd_error dd 0 ; set by wait_for_sector_buffer |
hd_setup dd 0 |
hd_wait_timeout dd 0 |
cluster_tmp dd 0 ; used by analyze_directory |
; and analyze_directory_to_write |
file_size dd 0 ; used by file_read |
cache_search_start dd 0 ; used by find_empty_slot |
endg |
iglobal |
fat_in_cache dd -1 |
endg |
uglobal |
align 4 |
fat_cache: times 512 db 0 |
Sector512: ; label for dev_hdcd.inc |
buffer: times 512 db 0 |
fsinfo_buffer: times 512 db 0 |
endg |
uglobal |
fat16_root db 0 ; flag for fat16 rootdir |
fat_change db 0 ; 1=fat has changed |
endg |
reserve_hd1: |
cli |
cmp [hd1_status],0 |
je reserve_ok1 |
sti |
call change_task |
jmp reserve_hd1 |
reserve_ok1: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [hd1_status],eax |
pop eax |
sti |
ret |
;******************************************** |
uglobal |
hd_in_cache db ? |
endg |
reserve_hd_channel: |
; BIOS disk accesses are protected with common mutex hd1_status |
; This must be modified when hd1_status will not be valid! |
cmp [hdpos], 0x80 |
jae .ret |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_2 |
.reserve_ok_1: |
mov [IDE_Channel_1], 1 |
push eax |
mov al, 1 |
jmp @f |
.reserve_ok_2: |
mov [IDE_Channel_2], 1 |
push eax |
mov al, 3 |
@@: |
cmp [hdid], 1 |
sbb al, -1 |
cmp al, [hd_in_cache] |
jz @f |
mov [hd_in_cache], al |
call clear_hd_cache |
@@: |
pop eax |
.ret: |
ret |
free_hd_channel: |
; see comment at reserve_hd_channel |
cmp [hdpos], 0x80 |
jae .ret |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
.ret: |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
ret |
;******************************************** |
problem_partition db 0 ; used for partitions search |
include 'part_set.inc' |
set_FAT: |
;-------------------------------- |
; input : EAX = cluster |
; EDX = value to save |
; output : EDX = old value |
;-------------------------------- |
push eax ebx esi |
cmp eax,2 |
jb sfc_error |
cmp eax,[LAST_CLUSTER] |
ja sfc_error |
cmp [fs_type],16 |
je sfc_1 |
add eax,eax |
sfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je sfc_in_cache ; yes |
cmp [fat_change],0 ; is fat changed? |
je sfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne sfc_error |
sfc_no_change: |
mov [fat_in_cache],eax ; save fat sector |
call hd_read |
cmp [hd_error],0 |
jne sfc_error |
sfc_in_cache: |
cmp [fs_type],16 |
jne sfc_test32 |
sfc_set16: |
xchg [ebx+esi],dx ; save new value and get old value |
jmp sfc_write |
sfc_test32: |
mov eax,[fatMASK] |
sfc_set32: |
and edx,eax |
xor eax,-1 ; mask for high bits |
and eax,[ebx+esi] ; get high 4 bits |
or eax,edx |
mov edx,[ebx+esi] ; get old value |
mov [ebx+esi],eax ; save new value |
sfc_write: |
mov [fat_change],1 ; fat has changed |
sfc_nonzero: |
and edx,[fatMASK] |
sfc_error: |
pop esi ebx eax |
ret |
get_FAT: |
;-------------------------------- |
; input : EAX = cluster |
; output : EAX = next cluster |
;-------------------------------- |
push ebx esi |
cmp [fs_type],16 |
je gfc_1 |
add eax,eax |
gfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je gfc_in_cache |
cmp [fat_change],0 ; is fat changed? |
je gfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_no_change: |
mov [fat_in_cache],eax |
call hd_read |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_in_cache: |
mov eax,[ebx+esi] |
and eax,[fatMASK] |
hd_error_01: |
pop esi ebx |
ret |
get_free_FAT: |
;----------------------------------------------------------- |
; output : if CARRY=0 EAX = # first cluster found free |
; if CARRY=1 disk full |
; Note : for more speed need to use fat_cache directly |
;----------------------------------------------------------- |
push ecx |
mov ecx,[LAST_CLUSTER] ; counter for full disk |
sub ecx,2 |
mov eax,[fatStartScan] |
cmp eax,2 |
jb gff_reset |
gff_test: |
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2 |
jbe gff_in_range |
gff_reset: |
mov eax,2 |
gff_in_range: |
push eax |
call get_FAT ; get cluster state |
cmp [hd_error],0 |
jne gff_not_found_1 |
test eax,eax ; is it free? |
pop eax |
je gff_found ; yes |
inc eax ; next cluster |
dec ecx ; is all checked? |
jns gff_test ; no |
gff_not_found_1: |
add esp,4 |
gff_not_found: |
pop ecx ; yes. disk is full |
stc |
ret |
gff_found: |
lea ecx,[eax+1] |
mov [fatStartScan],ecx |
pop ecx |
clc |
ret |
write_fat_sector: |
;----------------------------------------------------------- |
; write changed fat to disk |
;----------------------------------------------------------- |
push eax ebx ecx |
mov [fat_change],0 |
mov eax,[fat_in_cache] |
cmp eax,-1 |
jz write_fat_not_used |
mov ebx,fat_cache |
mov ecx,[NUMBER_OF_FATS] |
write_next_fat: |
call hd_write |
cmp [hd_error],0 |
jne write_fat_not_used |
add eax,[SECTORS_PER_FAT] |
dec ecx |
jnz write_next_fat |
write_fat_not_used: |
pop ecx ebx eax |
ret |
analyze_directory: |
;----------------------------------------------------------- |
; input : EAX = first cluster of the directory |
; EBX = pointer to filename |
; output : IF CARRY=0 EAX = sector where th file is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,ESI,EDI not changed |
; IF CARRY=1 filename not found |
; Note : if cluster=0 it's changed to read rootdir |
; save 2 previous directory sectors in longname_sec |
;----------------------------------------------------------- |
push ecx edx esi edi ebx ; ebx = [esp+0] |
mov [longname_sec1],0 |
mov [longname_sec2],0 |
adr_new_cluster: |
mov [cluster_tmp],eax |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja adr_not_found ; too big cluster number, something is wrong |
cmp eax,2 |
jnb adr_data_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fs_type],16 |
jne adr_data_cluster |
mov eax,[ROOT_START] |
mov edx,[ROOT_SECTORS] |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp adr_new_sector |
adr_data_cluster: |
sub eax,2 |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
adr_new_sector: |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne adr_not_found |
mov ecx,512/32 ; count of dir entrys per sector = 16 |
adr_analyze: |
mov edi,[ebx+11] ; file attribute |
and edi,0xf |
cmp edi,0xf |
je adr_long_filename |
test edi,0x8 ; skip over volume label |
jne adr_long_filename ; Note: label can be same name as file/dir |
mov esi,[esp+0] ; filename need to be uppercase |
mov edi,ebx |
push ecx |
mov ecx,11 |
cld |
rep cmpsb ; compare 8+3 filename |
pop ecx |
je adr_found |
adr_long_filename: |
add ebx,32 ; position of next dir entry |
dec ecx |
jnz adr_analyze |
mov ecx,[longname_sec1] ; save 2 previous directory sectors |
mov [longname_sec1],eax ; for delete long filename |
mov [longname_sec2],ecx |
inc eax ; next sector |
dec edx |
jne adr_new_sector |
cmp [fat16_root],1 ; end of fat16 rootdir |
je adr_not_found |
adr_next_cluster: |
mov eax,[cluster_tmp] |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne adr_not_found |
cmp eax,2 ; incorrect fat chain? |
jb adr_not_found ; yes |
cmp eax,[fatRESERVED] ; is it end of directory? |
jb adr_new_cluster ; no. analyse it |
adr_not_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
stc ; file not found |
ret |
adr_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
clc ; file found |
ret |
get_data_cluster: |
;----------------------------------------------------------- |
; input : EAX = cluster |
; EBX = pointer to buffer |
; EDX = # blocks to read in buffer |
; ESI = # blocks to skip over |
; output : if CARRY=0 ok EBX/EDX/ESI updated |
; if CARRY=1 cluster out of range |
; Note : if cluster=0 it's changed to read rootdir |
;----------------------------------------------------------- |
push eax ecx |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja gdc_error ; too big cluster number, something is wrong |
cmp eax,2 |
jnb gdc_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fs_type],16 |
jne gdc_cluster |
mov eax,[ROOT_START] |
mov ecx,[ROOT_SECTORS] ; Note: not cluster size |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp gdc_read |
gdc_cluster: |
sub eax,2 |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
gdc_read: |
test esi,esi ; first wanted block |
je gdcl1 ; yes, skip count is 0 |
dec esi |
jmp gdcl2 |
gdcl1: |
call hd_read |
cmp [hd_error],0 |
jne gdc_error |
add ebx,512 ; update pointer |
dec edx |
gdcl2: |
test edx,edx ; is all read? |
je out_of_read |
inc eax ; next sector |
dec ecx |
jnz gdc_read |
out_of_read: |
pop ecx eax |
clc |
ret |
gdc_error: |
pop ecx eax |
stc |
ret |
get_cluster_of_a_path: |
;--------------------------------------------------------- |
; input : EBX = pointer to a path string |
; (example: the path "/files/data/document" become |
; "files......data.......document...0" |
; '.' = space char |
; '0' = char(0) (ASCII=0) !!! ) |
; output : if (CARRY=1) -> ERROR in the PATH |
; if (CARRY=0) -> EAX=cluster |
;--------------------------------------------------------- |
push ebx edx |
mov eax,[ROOT_CLUSTER] |
mov edx,ebx |
search_end_of_path: |
cmp byte [edx],0 |
je found_end_of_path |
inc edx ; '/' |
mov ebx,edx |
call analyze_directory |
jc directory_not_found |
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field |
mov ax,[ebx+26] ; read the LOW 16bit cluster field |
and eax,[fatMASK] |
add edx,11 ; 8+3 (name+extension) |
jmp search_end_of_path |
found_end_of_path: |
pop edx ebx |
clc ; no errors |
ret |
directory_not_found: |
pop edx ebx |
stc ; errors occour |
ret |
bcd2bin: |
;---------------------------------- |
; input : AL=BCD number (eg. 0x11) |
; output : AH=0 |
; AL=decimal number (eg. 11) |
;---------------------------------- |
xor ah,ah |
shl ax,4 |
shr al,4 |
aad |
ret |
get_date_for_file: |
;----------------------------------------------------- |
; Get date from CMOS and pack day,month,year in AX |
; DATE bits 0..4 : day of month 0..31 |
; 5..8 : month of year 1..12 |
; 9..15 : count of years from 1980 |
;----------------------------------------------------- |
mov al,0x7 ;day |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,5 |
mov al,0x8 ;month |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,4 |
mov al,0x9 ;year |
out 0x70,al |
in al,0x71 |
call bcd2bin |
add ax,20 ;because CMOS return only the two last |
;digit (eg. 2000 -> 00 , 2001 -> 01) and we |
rol eax,9 ;need the difference with 1980 (eg. 2001-1980) |
ret |
get_time_for_file: |
;----------------------------------------------------- |
; Get time from CMOS and pack hour,minute,second in AX |
; TIME bits 0..4 : second (the low bit is lost) |
; 5..10 : minute 0..59 |
; 11..15 : hour 0..23 |
;----------------------------------------------------- |
mov al,0x0 ;second |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x2 ;minute |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x4 ;hour |
out 0x70,al |
in al,0x71 |
call bcd2bin |
rol eax,11 |
ret |
set_current_time_for_entry: |
;----------------------------------------------------- |
; Set current time/date for file entry |
; input : ebx = file entry pointer |
;----------------------------------------------------- |
push eax |
call get_time_for_file ; update files date/time |
mov [ebx+22],ax |
call get_date_for_file |
mov [ebx+24],ax |
pop eax |
ret |
add_disk_free_space: |
;----------------------------------------------------- |
; input : ecx = cluster count |
; Note : negative = remove clusters from free space |
; positive = add clusters to free space |
;----------------------------------------------------- |
test ecx,ecx ; no change |
je add_dfs_no |
cmp [fs_type],32 ; free disk space only used by fat32 |
jne add_dfs_no |
push eax ebx |
mov eax,[ADR_FSINFO] |
mov ebx,fsinfo_buffer |
call hd_read |
cmp [hd_error],0 |
jne add_not_fs |
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id |
jne add_not_fs |
add [ebx+0x1e8],ecx |
push [fatStartScan] |
pop dword [ebx+0x1ec] |
call hd_write |
; cmp [hd_error],0 |
; jne add_not_fs |
add_not_fs: |
pop ebx eax |
add_dfs_no: |
ret |
file_read: |
;-------------------------------------------------------------------------- |
; INPUT : user-register register-in-this meaning symbol-in-this |
; |
; EAX EDI system call to write / |
; EBX EAX (PAR0) pointer to file-name PAR0 |
; EDX ECX (PAR1) pointer to buffer PAR1 |
; ECX EBX (PAR2) vt file blocks to read PAR2 |
; ESI EDX (PAR3) pointer to path PAR3 |
; EDI ESI vt first 512 block to read |
; EDI if 0 - read root |
; |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 6 - end of file |
; 9 - fat table corrupted |
; 10 - access denied |
; ebx = size of file/directory |
;-------------------------------------------------------------------------- |
cmp [fs_type], 16 |
jz fat_ok_for_reading |
cmp [fs_type], 32 |
jz fat_ok_for_reading |
xor ebx,ebx |
mov eax,ERROR_UNKNOWN_FS |
mov [hd1_status], ebx |
ret |
fat_ok_for_reading: |
; call reserve_hd1 |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jc file_to_read_not_found |
test edi,edi ; read rootdir |
jne no_read_root |
xor eax,eax |
call get_dir_size ; return rootdir size |
cmp [hd_error],0 |
jne file_access_denied |
mov [file_size],eax |
mov eax,[ROOT_CLUSTER] |
jmp file_read_start |
no_read_root: |
mov ebx,PUSHAD_EAX ; file name |
call analyze_directory |
jc file_to_read_not_found |
mov eax,[ebx+28] ; file size |
test byte [ebx+11],0x10 ; is it directory? |
jz read_set_size ; no |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
call get_dir_size |
cmp [hd_error],0 |
jne file_access_denied |
read_set_size: |
mov [file_size],eax |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
file_read_start: |
mov ebx,PUSHAD_ECX ; pointer to buffer |
mov edx,PUSHAD_EBX ; file blocks to read |
mov esi,PUSHAD_ESI ; first 512 block to read |
file_read_new_cluster: |
call get_data_cluster |
jc file_read_eof ; end of file or cluster out of range |
test edx,edx ; is all read? |
je file_read_OK ; yes |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne file_access_denied |
cmp eax,[fatRESERVED] ; end of file |
jnb file_read_eof |
cmp eax,2 ; incorrect fat chain |
jnb file_read_new_cluster |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_FAT_TABLE |
ret |
file_read_eof: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_END_OF_FILE |
ret |
file_read_OK: |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
xor eax,eax |
ret |
file_to_read_not_found: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
file_access_denied: |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_ACCESS_DENIED |
ret |
get_dir_size: |
;----------------------------------------------------- |
; input : eax = first cluster (0=rootdir) |
; output : eax = directory size in bytes |
;----------------------------------------------------- |
push edx |
xor edx,edx ; count of directory clusters |
test eax,eax |
jnz dir_size_next |
mov eax,[ROOT_SECTORS] |
shl eax,9 ; fat16 rootdir size in bytes |
cmp [fs_type],16 |
je dir_size_ret |
mov eax,[ROOT_CLUSTER] |
dir_size_next: |
cmp eax,2 ; incorrect fat chain |
jb dir_size_end |
cmp eax,[fatRESERVED] ; end of directory |
ja dir_size_end |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne dir_size_ret |
inc edx |
jmp dir_size_next |
dir_size_end: |
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
imul eax,edx |
dir_size_ret: |
pop edx |
ret |
clear_cluster_chain: |
;----------------------------------------------------- |
; input : eax = first cluster |
;----------------------------------------------------- |
push eax ecx edx |
xor ecx,ecx ; cluster count |
clean_new_chain: |
cmp eax,[LAST_CLUSTER] ; end of file |
ja delete_OK |
cmp eax,2 ; unfinished fat chain or zero length file |
jb delete_OK |
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster |
jz delete_OK |
xor edx,edx |
call set_FAT ; clear fat entry |
cmp [hd_error],0 |
jne access_denied_01 |
inc ecx ; update cluster count |
mov eax,edx ; old cluster |
jmp clean_new_chain |
delete_OK: |
call add_disk_free_space ; add clusters to free disk space |
access_denied_01: |
pop edx ecx eax |
ret |
get_hd_info: |
;----------------------------------------------------------- |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 10 - access denied |
; edx = cluster size in bytes |
; ebx = total clusters on disk |
; ecx = free clusters on disk |
;----------------------------------------------------------- |
cmp [fs_type], 16 |
jz info_fat_ok |
cmp [fs_type], 32 |
jz info_fat_ok |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_UNKNOWN_FS |
ret |
info_fat_ok: |
; call reserve_hd1 |
xor ecx,ecx ; count of free clusters |
mov eax,2 |
mov ebx,[LAST_CLUSTER] |
info_cluster: |
push eax |
call get_FAT ; get cluster info |
cmp [hd_error],0 |
jne info_access_denied |
test eax,eax ; is it free? |
jnz info_used ; no |
inc ecx |
info_used: |
pop eax |
inc eax |
cmp eax,ebx ; is above last cluster? |
jbe info_cluster ; no. test next cluster |
dec ebx ; cluster count |
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
mov [hd1_status],0 |
xor eax,eax |
ret |
info_access_denied: |
add esp,4 |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_ACCESS_DENIED |
ret |
update_disk: |
;----------------------------------------------------------- |
; write changed fat and cache to disk |
;----------------------------------------------------------- |
cmp [fat_change],0 ; is fat changed? |
je upd_no_change |
call write_fat_sector |
cmp [hd_error],0 |
jne update_disk_acces_denied |
upd_no_change: |
call write_cache |
update_disk_acces_denied: |
ret |
; \begin{diamond} |
hd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=sector |
; destroys eax |
push esi edi |
push 0 |
push 0 |
push fat16_root_first |
push fat16_root_next |
mov eax, [ROOT_CLUSTER] |
cmp [fs_type], 32 |
jz .fat32 |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
and dword [esp+12], 0 |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; cluster |
.fat32: |
mov [esp+8], eax |
mov dword [esp+4], fat_notroot_first |
mov dword [esp], fat_notroot_next |
jmp .loop |
.notfound: |
add esp, 16 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
lea eax, [esp+8] |
cmp dword [eax], 0 |
jz .root |
call fat_get_sector |
jmp .cmn |
.root: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
.cmn: |
add esp, 20 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRead - LFN variant for reading hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdRead: |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
cmp [fs_type], 1 |
jz ntfs_HdRead |
or ebx, -1 |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
push edi |
cmp byte [esi], 0 |
jnz @f |
.noaccess: |
pop edi |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
@@: |
call hd_find_lfn |
jnc .found |
pop edi |
cmp [hd_error],0 |
jne .noaccess_2 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read directories |
jnz .noaccess |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 |
@@: |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_cluster: |
jecxz .new_sector |
test eax, eax |
jz .eof |
cmp eax, [fatRESERVED] |
jae .eof |
mov [cluster_tmp], eax |
dec eax |
dec eax |
mov edi, [SECTORS_PER_CLUSTER] |
imul eax, edi |
add eax, [DATA_START] |
.new_sector: |
test ecx, ecx |
jz .done |
sub ebx, 512 |
jae .skip |
add ebx, 512 |
jnz .force_buf |
cmp ecx, 512 |
jb .force_buf |
; we may read directly to given buffer |
push ebx |
mov ebx, edx |
call hd_read |
pop ebx |
cmp [hd_error],0 |
jne .noaccess_1 |
add edx, 512 |
sub ecx, 512 |
jmp .skip |
.force_buf: |
; we must read sector to temporary buffer and then copy it to destination |
push eax ebx |
mov ebx, buffer |
call hd_read |
mov eax, ebx |
pop ebx |
cmp [hd_error],0 |
jne .noaccess_3 |
add eax, ebx |
push ecx |
add ecx, ebx |
cmp ecx, 512 |
jbe @f |
mov ecx, 512 |
@@: |
sub ecx, ebx |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
pop eax |
xor ebx, ebx |
.skip: |
inc eax |
dec edi |
jnz .new_sector |
mov eax, [cluster_tmp] |
call get_FAT |
cmp [hd_error],0 |
jne .noaccess_1 |
jmp .new_cluster |
.noaccess_3: |
pop eax |
.noaccess_1: |
pop eax |
push 11 |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
;---------------------------------------------------------------- |
; |
; fs_HdReadFolder - LFN variant for reading hard disk folder |
; |
; esi points to filename |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdReadFolder: |
cmp [fs_type], 1 |
jz ntfs_HdReadFolder |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNSUPPORTED_FS |
pop eax |
or ebx, -1 |
ret |
@@: |
mov eax, [ROOT_CLUSTER] |
push edi |
cmp byte [esi], 0 |
jz .doit |
call hd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; eax=cluster |
.doit: |
push esi ecx |
push ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.new_cluster: |
mov [cluster_tmp], eax |
test eax, eax |
jnz @f |
cmp [fs_type], 32 |
jz .notfound |
mov eax, [ROOT_START] |
push [ROOT_SECTORS] |
push ebx |
jmp .new_sector |
@@: |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
push [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
push ebx |
.new_sector: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, ebx |
jb .do_bdfe |
pop eax |
inc eax |
dec dword [esp+4] |
jnz @f |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
mov [cluster_tmp], eax |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
@@: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec dword [esp+4] |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, ebx |
jb .l1 |
pop eax |
inc eax |
dec dword [esp+4] |
jnz .new_sector |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
pop ebx |
add esp, 4 |
jmp .new_cluster |
.notfound2: |
add esp, 8 |
.notfound: |
add esp, 262*2+4 |
pop ebp ecx esi edi |
mov eax, ERROR_FILE_NOT_FOUND |
or ebx, -1 |
ret |
.done: |
add esp, 262*2+4+8 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi |
ret |
fat16_root_next: |
cmp edi, buffer+0x200-0x20 |
jae fat16_root_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat16_root_next_sector: |
; read next sector |
push [longname_sec2] |
pop [longname_sec1] |
push ecx |
mov ecx, [eax+4] |
push ecx |
add ecx, [ROOT_START] |
mov [longname_sec2], ecx |
pop ecx |
inc ecx |
mov [eax+4], ecx |
cmp ecx, [ROOT_SECTORS] |
pop ecx |
jae fat16_root_first.readerr |
fat16_root_first: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .readerr |
ret ; CF=0 |
.readerr: |
stc |
ret |
fat16_root_begin_write: |
push edi eax |
call fat16_root_first |
pop eax edi |
ret |
fat16_root_end_write: |
pusha |
mov eax, [eax+4] |
add eax, [ROOT_START] |
mov ebx, buffer |
call hd_write |
popa |
ret |
fat16_root_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
call fat16_root_end_write |
jmp fat16_root_next_sector |
fat16_root_extend_dir: |
stc |
ret |
fat_notroot_next: |
cmp edi, buffer+0x200-0x20 |
jae fat_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat_notroot_next_sector: |
push [longname_sec2] |
pop [longname_sec1] |
push eax |
call fat_get_sector |
mov [longname_sec2], eax |
pop eax |
push ecx |
mov ecx, [eax+4] |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jae fat_notroot_next_cluster |
mov [eax+4], ecx |
jmp @f |
fat_notroot_next_cluster: |
push eax |
mov eax, [eax] |
call get_FAT |
mov ecx, eax |
pop eax |
cmp [hd_error], 0 |
jnz fat_notroot_next_err |
cmp ecx, [fatRESERVED] |
jae fat_notroot_next_err |
mov [eax], ecx |
and dword [eax+4], 0 |
@@: |
pop ecx |
fat_notroot_first: |
call fat_get_sector |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz @f |
ret ; CF=0 |
fat_notroot_next_err: |
pop ecx |
@@: |
stc |
ret |
fat_notroot_begin_write: |
push eax edi |
call fat_notroot_first |
pop edi eax |
ret |
fat_notroot_end_write: |
call fat_get_sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
ret |
fat_notroot_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
push eax |
call fat_notroot_end_write |
pop eax |
jmp fat_notroot_next_sector |
fat_notroot_extend_dir: |
push eax |
call get_free_FAT |
jnc .found |
pop eax |
ret ; CF=1 |
.found: |
push edx |
mov edx, [fatEND] |
call set_FAT |
mov edx, eax |
mov eax, [esp+4] |
mov eax, [eax] |
push edx |
call set_FAT |
pop edx |
cmp [hd_error], 0 |
jz @f |
pop edx |
pop eax |
stc |
ret |
@@: |
push ecx |
or ecx, -1 |
call add_disk_free_space |
; zero new cluster |
mov ecx, 512/4 |
mov edi, buffer |
push edi |
xor eax, eax |
rep stosd |
pop edi |
pop ecx |
mov eax, [esp+4] |
mov [eax], edx |
and dword [eax+4], 0 |
pop edx |
mov eax, [eax] |
dec eax |
dec eax |
push ebx ecx |
mov ecx, [SECTORS_PER_CLUSTER] |
imul eax, ecx |
add eax, [DATA_START] |
mov ebx, edi |
@@: |
call hd_write |
inc eax |
loop @b |
pop ecx ebx eax |
clc |
ret |
fat_get_sector: |
push ecx |
mov ecx, [eax] |
dec ecx |
dec ecx |
imul ecx, [SECTORS_PER_CLUSTER] |
add ecx, [DATA_START] |
add ecx, [eax+4] |
mov eax, ecx |
pop ecx |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRewrite - LFN variant for writing hard disk |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fshrad: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fshrfs: |
mov eax, ERROR_UNKNOWN_FS |
xor ebx, ebx |
ret |
fs_HdCreateFolder: |
mov al, 1 |
jmp fs_HdRewrite.common |
fs_HdRewrite: |
xor eax, eax |
.common: |
cmp [fs_type], 1 |
jz ntfs_HdRewrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jnz fshrfs |
@@: |
cmp byte [esi], 0 |
jz fshrad |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
mov ebp, [ROOT_CLUSTER] |
cmp [fs_type], 32 |
jz .pushnotroot |
push fat16_root_extend_dir |
push fat16_root_end_write |
push fat16_root_next_write |
push fat16_root_begin_write |
xor ebp, ebp |
push ebp |
push ebp |
push fat16_root_first |
push fat16_root_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call hd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call hd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
mov ebp, [edi+20-2] |
mov bp, [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
.pushnotroot: |
push fat_notroot_extend_dir |
push fat_notroot_end_write |
push fat_notroot_next_write |
push fat_notroot_begin_write |
push 0 |
push ebp |
push fat_notroot_first |
push fat_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 32 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+32+28], 0 |
jz @f |
add esp, 32 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xor ecx, ecx |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov word [edi+20], cx |
mov word [edi+26], cx |
test eax, eax |
jz .done1 |
@@: |
cmp eax, [fatRESERVED] |
jae .done1 |
push edx |
xor edx, edx |
call set_FAT |
mov eax, edx |
pop edx |
inc ecx |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 32 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+32 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+16+8+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 12+8+12+32 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [hd_error], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax+20] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 12+8+12+32 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+12+8+12+8] |
mov [esp+4], ecx |
mov ecx, [esp+12+8+12+12] |
mov [esp+8], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+12] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+12] |
pop dword [esp+8+12+12] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+12] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+16] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
xor ecx, ecx |
mov word [edi+20], cx ; high word of cluster |
mov word [edi+26], cx ; low word of cluster - to be filled |
mov dword [edi+28], ecx ; file size - to be filled |
cmp byte [esp+32+28], cl |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov edx, edi |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [SECTORS_PER_CLUSTER] |
shl ecx, 9 |
jmp .doit2 |
.doit: |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [esp+4+32+24] |
.doit2: |
push ecx |
push edi |
mov esi, edx |
test ecx, ecx |
jz .done |
call get_free_FAT |
jc .diskfull |
push eax |
mov [edi+26], ax |
shr eax, 16 |
mov [edi+20], ax |
lea eax, [esp+16+8] |
call dword [eax+16] ; flush directory |
pop eax |
push edx |
mov edx, [fatEND] |
call set_FAT |
pop edx |
.write_cluster: |
push eax |
dec eax |
dec eax |
mov ebp, [SECTORS_PER_CLUSTER] |
imul eax, ebp |
add eax, [DATA_START] |
; write data |
.write_sector: |
cmp byte [esp+16+32+28], 0 |
jnz .writedir |
mov ecx, 512 |
cmp dword [esp+8], ecx |
jb .writeshort |
; we can write directly from given buffer |
mov ebx, esi |
add esi, ecx |
jmp .writecommon |
.writeshort: |
mov ecx, [esp+8] |
push ecx |
mov edi, buffer |
mov ebx, edi |
rep movsb |
.writedircont: |
mov ecx, buffer+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pop ecx |
.writecommon: |
call hd_write |
cmp [hd_error], 0 |
jnz .writeerr |
inc eax |
sub dword [esp+8], ecx |
jz .writedone |
dec ebp |
jnz .write_sector |
; allocate new cluster |
pop eax |
mov ecx, eax |
call get_free_FAT |
jc .diskfull |
push edx |
mov edx, [fatEND] |
call set_FAT |
xchg eax, ecx |
mov edx, ecx |
call set_FAT |
pop edx |
xchg eax, ecx |
jmp .write_cluster |
.diskfull: |
mov eax, ERROR_DISK_FULL |
jmp .ret |
.writeerr: |
pop eax |
sub esi, ecx |
mov eax, 11 |
jmp .ret |
.writedone: |
pop eax |
.done: |
xor eax, eax |
.ret: |
pop edi ecx |
mov ebx, esi |
sub ebx, edx |
pop ebp |
mov [esp+32+28], eax |
lea eax, [esp+8] |
call dword [eax+8] |
mov [edi+28], ebx |
call dword [eax+16] |
mov [esp+32+16], ebx |
lea eax, [ebx+511] |
shr eax, 9 |
mov ecx, [SECTORS_PER_CLUSTER] |
lea eax, [eax+ecx-1] |
xor edx, edx |
div ecx |
mov ecx, ebp |
sub ecx, eax |
call add_disk_free_space |
add esp, 32 |
call update_disk |
popad |
ret |
.writedir: |
push 512 |
mov edi, buffer |
mov ebx, edi |
mov ecx, [SECTORS_PER_CLUSTER] |
shl ecx, 9 |
cmp ecx, [esp+12] |
jnz .writedircont |
dec dword [esp+16] |
push esi |
mov ecx, 32/4 |
rep movsd |
pop esi |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
push esi |
mov ecx, 32/4 |
rep movsd |
pop esi |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov ecx, [esp+20+8] |
cmp ecx, [ROOT_CLUSTER] |
jnz @f |
xor ecx, ecx |
@@: |
mov word [edi-32+26], cx |
shr ecx, 16 |
mov [edi-32+20], cx |
jmp .writedircont |
;---------------------------------------------------------------- |
; |
; fs_HdWrite - LFN variant for writing to hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdWrite.access_denied: |
push ERROR_ACCESS_DENIED |
fs_HdWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_HdWrite.ret11: |
push 11 |
jmp fs_HdWrite.ret0 |
fs_HdWrite: |
cmp [fs_type], 1 |
jz ntfs_HdWrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
jmp .ret0 |
@@: |
cmp byte [esi], 0 |
jz .access_denied |
pushad |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
popad |
push 11 |
jmp .ret0 |
@@: |
popfd |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push eax ; save directory sector |
push 0 ; return value=0 |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
push dword [edi+28] ; save current file size |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call hd_extend_file |
jnc .length_ok |
mov [esp+4], eax |
; hd_extend_file can return three error codes: FAT table error, device error or disk full. |
; First two cases are fatal errors, in third case we may write some data |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
pop eax |
mov [esp+4+28], eax |
pop eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
call update_disk |
cmp [hd_error], 0 |
jz @f |
mov byte [esp+4], 11 |
@@: |
pop eax |
pop eax |
mov [esp+4+28], eax ; eax=return value |
pop eax |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
mov esi, [edi+28] |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov edi, eax ; edi=current cluster |
xor ebp, ebp ; ebp=current sector in cluster |
; save directory |
mov eax, [esp+8] |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jz @f |
.device_err: |
mov byte [esp+4], 11 |
jmp .ret |
@@: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
.write_loop: |
; skip unmodified sectors |
cmp dword [esp], 0x200 |
jb .modify |
sub ebx, 0x200 |
jae .skip |
add ebx, 0x200 |
.modify: |
; get length of data in current sector |
push ecx |
sub ebx, 0x200 |
jb .hasdata |
neg ebx |
xor ecx, ecx |
jmp @f |
.hasdata: |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
; get current sector number |
mov eax, edi |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ebp |
; load sector if needed |
cmp dword [esp+4], 0 ; we don't need to read uninitialized data |
jz .noread |
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten |
jz .noread |
cmp ecx, esi ; (same for the last sector) |
jz .noread |
push ebx |
mov ebx, buffer |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jz @f |
.device_err2: |
pop ecx |
jmp .device_err |
@@: |
.noread: |
; zero uninitialized data if file was extended (because hd_extend_file does not this) |
push eax ecx edi |
xor eax, eax |
mov ecx, 0x200 |
sub ecx, [esp+4+12] |
jbe @f |
mov edi, buffer |
add edi, [esp+4+12] |
rep stosb |
@@: |
; zero uninitialized data in the last sector |
mov ecx, 0x200 |
sub ecx, esi |
jbe @f |
mov edi, buffer |
add edi, esi |
rep stosb |
@@: |
pop edi ecx |
; copy new data |
mov eax, edx |
neg ebx |
jecxz @f |
add ebx, buffer+0x200 |
call memmove |
xor ebx, ebx |
@@: |
pop eax |
; save sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jnz .device_err2 |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .ret |
.skip: |
; next sector |
inc ebp |
cmp ebp, [SECTORS_PER_CLUSTER] |
jb @f |
xor ebp, ebp |
mov eax, edi |
call get_FAT |
mov edi, eax |
cmp [hd_error], 0 |
jnz .device_err |
@@: |
sub esi, 0x200 |
jae @f |
xor esi, esi |
@@: |
sub dword [esp], 0x200 |
jae @f |
and dword [esp], 0 |
@@: jmp .write_loop |
hd_extend_file.zero_size: |
xor eax, eax |
jmp hd_extend_file.start_extend |
; extends file on hd to given size (new data area is undefined) |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) |
hd_extend_file: |
push ebp |
mov ebp, [SECTORS_PER_CLUSTER] |
imul ebp, [BYTES_PER_SECTOR] |
push ecx |
; find the last cluster of file |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov ecx, [edi+28] |
jecxz .zero_size |
.last_loop: |
sub ecx, ebp |
jbe .last_found |
call get_FAT |
cmp [hd_error], 0 |
jz @f |
.device_err: |
pop ecx |
.device_err2: |
pop ebp |
push 11 |
.ret_err: |
pop eax |
stc |
ret |
@@: |
cmp eax, 2 |
jb .fat_err |
cmp eax, [fatRESERVED] |
jb .last_loop |
.fat_err: |
pop ecx ebp |
push ERROR_FAT_TABLE |
jmp .ret_err |
.last_found: |
push eax |
call get_FAT |
cmp [hd_error], 0 |
jz @f |
pop eax |
jmp .device_err |
@@: |
cmp eax, [fatRESERVED] |
pop eax |
jb .fat_err |
; set length to full number of clusters |
sub [edi+28], ecx |
.start_extend: |
pop ecx |
; now do extend |
push edx |
mov edx, 2 ; start scan from cluster 2 |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new cluster |
push eax |
call get_free_FAT |
jc .disk_full |
mov edx, [fatEND] |
call set_FAT |
mov edx, eax |
pop eax |
test eax, eax |
jz .first_cluster |
push edx |
call set_FAT |
pop edx |
jmp @f |
.first_cluster: |
ror edx, 16 |
mov [edi+20], dx |
ror edx, 16 |
mov [edi+26], dx |
@@: |
push ecx |
mov ecx, -1 |
call add_disk_free_space |
pop ecx |
mov eax, edx |
cmp [hd_error], 0 |
jnz .device_err3 |
add [edi+28], ebp |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop edx ebp |
xor eax, eax ; CF=0 |
ret |
.device_err3: |
pop edx |
jmp .device_err2 |
.disk_full: |
pop eax edx ebp |
push ERROR_DISK_FULL |
pop eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: stc |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdSetFileEnd - set end of file on hard disk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdSetFileEnd: |
cmp [fs_type], 1 |
jz ntfs_HdSetFileEnd |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
.ret: |
pop eax |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
push 11 |
jmp .ret |
@@: |
popfd |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4 Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
push eax ; save directory sector |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop eax |
mov ebx, buffer |
call hd_write |
pop edi |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
.expand: |
push ebx ebp ecx |
push dword [edi+28] ; save old size |
mov ecx, eax |
call hd_extend_file |
push eax ; return code |
jnc .expand_ok |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
.pop_ret: |
call update_disk |
pop eax ecx ebp ebx ecx edi edi |
ret |
.expand_ok: |
.disk_full: |
; save directory |
mov eax, [edi+28] |
xchg eax, [esp+20] |
mov ebx, buffer |
call hd_write |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov edi, eax |
cmp [hd_error], 0 |
jz @f |
.pop_ret11: |
mov byte [esp], 11 |
jmp .pop_ret |
@@: |
; now zero new data |
xor ebp, ebp |
; edi=current cluster, ebp=sector in cluster |
; [esp+20]=new size, [esp+4]=old size, [esp]=return code |
.zero_loop: |
sub dword [esp+4], 0x200 |
jae .next_cluster |
lea eax, [edi-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ebp |
cmp dword [esp+4], -0x200 |
jz .noread |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jnz .err_next |
.noread: |
mov ecx, [esp+4] |
neg ecx |
push edi |
mov edi, buffer+0x200 |
add edi, [esp+8] |
push eax |
xor eax, eax |
mov [esp+12], eax |
rep stosb |
pop eax |
pop edi |
call hd_write |
cmp [hd_error], 0 |
jz .next_cluster |
.err_next: |
mov byte [esp], 11 |
.next_cluster: |
sub dword [esp+20], 0x200 |
jbe .pop_ret |
inc ebp |
cmp ebp, [SECTORS_PER_CLUSTER] |
jb .zero_loop |
xor ebp, ebp |
mov eax, edi |
call get_FAT |
mov edi, eax |
cmp [hd_error], 0 |
jnz .pop_ret11 |
jmp .zero_loop |
.truncate: |
mov [edi+28], eax |
push ecx |
mov ecx, [edi+20-2] |
mov cx, [edi+26] |
push eax |
test eax, eax |
jz .zero_size |
; find new last cluster |
@@: |
mov eax, [SECTORS_PER_CLUSTER] |
shl eax, 9 |
sub [esp], eax |
jbe @f |
mov eax, ecx |
call get_FAT |
mov ecx, eax |
cmp [hd_error], 0 |
jz @b |
.device_err3: |
pop eax ecx eax edi |
push 11 |
pop eax |
ret |
@@: |
; we will zero data at the end of last sector - remember it |
push ecx |
; terminate FAT chain |
push edx |
mov eax, ecx |
mov edx, [fatEND] |
call set_FAT |
mov eax, edx |
pop edx |
cmp [hd_error], 0 |
jz @f |
.device_err4: |
pop ecx |
jmp .device_err3 |
.zero_size: |
and word [edi+20], 0 |
and word [edi+26], 0 |
push 0 |
mov eax, ecx |
@@: |
; delete FAT chain |
call clear_cluster_chain |
cmp [hd_error], 0 |
jnz .device_err4 |
; save directory |
mov eax, [esp+12] |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jnz .device_err4 |
; zero last sector, ignore errors |
pop ecx |
pop eax |
dec ecx |
imul ecx, [SECTORS_PER_CLUSTER] |
add ecx, [DATA_START] |
push eax |
sar eax, 9 |
add ecx, eax |
pop eax |
and eax, 0x1FF |
jz .truncate_done |
push ebx eax |
mov eax, ecx |
mov ebx, buffer |
call hd_read |
pop eax |
lea edi, [buffer+eax] |
push ecx |
mov ecx, 0x200 |
sub ecx, eax |
xor eax, eax |
rep stosb |
pop eax |
call hd_write |
pop ebx |
.truncate_done: |
pop ecx eax edi |
call update_disk |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
fs_HdGetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdGetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jmp fs_GetFileInfo_finish |
fs_HdSetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdSetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
mov ebx, buffer |
call hd_write |
call update_disk |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdDelete - delete file or empty folder from hard disk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdDelete: |
cmp [fs_type], 1 |
jz ntfs_HdDelete |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
.pop_ret: |
pop eax |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .pop_ret |
@@: |
and [longname_sec1], 0 |
and [longname_sec2], 0 |
push edi |
call hd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
pushad |
mov ebp, [edi+20-2] |
mov bp, [edi+26] |
xor ecx, ecx |
lea eax, [ebp-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jnz .err1 |
add ebx, 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
cmp ebx, buffer+0x200 |
jb .checkempty |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jb @f |
mov eax, ebp |
call get_FAT |
cmp [hd_error], 0 |
jnz .err1 |
mov ebp, eax |
xor ecx, ecx |
@@: |
lea eax, [ebp-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ecx |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jz .checkempty |
.err1: |
popad |
.err2: |
pop edi |
push 11 |
pop eax |
ret |
.notempty: |
popad |
.access_denied2: |
pop edi |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
.empty: |
popad |
push ebx |
mov ebx, buffer |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .err2 |
.dodel: |
push eax |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
xchg eax, [esp] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
cmp edi, buffer |
ja @f |
cmp [longname_sec2], 0 |
jz .lfndone |
push [longname_sec2] |
push [longname_sec1] |
pop [longname_sec2] |
and [longname_sec1], 0 |
push ebx |
mov ebx, buffer |
call hd_write |
mov eax, [esp+4] |
call hd_read |
pop ebx |
pop eax |
mov edi, buffer+0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
; delete FAT chain |
pop eax |
call clear_cluster_chain |
call update_disk |
pop edi |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/fs.inc |
---|
0,0 → 1,797 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; System service for filesystem call ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout (for LBA) - Mario79 ;; |
;; 15.01.2005 get file size/attr/date, ;; |
;; file_append (only for hd) - ATV ;; |
;; 23.11.2004 test if hd/partition is set - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;; |
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
dir0: db 'HARDDISK ' |
db 'RAMDISK ' |
db 'FLOPPYDISK ' |
db 0 |
dir1: db 'FIRST ' |
db 'SECOND ' |
db 'THIRD ' |
db 'FOURTH ' |
db 0 |
not_select_IDE db 0 |
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 |
dd 0x170,0x00,0x170,0x10 |
endg |
file_system: |
; IN: |
; |
; eax = 0 ; read file /RamDisk/First 6 |
; eax = 8 ; lba read |
; eax = 15 ; get_disk_info |
; |
; OUT: |
; |
; eax = 0 : read ok |
; eax = 1 : no hd base and/or partition defined |
; eax = 2 : function is unsupported for this FS |
; eax = 3 : unknown FS |
; eax = 4 : partition not defined at hd |
; eax = 5 : file not found |
; eax = 6 : end of file |
; eax = 7 : memory pointer not in application area |
; eax = 8 : disk full |
; eax = 9 : fat table corrupted |
; eax = 10 : access denied |
; eax = 11 : disk error |
; |
; ebx = size |
; \begin{diamond}[18.03.2006] |
; for subfunction 16 (start application) error codes must be negative |
; because positive values are valid PIDs |
; so possible return values are: |
; eax > 0 : process created, eax=PID |
; -0x10 <= eax < 0 : -eax is filesystem error code: |
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined |
; eax = -3 = 0xFFFFFFFD : unknown FS |
; eax = -5 = 0xFFFFFFFB : file not found |
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file) |
; eax = -9 = 0xFFFFFFF7 : fat table corrupted |
; eax = -10 = 0xFFFFFFF6 : access denied |
; -0x20 <= eax < -0x10: eax is process creation error code: |
; eax = -0x20 = 0xFFFFFFE0 : too many processes |
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable |
; eax = -0x1E = 0xFFFFFFE2 : no memory |
; ebx is not changed |
; \end{diamond}[18.03.2006] |
; Extract parameters |
; add eax, std_application_base_address ; abs start of info block |
cmp dword [eax+0],15 ; GET_DISK_INFO |
je fs_info |
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests |
jz no_checks_for_kernel |
mov edx,eax |
cmp dword [eax+0],1 |
jnz .usual_check |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
mov ecx,[eax+8] |
call check_region |
test eax,eax |
jnz area_in_app_mem |
.error_output: |
mov esi,buffer_failed |
call sys_msg_board_str |
; mov eax,7 |
mov dword [esp+36],7 |
ret |
iglobal |
buffer_failed db 'K : Buffer check failed',13,10,0 |
endg |
.usual_check: |
cmp dword [eax+0],0 |
mov ecx,512 |
jnz .small_size |
mov ecx,[eax+8] |
shl ecx,9 |
.small_size: |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
call check_region |
test eax,eax |
jz .error_output |
area_in_app_mem: |
mov eax,edx |
no_checks_for_kernel: |
fs_read: |
mov ebx,[eax+20] ; program wants root directory ? |
test bl,bl |
je fs_getroot |
test bh,bh |
jne fs_noroot |
fs_getroot: |
; \begin{diamond}[18.03.2006] |
; root - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [eax], 0 |
jz .read_root |
mov dword [esp+36], 10 |
ret |
.read_root: |
; \end{diamond}[18.03.2006] |
mov esi,dir0 |
mov edi,[eax+12] |
; add edi,std_application_base_address |
mov ecx,11 |
push ecx |
; cld ; already is |
rep movsb |
mov al,0x10 |
stosb |
add edi,32-11-1 |
pop ecx |
rep movsb |
stosb |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*2 ; size of root |
ret |
fs_info: ;start of code - Mihasik |
push eax |
cmp [eax+21],byte 'h' |
je fs_info_h |
cmp [eax+21],byte 'H' |
je fs_info_h |
cmp [eax+21],byte 'r' |
je fs_info_r |
cmp [eax+21],byte 'R' |
je fs_info_r |
mov eax,3 ;if unknown disk |
xor ebx,ebx |
xor ecx,ecx |
xor edx,edx |
jmp fs_info1 |
fs_info_r: |
call ramdisk_free_space ;if ramdisk |
mov ecx,edi ;free space in ecx |
shr ecx,9 ;free clusters |
mov ebx,2847 ;total clusters |
mov edx,512 ;cluster size |
xor eax,eax ;always 0 |
jmp fs_info1 |
fs_info_h: ;if harddisk |
call get_hd_info |
fs_info1: |
pop edi |
mov [esp+36],eax |
mov [esp+24],ebx ; total clusters on disk |
mov [esp+32],ecx ; free clusters on disk |
mov [edi],edx ; cluster size in bytes |
ret ;end of code - Mihasik |
fs_noroot: |
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run |
push dword [eax+4] ; 512 block number to read |
push dword [eax+8] ; bytes to write/append or 512 blocks to read |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
push ebx ; abs start of return/save area |
lea esi,[eax+20] ; abs start of dir + filename |
mov edi,[eax+16] |
; add edi,std_application_base_address ; abs start of work area |
call expand_pathz |
push edi ; dir start |
push ebx ; name of file start |
mov eax,[edi+1] |
cmp eax,'RD ' |
je fs_yesramdisk |
cmp eax,'RAMD' |
jne fs_noramdisk |
fs_yesramdisk: |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesramdisk_first |
cmp eax,'FIRS' |
jne fs_noramdisk |
fs_yesramdisk_first: |
cmp dword [esp+20],8 ; LBA read ramdisk |
jne fs_no_LBA_read_ramdisk |
mov eax,[esp+16] ; LBA block to read |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read_ramdisk |
jmp file_system_return |
fs_no_LBA_read_ramdisk: |
cmp dword [esp+20],0 ; READ |
jne fs_noramdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call fileread |
jmp file_system_return |
fs_noramdisk_read: |
fs_noramdisk: |
;******************************************************************** |
mov eax,[edi+1] |
cmp eax,'FD ' |
je fs_yesflpdisk |
cmp eax,'FLOP' |
jne fs_noflpdisk |
fs_yesflpdisk: |
call reserve_flp |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesflpdisk_first |
cmp eax,'FIRS' |
je fs_yesflpdisk_first |
cmp eax,'2 ' |
je fs_yesflpdisk_second |
cmp eax,'SECO' |
jne fs_noflpdisk |
jmp fs_yesflpdisk_second |
fs_yesflpdisk_first: |
mov [flp_number],1 |
jmp fs_yesflpdisk_start |
fs_yesflpdisk_second: |
mov [flp_number],2 |
fs_yesflpdisk_start: |
cmp dword [esp+20],0 ; READ |
jne fs_noflpdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call floppy_fileread |
jmp file_system_return |
fs_noflpdisk_read: |
fs_noflpdisk: |
;***************************************************************** |
mov eax,[edi+1] |
cmp eax,'HD0 ' |
je fs_yesharddisk_IDE0 |
cmp eax,'HD1 ' |
je fs_yesharddisk_IDE1 |
cmp eax,'HD2 ' |
je fs_yesharddisk_IDE2 |
cmp eax,'HD3 ' |
je fs_yesharddisk_IDE3 |
jmp old_path_harddisk |
fs_yesharddisk_IDE0: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE1: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE2: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE3: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
fs_yesharddisk_partition: |
call reserve_hd_channel |
; call choice_necessity_partition |
; jmp fs_yesharddisk_all |
jmp fs_for_new_semantic |
choice_necessity_partition: |
mov eax,[edi+1+12] |
call StringToNumber |
mov [fat32part],eax |
choice_necessity_partition_1: |
mov ecx,[hdpos] |
xor eax,eax |
mov [hd_entries], eax ; entries in hd cache |
mov edx,DRIVE_DATA+2 |
cmp ecx,0x80 |
jb search_partition_array |
mov ecx,4 |
search_partition_array: |
mov bl,[edx] |
movzx ebx,bl |
add eax,ebx |
inc edx |
loop search_partition_array |
mov ecx,[hdpos] |
mov edx,BiosDiskPartitions |
sub ecx,0x80 |
jb .s |
je .f |
@@: |
mov ebx,[edx] |
add edx,4 |
add eax,ebx |
loop @b |
jmp .f |
.s: |
sub eax,ebx |
.f: |
add eax,[fat32part] |
dec eax |
xor edx,edx |
imul eax,100 |
add eax,DRIVE_DATA+0xa |
mov [transfer_adress],eax |
call partition_data_transfer_1 |
ret |
old_path_harddisk: |
mov eax,[edi+1] |
cmp eax,'HD ' |
je fs_yesharddisk |
cmp eax,'HARD' |
jne fs_noharddisk |
fs_yesharddisk: |
cmp dword [esp+20],8 ; LBA read |
jne fs_no_LBA_read |
mov eax,[esp+16] ; LBA block to read |
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read |
jmp file_system_return |
fs_no_LBA_read: |
cmp byte [edi+1+11],0 ; directory read |
je fs_give_dir1 |
call reserve_hd1 |
fs_for_new_semantic: |
call choice_necessity_partition |
fs_yesharddisk_all: |
mov eax,1 |
mov ebx, [esp+24+24] |
cmp [hdpos],0 ; is hd base set? |
jz hd_err_return |
cmp [fat32part],0 ; is partition set? |
jnz @f |
hd_err_return: |
call free_hd_channel |
and [hd1_status], 0 |
jmp file_system_return |
@@: |
cmp dword [esp+20],0 ; READ |
jne fs_noharddisk_read |
mov eax,[esp+0] ; /fname |
lea edi,[eax+12] |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov ebx,[esp+12] ; count to read |
mov ecx,[esp+8] ; buffer |
mov edx,[esp+4] |
add edx,12*2 ; dir start |
sub edi,edx ; path length |
mov esi,[esp+16] ; blocks to read |
call file_read |
mov edi,[esp+0] |
mov byte [edi],'/' |
call free_hd_channel |
and [hd1_status], 0 |
jmp file_system_return |
fs_noharddisk_read: |
call free_hd_channel |
and [hd1_status], 0 |
fs_noharddisk: |
; \begin{diamond}[18.03.2006] |
mov eax, 5 ; file not found |
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè? |
mov ebx, [esp+24+24] ; do not change ebx in application |
; \end{diamond}[18.03.2006] |
file_system_return: |
add esp,24 |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
fs_give_dir1: |
; \begin{diamond}[18.03.2006] |
; /RD,/FD,/HD - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [esp+20], 0 |
jz .read |
add esp, 20 |
pop ecx |
mov dword [esp+36], 10 |
ret |
.read: |
; \end{diamond}[18.03.2006] |
mov al,0x10 |
mov ebx,1 |
mov edi,[esp+8] |
mov esi,dir1 |
fs_d1_new: |
mov ecx,11 |
; cld |
rep movsb |
stosb |
add edi,32-11-1 |
dec ebx |
jne fs_d1_new |
add esp,24 |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*1 ; dir/data size |
ret |
LBA_read_ramdisk: |
cmp [lba_read_enabled],1 |
je lbarrl1 |
xor ebx,ebx |
mov eax,2 |
ret |
lbarrl1: |
cmp eax,18*2*80 |
jb lbarrl2 |
xor ebx,ebx |
mov eax,3 |
ret |
lbarrl2: |
pushad |
call restorefatchain |
mov edi,ecx |
mov esi,eax |
shl esi,9 |
add esi,RAMDISK |
mov ecx,512/4 |
; cld |
rep movsd |
popad |
xor ebx,ebx |
xor eax,eax |
ret |
LBA_read: |
; IN: |
; |
; eax = LBA block to read |
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH |
; ecx = abs pointer to return area |
cmp [lba_read_enabled],1 |
je lbarl1 |
mov eax,2 |
ret |
lbarl1: |
call reserve_hd1 |
push eax |
push ecx |
mov edi,hd_address_table |
mov esi,dir1 |
mov eax,[ebx] |
mov edx,'1 ' |
mov ecx,4 |
blar0: |
cmp eax,[esi] |
je blar2 |
cmp eax,edx |
je blar2 |
inc edx |
add edi,8 |
add esi,11 |
dec ecx |
jnz blar0 |
mov eax,1 |
mov ebx,1 |
jmp LBA_read_ret |
blar2: |
mov eax,[edi+0] |
mov ebx,[edi+4] |
mov [hdbase],eax |
mov [hdid],ebx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_lba_error |
; eax = hd port |
; ebx = set for primary (0x00) or slave (0x10) |
cli |
mov edx,eax |
inc edx |
xor eax,eax |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esp+4] |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,bl |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,20h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_lba_error |
cli |
mov edi,[esp+0] |
mov ecx,256 |
sub edx,7 |
cld |
rep insw |
sti |
xor eax,eax |
xor ebx,ebx |
LBA_read_ret: |
mov [hd_error],0 |
mov [hd1_status],0 |
add esp,2*4 |
ret |
expand_pathz: |
; IN: |
; esi = asciiz path & file |
; edi = buffer for path & file name |
; OUT: |
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated |
; ebx = /file name - zero terminated |
; esi = pointer after source |
push eax |
push ecx |
push edi ;[esp+0] |
pathz_start: |
mov byte [edi],'/' |
inc edi |
mov al,32 |
mov ecx,11 |
cld |
rep stosb ; clear filename area |
sub edi,11 |
mov ebx,edi ; start of dir/file name |
pathz_new_char: |
mov al,[esi] |
inc esi |
cmp al,0 |
je pathz_end |
cmp al,'/' |
jne pathz_not_path |
cmp edi,ebx ; skip first '/' |
jz pathz_new_char |
lea edi,[ebx+11] ; start of next directory |
jmp pathz_start |
pathz_not_path: |
cmp al,'.' |
jne pathz_not_ext |
lea edi,[ebx+8] ; start of extension |
jmp pathz_new_char |
pathz_not_ext: |
cmp al,'a' |
jb pathz_not_low |
cmp al,'z' |
ja pathz_not_low |
sub al,0x20 ; char to uppercase |
pathz_not_low: |
mov [edi],al |
inc edi |
mov eax,[esp+0] ; start_of_dest_path |
add eax,512 ; keep maximum path under 512 bytes |
cmp edi,eax |
jb pathz_new_char |
pathz_end: |
cmp ebx,edi ; if path end with '/' |
jnz pathz_put_zero ; go back 1 level |
sub ebx,12 |
pathz_put_zero: |
mov byte [ebx+11],0 |
dec ebx ; include '/' char into file name |
pop edi |
pop ecx |
pop eax |
ret |
;******************************************* |
;* string to number |
;* input eax - 4 byte string |
;* output eax - number |
;******************************************* |
StringToNumber: |
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ |
; Âõîä: |
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh |
; Âûõîä: |
; CF - èíäèêàòîð îøèáîê: |
; 0 - îøèáîê íåò; |
; 1 - îøèáêà |
; Åñëè CF=0, òî AX - ÷èñëî. |
push bx |
push cx |
push dx |
push edi |
mov [partition_string],eax |
mov edi,partition_string |
xor cx,cx |
i1: |
mov al,[edi] |
cmp al,32 ;13 |
je i_exit |
; cmp al,'0' |
; jb err |
; cmp al,'9' |
; ja err |
sub al,48 |
shl cx,1 |
jc error |
mov bx,cx |
shl cx,1 |
jc error |
shl cx,1 |
jc error |
add cx,bx |
jc error |
cbw |
add cx,ax |
jc error |
i3: |
inc edi |
jmp i1 |
i_exit: |
mov ax,cx |
clc |
i4: |
movzx eax,ax |
pop edi |
pop dx |
pop cx |
pop bx |
ret |
error: |
stc |
jmp i4 |
partition_string: dd 0 |
db 32 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/iso9660.inc |
---|
0,0 → 1,757 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
uglobal |
cd_current_pointer_of_input dd 0 |
cd_current_pointer_of_input_2 dd 0 |
cd_mem_location dd 0 |
cd_counter_block dd 0 |
IDE_Channel_1 db 0 |
IDE_Channel_2 db 0 |
endg |
reserve_cd: |
cli |
cmp [cd_status],0 |
je reserve_ok2 |
sti |
call change_task |
jmp reserve_cd |
reserve_ok2: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [cd_status],eax |
pop eax |
sti |
ret |
reserve_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.reserve_ok_1: |
mov [IDE_Channel_1],1 |
ret |
.reserve_ok_2: |
mov [IDE_Channel_2],1 |
ret |
free_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
ret |
uglobal |
cd_status dd 0 |
endg |
;---------------------------------------------------------------- |
; |
; fs_CdRead - LFN variant for reading CD disk |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdRead: |
push edi |
cmp byte [esi], 0 |
jnz @f |
.noaccess: |
pop edi |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.noaccess_3: |
pop eax edx ecx edi |
jmp .noaccess_2 |
@@: |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode],0 |
jne .noaccess_2 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi,[cd_current_pointer_of_input] |
test byte [edi+25],10b ; do not allow read directories |
jnz .noaccess |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; end of file |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 |
@@: |
mov eax,[edi+2] |
mov [CDSectorAddress],eax |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_sector: |
test ecx, ecx |
jz .done |
sub ebx, 2048 |
jae .next |
add ebx, 2048 |
jnz .incomplete_sector |
cmp ecx, 2048 |
jb .incomplete_sector |
; we may read and memmove complete sector |
mov [CDDataBuf_pointer],edx |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
add edx, 2048 |
sub ecx, 2048 |
.next: |
inc dword [CDSectorAddress] |
jmp .new_sector |
.incomplete_sector: |
; we must read and memmove incomplete sector |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
push ecx |
add ecx, ebx |
cmp ecx, 2048 |
jbe @f |
mov ecx, 2048 |
@@: |
sub ecx, ebx |
push edi esi ecx |
mov edi,edx |
lea esi, [CDDataBuf + ebx] |
cld |
rep movsb |
pop ecx esi edi |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
jmp .next |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
;---------------------------------------------------------------- |
; |
; fs_CdReadFolder - LFN variant for reading CD disk folder |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdReadFolder: |
push edi |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi, [cd_current_pointer_of_input] |
test byte [edi+25], 10b ; do not allow read directories |
jnz .found_dir |
pop edi |
.noaccess_1: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax, [edi+2] ; eax=cluster |
mov [CDSectorAddress], eax |
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè |
.doit: |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov [cd_mem_location], edx |
add [cd_mem_location], 32 |
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ |
;.mainloop: |
mov [cd_counter_block], dword 0 |
dec dword [CDSectorAddress] |
push ecx |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
call .get_names_from_buffer |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
ja .read_to_buffer |
mov edi, [cd_counter_block] |
mov [edx+8], edi |
mov edi, [ebx] |
sub [edx+4], edi |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx edi |
mov ebx, [edx+4] |
ret |
.get_names_from_buffer: |
mov [cd_current_pointer_of_input_2],CDDataBuf |
push eax esi edi edx |
.get_names_from_buffer_1: |
call cd_get_name |
jc .end_buffer |
inc dword [cd_counter_block] |
mov eax,[cd_counter_block] |
cmp [ebx],eax |
jae .get_names_from_buffer_1 |
test ecx, ecx |
jz .get_names_from_buffer_1 |
mov edi,[cd_counter_block] |
mov [edx+4],edi |
dec ecx |
mov esi,ebp |
mov edi,[cd_mem_location] |
add edi,40 |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode |
; jmp .unicode |
.ansi: |
cmp [cd_counter_block],2 |
jbe .ansi_parent_directory |
cld |
lodsw |
xchg ah,al |
call uni2ansi_char |
cld |
stosb |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .ansi |
.cd_get_parameters_of_file_1: |
mov [edi],byte 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],304 |
jmp .get_names_from_buffer_1 |
.ansi_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],byte '.' |
inc edi |
jmp .cd_get_parameters_of_file_1 |
@@: |
mov [edi],word '..' |
add edi,2 |
jmp .cd_get_parameters_of_file_1 |
.unicode: |
cmp [cd_counter_block],2 |
jbe .unicode_parent_directory |
cld |
movsw |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .unicode |
.cd_get_parameters_of_file_2: |
mov [edi],word 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],560 |
jmp .get_names_from_buffer_1 |
.unicode_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],word 2E00h ; '.' |
add edi,2 |
jmp .cd_get_parameters_of_file_2 |
@@: |
mov [edi],dword 2E002E00h ; '..' |
add edi,4 |
jmp .cd_get_parameters_of_file_2 |
.end_buffer: |
pop edx edi esi eax |
ret |
cd_get_parameters_of_file: |
mov edi,[cd_mem_location] |
cd_get_parameters_of_file_1: |
; ïîëó÷àåì àòðèáóòû ôàéëà |
xor eax,eax |
; ôàéë íå àðõèâèðîâàëñÿ |
inc eax |
shl eax,1 |
; ýòî êàòàëîã? |
test [ebp-8],byte 2 |
jz .file |
inc eax |
.file: |
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò |
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì |
shl eax,3 |
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå) |
test [ebp-8],byte 1 |
jz .hidden |
inc eax |
.hidden: |
shl eax,1 |
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD |
inc eax |
mov [edi],eax |
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà |
;÷àñ |
movzx eax,byte [ebp-12] |
shl eax,8 |
;ìèíóòà |
mov al,[ebp-11] |
shl eax,8 |
;ñåêóíäà |
mov al,[ebp-10] |
;âðåìÿ ñîçäàíèÿ ôàéëà |
mov [edi+8],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+16],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+24],eax |
; ïîëó÷àåì äàòó äëÿ ôàéëà |
;ãîä |
movzx eax,byte [ebp-15] |
add eax,1900 |
shl eax,8 |
;ìåñÿö |
mov al,[ebp-14] |
shl eax,8 |
;äåíü |
mov al,[ebp-13] |
;äàòà ñîçäàíèÿ ôàéëà |
mov [edi+12],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+20],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+28],eax |
; ïîëó÷àåì òèï äàííûõ èìåíè |
xor eax,eax |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode_1 |
mov [edi+4],eax |
jmp @f |
.unicode_1: |
inc eax |
mov [edi+4],eax |
@@: |
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ |
xor eax,eax |
mov [edi+32+4],eax |
mov eax,[ebp-23] |
mov [edi+32],eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_CdGetFileInfo - LFN variant for CD |
; get file/directory attributes structure |
; |
;---------------------------------------------------------------- |
fs_CdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call cd_find_lfn |
pushfd |
cmp [DevErrorCode], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
mov edi, edx |
push ebp |
mov ebp, [cd_current_pointer_of_input] |
add ebp, 33 |
call cd_get_parameters_of_file_1 |
pop ebp |
and dword [edi+4], 0 |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
cd_find_lfn: |
mov [cd_appl_data],0 |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and [cd_current_pointer_of_input] direntry |
push eax esi |
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ |
call WaitUnitReady |
cmp [DevErrorCode],0 |
jne .access_denied |
call prevent_medium_removal |
; òåñòîâîå ÷òåíèå |
mov [CDSectorAddress],dword 16 |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ;_1 |
cmp [DevErrorCode],0 |
jne .access_denied |
; âû÷èñëåíèå ïîñëåäíåé ñåññèè |
call WaitUnitReady |
cmp [DevErrorCode],0 |
jne .access_denied |
call Read_TOC |
mov ah,[CDDataBuf+4+4] |
mov al,[CDDataBuf+4+5] |
shl eax,16 |
mov ah,[CDDataBuf+4+6] |
mov al,[CDDataBuf+4+7] |
add eax,15 |
mov [CDSectorAddress],eax |
; mov [CDSectorAddress],dword 15 |
mov [CDDataBuf_pointer],CDDataBuf |
.start: |
inc dword [CDSectorAddress] |
call ReadCDWRetr ;_1 |
cmp [DevErrorCode],0 |
jne .access_denied |
.start_check: |
; ïðîâåðêà íà âøèâîñòü |
cmp [CDDataBuf+1],dword 'CD00' |
jne .access_denied |
cmp [CDDataBuf+5],byte '1' |
jne .access_denied |
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ? |
cmp [CDDataBuf],byte 0xff |
je .access_denied |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf],byte 0x2 |
jne .start |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf+6],byte 0x1 |
jne .start |
; ïàðàìåòðû root äèðåêòðîðèè |
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè |
mov [CDSectorAddress],eax |
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè |
cmp byte [esi], 0 |
jnz @f |
mov [cd_current_pointer_of_input],CDDataBuf+0x9c |
jmp .done |
@@: |
; íà÷èíàåì ïîèñê |
.mainloop: |
dec dword [CDSectorAddress] |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode],0 |
jne .access_denied |
push ebp |
call cd_find_name_in_buffer |
pop ebp |
jnc .found |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
cmp eax,0 |
ja .read_to_buffer |
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè |
.access_denied: |
pop esi eax |
mov [cd_appl_data],1 |
stc |
ret |
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí |
.found: |
; êîíåö ïóòè ôàéëà |
cmp byte [esi-1], 0 |
jz .done |
.nested: |
mov eax,[cd_current_pointer_of_input] |
push dword [eax+2] |
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè |
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè |
jmp .mainloop |
; óêàçàòåëü ôàéëà íàéäåí |
.done: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .nested |
@@: |
pop esi eax |
mov [cd_appl_data],1 |
clc |
ret |
cd_find_name_in_buffer: |
mov [cd_current_pointer_of_input_2],CDDataBuf |
.start: |
call cd_get_name |
jc .not_found |
call cd_compare_name |
jc .start |
.found: |
clc |
ret |
.not_found: |
stc |
ret |
cd_get_name: |
push eax |
mov ebp,[cd_current_pointer_of_input_2] |
mov [cd_current_pointer_of_input],ebp |
mov eax,[ebp] |
cmp eax,0 ; âõîäû çàêîí÷èëèñü? |
je .next_sector |
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ? |
jae .next_sector |
movzx eax, byte [ebp] |
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà |
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè |
pop eax |
clc |
ret |
.next_sector: |
pop eax |
stc |
ret |
cd_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push esi eax edi |
mov edi,ebp |
.loop: |
cld |
lodsb |
push eax |
call char_todown |
call ansi2uni_char |
xchg ah,al |
scasw |
pop eax |
je .coincides |
call char_toupper |
call ansi2uni_char |
xchg ah,al |
sub edi,2 |
scasw |
jne .name_not_coincide |
.coincides: |
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
jmp .loop |
.name_not_coincide: |
pop edi eax esi |
stc |
ret |
.done: |
; ïðîâåðêà êîíöà ôàéëà |
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .done_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp edi,eax |
je .done_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp edi,eax |
jne .name_not_coincide |
.done_1: |
pop edi eax |
add esp,4 |
inc esi |
clc |
ret |
char_todown: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'A' |
jb .ret |
cmp al, 'Z' |
jbe .az |
cmp al, '' |
jb .ret |
cmp al, '' |
jb .rus1 |
cmp al, '' |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0x80-0x8F -> 0xA0-0xAF |
.az: |
add al, 0x20 |
ret |
uni2ansi_char: |
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding |
; in: ax=UNICODE character |
; out: al=converted ANSI character |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/ntfs.inc |
---|
0,0 → 1,1815 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
ntfs_test_bootsec: |
; in: ebx->buffer, edx=size of partition |
; out: CF set <=> invalid |
; 1. Name=='NTFS ' |
cmp dword [ebx+3], 'NTFS' |
jnz .no |
cmp dword [ebx+7], ' ' |
jnz .no |
; 2. Number of bytes per sector is the same as for physical device |
; (that is, 0x200 for hard disk) |
cmp word [ebx+11], 0x200 |
jnz .no |
; 3. Number of sectors per cluster must be power of 2 |
movzx eax, byte [ebx+13] |
dec eax |
js .no |
test al, [ebx+13] |
jnz .no |
; 4. FAT parameters must be zero |
cmp word [ebx+14], 0 |
jnz .no |
cmp dword [ebx+16], 0 |
jnz .no |
cmp byte [ebx+20], 0 |
jnz .no |
cmp word [ebx+22], 0 |
jnz .no |
cmp dword [ebx+32], 0 |
jnz .no |
; 5. Number of sectors <= partition size |
cmp dword [ebx+0x2C], 0 |
ja .no |
cmp [ebx+0x28], edx |
ja .no |
; 6. $MFT and $MFTMirr clusters must be within partition |
cmp dword [ebx+0x34], 0 |
ja .no |
push edx |
movzx eax, byte [ebx+13] |
mul dword [ebx+0x30] |
test edx, edx |
pop edx |
jnz .no |
cmp eax, edx |
ja .no |
cmp dword [ebx+0x3C], 0 |
ja .no |
push edx |
movzx eax, byte [ebx+13] |
mul dword [ebx+0x38] |
test edx, edx |
pop edx |
jnz .no |
cmp eax, edx |
ja .no |
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 |
movsx eax, byte [ebx+0x40] |
cmp al, -31 |
jl .no |
cmp al, -9 |
jle @f |
dec eax |
js .no |
test [ebx+0x40], al |
jnz .no |
@@: |
; 8. Same for clusters per IndexAllocationBuffer |
movsx eax, byte [ebx+0x44] |
cmp al, -31 |
jl .no |
cmp al, -9 |
jle @f |
dec eax |
js .no |
test [ebx+0x44], al |
jnz .no |
@@: |
; OK, this is correct NTFS bootsector |
clc |
ret |
.no: |
; No, this bootsector isn't NTFS |
stc |
ret |
ntfs_setup: ; CODE XREF: part_set.inc |
; By given bootsector, initialize some NTFS variables |
call ntfs_test_bootsec |
jc problem_fat_dec_count |
movzx eax, byte [ebx+13] |
mov [ntfs_data.sectors_per_cluster], eax |
mov eax, [ebx+0x28] |
add eax, [PARTITION_START] |
dec eax |
mov [PARTITION_END], eax |
mov [fs_type], 1 |
mov eax, [ebx+0x30] |
mov [ntfs_data.mft_cluster], eax |
mov eax, [ebx+0x38] |
mov [ntfs_data.mftmirr_cluster], eax |
movsx eax, byte [ebx+0x40] |
test eax, eax |
js .1 |
mul [ntfs_data.sectors_per_cluster] |
shl eax, 9 |
jmp .2 |
.1: |
neg eax |
mov ecx, eax |
mov eax, 1 |
shl eax, cl |
.2: |
mov [ntfs_data.frs_size], eax |
movsx eax, byte [ebx+0x44] |
test eax, eax |
js .3 |
mul [ntfs_data.sectors_per_cluster] |
shl eax, 9 |
jmp .4 |
.3: |
neg eax |
mov ecx, eax |
mov eax, 1 |
shl eax, cl |
.4: |
mov [ntfs_data.iab_size], eax |
; allocate space for buffers |
add eax, [ntfs_data.frs_size] |
push eax |
call kernel_alloc |
test eax, eax |
jz problem_fat_dec_count |
mov [ntfs_data.frs_buffer], eax |
add eax, [ntfs_data.frs_size] |
mov [ntfs_data.iab_buffer], eax |
; read $MFT disposition |
mov eax, [ntfs_data.mft_cluster] |
mul [ntfs_data.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
jnz .usemirr |
cmp dword [ebx], 'FILE' |
jnz .usemirr |
call ntfs_restore_usa_frs |
jnc .mftok |
.usemirr: |
and [hd_error], 0 |
mov eax, [ntfs_data.mftmirr_cluster] |
mul [ntfs_data.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
jnz @f |
cmp dword [ebx], 'FILE' |
jnz @f |
call ntfs_restore_usa_frs |
jnc .mftok |
@@: |
; $MFT and $MFTMirr invalid! |
.fail_free_frs: |
push [ntfs_data.frs_buffer] |
call kernel_free |
jmp problem_fat_dec_count |
.fail_free_mft: |
push [ntfs_data.mft_retrieval] |
call kernel_free |
jmp .fail_free_frs |
.mftok: |
; read $MFT table retrieval information |
; start with one page, increase if not enough (when MFT too fragmented) |
push ebx |
push 0x1000 |
call kernel_alloc |
pop ebx |
test eax, eax |
jz .fail_free_frs |
mov [ntfs_data.mft_retrieval], eax |
and [ntfs_data.mft_retrieval_size], 0 |
mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 |
; $MFT base record must contain unnamed non-resident $DATA attribute |
movzx eax, word [ebx+14h] |
add eax, ebx |
.scandata: |
cmp dword [eax], -1 |
jz .fail_free_mft |
cmp dword [eax], 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jz .founddata |
@@: |
add eax, [eax+4] |
jmp .scandata |
.founddata: |
cmp byte [eax+8], 0 |
jz .fail_free_mft |
; load first portion of $DATA attribute retrieval information |
mov edx, [eax+0x18] |
mov [ntfs_data.mft_retrieval_end], edx |
mov esi, eax |
movzx eax, word [eax+0x20] |
add esi, eax |
sub esp, 10h |
.scanmcb: |
call ntfs_decode_mcb_entry |
jnc .scanmcbend |
call .get_mft_retrieval_ptr |
mov edx, [esp] ; block length |
mov [eax], edx |
mov edx, [esp+8] ; block addr (relative) |
mov [eax+4], edx |
inc [ntfs_data.mft_retrieval_size] |
jmp .scanmcb |
.scanmcbend: |
add esp, 10h |
; there may be other portions of $DATA attribute in auxiliary records; |
; if they will be needed, they will be loaded later |
mov [ntfs_data.cur_index_size], 0x1000/0x200 |
push 0x1000 |
call kernel_alloc |
test eax, eax |
jz .fail_free_mft |
mov [ntfs_data.cur_index_buf], eax |
popad |
call free_hd_channel |
and [hd1_status], 0 |
ret |
.get_mft_retrieval_ptr: |
pushad |
mov eax, [ntfs_data.mft_retrieval_size] |
cmp eax, [ntfs_data.mft_retrieval_alloc] |
jnz .ok |
add eax, 0x1000/8 |
mov [ntfs_data.mft_retrieval_alloc], eax |
shl eax, 3 |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
popad |
add esp, 14h |
jmp .fail_free_mft |
@@: |
mov esi, [ntfs_data.mft_retrieval] |
mov edi, eax |
mov ecx, [ntfs_data.mft_retrieval_size] |
add ecx, ecx |
rep movsd |
push [ntfs_data.mft_retrieval] |
mov [ntfs_data.mft_retrieval], eax |
call kernel_free |
mov eax, [ntfs_data.mft_retrieval_size] |
.ok: |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
mov [esp+28], eax |
popad |
ret |
ntfs_read_frs_sector: |
push eax ecx |
add eax, [PARTITION_START] |
mov ecx, [ntfs_data.frs_size] |
shr ecx, 9 |
mov ebx, [ntfs_data.frs_buffer] |
push ebx |
@@: |
call hd_read |
cmp [hd_error], 0 |
jnz .fail |
add ebx, 0x200 |
inc eax |
loop @b |
.fail: |
pop ebx |
pop ecx eax |
ret |
uglobal |
align 4 |
ntfs_cur_attr dd ? |
ntfs_cur_iRecord dd ? |
ntfs_cur_offs dd ? ; in sectors |
ntfs_cur_size dd ? ; in sectors |
ntfs_cur_buf dd ? |
ntfs_cur_read dd ? ; [output] |
ntfs_bCanContinue db ? |
rb 3 |
ntfs_attrlist_buf rb 0x400 |
ntfs_attrlist_mft_buf rb 0x400 |
ntfs_bitmap_buf rb 0x400 |
ntfs_attr_iRecord dd ? |
ntfs_attr_iBaseRecord dd ? |
ntfs_attr_offs dd ? |
ntfs_attr_list dd ? |
ntfs_attr_size dq ? |
ntfs_cur_tail dd ? |
endg |
ntfs_read_attr: |
; in: global variables |
; out: [ntfs_cur_read] |
pushad |
and [ntfs_cur_read], 0 |
cmp [ntfs_cur_iRecord], 0 |
jnz .nomft |
cmp [ntfs_cur_attr], 0x80 |
jnz .nomft |
mov eax, [ntfs_data.mft_retrieval_end] |
inc eax |
mul [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
jbe .nomft |
; precalculated part of $Mft $DATA |
mov esi, [ntfs_data.mft_retrieval] |
mov eax, [ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
; eax = VCN, edx = offset in sectors from beginning of cluster |
xor ecx, ecx ; ecx will contain LCN |
.mftscan: |
add ecx, [esi+4] |
sub eax, [esi] |
jb @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
cmp eax, esi |
pop eax |
jnz .mftscan |
jmp .nomft |
@@: |
push ecx |
add ecx, eax |
add ecx, [esi] |
push eax |
push edx |
mov eax, [ntfs_data.sectors_per_cluster] |
mul ecx |
; eax = sector on partition |
add eax, [PARTITION_START] |
pop edx |
add eax, edx |
mov ebx, [ntfs_cur_buf] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
@@: |
; ecx = number of sequential sectors to read |
call hd_read |
cmp [hd_error], 0 |
jnz .errread |
add [ntfs_cur_read], 0x200 |
dec [ntfs_cur_size] |
inc [ntfs_cur_offs] |
add ebx, 0x200 |
mov [ntfs_cur_buf], ebx |
inc eax |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], eax |
jz @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
cmp eax, esi |
pop eax |
jz .nomft |
jmp .mftscan |
@@: |
popad |
ret |
.errread: |
pop ecx |
.errret: |
stc |
popad |
ret |
.nomft: |
; 1. Read file record. |
; N.B. This will do recursive call of read_attr for $MFT::$Data. |
mov eax, [ntfs_cur_iRecord] |
mov [ntfs_attr_iRecord], eax |
and [ntfs_attr_list], 0 |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
or [ntfs_attr_iBaseRecord], -1 |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
; 2. Find required attribute. |
mov eax, [ntfs_data.frs_buffer] |
; a) For auxiliary records, read base record |
; N.B. If base record is present, |
; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero |
cmp dword [eax+24h], 0 |
jz @f |
mov eax, [eax+20h] |
; test eax, eax |
; jz @f |
.beginfindattr: |
mov [ntfs_attr_iRecord], eax |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
@@: |
; b) Scan for required attribute and for $ATTR_LIST |
mov eax, [ntfs_data.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
and [ntfs_attr_offs], 0 |
.scanattr: |
cmp dword [eax], -1 |
jz .scandone |
cmp dword [eax], ecx |
jz .okattr |
cmp [ntfs_attr_iBaseRecord], -1 |
jnz .scancont |
cmp dword [eax], 0x20 ; $ATTR_LIST |
jnz .scancont |
mov [ntfs_attr_list], eax |
jmp .scancont |
.okattr: |
; ignore named $DATA attributes (aka NTFS streams) |
cmp ecx, 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jnz .scancont |
@@: |
mov [ntfs_attr_offs], eax |
.scancont: |
add eax, [eax+4] |
jmp .scanattr |
.continue: |
pushad |
and [ntfs_cur_read], 0 |
.scandone: |
; c) Check for required offset and length |
mov ecx, [ntfs_attr_offs] |
jecxz .noattr |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
call .doreadattr |
pop edx |
pop eax |
jc @f |
cmp [ntfs_bCanContinue], 0 |
jz @f |
sub edx, [ntfs_cur_read] |
neg edx |
shr edx, 9 |
sub eax, edx |
mov [ntfs_cur_size], eax |
jnz .not_in_cur |
@@: |
popad |
ret |
.noattr: |
.not_in_cur: |
cmp [ntfs_cur_attr], 0x20 |
jz @f |
mov ecx, [ntfs_attr_list] |
test ecx, ecx |
jnz .lookattr |
.ret_is_attr: |
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 |
popad |
ret |
.lookattr: |
; required attribute or required offset was not found in base record; |
; it may be present in auxiliary records; |
; scan $ATTR_LIST |
mov eax, [ntfs_attr_iBaseRecord] |
cmp eax, -1 |
jz @f |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
or [ntfs_attr_iBaseRecord], -1 |
@@: |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
push [ntfs_cur_buf] |
push dword [ntfs_attr_size] |
push dword [ntfs_attr_size+4] |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 2 |
and [ntfs_cur_read], 0 |
mov eax, ntfs_attrlist_buf |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
mov eax, ntfs_attrlist_mft_buf |
@@: |
mov [ntfs_cur_buf], eax |
push eax |
call .doreadattr |
pop esi |
mov edx, 1 |
pop dword [ntfs_attr_size+4] |
pop dword [ntfs_attr_size] |
mov ebp, [ntfs_cur_read] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_read] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
jc .errret |
or edi, -1 |
lea ebp, [ebp+esi-1Ah] |
.scanliststart: |
mov eax, [ntfs_cur_attr] |
.scanlist: |
cmp esi, ebp |
jae .scanlistdone |
cmp eax, [esi] |
jz @f |
.scanlistcont: |
movzx ecx, word [esi+4] |
add esi, ecx |
jmp .scanlist |
@@: |
; ignore named $DATA attributes (aka NTFS streams) |
cmp eax, 0x80 |
jnz @f |
cmp byte [esi+6], 0 |
jnz .scanlistcont |
@@: |
push eax |
mov eax, [esi+8] |
test eax, eax |
jnz .testf |
mov eax, dword [ntfs_attr_size] |
and eax, dword [ntfs_attr_size+4] |
cmp eax, -1 |
jnz .testfz |
; if attribute is in auxiliary records, its size is defined only in first |
mov eax, [esi+10h] |
call ntfs_read_file_record |
test eax, eax |
jnz @f |
.errret_pop: |
pop eax |
jmp .errret |
@@: |
mov eax, [ntfs_data.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
@@: |
cmp dword [eax], -1 |
jz .errret_pop |
cmp dword [eax], ecx |
jz @f |
.l1: |
add eax, [eax+4] |
jmp @b |
@@: |
cmp eax, 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jnz .l1 |
@@: |
cmp byte [eax+8], 0 |
jnz .sdnores |
mov eax, [eax+10h] |
mov dword [ntfs_attr_size], eax |
and dword [ntfs_attr_size+4], 0 |
jmp .testfz |
.sdnores: |
mov ecx, [eax+30h] |
mov dword [ntfs_attr_size], ecx |
mov ecx, [eax+34h] |
mov dword [ntfs_attr_size+4], ecx |
.testfz: |
xor eax, eax |
.testf: |
imul eax, [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
pop eax |
ja @f |
mov edi, [esi+10h] ; keep previous iRecord |
jmp .scanlistcont |
@@: |
.scanlistfound: |
cmp edi, -1 |
jnz @f |
popad |
ret |
@@: |
mov eax, [ntfs_cur_iRecord] |
mov [ntfs_attr_iBaseRecord], eax |
mov eax, edi |
jmp .beginfindattr |
.sde: |
popad |
stc |
ret |
.scanlistdone: |
sub ebp, ntfs_attrlist_buf-1Ah |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
@@: |
cmp ebp, 0x400 |
jnz .scanlistfound |
inc edx |
push esi edi |
mov esi, ntfs_attrlist_buf+0x200 |
mov edi, ntfs_attrlist_buf |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
mov esi, ntfs_attrlist_mft_buf+0x200 |
mov edi, ntfs_attrlist_mft_buf |
@@: |
mov ecx, 0x200/4 |
rep movsd |
mov eax, edi |
pop edi esi |
sub esi, 0x200 |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
push [ntfs_cur_buf] |
push dword [ntfs_attr_size] |
push dword [ntfs_attr_size+4] |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
mov [ntfs_cur_offs], edx |
mov [ntfs_cur_size], 1 |
and [ntfs_cur_read], 0 |
mov [ntfs_cur_buf], eax |
mov ecx, [ntfs_attr_list] |
push esi edx |
call .doreadattr |
pop edx esi |
mov ebp, [ntfs_cur_read] |
pop dword [ntfs_attr_size+4] |
pop dword [ntfs_attr_size] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_read] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
jc .errret |
add ebp, ntfs_attrlist_buf+0x200-0x1A |
cmp [ntfs_cur_iRecord], 0 |
jnz .scanliststart |
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
jmp .scanliststart |
.doreadattr: |
mov [ntfs_bCanContinue], 0 |
cmp byte [ecx+8], 0 |
jnz .nonresident |
mov eax, [ecx+10h] ; length |
mov esi, eax |
mov edx, [ntfs_cur_offs] |
shr eax, 9 |
cmp eax, edx |
jb .okret |
shl edx, 9 |
sub esi, edx |
movzx eax, word [ecx+14h] |
add edx, eax |
add edx, ecx ; edx -> data |
mov eax, [ntfs_cur_size] |
cmp eax, (0xFFFFFFFF shr 9)+1 |
jbe @f |
mov eax, (0xFFFFFFFF shr 9)+1 |
@@: |
shl eax, 9 |
cmp eax, esi |
jbe @f |
mov eax, esi |
@@: |
; eax = length, edx -> data |
mov [ntfs_cur_read], eax |
mov ecx, eax |
mov eax, edx |
mov ebx, [ntfs_cur_buf] |
call memmove |
and [ntfs_cur_size], 0 ; CF=0 |
ret |
.nonresident: |
; Not all auxiliary records contain correct FileSize info |
mov eax, dword [ntfs_attr_size] |
mov edx, dword [ntfs_attr_size+4] |
push eax |
and eax, edx |
cmp eax, -1 |
pop eax |
jnz @f |
mov eax, [ecx+30h] ; FileSize |
mov edx, [ecx+34h] |
mov dword [ntfs_attr_size], eax |
mov dword [ntfs_attr_size+4], edx |
@@: |
add eax, 0x1FF |
adc edx, 0 |
shrd eax, edx, 9 |
sub eax, [ntfs_cur_offs] |
ja @f |
; return with nothing read |
and [ntfs_cur_size], 0 |
.okret: |
clc |
ret |
@@: |
; reduce read length |
and [ntfs_cur_tail], 0 |
cmp [ntfs_cur_size], eax |
jb @f |
mov [ntfs_cur_size], eax |
mov eax, dword [ntfs_attr_size] |
and eax, 0x1FF |
mov [ntfs_cur_tail], eax |
@@: |
cmp [ntfs_cur_size], 0 |
jz .okret |
mov eax, [ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
sub eax, [ecx+10h] ; first_vbo |
jb .okret |
; eax = cluster, edx = starting sector |
sub esp, 10h |
movzx esi, word [ecx+20h] ; mcb_info_ofs |
add esi, ecx |
xor ebp, ebp |
.readloop: |
call ntfs_decode_mcb_entry |
jnc .break |
add ebp, [esp+8] |
sub eax, [esp] |
jae .readloop |
push ecx |
push eax |
add eax, [esp+8] |
add eax, ebp |
imul eax, [ntfs_data.sectors_per_cluster] |
add eax, edx |
add eax, [PARTITION_START] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
@@: |
mov ebx, [ntfs_cur_buf] |
@@: |
call hd_read |
cmp [hd_error], 0 |
jnz .errread2 |
add ebx, 0x200 |
mov [ntfs_cur_buf], ebx |
inc eax |
add [ntfs_cur_read], 0x200 |
dec [ntfs_cur_size] |
inc [ntfs_cur_offs] |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], 0 |
jnz .readloop |
add esp, 10h |
mov eax, [ntfs_cur_tail] |
test eax, eax |
jz @f |
sub eax, 0x200 |
add [ntfs_cur_read], eax |
@@: |
clc |
ret |
.errread2: |
pop ecx |
add esp, 10h |
stc |
ret |
.break: |
add esp, 10h ; CF=0 |
mov [ntfs_bCanContinue], 1 |
ret |
ntfs_read_file_record: |
; in: eax=iRecord |
; out: [ntfs_data.frs_buffer] contains information |
; eax=0 - failed, eax=1 - success |
; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] |
push ecx edx |
mov ecx, [ntfs_data.frs_size] |
mul ecx |
shrd eax, edx, 9 |
shr edx, 9 |
jnz .err |
push [ntfs_attr_iRecord] |
push [ntfs_attr_iBaseRecord] |
push [ntfs_attr_offs] |
push [ntfs_attr_list] |
push dword [ntfs_attr_size+4] |
push dword [ntfs_attr_size] |
push [ntfs_cur_iRecord] |
push [ntfs_cur_attr] |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_buf] |
push [ntfs_cur_read] |
mov [ntfs_cur_attr], 0x80 ; $DATA |
and [ntfs_cur_iRecord], 0 ; $Mft |
mov [ntfs_cur_offs], eax |
shr ecx, 9 |
mov [ntfs_cur_size], ecx |
mov eax, [ntfs_data.frs_buffer] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
mov eax, [ntfs_cur_read] |
pop [ntfs_cur_read] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
pop [ntfs_cur_attr] |
pop [ntfs_cur_iRecord] |
pop dword [ntfs_attr_size] |
pop dword [ntfs_attr_size+4] |
pop [ntfs_attr_list] |
pop [ntfs_attr_offs] |
pop [ntfs_attr_iBaseRecord] |
pop [ntfs_attr_iRecord] |
pop edx ecx |
jc .errret |
cmp eax, [ntfs_data.frs_size] |
jnz .errret |
mov eax, [ntfs_data.frs_buffer] |
cmp dword [eax], 'FILE' |
jnz .errret |
push ebx |
mov ebx, eax |
call ntfs_restore_usa_frs |
pop ebx |
setnc al |
movzx eax, al |
.ret: |
ret |
.err: |
pop edx ecx |
.errret: |
xor eax, eax |
ret |
ntfs_restore_usa_frs: |
mov eax, [ntfs_data.frs_size] |
ntfs_restore_usa: |
pushad |
shr eax, 9 |
mov ecx, eax |
inc eax |
cmp [ebx+6], ax |
jnz .err |
movzx eax, word [ebx+4] |
lea esi, [eax+ebx] |
lodsw |
mov edx, eax |
lea edi, [ebx+0x1FE] |
@@: |
cmp [edi], dx |
jnz .err |
lodsw |
stosw |
add edi, 0x1FE |
loop @b |
popad |
clc |
ret |
.err: |
popad |
stc |
ret |
ntfs_decode_mcb_entry: |
push eax ecx edi |
lea edi, [esp+16] |
xor eax, eax |
lodsb |
test al, al |
jz .end |
mov ecx, eax |
and ecx, 0xF |
cmp ecx, 8 |
ja .end |
push ecx |
rep movsb |
pop ecx |
sub ecx, 8 |
neg ecx |
cmp byte [esi-1], 80h |
jae .end |
push eax |
xor eax, eax |
rep stosb |
pop ecx |
shr ecx, 4 |
cmp ecx, 8 |
ja .end |
push ecx |
rep movsb |
pop ecx |
sub ecx, 8 |
neg ecx |
cmp byte [esi-1], 80h |
cmc |
sbb eax, eax |
rep stosb |
stc |
.end: |
pop edi ecx eax |
ret |
ntfs_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory |
mov [ntfs_cur_iRecord], 5 ; start parse from root cluster |
.doit2: |
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ntfs_cur_offs], 0 |
mov eax, [ntfs_data.cur_index_size] |
mov [ntfs_cur_size], eax |
mov eax, [ntfs_data.cur_index_buf] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc @f |
.ret: |
ret |
@@: |
cmp [ntfs_cur_read], 0x20 |
jc .ret |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
ja @f |
.stc_ret: |
popad |
stc |
ret |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
and [ntfs_data.cur_index_size], 0 |
and [ntfs_data.cur_index_buf], 0 |
jmp .stc_ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
call kernel_alloc |
pop ebp esi |
test eax, eax |
jz .stc_ret |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
shl ecx, 9-2 |
rep movsd |
mov esi, eax |
mov [ntfs_data.cur_index_size], ebp |
push esi ebp |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
.ok2: |
add esi, 10h |
mov edi, [esp+4] |
; edi -> name, esi -> current index data, ebp = subnode size |
.scanloop: |
add esi, [esi] |
.scanloopint: |
test byte [esi+0Ch], 2 |
jnz .subnode |
push esi |
add esi, 0x52 |
movzx ecx, byte [esi-2] |
push edi |
@@: |
lodsw |
call uni2ansi_char |
call char_toupper |
push eax |
mov al, [edi] |
inc edi |
cmp al, '/' |
jz .slash |
call char_toupper |
cmp al, [esp] |
pop eax |
loopz @b |
jz .found |
pop edi |
pop esi |
jb .subnode |
.scanloopcont: |
movzx eax, word [esi+8] |
add esi, eax |
jmp .scanloopint |
.slash: |
pop eax |
pop edi |
pop esi |
.subnode: |
test byte [esi+0Ch], 1 |
jz .notfound |
movzx eax, word [esi+8] |
mov eax, [esi+eax-8] |
mul [ntfs_data.sectors_per_cluster] |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION |
mov [ntfs_cur_size], ebp |
mov eax, [ntfs_data.cur_index_buf] |
mov esi, eax |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
mov eax, ebp |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
jnz .notfound |
cmp dword [esi], 'INDX' |
jnz .notfound |
mov ebx, esi |
call ntfs_restore_usa |
jc .notfound |
add esi, 0x18 |
jmp .scanloop |
.notfound: |
popad |
stc |
ret |
.found: |
cmp byte [edi], 0 |
jz .done |
cmp byte [edi], '/' |
jz .next |
pop edi |
pop esi |
jmp .scanloopcont |
.done: |
.next: |
pop esi |
pop esi |
mov eax, [esi] |
mov [ntfs_cur_iRecord], eax |
mov [esp+1Ch], esi |
mov [esp+4], edi |
popad |
inc esi |
cmp byte [esi-1], 0 |
jnz .doit2 |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .doit2 |
@@: |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdRead - read NTFS hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
@@: |
call ntfs_find_lfn |
jnc .found |
or ebx, -1 |
push ERROR_FILE_NOT_FOUND |
pop eax |
ret |
.found: |
mov [ntfs_cur_attr], 0x80 ; $DATA |
and [ntfs_cur_offs], 0 |
and [ntfs_cur_size], 0 |
call ntfs_read_attr |
jnc @f |
or ebx, -1 |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
@@: |
pushad |
and dword [esp+10h], 0 |
xor eax, eax |
test ebx, ebx |
jz .zero1 |
cmp dword [ebx+4], 0x200 |
jb @f |
.eof0: |
popad |
xor ebx, ebx |
.eof: |
push ERROR_END_OF_FILE |
pop eax |
ret |
@@: |
mov eax, [ebx] |
test eax, 0x1FF |
jz .alignedstart |
push edx |
mov edx, [ebx+4] |
shrd eax, edx, 9 |
pop edx |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr.continue |
mov eax, [ebx] |
and eax, 0x1FF |
lea esi, [ntfs_bitmap_buf+eax] |
sub eax, [ntfs_cur_read] |
jae .eof0 |
neg eax |
push ecx |
cmp ecx, eax |
jb @f |
mov ecx, eax |
@@: |
mov [esp+10h+4], ecx |
mov edi, edx |
rep movsb |
mov edx, edi |
pop ecx |
sub ecx, [esp+10h] |
jnz @f |
.retok: |
popad |
xor eax, eax |
ret |
@@: |
cmp [ntfs_cur_read], 0x200 |
jz .alignedstart |
.eof_ebx: |
popad |
jmp .eof |
.alignedstart: |
mov eax, [ebx] |
push edx |
mov edx, [ebx+4] |
add eax, 511 |
adc edx, 0 |
shrd eax, edx, 9 |
pop edx |
.zero1: |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_buf], edx |
mov eax, ecx |
shr eax, 9 |
mov [ntfs_cur_size], eax |
add eax, [ntfs_cur_offs] |
push eax |
call ntfs_read_attr.continue |
pop [ntfs_cur_offs] |
mov eax, [ntfs_cur_read] |
add [esp+10h], eax |
mov eax, ecx |
and eax, not 0x1FF |
cmp [ntfs_cur_read], eax |
jnz .eof_ebx |
and ecx, 0x1FF |
jz .retok |
add edx, [ntfs_cur_read] |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr.continue |
cmp [ntfs_cur_read], ecx |
jb @f |
mov [ntfs_cur_read], ecx |
@@: |
xchg ecx, [ntfs_cur_read] |
push ecx |
mov edi, edx |
mov esi, ntfs_bitmap_buf |
add [esp+10h+4], ecx |
rep movsb |
pop ecx |
xor eax, eax |
cmp ecx, [ntfs_cur_read] |
jz @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+1Ch], eax |
popad |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdReadFolder - read NTFS hard disk folder |
; |
; esi points to filename |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdReadFolder: |
mov eax, 5 ; root cluster |
cmp byte [esi], 0 |
jz .doit |
call ntfs_find_lfn |
jnc .doit2 |
.notfound: |
or ebx, -1 |
push ERROR_FILE_NOT_FOUND |
.pop_ret: |
pop eax |
ret |
.doit: |
mov [ntfs_cur_iRecord], eax |
.doit2: |
mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr |
jc .notfound |
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ntfs_cur_offs], 0 |
mov eax, [ntfs_data.cur_index_size] |
mov [ntfs_cur_size], eax |
mov eax, [ntfs_data.cur_index_buf] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc .ok |
cmp [hd_error], 0 |
jz .notfound |
or ebx, -1 |
push 11 |
jmp .pop_ret |
.ok: |
cmp [ntfs_cur_read], 0x20 |
jae @f |
or ebx, -1 |
.fserr: |
push ERROR_FAT_TABLE |
jmp .pop_ret |
@@: |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
ja @f |
popad |
jmp .fserr |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
and [ntfs_data.cur_index_size], 0 |
and [ntfs_data.cur_index_buf], 0 |
.nomem: |
popad |
or ebx, -1 |
push 12 |
pop eax |
ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
call kernel_alloc |
pop ebp esi |
test eax, eax |
jz .nomem |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
shl ecx, 9-2 |
rep movsd |
mov esi, eax |
mov [ntfs_data.cur_index_size], ebp |
push esi ebp |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
.ok2: |
add esi, 10h |
mov ebx, [esp+10h] |
mov edx, [esp+14h] |
push dword [ebx+4] ; read ANSI/UNICODE name |
mov ebx, [ebx] |
; init header |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
mov ecx, [esp+4+18h] |
push edx |
mov edx, esp |
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, |
; ecx = number of blocks to read |
; edx -> parameters block: dd <output>, dd <flags> |
cmp [ntfs_cur_iRecord], 5 |
jz .skip_specials |
; dot and dotdot entries |
push esi |
xor esi, esi |
call .add_special_entry |
inc esi |
call .add_special_entry |
pop esi |
.skip_specials: |
; at first, dump index root |
add esi, [esi] |
.dump_root: |
test byte [esi+0Ch], 2 |
jnz .dump_root_done |
call .add_entry |
movzx eax, word [esi+8] |
add esi, eax |
jmp .dump_root |
.dump_root_done: |
; now dump all subnodes |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
mov ecx, 0x400/4 |
xor eax, eax |
rep stosd |
mov [ntfs_cur_attr], 0xB0 ; $BITMAP |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 2 |
call ntfs_read_attr |
pop edi ecx |
push 0 ; save offset in $BITMAP attribute |
and [ntfs_cur_offs], 0 |
.dumploop: |
mov [ntfs_cur_attr], 0xA0 |
mov [ntfs_cur_size], ebp |
mov eax, [ntfs_data.cur_index_buf] |
mov esi, eax |
mov [ntfs_cur_buf], eax |
push [ntfs_cur_offs] |
mov eax, [ntfs_cur_offs] |
imul eax, ebp |
mov [ntfs_cur_offs], eax |
call ntfs_read_attr |
pop [ntfs_cur_offs] |
mov eax, ebp |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
jnz .done |
push eax |
mov eax, [ntfs_cur_offs] |
and eax, 0x400*8-1 |
bt dword [ntfs_bitmap_buf], eax |
pop eax |
jnc .dump_subnode_done |
cmp dword [esi], 'INDX' |
jnz .dump_subnode_done |
push ebx |
mov ebx, esi |
call ntfs_restore_usa |
pop ebx |
jc .dump_subnode_done |
add esi, 0x18 |
add esi, [esi] |
.dump_subnode: |
test byte [esi+0Ch], 2 |
jnz .dump_subnode_done |
call .add_entry |
movzx eax, word [esi+8] |
add esi, eax |
jmp .dump_subnode |
.dump_subnode_done: |
inc [ntfs_cur_offs] |
test [ntfs_cur_offs], 0x400*8-1 |
jnz .dumploop |
mov [ntfs_cur_attr], 0xB0 |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
mov ecx, 0x400/4 |
xor eax, eax |
rep stosd |
pop edi ecx |
pop eax |
push [ntfs_cur_offs] |
inc eax |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 2 |
push eax |
call ntfs_read_attr |
pop eax |
pop [ntfs_cur_offs] |
push eax |
jmp .dumploop |
.done: |
pop eax |
pop edx |
mov ebx, [edx+4] |
pop edx |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+1Ch], eax |
mov [esp+10h], ebx |
popad |
ret |
.add_special_entry: |
mov eax, [edx] |
inc dword [eax+8] ; new file found |
dec ebx |
jns .ret |
dec ecx |
js .ret |
inc dword [eax+4] ; new file block copied |
mov eax, [edx+4] |
mov [edi+4], eax |
; mov eax, dword [ntfs_bitmap_buf+0x20] |
; or al, 0x10 |
mov eax, 0x10 |
stosd |
scasd |
push edx |
mov eax, dword [ntfs_bitmap_buf] |
mov edx, dword [ntfs_bitmap_buf+4] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+0x18] |
mov edx, dword [ntfs_bitmap_buf+0x1C] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+8] |
mov edx, dword [ntfs_bitmap_buf+0xC] |
call ntfs_datetime_to_bdfe |
pop edx |
xor eax, eax |
stosd |
stosd |
mov al, '.' |
push edi ecx |
lea ecx, [esi+1] |
test byte [edi-0x24], 1 |
jz @f |
rep stosw |
pop ecx |
xor eax, eax |
stosw |
pop edi |
add edi, 520 |
ret |
@@: |
rep stosb |
pop ecx |
xor eax, eax |
stosb |
pop edi |
add edi, 264 |
.ret: |
ret |
.add_entry: |
; do not return DOS 8.3 names |
cmp byte [esi+0x51], 2 |
jz .ret |
; do not return system files |
; ... note that there will be no bad effects if system files also were reported ... |
cmp dword [esi], 0x10 |
jb .ret |
mov eax, [edx] |
inc dword [eax+8] ; new file found |
dec ebx |
jns .ret |
dec ecx |
js .ret |
inc dword [eax+4] ; new file block copied |
mov eax, [edx+4] ; flags |
call ntfs_direntry_to_bdfe |
push ecx esi edi |
movzx ecx, byte [esi+0x50] |
add esi, 0x52 |
test byte [edi-0x24], 1 |
jz .ansi |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
and word [edi], 0 |
pop edi |
add edi, 520 |
pop esi ecx |
ret |
.ansi: |
jecxz .skip |
@@: |
lodsw |
call uni2ansi_char |
stosb |
loop @b |
.skip: |
xor al, al |
stosb |
pop edi |
add edi, 264 |
pop esi ecx |
ret |
ntfs_direntry_to_bdfe: |
mov [edi+4], eax ; ANSI/UNICODE name |
mov eax, [esi+48h] |
test eax, 0x10000000 |
jz @f |
and eax, not 0x10000000 |
or al, 0x10 |
@@: |
stosd |
scasd |
push edx |
mov eax, [esi+0x18] |
mov edx, [esi+0x1C] |
call ntfs_datetime_to_bdfe |
mov eax, [esi+0x30] |
mov edx, [esi+0x34] |
call ntfs_datetime_to_bdfe |
mov eax, [esi+0x20] |
mov edx, [esi+0x24] |
call ntfs_datetime_to_bdfe |
pop edx |
mov eax, [esi+0x40] |
stosd |
mov eax, [esi+0x44] |
stosd |
ret |
iglobal |
_24 dd 24 |
_60 dd 60 |
_10000000 dd 10000000 |
days400year dd 365*400+100-4+1 |
days100year dd 365*100+25-1 |
days4year dd 365*4+1 |
days1year dd 365 |
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
_400 dd 400 |
_100 dd 100 |
endg |
ntfs_datetime_to_bdfe: |
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC |
push eax |
mov eax, edx |
xor edx, edx |
div [_10000000] |
xchg eax, [esp] |
div [_10000000] |
pop edx |
; edx:eax = number of seconds since January 1, 1601 |
push eax |
mov eax, edx |
xor edx, edx |
div [_60] |
xchg eax, [esp] |
div [_60] |
mov [edi], dl |
pop edx |
; edx:eax = number of minutes |
div [_60] |
mov [edi+1], dl |
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32) |
xor edx, edx |
div [_24] |
mov [edi+2], dl |
mov [edi+3], byte 0 |
; eax = number of days since January 1, 1601 |
xor edx, edx |
div [days400year] |
imul eax, 400 |
add eax, 1601 |
mov [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days100year] |
cmp al, 4 |
jnz @f |
dec eax |
add edx, [days100year] |
@@: |
imul eax, 100 |
add [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days4year] |
shl eax, 2 |
add [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days1year] |
cmp al, 4 |
jnz @f |
dec eax |
add edx, [days1year] |
@@: |
add [edi+6], ax |
push esi edx |
mov esi, months |
movzx eax, word [edi+6] |
test al, 3 |
jnz .noleap |
xor edx, edx |
push eax |
div [_400] |
pop eax |
test edx, edx |
jz .leap |
xor edx, edx |
div [_100] |
test edx, edx |
jz .noleap |
.leap: |
mov esi, months2 |
.noleap: |
pop edx |
xor eax, eax |
inc eax |
@@: |
sub edx, [esi] |
jb @f |
add esi, 4 |
inc eax |
jmp @b |
@@: |
add edx, [esi] |
pop esi |
inc edx |
mov [edi+4], dl |
mov [edi+5], al |
add edi, 8 |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdRewrite - write to NTFS hard disk |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdRewrite: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdWrite - write to NTFS hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdWrite: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdSetFileEnd - set end of file on NTFS hard disk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdSetFileEnd: |
ntfs_HdSetFileInfo: |
;---------------------------------------------------------------- |
; |
; ntfs_HdDelete - delete file or empty folder from NTFS hard disk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdDelete: |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
ntfs_HdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
push 2 |
pop eax |
ret |
@@: |
call ntfs_find_lfn |
jnc .doit |
push ERROR_FILE_NOT_FOUND |
pop eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
.doit: |
push esi edi |
mov esi, eax |
mov edi, edx |
xor eax, eax |
call ntfs_direntry_to_bdfe |
pop edi esi |
xor eax, eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs/parse_fn.inc |
---|
0,0 → 1,236 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;------------------------------------------------------------------------- |
; |
; File path partial substitution (according to configuration) |
; |
; |
; SPraid |
; |
;------------------------------------------------------------------------- |
$Revision$ |
iglobal |
; pointer to memory for path replace table, |
; size of one record is 128 bytes: 64 bytes for search pattern + 64 bytes for replace string |
; start with one entry: sys -> <sysdir> |
full_file_name_table dd sysdir_name |
.size dd 1 |
tmp_file_name_size dd 1 |
endg |
uglobal |
; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir> |
sysdir_name rb 64 |
sysdir_path rb 64 |
tmp_file_name_table dd ? |
endg |
; use bx_from_load and init system directory /sys |
proc Parser_params |
locals |
buff db 4 dup(?) ; for test cd |
endl |
mov eax,[OS_BASE+0x10000+bx_from_load] |
mov ecx,sysdir_path |
mov [ecx-64],dword 'sys' |
cmp al,'r' ; if ram disk |
jnz @f |
mov [ecx],dword 'RD/?' |
mov [ecx+3],byte ah |
mov [ecx+4],byte 0 |
ret |
@@: |
cmp al,'m' ; if ram disk |
jnz @f |
mov [ecx],dword 'CD?/' ; if cd disk {m} |
mov [ecx+4],byte '1' |
mov [ecx+5],dword '/KOL' |
mov [ecx+9],dword 'IBRI' |
mov [ecx+13],byte 0 |
.next_cd: |
mov [ecx+2],byte ah |
inc ah |
cmp ah,'5' |
je .not_found_cd |
lea edx,[buff] |
pushad |
stdcall read_file,read_firstapp,edx,0,4 |
popad |
cmp [edx],dword 'MENU' |
jne .next_cd |
jmp .ok |
@@: |
sub al,49 |
mov [ecx],dword 'HD?/' ; if hard disk |
mov [ecx+2],byte al |
mov [ecx+4],byte ah |
mov [ecx+5],dword '/KOL' |
mov [ecx+9],dword 'IBRI' |
mov [ecx+13],byte 0 |
.ok: |
.not_found_cd: |
ret |
endp |
proc load_file_parse_table |
stdcall kernel_alloc,0x1000 |
mov [tmp_file_name_table],eax |
mov edi,eax |
mov esi,sysdir_name |
mov ecx,128/4 |
rep movsd |
invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key |
mov eax,[tmp_file_name_table] |
mov [full_file_name_table],eax |
mov eax,[tmp_file_name_size] |
mov [full_file_name_table.size],eax |
ret |
endp |
uglobal |
def_val_1 db 0 |
endg |
proc get_every_key stdcall, f_name, sec_name, key_name |
mov esi, [key_name] |
mov ecx, esi |
cmp byte [esi], '/' |
jnz @f |
inc esi |
@@: |
mov edi, [tmp_file_name_size] |
shl edi, 7 |
cmp edi, 0x1000 |
jae .stop_parse |
add edi, [tmp_file_name_table] |
lea ebx, [edi+64] |
@@: |
cmp edi, ebx |
jae .skip_this_key |
lodsb |
test al, al |
jz @f |
or al, 20h |
stosb |
jmp @b |
@@: |
stosb |
invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1 |
cmp byte [ebx], '/' |
jnz @f |
lea esi, [ebx+1] |
mov edi, ebx |
mov ecx, 63 |
rep movsb |
@@: |
push ebp |
mov ebp, [tmp_file_name_table] |
mov ecx, [tmp_file_name_size] |
jecxz .noreplace |
mov eax, ecx |
dec eax |
shl eax, 7 |
add ebp, eax |
.replace_loop: |
mov edi, ebx |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz .doreplace |
mov dl, [edi] |
inc edi |
test dl, dl |
jz .replace_loop_cont |
or dl, 20h |
cmp al, dl |
jz @b |
jmp .replace_loop_cont |
.doreplace: |
cmp byte [edi], 0 |
jz @f |
cmp byte [edi], '/' |
jnz .replace_loop_cont |
@@: |
lea esi, [ebp+64] |
call .replace |
jc .skip_this_key2 |
.replace_loop_cont: |
sub ebp, 128 |
loop .replace_loop |
.noreplace: |
pop ebp |
inc [tmp_file_name_size] |
.skip_this_key: |
xor eax, eax |
inc eax |
ret |
.skip_this_key2: |
pop ebp |
jmp .skip_this_key |
.stop_parse: |
xor eax, eax |
ret |
endp |
proc get_every_key.replace |
; in: ebx->destination, esi->first part of name, edi->second part of name |
; maximum length is 64 bytes |
; out: CF=1 <=> overflow |
; 1) allocate temporary buffer in stack |
sub esp, 64 |
; 2) save second part of name to temporary buffer |
push esi |
lea esi, [esp+4] ; esi->tmp buffer |
xchg esi, edi ; edi->tmp buffer, esi->source |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
; 3) copy first part of name to destination |
pop esi |
mov edi, ebx |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
jmp @b |
@@: |
; 4) restore second part of name from temporary buffer to destination |
; (may cause overflow) |
lea edx, [ebx+64] ; limit of destination |
mov esi, esp |
@@: |
cmp edi, edx |
jae .overflow |
lodsb |
stosb |
test al, al |
jnz @b |
; all is OK |
add esp, 64 ; CF is cleared |
ret |
.overflow: |
; name is too long |
add esp, 64 |
stc |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/fs |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt |
---|
0,0 → 1,4626 |
Kolibri 0.7.5.0+ |
®¬¥à äãªæ¨¨ ¯®¬¥é ¥âáï ¢ ॣ¨áâà eax. |
맮¢ á¨á⥬®© äãªæ¨¨ ®áãé¥á⢫ï¥âáï ª®¬ ¤®© "int 0x40". |
ᥠॣ¨áâàë, ªà®¬¥  㪠§ ëå ¢ ¢®§¢à é ¥¬®¬ § 票¨, |
¢ª«îç ï ॣ¨áâà ä« £®¢ eflags, á®åà ïîâáï. |
====================================================================== |
============== ãªæ¨ï 0 - ®¯à¥¤¥«¨âì ¨ à¨á®¢ âì ®ª®. ============= |
====================================================================== |
¯à¥¤¥«ï¥â ®ª® ¯à¨«®¦¥¨ï. ¨áã¥â à ¬ªã ®ª , § £®«®¢®ª ¨ à ¡®çãî |
®¡« áâì. «ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥â áâ ¤ àâë¥ ª®¯ª¨ § ªàëâ¨ï ¨ |
¬¨¨¬¨§ 樨. |
à ¬¥âàë: |
* eax = 0 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYRRGGBB, £¤¥: |
* Y = áâ¨«ì ®ª : |
* Y=0 - ⨯ I - ®ª® 䨪á¨à®¢ ëå à §¬¥à®¢ |
* Y=1 - ⮫쪮 ®¯à¥¤¥«¨âì ®¡« áâì ®ª , ¨ç¥£® ¥ à¨á®¢ âì |
* Y=2 - ⨯ II - ®ª® ¨§¬¥ï¥¬ëå à §¬¥à®¢ |
* Y=3 - ®ª® ᮠ᪨®¬ |
* Y=4 - ®ª® ᮠ᪨®¬ 䨪á¨à®¢ ëå à §¬¥à®¢ |
* ®áâ «ìë¥ ¢®§¬®¦ë¥ § 票ï (®â 5 ¤® 15) § १¥à¢¨à®¢ ë, |
¢ë§®¢ äãªæ¨¨ á â ª¨¬¨ Y ¨£®à¨àã¥âáï |
* RR, GG, BB = ᮮ⢥âá⢥® ªà á ï, §¥«¥ ï, á¨ïï |
á®áâ ¢«ïî騥 梥â à ¡®ç¥© ®¡« á⨠®ª |
(¨£®à¨àã¥âáï ¤«ï á⨫ï Y=2) |
* X = DCBA (¡¨âë) |
* A = 1 - ã ®ª ¥áâì § £®«®¢®ª; ¤«ï á⨫¥© Y=3,4 ¤à¥á áâப¨ |
§ £®«®¢ª § ¤ ñâáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥© |
¨á¯®«ì§ã¥âáï ¯®¤äãªæ¨ï 1 äãªæ¨¨ 71 |
* B = 1 - ª®®à¤¨ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï |
®â®á¨â¥«ì® ª«¨¥â᪮© ®¡« á⨠®ª |
* C = 1 - ¥ § ªà 訢 âì à ¡®çãî ®¡« áâì ¯à¨ ®âà¨á®¢ª¥ ®ª |
* D = 0 - ®à¬ «ì ï § «¨¢ª à ¡®ç¥© ®¡« áâ¨, 1 - £à ¤¨¥â ï |
«¥¤ãî騥 ¯ à ¬¥âàë ¯à¥¤ § ç¥ë ¤«ï ®ª® ⨯ I ¨ II ¨ |
¨£®à¨àãîâáï ¤«ï á⨫¥© Y=1,3: |
* esi = 0xXYRRGGBB - 梥⠧ £®«®¢ª |
* RR, GG, BB ®¯à¥¤¥«ïîâ á ¬ 梥â |
* Y=0 - ®¡ë箥 ®ª®, Y=1 - ¥¯¥à¥¬¥é ¥¬®¥ ®ª® |
* X ®¯à¥¤¥«ï¥â £à ¤¨¥â § £®«®¢ª : X=0 - ¥â £à ¤¨¥â , |
X=8 - ®¡ëçë© £à ¤¨¥â, |
¤«ï ®ª® ⨯ II X=4 - ¥£ â¨¢ë© £à ¤¨¥â |
* ¯à®ç¨¥ § 票ï X ¨ Y § १¥à¢¨à®¢ ë |
* edi = 0x00RRGGBB - 梥â à ¬ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®«®¦¥¨¥ ¨ à §¬¥àë ®ª ãáâ ¢«¨¢ îâáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ |
í⮩ äãªæ¨¨ ¨ ¨£®à¨àãîâáï ¯à¨ ¯®á«¥¤ãîé¨å; ¤«ï ¨§¬¥¥¨ï |
¯®«®¦¥¨ï ¨/¨«¨ à §¬¥à®¢ 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
67-î äãªæ¨î. |
* «ï ®ª® á⨫¥© Y=3,4 á § £®«®¢ª®¬ (A=1) áâப § £®«®¢ª |
ãáâ ¢«¨¢ ¥âáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ í⮩ äãªæ¨¨ ¨ ¨£®à¨àã¥âáï ¯à¨ |
¯®á«¥¤ãîé¨å (â®ç¥¥ £®¢®àï, ¨£®à¨àã¥âáï ¯®á«¥ ¢ë§®¢ |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 12 - ª®æ ¯¥à¥à¨á®¢ª¨); |
¤«ï ¨§¬¥¥¨ï áâப¨ § £®«®¢ª 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 1 äãªæ¨¨ 71. |
* ᫨ ¨á¯®«ì§®¢ âì ®ª ᮮ⢥âáâ¢ãîé¨å á⨫¥©, â® ¯®«®¦¥¨¥ |
¨/¨«¨ à §¬¥àë ®ª ¬®£ãâ ¬¥ïâìáï ¯®«ì§®¢ ⥫¥¬. |
¥ªã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì ¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ª® ¤®«¦® 㬥é âìáï íªà ¥. ᫨ ¯¥à¥¤ ë¥ ª®®à¤¨ âë |
¨ à §¬¥àë ¥ 㤮¢«¥â¢®àïîâ í⮬ã ãá«®¢¨î, ⮠ᮮ⢥âáâ¢ãîé ï |
ª®®à¤¨ â (¨«¨, ¢®§¬®¦®, ®¡¥) áç¨â ¥âáï ã«¥¬, ¥á«¨ ¨ íâ® |
¥ ¯®¬®£ ¥â, ⮠ᮮ⢥âáâ¢ãî騩 à §¬¥à (¨«¨, ¢®§¬®¦®, ®¡ ) |
ãáâ ¢«¨¢ ¥âáï ¢ à §¬¥à íªà . |
«¥¥ ®¡®§ 稬 xpos,ypos,xsize,ysize - § 票ï, ¯¥à¥¤ ¢ ¥¬ë¥ |
¢ ebx,ecx. ®®à¤¨ âë ¯à¨¢®¤ïâáï ®â®á¨â¥«ì® «¥¢®£® ¢¥à奣® |
㣫 ®ª , ª®â®àë©, â ª¨¬ ®¡à §®¬, § ¤ ¥âáï ª ª (0,0), ª®®à¤¨ âë |
¯à ¢®£® ¨¦¥£® 㣫 áãâì (xsize,ysize). |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 . |
â® ¦¥ ®â®á¨âáï ¨ ª® ¢á¥¬ ®áâ «ìë¬ äãªæ¨ï¬. |
â® ®§ ç ¥â, ç⮠ॠ«ìë¥ à §¬¥àë 1 ¯¨ªá¥«ì ¡®«ìè¥. |
* ¨¤ ®ª ⨯ I: |
* à¨áã¥âáï ¢¥èïï à ¬ª 梥â , 㪠§ ®£® ¢ edi, |
è¨à¨®© 1 ¯¨ªá¥«ì |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,1) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-1,min(25,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,21) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-1,ysize-1) (à §¬¥à ¬¨ (xsize-1)*(ysize-21)) - 梥⮬, |
㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª á⨫ï Y=1: |
* ¯®«®áâìî ®¯à¥¤¥«ï¥âáï ¯à¨«®¦¥¨¥¬ |
* ¨¤ ®ª ⨯ II: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì "§ â¥ñ®£®" 梥â |
edi (¢á¥ á®áâ ¢«ïî騥 梥â 㬥ìè îâáï ¢ ¤¢ à § ) |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï 梥â edi |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
"§ â¥ñ®£®" 梥â edi |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (4,4) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-4,min(20,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,20) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª ᮠ᪨®¬: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'outer' ¨§ ᪨ |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï |
梥â 'frame' ¨§ ᪨ |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'inner' ¨§ ᪨ |
* à¨áã¥âáï § £®«®¢®ª (¯® ª à⨪ ¬ ¨§ ᪨ ) ¢ ¯àאַ㣮«ì¨ª¥ |
(0,0) - (xsize,_skinh-1) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,_skinh) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ®¯à¥¤¥«ïîâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨: § ªàëâ¨ï ¨ ¬¨¨¬¨§ 樨 |
(ᬮâਠäãªæ¨î 8) |
* ¥á«¨ A=1 ¨ ¢ edi (¥ã«¥¢®©) 㪠§ ⥫ì áâப㠧 £®«®¢ª , |
â® ® ¢ë¢®¤¨âáï ¢ § £®«®¢ª¥ ¢ ¬¥áâ¥, ®¯à¥¤¥«ï¥¬®¬ ᪨®¬ |
* 票¥ ¯¥à¥¬¥®© _skinh ¤®áâ㯮 ª ª १ã«ìâ ⠢맮¢ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 48 |
====================================================================== |
================= ãªæ¨ï 1 - ¯®áâ ¢¨âì â®çªã ¢ ®ª¥. ================ |
====================================================================== |
à ¬¥âàë: |
* eax = 1 - ®¬¥à äãªæ¨¨ |
* ebx = x-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* ecx = y-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* edx = 0x00RRGGBB - 梥â â®çª¨ |
edx = 0x01xxxxxx - ¨¢¥àâ¨à®¢ âì 梥â â®çª¨ |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
============== ãªæ¨ï 2 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª« ¢¨è¨. ============= |
====================================================================== |
¡¨à ¥â ª®¤ ¦ ⮩ ª« ¢¨è¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 2 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, ah=ª®¤ ¦ ⮩ ª« ¢¨è¨, |
áâ à襥 á«®¢® ॣ¨áâà eax ®¡ã«¥® |
* ¥á«¨ ¥áâì "£®àïç ï ª« ¢¨è ", â® ¢®§¢à é ¥âáï |
al=2, ah=᪠ª®¤ ¦ ⮩ ª« ¢¨è¨ (0 ¤«ï ã¯à ¢«ïîé¨å ª« ¢¨è), |
áâ à襥 á«®¢® ॣ¨áâà eax ᮤ¥à¦¨â á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è |
¢ ¬®¬¥â ¦ â¨ï £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ãé¥áâ¢ã¥â ®¡é¥á¨áâ¥¬ë© ¡ãä¥à ¦ âëå ª« ¢¨è à §¬¥à®¬ 120 ¡ ©â, |
®à£ ¨§®¢ ë© ª ª ®ç¥à¥¤ì. |
* ãé¥áâ¢ã¥â ¥éñ ®¤¨ ®¡é¥á¨áâ¥¬ë© ¡ãä¥à 120 "£®àïç¨å ª« ¢¨è". |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
áç¨â ¥âáï, çâ® ¡ãä¥à ¦ âëå ª« ¢¨è ¯ãáâ. |
* ® 㬮«ç ¨î íâ äãªæ¨ï ¢®§¢à é ¥â ASCII-ª®¤ë; ¯¥à¥ª«îç¨âìáï |
०¨¬ ᪠ª®¤®¢ (¨ § ¤) ¬®¦® á ¨á¯®«ì§®¢ ¨¥¬ äãªæ¨¨ 66. |
¤ ª®, £®àï稥 ª« ¢¨è¨ ¢á¥£¤ ¢®§¢à é îâáï ª ª ᪠ª®¤ë. |
* § âì, ª ª¨¥ ª®¬¡¨ 樨 ª« ¢¨è ᮮ⢥âáâ¢ãîâ ª ª¨¬ ª®¤ ¬, ¬®¦®, |
§ ¯ãá⨢ ¯à¨«®¦¥¨ï keyascii ¨ scancode. |
* ª ª®¤ë ¢®§¢à é îâáï ¥¯®á।á⢥® ª« ¢¨ âãன ¨ 䨪á¨à®¢ ë; |
ASCII-ª®¤ë ¯®«ãç îâáï á ¨á¯®«ì§®¢ ¨¥¬ â ¡«¨æ ¯à¥®¡à §®¢ ¨ï, |
ª®â®àë¥ ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2 äãªæ¨¨ 21 ¨ ¯à®ç¨â âì |
¯®¤äãªæ¨¥© 2 äãªæ¨¨ 26. |
* ª á«¥¤á⢨¥, ASCII-ª®¤ë ãç¨âë¢ îâ ⥪ãéãî à ᪫ ¤ªã ª« ¢¨ âãàë |
(rus/en) ¢ ®â«¨ç¨¥ ®â ᪠ª®¤®¢. |
* ®áâ㯠¥â ¨ä®à¬ æ¨ï ⮫쪮 ® â¥å £®àïç¨å ª« ¢¨è å, ª®â®àë¥ ¡ë«¨ |
®¯à¥¤¥«¥ë í⨬ ¯®â®ª®¬ ¯®¤äãªæ¨¥© 4 äãªæ¨¨ 66. |
====================================================================== |
================ ãªæ¨ï 3 - ¯®«ãç¨âì á¨á⥬®¥ ¢à¥¬ï. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 3 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00SSMMHH, £¤¥ HH:MM:SS = ç áë:¬¨ãâë:ᥪã¤ë |
* ª ¦¤ë© í«¥¬¥â ¢®§¢à é ¥âáï ª ª BCD-ç¨á«®, ¯à¨¬¥à, |
¤«ï ¢à¥¬¥¨ 23:59:59 १ã«ìâ ⠡㤥â 0x00595923 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 9 äãªæ¨¨ 26 - ¯®«ã票¥ ¢à¥¬¥¨ |
á ¬®¬¥â § ¯ã᪠á¨á⥬ë; ® ¢® ¬®£¨å á«ãç ïå 㤮¡¥¥, |
¯®áª®«ìªã ¢®§¢à é ¥â ¯à®áâ® DWORD-§ 票¥ áç¥â稪 ¢à¥¬¥¨. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
============== ãªæ¨ï 4 - ¢ë¢¥á⨠áâபã ⥪áâ ¢ ®ª®. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 4 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* ecx = 0xX0RRGGBB, £¤¥ |
* RR, GG, BB § ¤ îâ 梥â ⥪áâ |
* X=ABnn (¡¨âë): |
* nn § ¤ ¥â ¨á¯®«ì§ã¥¬ë© èà¨äâ: 0=á¨áâ¥¬ë© ¬®®è¨à¨ë©, |
1=á¨áâ¥¬ë© èà¨äâ ¯¥à¥¬¥®© è¨à¨ë |
* A=0 - ¢ë¢®¤¨âì esi ᨬ¢®«®¢, A=1 - ¢ë¢®¤¨âì ASCIIZ-áâபã |
* B=1 - § ªà 訢 âì ä® æ¢¥â®¬ edi |
* edx = 㪠§ ⥫ì ç «® áâப¨ |
* esi = ¤«ï A=0 ¤«¨ áâப¨, ¤®«¦ ¡ëâì ¥ ¡®«ìè¥ 255; |
¤«ï A=1 ¨£®à¨àã¥âáï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥à¢ë© á¨áâ¥¬ë© èà¨äâ áç¨âë¢ ¥âáï ¯à¨ § £à㧪¥ ¨§ ä ©« char.mt, |
¢â®à®© - ¨§ char2.mt. |
* ¡ èà¨äâ ¨¬¥îâ ¢ëá®âã 9 ¯¨ªá¥«¥©, è¨à¨ ¬®®è¨à¨®£® èà¨äâ |
à ¢ 6 ¯¨ªá¥«¥©. |
====================================================================== |
========================= ãªæ¨ï 5 - ¯ 㧠. ========================= |
====================================================================== |
¤¥à¦¨¢ ¥â ¢ë¯®«¥¨¥ ¯à®£à ¬¬ë § ¤ ®¥ ¢à¥¬ï. |
à ¬¥âàë: |
* eax = 5 - ®¬¥à äãªæ¨¨ |
* ebx = ¢à¥¬ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥à¥¤ ç ebx=0 ¥ ¯¥à¥¤ ¥â ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã ¨ |
¢®®¡é¥ ¥ ¯à®¨§¢®¤¨â ¨ª ª¨å ¤¥©á⢨©. ᫨ ¤¥©áâ¢¨â¥«ì® |
âॡã¥âáï ¯¥à¥¤ âì ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã |
(§ ª®ç¨âì ⥪ã騩 ª¢ ⠢६¥¨), ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 1 |
äãªæ¨¨ 68. |
====================================================================== |
=============== ãªæ¨ï 6 - ¯à®ç¨â âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 6 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = ®¬¥à áâ à⮢®£® ¡«®ª , áç¨â ï á 1; |
ecx=0 - ç¨â âì á ç « ä ©« (â® ¦¥ á ¬®¥, çâ® ¨ ecx=1) |
* edx = ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï; |
edx=0 - ç¨â âì ®¤¨ ¡«®ª (â® ¦¥ á ¬®¥, çâ® ¨ edx=1) |
* esi = 㪠§ â¥«ì ®¡« áâì ¯ ¬ïâ¨, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤«¨ ä ©« ¢ ¡ ©â å, ¥á«¨ ä ©« ãá¯¥è® ¯à®ç¨â |
* eax = -1, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ï äãªæ¨ï ï¥âáï ãáâ ॢ襩; äãªæ¨ï 70 |
¯®§¢®«ï¥â ¢ë¯®«ïâì ⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* «®ª = 512 ¡ ©â. |
* «ï çâ¥¨ï ¢á¥£® ä ©« ¬®¦® 㪠§ âì § ¢¥¤®¬® ¡®«ì讥 § 票¥ |
¢ edx, ¯à¨¬¥à, edx = -1; ® ¢ í⮬ á«ãç ¥ ¡ã¤ì⥠£®â®¢ë ª ⮬ã, |
çâ® ¯à®£à ¬¬ "㯠¤¥â", ¥á«¨ ä ©« ®ª ¦¥âáï ᫨誮¬ ¡®«ì訬 |
¨ "¥ ¢«¥§¥â" ¢ ¯ ¬ïâì ¯à®£à ¬¬ë. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯ª¨ à ¬¤¨áª¥. |
====================================================================== |
=============== ãªæ¨ï 7 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ ¢ ®ª®. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 7 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize. |
====================================================================== |
=============== ãªæ¨ï 8 - ®¯à¥¤¥«¨âì/㤠«¨âì ª®¯ªã. =============== |
====================================================================== |
à ¬¥âàë ¤«ï ®¯à¥¤¥«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYnnnnnn, £¤¥: |
* nnnnnn = ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
* áâ à訩 (31-©) ¡¨â edx á¡à®è¥ |
* ¥á«¨ 30-© ¡¨â edx ãáâ ®¢«¥ - ¥ ¯à®à¨á®¢ë¢ âì ª®¯ªã |
* ¥á«¨ 29-© ¡¨â edx ãáâ ®¢«¥ - ¥ à¨á®¢ âì à ¬ªã |
¯à¨ ¦ ⨨ ª®¯ªã |
* esi = 0x00RRGGBB - 梥⠪®¯ª¨ |
à ¬¥âàë ¤«ï 㤠«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* edx = 0x80nnnnnn, £¤¥ nnnnnn - ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* §¬¥àë ª®¯ª¨ ¤®«¦ë ¡ëâì ¡®«ìè¥ 0 ¨ ¬¥ìè¥ 0x8000. |
* «ï ®ª® ᮠ᪨®¬ ¯à¨ ®¯à¥¤¥«¥¨¨ ®ª (¢ë§®¢¥ 0-© äãªæ¨¨) |
ᮧ¤ îâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨ - § ªàëâ¨ï ®ª |
á ¨¤¥â¨ä¨ª â®à®¬ 1 ¨ ¬¨¨¬¨§ 樨 ®ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff. |
* ®§¤ ¨¥ ¤¢ãå ª®¯®ª á ®¤¨ ª®¢ë¬¨ ¨¤¥â¨ä¨ª â®à ¬¨ |
¢¯®«¥ ¤®¯ãá⨬®. |
* ®¯ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff ¯à¨ ¦ ⨨ ¨â¥à¯à¥â¨àã¥âáï |
á¨á⥬®© ª ª ª®¯ª ¬¨¨¬¨§ 樨, á¨á⥬ ®¡à ¡ âë¢ ¥â â ª®¥ |
¦ ⨥ á ¬®áâ®ï⥫ì®, ¥ ®¡à é ïáì ª ¯à¨«®¦¥¨î. |
®á⠫쮬 íâ® ®¡ëç ï ª®¯ª . |
* ¡é¥¥ ª®«¨ç¥á⢮ ª®¯®ª ¤«ï ¢á¥å ¯à¨«®¦¥¨© ®£à ¨ç¥® |
ç¨á«®¬ 4095. |
====================================================================== |
============= ãªæ¨ï 9 - ¨ä®à¬ æ¨ï ® ¯®â®ª¥ ¢ë¯®«¥¨ï. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 9 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 1 ¡ |
* ecx = ®¬¥à ᫮⠯®â®ª |
ecx = -1 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¯®â®ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ªá¨¬ «ìë© ®¬¥à ᫮⠯®â®ª |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ebx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ¨á¯®«ì§®¢ ¨¥ ¯à®æ¥áá®à (᪮«ìª® ⠪⮢ ¢ ᥪã¤ã |
ã室¨â ¨á¯®«¥¨¥ ¨¬¥® í⮣® ¯®â®ª ) |
* +4: word: ¯®§¨æ¨ï ®ª ¯®â®ª ¢ ®ª®®¬ áâíª¥ |
* +6: word: (¥ ¨¬¥¥â ®â®è¥¨ï ª § ¯à®è¥®¬ã ¯®â®ªã) |
®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® 室¨âáï ¢ ®ª®®¬ áâíª¥ |
¢ ¯®§¨æ¨¨ ecx |
* +8: word: § १¥à¢¨à®¢ ® |
* +10 = +0xA: 11 ¡ ©â: ¨¬ï ¯à®æ¥áá |
(¨¬ï ᮮ⢥âáâ¢ãî饣® ¨á¯®«ï¥¬®£® ä ©« ¢ ä®à¬ ⥠8+3) |
* +21 = +0x15: byte: § १¥à¢¨à®¢ ®, íâ®â ¡ ©â ¥ ¨§¬¥ï¥âáï |
* +22 = +0x16: dword: ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ï⨠|
* +26 = +0x1A: dword: à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠- 1 |
* +30 = +0x1E: dword: ¨¤¥â¨ä¨ª â®à (PID/TID) |
* +34 = +0x22: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ x |
* +38 = +0x26: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ y |
* +42 = +0x2A: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ x |
* +46 = +0x2E: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ y |
* +50 = +0x32: word: á®áâ®ï¨¥ ᫮⠯®â®ª : |
* 0 = ¯®â®ª ¢ë¯®«ï¥âáï |
* 1 = ¯®â®ª ¯à¨®áâ ®¢«¥ |
* 2 = ¯®â®ª ¯à¨®áâ ®¢«¥ ¢ ¬®¬¥â ®¦¨¤ ¨ï ᮡëâ¨ï |
* 3 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¢ë§®¢ äãªæ¨¨ -1 ¨«¨ |
ᨫìá⢥® ª ª á«¥¤á⢨¥ ¢ë§®¢ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 |
¨«¨ § ¢¥à襨ï à ¡®âë á¨á⥬ë |
* 4 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¨áª«î票ï |
* 5 = ¯®â®ª ®¦¨¤ ¥â ᮡëâ¨ï |
* 9 = § ¯à®è¥ë© á«®â ᢮¡®¤¥, ¢áï ®áâ «ì ï ¨ä®à¬ æ¨ï ® |
᫮⥠¥ ¨¬¥¥â á¬ëá« |
* +52 = +0x34: word: § १¥à¢¨à®¢ ®, íâ® á«®¢® ¥ ¨§¬¥ï¥âáï |
* +54 = +0x36: dword: ª®®à¤¨ â ç « ª«¨¥â᪮© ®¡« á⨠|
¯® ®á¨ x |
* +58 = +0x3A: dword: ª®®à¤¨ â ç « ª«¨¥â᪮© ®¡« á⨠|
¯® ®á¨ y |
* +62 = +0x3E: dword: è¨à¨ ª«¨¥â᪮© ®¡« á⨠|
* +66 = +0x42: dword: ¢ëá®â ª«¨¥â᪮© ®¡« á⨠|
* +70 = +0x46: byte: á®áâ®ï¨¥ ®ª - ¡¨â®¢®¥ ¯®«¥ |
* ¡¨â 0 (¬ ᪠1): ®ª® ¬ ªá¨¬¨§¨à®¢ ® |
* ¡¨â 1 (¬ ᪠2): ®ª® ¬¨¨¬¨§¨à®¢ ® ¢ ¯ ¥«ì § ¤ ç |
* ¡¨â 2 (¬ ᪠4): ®ª® á¢ñàãâ® ¢ § £®«®¢®ª |
¬¥ç ¨ï: |
* «®âë 㬥àãîâáï á 1. |
* ®§¢à é ¥¬®¥ § 票¥ ¥ ¥áâì ®¡é¥¥ ç¨á«® ¯®â®ª®¢, ¯®áª®«ìªã |
¡ë¢ îâ ᢮¡®¤ë¥ á«®âë. |
* ਠᮧ¤ ¨¨ ¯à®æ¥áá ¢â®¬ â¨ç¥áª¨ ᮧ¤ ¥âáï ¯®â®ª ¢ë¯®«¥¨ï. |
* ãªæ¨ï ¢ë¤ ¥â ¨ä®à¬ æ¨î ® ¯®â®ª¥. ¦¤ë© ¯à®æ¥áá ¨¬¥¥â |
å®âï ¡ë ®¤¨ ¯®â®ª. ¤¨ ¯à®æ¥áá ¬®¦¥â ᮧ¤ âì ¥áª®«ìª® ¯®â®ª®¢, |
¢ í⮬ á«ãç ¥ ª ¦¤ë© ¯®â®ª ¯®«ãç ¥â ᢮© á«®â, ¯à¨ç¥¬ ¯®«ï |
+10, +22, +26 ¢ íâ¨å á«®â å ᮢ¯ ¤ îâ. |
«ï ¯à¨«®¦¥¨© ¥ áãé¥áâ¢ã¥â ®¡é¥£® ᯮᮡ ®¯à¥¤¥«¨âì, |
¯à¨ ¤«¥¦ â «¨ ¤¢ ¯®â®ª ®¤®¬ã ¯à®æ¥ááã. |
* ªâ¨¢®¥ ®ª® - ®ª®, 室ï饥áï ¢¥à訥 ®ª®®£® áâíª , |
®® ¯®«ãç ¥â á®®¡é¥¨ï ® ¢¢®¤¥ á ª« ¢¨ âãàë. «ï ¥£® ¯®§¨æ¨ï ¢ |
®ª®®¬ áâíª¥ ᮢ¯ ¤ ¥â á ¢®§¢à é ¥¬ë¬ § 票¥¬. |
* «®â 1 ᮮ⢥âáâ¢ã¥â á¯¥æ¨ «ì®¬ã ¯®â®ªã ®¯¥à 樮®© á¨á⥬ë, |
¤«ï ª®â®à®£®: |
* ®ª® 室¨âáï ¢¨§ã ®ª®®£® áâíª , ¯®«ï +4 ¨ +6 ᮤ¥à¦ â |
§ 票¥ 1 |
* ¨¬ï ¯à®æ¥áá - "OS/IDLE" (¤®¯®«¥®¥ ¯à®¡¥« ¬¨) |
* ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ïâ¨ à ¢¥ 0, à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠|
16 Mb (0x1000000) |
* PID=1 |
* ª®®à¤¨ âë ¨ à §¬¥àë ®ª , à ¢® ª ª ¨ ª«¨¥â᪮© ®¡« áâ¨, |
ãá«®¢® ¯®« £ îâáï à ¢ë¬¨ 0 |
* á®áâ®ï¨¥ á«®â - ¢á¥£¤ 0 (¢ë¯®«ï¥âáï) |
* ¢à¥¬ï ¢ë¯®«¥¨ï ᪫ ¤ë¢ ¥âáï ¨§ ¢à¥¬¥¨, ã室ï饣® |
ᮡá⢥® à ¡®âã, ¨ ¢à¥¬¥¨ ¯à®áâ®ï ¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï |
(ª®â®à®¥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 18). |
* ç¨ ï á® á«®â 2, à §¬¥é îâáï ®¡ëçë¥ ¯à¨«®¦¥¨ï. |
* ¡ëçë¥ ¯à¨«®¦¥¨ï à §¬¥é îâáï ¢ ¯ ¬ï⨠¯® ¤à¥áã 0x60400000 |
(ª®áâ â ï¤à std_application_base_address). |
«®¦¥¨ï ¥ ¯à®¨á室¨â, ¯®áª®«ìªã ã ª ¦¤®£® ¯à®æ¥áá ᢮ï |
â ¡«¨æ áâà ¨æ. |
* ਠᮧ¤ ¨¨ ¯®â®ª ¥¬ã § ç îâáï ᫮⠢ á¨á⥬®© â ¡«¨æ¥ ¨ |
¨¤¥â¨ä¨ª â®à (Process/Thread IDentifier = PID/TID), ª®â®àë¥ ¤«ï |
§ ¤ ®£® ¯®â®ª ¥ ¨§¬¥ïîâáï á® ¢à¥¬¥¥¬. |
®á«¥ § ¢¥àè¥¨ï ¯®â®ª ¥£® ᫮⠬®¦¥â ¡ëâì § ®¢® ¨á¯®«ì§®¢ |
¤«ï ¤à㣮£® ¯®â®ª . ¤¥â¨ä¨ª â®à ¯®â®ª ¥ ¬®¦¥â ¡ëâì § ç¥ |
¤à㣮¬ã ¯®â®ªã ¤ ¦¥ ¯®á«¥ § ¢¥àè¥¨ï ¯¥à¢®£®. |
§ ç ¥¬ë¥ ®¢ë¬ ¯®â®ª ¬ ¨¤¥â¨ä¨ª â®àë ¬®®â®® à áâãâ. |
* ᫨ ¯®â®ª ¥é¥ ¥ ®¯à¥¤¥«¨« ᢮¥ ®ª® ¢ë§®¢®¬ äãªæ¨¨ 0, â® |
¯®«®¦¥¨¥ ¨ à §¬¥àë í⮣® ®ª ¯®« £ îâáï ã«ï¬¨. |
* ®®à¤¨ âë ª«¨¥â᪮© ®¡« á⨠®ª ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ¤ ë© ¬®¬¥â ¨á¯®«ì§ã¥âáï ⮫쪮 ç áâì ¡ãä¥à à §¬¥à®¬ |
71 = 0x47 ¡ ©â . ¥¬ ¥ ¬¥¥¥ ४®¬¥¤ã¥âáï ¨á¯®«ì§®¢ âì ¡ãä¥à |
à §¬¥à®¬ 1 ¡ ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨, ¢ ¡ã¤ã饬 ¬®£ãâ ¡ëâì |
¤®¡ ¢«¥ë ¥ª®â®àë¥ ¯®«ï. |
====================================================================== |
==================== ãªæ¨ï 10 - ®¦¨¤ âì ᮡëâ¨ï. =================== |
====================================================================== |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , â® ¦¤¥â ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨. |
â ª®¬ á®áâ®ï¨¨ ¯®â®ª ¥ ¯®«ãç ¥â ¯à®æ¥áá®à®£® ¢à¥¬¥¨. |
⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
à ¬¥âàë: |
* eax = 10 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
======= ãªæ¨ï 11 - ¯à®¢¥à¨âì, ¥áâì «¨ ᮡë⨥, ¡¥§ ®¦¨¤ ¨ï. ======= |
====================================================================== |
᫨ ¢ ®ç¥à¥¤¨ á®®¡é¥¨© ¥áâì ª ª®¥-⮠ᮡë⨥, â® áç¨âë¢ ¥â ¨ |
¢®§¢à é ¥â ¥£®. ᫨ ®ç¥à¥¤ì ¯ãáâ , ¢®§¢à é ¥â ã«ì. |
à ¬¥âàë: |
* eax = 11 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ®¦¨¤ ¨ï ¯®ï¢«¥¨ï ᮡëâ¨ï ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
=========== ãªæ¨ï 12 - ç âì/§ ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ========== |
====================================================================== |
-------------- ®¤äãªæ¨ï 1 - ç âì ¯¥à¥à¨á®¢ªã ®ª . --------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------- ®¤äãªæ¨ï 2 - § ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ç « ¯¥à¥à¨á®¢ª¨ 㤠«ï¥â ¢á¥ ®¯à¥¤¥«ñë¥ |
äãªæ¨¥© 8 ª®¯ª¨, ¨å á«¥¤ã¥â ®¯à¥¤¥«¨âì ¯®¢â®à®. |
====================================================================== |
============ ãªæ¨ï 13 - à¨á®¢ âì ¯àאַ㣮«ì¨ª ¢ ®ª¥. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 13 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 梥â 0xRRGGBB ¨«¨ 0x80RRGGBB ¤«ï £à ¤¨¥â®© § «¨¢ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®¤ ª®®à¤¨ â ¬¨ ¯®¨¬ îâáï ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 |
¯àאַ㣮«ì¨ª ®â®á¨â¥«ì® ®ª . |
====================================================================== |
================ ãªæ¨ï 14 - ¯®«ãç¨âì à §¬¥àë íªà . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 14 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [xsize]*65536 + [ysize], £¤¥ |
* xsize = x-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® £®à¨§®â «¨ - 1 |
* ysize = y-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® ¢¥à⨪ «¨ - 1 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 5 äãªæ¨¨ 48 - ¯®«ãç¨âì à §¬¥àë à ¡®ç¥© |
®¡« á⨠íªà . |
====================================================================== |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = è¨à¨ ¨§®¡à ¦¥¨ï |
* edx = ¢ëá®â ¨§®¡à ¦¥¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ®¡ï§ ⥫¥ ¯¥à¥¤ ¢ë§®¢®¬ ¯®¤äãªæ¨© 2 ¨ 5. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 39. |
====================================================================== |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ä®®¢®¬ ¨§®¡à ¦¥¨¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
* edx = 梥â â®çª¨ 0xRRGGBB |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¬¥é¥¨¥ ¤«ï â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª |
(x+y*xsize)*3. |
* ᫨ 㪠§ ®¥ ᬥ饨¥ ¯à¥¢ëè ¥â ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 1 |
à §¬¥à, ¢ë§®¢ ¨£®à¨àã¥âáï. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï â®çª¨ á ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 39. |
====================================================================== |
============ ãªæ¨ï 15, ¯®¤äãªæ¨ï 3 - ¯¥à¥à¨á®¢ âì ä®. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬ ®âà¨á®¢ª¨: |
* 1 = § ¬®áâ¨âì |
* 2 = à áâïãâì |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï ª®¬ ¤ ¯®«ã票ï ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 39. |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 5 - ¯®¬¥áâ¨âì ¡«®ª ¯¨ªá¥«¥© ä®. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* edx = ᬥ饨¥ ¢ ¤ ëå ä®®¢®£® ¨§®¡à ¦¥¨ï |
* esi = à §¬¥à ¤ ëå ¢ ¡ ©â å = 3 * ç¨á«® ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ஢¥àª¨ ª®à४â®áâ¨ á¬¥é¥¨ï ¨ à §¬¥à ¥ ¯à®¨§¢®¤¨âáï. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
* ¬¥é¥¨¥ ¯¨ªá¥«ï á ª®®à¤¨ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
====================================================================== |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 6 ====================== |
==== ¯à®¥æ¨à®¢ âì ¤ ë¥ ä® ¤à¥á®¥ ¯à®áâà á⢮ ¯à®æ¥áá . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¤ ë¥ ä® , 0 ¯à¨ ®è¨¡ª¥ |
¬¥ç ¨ï: |
* ¯à®¥æ¨à®¢ ë¥ ¤ ë¥ ¤®áâã¯ë ç⥨¥ ¨ § ¯¨áì. |
* §¬¥à ¤ ëå ä® à ¢¥ 3*xsize*ysize. §¬¥¥¨¥ à §¬¥à®¢ ä® |
¡«®ª¨àã¥âáï ¢à¥¬ï à ¡®âë á á¯à®¥æ¨à®¢ 묨 ¤ 묨. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â®¢ ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
====================================================================== |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 7 ====================== |
=== ªàëâì ¯à®¥ªæ¨î ¤ ëå ä® ¤à¥á®¥ ¯à®áâà á⢮ ¯à®æ¥áá . == |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä® |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 ¯à¨ ãᯥå¥, 0 ¯à¨ ®è¨¡ª¥ |
====================================================================== |
============= ãªæ¨ï 16 - á®åà ¨âì à ¬¤¨áª ¤¨áª¥âã. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 16 - ®¬¥à äãªæ¨¨ |
* ebx = 1 ¨«¨ ebx = 2 - ª ªãî ¤¨áª¥âã á®åà ïâì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
====================================================================== |
============== ãªæ¨ï 17 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª®¯ª¨. ============= |
====================================================================== |
¡¨à ¥â ª®¤ ¦ ⮩ ª®¯ª¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 17 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ: |
* áâ à訥 24 ¡¨â eax ᮤ¥à¦ â ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
(¢ ç áâ®áâ¨, ¢ ah ®ª §ë¢ ¥âáï ¬« ¤è¨© ¡ ©â ¨¤¥â¨ä¨ª â®à ; |
¥á«¨ ¢á¥ ª®¯ª¨ ¨¬¥îâ ¨¤¥â¨ä¨ª â®à, ¬¥ì訩 256, |
â® ¤«ï à §«¨ç¥¨ï ¤®áâ â®ç® ah) |
* al = 0 - ª®¯ª ¡ë« ¦ â «¥¢®© ª®¯ª®© ¬ëè¨ |
* al = ¡¨â, ᮮ⢥âáâ¢ãî騩 ¦ ¢è¥© ª®¯ª¥ ¬ëè¨, ¥á«¨ ¥ «¥¢®© |
¬¥ç ¨ï: |
* "ãä¥à" åà ¨â ⮫쪮 ®¤ã ª®¯ªã, ¯à¨ ¦ ⨨ ®¢®© ª®¯ª¨ |
¨ä®à¬ æ¨ï ® áâ ன â¥àï¥âáï. |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
¢®§¢à é ¥âáï ®â¢¥â "¡ãä¥à ¯ãáâ". |
* ®§¢à é ¥¬®¥ § 票¥ al ᮮ⢥âáâ¢ã¥â á®áâ®ï¨î ª®¯®ª ¬ëè¨ |
¢ ä®à¬ ⥠¯®¤äãªæ¨¨ 2 äãªæ¨¨ 37 ¢ ¬®¬¥â ç « ¦ â¨ï |
ª®¯ªã, § ¨áª«î票¥¬ ¬« ¤è¥£® ¡¨â (ᮮ⢥âáâ¢ãî饣® «¥¢®© |
ª®¯ª¥ ¬ëè¨), ª®â®àë© á¡à áë¢ ¥âáï. |
====================================================================== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 2 - § ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® á«®âã. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯à®æ¥áá /¯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 18 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª á § ¤ ë¬ ¨¤¥â¨ä¨ª â®à®¬. |
====================================================================== |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 3 - ᤥ« âì ªâ¨¢ë¬ ®ª® § ¤ ®£® ¯®â®ª . = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ਠ㪠§ ¨¨ ª®à४⮣®, ® ¥áãé¥áâ¢ãî饣® ᫮⠪⨢¨§¨àã¥âáï |
ª ª®¥-â® ®ª®. |
* § âì, ª ª®¥ ®ª® ï¥âáï ªâ¨¢ë¬, ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7. |
====================================================================== |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì áçñâ稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã. |
====================================================================== |
®¤ ¯ãáâ묨 ⠪⠬¨ ¯®¨¬ ¥âáï ¢à¥¬ï, ¢ ª®â®à®¥ ¯à®æ¥áá®à ¯à®áâ ¨¢ ¥â |
¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï (¢ ¨áâàãªæ¨¨ hlt). |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § 票¥ áçñâ稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã |
====================================================================== |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ⠪⮢ãî ç áâ®âã. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⠪⮢ ï ç áâ®â (¯® ¬®¤ã«î 2^32 ⠪⮢ = 4æ) |
====================================================================== |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 6 - á®åà ¨âì à ¬¤¨áª ¢ ä ©« ¦ñá⪮¬ ¤¨áª¥. |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì áâபã á ¯®«ë¬ ¨¬¥¥¬ ä ©« |
( ¯à¨¬¥à, "/hd0/1/kolibri/kolibri.img") |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* ¨ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* ᥠ¯ ¯ª¨ ¢ 㪠§ ®¬ ¯ã⨠¤®«¦ë áãé¥á⢮¢ âì, ¨ ç¥ ¢¥àñâáï |
§ 票¥ 5, "ä ©« ¥ ©¤¥". |
====================================================================== |
====== ãªæ¨ï 18, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ®¬¥à ªâ¨¢®£® ®ª . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ªâ¨¢®£® ®ª (®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® |
ªâ¨¢®) |
¬¥ç ¨ï: |
* ªâ¨¢®¥ ®ª® 室¨âáï ¢¢¥àåã ®ª®®£® áâíª ¨ ¯®«ãç ¥â |
á®®¡é¥¨ï ®¡® ¢áñ¬ ¢¢®¤¥ á ª« ¢¨ âãàë. |
* ¤¥« âì ®ª® ªâ¨¢ë¬ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3. |
====================================================================== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 8 - ®âª«îç¨âì/à §à¥è¨âì §¢ãª ᯨª¥à . ==== |
====================================================================== |
ਠ®âª«îçñ®¬ §¢ãª¥ ¢ë§®¢ë ¯®¤äãªæ¨¨ 55 äãªæ¨¨ 55 ¨£®à¨àãîâáï. |
ਠ¢ª«îçñ®¬ - ¯à ¢«ïîâáï ¢áâà®¥ë© á¯¨ª¥à. |
--------------- ®¤¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥. ---------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - §¢ãª ᯨª¥à à §à¥èñ; 1 - § ¯à¥éñ |
-------------- ®¤¯®¤äãªæ¨ï 2 - ¯¥à¥ª«îç¨âì á®áâ®ï¨¥. -------------- |
¥à¥ª«îç ¥â á®áâ®ï¨ï à §à¥è¥¨ï/§ ¯à¥é¥¨ï. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 9 - § ¢¥à襨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬. = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¯ à ¬¥âà: |
* 2 = ¢ëª«îç¨âì ª®¬¯ìîâ¥à |
* 3 = ¯¥à¥§ £à㧨âì ª®¬¯ìîâ¥à |
* 4 = ¯¥à¥§ ¯ãáâ¨âì ï¤à® ¨§ ä ©« kernel.mnt à ¬¤¨áª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* ¯à¨ ¥¢¥à®¬ ecx ॣ¨áâàë ¥ ¬¥ïîâáï (â.¥. eax=18) |
* ¯à¨ ¯à ¢¨«ì®¬ ¢ë§®¢¥ ¢á¥£¤ ¢®§¢à é ¥âáï ¯à¨§ ª ãᯥå eax=0 |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¯à¨ ¥¢¥à®¬ |
¢ë§®¢¥, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¯®á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
====================================================================== |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 10 - ᢥàãâì ®ª® ¯à¨«®¦¥¨ï. ======= |
====================================================================== |
¢®à 稢 ¥â ᮡá⢥®¥ ®ª®. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¨¨¬¨§¨à®¢ ®¥ ®ª® á â®çª¨ §à¥¨ï äãªæ¨¨ 9 á®åà ï¥â ¯®«®¦¥¨¥ |
¨ à §¬¥àë. |
* ®ááâ ®¢«¥¨¥ ®ª ¯à¨«®¦¥¨ï ¯à®¨á室¨â ¯à¨ ªâ¨¢¨§¨à®¢ ¨¨ |
¯®¤äãªæ¨¥© 3. |
* ¡ëç® ¥â ¥®¡å®¤¨¬®á⨠ ᢮à 稢 âì/à §¢®à 稢 âì ᢮ñ ®ª®: |
᢮à 稢 ¨¥ ®ª ®áãé¥á⢫ï¥âáï á¨á⥬®© ¯à¨ ¦ ⨨ ª®¯ªã |
¬¨¨¬¨§ 樨 (ª®â®à ï ¤«ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥âáï ¢â®¬ â¨ç¥áª¨ |
äãªæ¨¥© 0, ¤«ï ®ª® ¡¥§ ᪨ ¥ñ ¬®¦® ®¯à¥¤¥«¨âì äãªæ¨¥© 8), |
¢®ááâ ®¢«¥¨¥ - ¯à¨«®¦¥¨¥¬ @panel. |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 11 ===================== |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ¤¨áª®¢®© ¯®¤á¨á⥬¥. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ â ¡«¨æë: |
* 1 = ª®à®âª ï ¢¥àá¨ï, 10 ¡ ©â |
* 2 = ¯®« ï ¢¥àá¨ï, 65536 ¡ ©â |
* edx = 㪠§ â¥«ì ¡ãä¥à (¢ ¯à¨«®¦¥¨¨) ¤«ï â ¡«¨æë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë: ª®à®âª ï ¢¥àá¨ï: |
* +0: byte: ¨ä®à¬ æ¨ï ® (¤¨áª®¢®¤ å ¤«ï ¤¨áª¥â), AAAABBBB, |
£¤¥ AAAA § ¤ ñâ ⨯ ¯¥à¢®£® ¤¨áª®¢®¤ , BBBB - ¢â®à®£® ᮣ« á® |
á«¥¤ãî饬ã ᯨáªã: |
* 0 = ¥â ¤¨áª®¢®¤ |
* 1 = 360Kb, 5.25'' |
* 2 = 1.2Mb, 5.25'' |
* 3 = 720Kb, 3.5'' |
* 4 = 1.44Mb, 3.5'' |
* 5 = 2.88Mb, 3.5'' (â ª¨¥ ¤¨áª¥âë ᥩç á 㦥 ¥ ¨á¯®«ì§ãîâáï) |
¯à¨¬¥à, ¤«ï áâ ¤ à⮩ ª®ä¨£ãà 樨 ¨§ ®¤®£® 1.44-¤¨áª®¢®¤ |
§¤¥áì ¡ã¤¥â 40h, ¤«ï á«ãç ï 1.2Mb A: ¨ 1.44Mb B: |
§ 票¥ ®ª §ë¢ ¥âáï 24h. |
* +1: byte: ¨ä®à¬ æ¨ï ® ¦ñáâª¨å ¤¨áª å ¨ CD-¯à¨¢®¤ å, AABBCCDD, |
£¤¥ AA ᮮ⢥âáâ¢ã¥â ª®â஫«¥àã IDE0, ..., DD - IDE3: |
* 0 = ãáâனá⢮ ®âáãâáâ¢ã¥â |
* 1 = ¦ñá⪨© ¤¨áª |
* 2 = CD-¯à¨¢®¤ |
¯à¨¬¥à, ¢ á«ãç ¥ HD IDE0 ¨ CD IDE2 §¤¥áì ¡ã¤¥â 48h. |
* +2: 4 db: ç¨á«® ©¤¥ëå à §¤¥«®¢ ¦ñáâª¨å ¤¨áª å á |
ᮮ⢥âá⢥® IDE0,...,IDE3. |
ਠ®âáãâá⢨¨ ¦ñá⪮£® ¤¨áª IDEx ᮮ⢥âáâ¢ãî騩 ¡ ©â |
ã«¥¢®©, ¯à¨ «¨ç¨¨ ¯®ª §ë¢ ¥â ç¨á«® à ᯮ§ ëå à §¤¥«®¢, |
ª®â®àëå ¬®¦¥â ¨ ¥ ¡ëâì (¥á«¨ ®á¨â¥«ì ¥ ®âä®à¬ â¨à®¢ ¨«¨ |
¥á«¨ ä ©«®¢ ï á¨á⥬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï). ⥪ã饩 ¢¥àᨨ ï¤à |
¤«ï ¦ñáâª¨å ¤¨áª®¢ ¯®¤¤¥à¦¨¢ îâáï ⮫쪮 FAT16, FAT32 ¨ NTFS. |
* +6: 4 db: § १¥à¢¨à®¢ ® |
®à¬ â â ¡«¨æë: ¯®« ï ¢¥àá¨ï: |
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ |
* +10: 100 db: ¤ ë¥ ¤«ï ¯¥à¢®£® à §¤¥« |
* +110: 100 db: ¤ ë¥ ¤«ï ¢â®à®£® à §¤¥« |
* ... |
* +10+100*(n-1): 100 db: ¤ ë¥ ¤«ï ¯®á«¥¤¥£® à §¤¥« |
§¤¥«ë à ᯮ«®¦¥ë ¢ á«¥¤ãî饬 ¯®à浪¥: á ç « ¯®á«¥¤®¢ â¥«ì® ¢á¥ |
à ᯮ§ ë¥ à §¤¥«ë HD IDE0 (¥á«¨ ¥áâì), |
§ ⥬ HD IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3. |
®à¬ â ¨ä®à¬ 樨 ® à §¤¥«¥: |
* +0: dword: ç «ìë© ä¨§¨ç¥áª¨© ᥪâ®à à §¤¥« |
* +4: dword: ¯®á«¥¤¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« |
(¯à¨ ¤«¥¦¨â à §¤¥«ã) |
* +8: byte: ⨯ ä ©«®¢®© á¨á⥬ë: |
16=FAT16, 32=FAT32, 1=NTFS |
* ä®à¬ â ¤ «ì¥©è¨å ¤ ëå § ¢¨á¨â ®â ä ©«®¢®© á¨á⥬ë, |
¬®¦¥â ¬¥ïâìáï á ¨§¬¥¥¨ï¬¨ ¢ ï¤à¥ ¨ ¯®í⮬㠥 ®¯¨áë¢ ¥âáï |
¬¥ç ¨ï: |
* ®à®âª ï â ¡«¨æ ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ¤«ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 |
®¡ ¨¬¥îé¨åáï ãáâனá⢠å. |
====================================================================== |
========== ãªæ¨ï 18, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì ¢¥àá¨î ï¤à . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à (¥ ¬¥¥¥ 16 ¡ ©â), ªã¤ ¡ã¤¥â ¯®¬¥é¥ |
¨ä®à¬ æ¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
âàãªâãà ¡ãä¥à : |
db a,b,c,d ¤«ï ¢¥àᨨ a.b.c.d |
db UID_xxx: ®¤® ¨§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
dd REV - ®¬¥à svn-ॢ¨§¨¨ ï¤à |
«ï ï¤à Kolibri 0.7.1.0: |
db 0,7,1,0 |
db 2 |
dd 638 |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 14 ===================== |
======= ¦¨¤ âì ç « ®¡à ⮣® 室 «ãç à §¢ñà⪨ ¬®¨â®à . ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
¬¥ç ¨ï: |
* ãªæ¨ï ¯à¥¤ § ç¥ ¨áª«îç¨â¥«ì® ¤«ï ªâ¨¢ëå |
¢ë᮪®¯à®¨§¢®¤¨â¥«ìëå £à ä¨ç¥áª¨å ¯à¨«®¦¥¨©; ¨á¯®«ì§ã¥âáï ¤«ï |
¯« ¢®£® ¢ë¢®¤ £à 䨪¨. |
====================================================================== |
== ãªæ¨ï 18, ¯®¤äãªæ¨ï 15 - ¯®¬¥áâ¨âì ªãàá®à ¬ëè¨ ¢ æ¥âà íªà . = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 16 ===================== |
============ ®«ãç¨âì à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 16 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¬¥à ᢮¡®¤®© ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 17 ===================== |
============ ®«ãç¨âì à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 18 ===================== |
============= ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® ¨¤¥â¨ä¨ª â®àã. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 18 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª (PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡ª (¯à®æ¥áá ¥ ©¤¥ ¨«¨ ï¥âáï á¨á⥬ë¬) |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 2 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª ¯® § ¤ ®¬ã á«®âã. |
====================================================================== |
=== ãªæ¨ï 18, ¯®¤äãªæ¨ï 19 - ¯®«ãç¨âì/ãáâ ®¢¨âì áâனª¨ ¬ëè¨. == |
====================================================================== |
------------- ®¤¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ᪮à®áâì ¬ëè¨. -------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï ᪮à®áâì ¬ëè¨ |
------------ ®¤¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ᪮à®áâì ¬ëè¨. ------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ®¢®¥ § 票¥ ᪮à®á⨠|
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------- ®¤¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì § ¤¥à¦ªã ¬ëè¨. -------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï § ¤¥à¦ª ¬ëè¨ |
------------ ®¤¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì § ¤¥à¦ªã ¬ëè¨. ------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 3 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ®¢®¥ § 票¥ § ¤¥à¦ª¨ ¬ëè¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
-------- ®¤¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ¯®«®¦¥¨¥ ªãàá®à ¬ëè¨. -------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 4 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------- ®¤¯®¤äãªæ¨ï 5 - ᨬ㫨஢ âì á®áâ®ï¨¥ ª« ¢¨è ¬ëè¨. -------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 5 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ¨ä®à¬ æ¨ï ® í¬ã«¨à㥬®¬ á®áâ®ï¨¨ ª®¯®ª ¬ëè¨: |
(ᮮ⢥âáâ¢ã¥â ¢®§¢à é ¥¬®¬ã § ç¥¨î ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 37) |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â |
* ¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â |
* ¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥ª®¬¥¤ã¥¬ ï ᪮à®áâì ¬ëè¨ (¢ ¯®¤¯®¤äãªæ¨¨ 1) ®â 1 ¤® 9. |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à , ¯®í⮬ã |
¨á¯®«ì§ã©â¥ ®áâ®à®¦®, ¯à¨ ¥ª®à४⮬ § 票¨ ªãàá®à ¬®¦¥â |
"§ ¬ñà§ãâì". ª®à®áâì ¬ëè¨ ¬®¦® ॣ㫨஢ âì ¢ ¯à¨«®¦¥¨¨ SETUP. |
* ¥ª®¬¥¤ã¥¬ ï ¢¥«¨ç¨ § ¤¥à¦ª¨ (¢ ¯®¤¯®¤äãªæ¨¨ 3) = 10. |
¥ì訥 § ç¥¨ï ¥ ®¡à ¡ âë¢ îâáï COM-¬ëè ¬¨. ਠ®ç¥ì ¡®«ìè¨å |
§ 票ïå ¥¢®§¬®¦® ¯¥à¥¤¢¨¦¥¨¥ ¬ëè¨ 1 ¯¨ªá¥«ì ¨ ªãàá®à ¡ã¤¥â |
¯àë£ âì ¢¥«¨ç¨ã ãáâ ®¢«¥®© ᪮à®á⨠(¯®¤¯®¤äãªæ¨ï 1). |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à . |
¥«¨ç¨ã § ¤¥à¦ª¨ ¬®¦® ¬¥ïâì ¢ ¯à¨«®¦¥¨¨ SETUP. |
* ®¤¯®¤äãªæ¨ï 4 ¥ ¯à®¢¥àï¥â ¯¥à¥¤ ®¥ § 票¥. ¥à¥¤ ¢ë§®¢®¬ |
¥®¡å®¤¨¬® 㧠âì ⥪ã饥 à §à¥è¥¨¥ íªà (¯®¤äãªæ¨¥© 14) |
¨ ¯à®¢¥à¨âì, çâ® ãáâ ¢«¨¢ ¥¬®¥ ¯®«®¦¥¨¥ ¥ ¢ë室¨â § ¯à¥¤¥«ë |
íªà . |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 20 ===================== |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ®¡ ®¯¥à ⨢®© ¯ ¬ïâ¨. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 20 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¨ä®à¬ 樨 (36 ¡ ©â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ï⨠¢ ¡ ©â å |
¨«¨ -1 ¢ á«ãç ¥ ®è¨¡ª¨ |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ï⨠¢ áâà ¨æ å |
* +4: dword: à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ï⨠¢ áâà ¨æ å |
* +8: dword: ç¨á«® áâà ¨çëå ®è¨¡®ª (¨áª«î票© #PF) |
¢ ¯à¨«®¦¥¨ïå |
* +12: dword: à §¬¥à ªãç¨ ï¤à ¢ ¡ ©â å |
* +16: dword: à §¬¥à ᢮¡®¤®© ¯ ¬ï⨠¢ ªãç¥ ï¤à ¢ ¡ ©â å |
* +20: dword: ®¡é¥¥ ª®«¨ç¥á⢮ ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à |
* +24: dword: ª®«¨ç¥á⢮ ᢮¡®¤ëå ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à |
* +28: dword: à §¬¥à ¨¡®«ì襣® ᢮¡®¤®£® ¡«®ª ¢ ªãç¥ ï¤à |
(§ १¥à¢¨à®¢ ®) |
* +32: dword: à §¬¥à ¨¡®«ì襣® ¢ë¤¥«¥®£® ¡«®ª ¢ ªãç¥ ï¤à |
(§ १¥à¢¨à®¢ ®) |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 21 ===================== |
======= ®«ãç¨âì ®¬¥à ᫮⠯à®æ¥áá /¯®â®ª ¯® ¨¤¥â¨ä¨ª â®àã. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 21 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª (PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®è¨¡ª (¥¢¥àë© ¨¤¥â¨ä¨ª â®à) |
* ¨ ç¥ eax = ®¬¥à á«®â |
====================================================================== |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 22 - ®¯¥à 樨 á ®ª®¬ ¤à㣮£® ¯à®æ¥áá /¯®â®ª . |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 22 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ ®¯¥à 樨: |
* 0 = ¬¨¨¬¨§ æ¨ï ®ª , ¯®â®ª § ¤ ®¬¥à®¬ á«®â |
* 1 = ¬¨¨¬¨§ æ¨ï ®ª , ¯®â®ª § ¤ ¨¤¥â¨ä¨ª â®à®¬ |
* 2 = ¢®ááâ ®¢«¥¨¥ ®ª , ¯®â®ª § ¤ ®¬¥à®¬ á«®â |
* 3 = ¢®ááâ ®¢«¥¨¥ ®ª , ¯®â®ª § ¤ ¨¤¥â¨ä¨ª â®à®¬ |
* edx = ¯ à ¬¥âà ®¯¥à 樨 (®¬¥à ᫮⠨«¨ PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡ª (¥¯à ¢¨«ìë© ¯ à ¬¥âà) |
¬¥ç ¨ï: |
* ®â®ª ¬®¦¥â ᢥàãâì ᢮ñ ®ª® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 10. |
* ®ááâ ®¢«¥¨¥ ®ª á ®¤®¢à¥¬¥®© ªâ¨¢¨§ 樥© ®áãé¥á⢫ï¥âáï |
¯®¤äãªæ¨¨ 3 (¯à¨¨¬ î饩 ®¬¥à á«®â ). |
====================================================================== |
==================== ãªæ¨ï 20 - ¨â¥à䥩á MIDI. ==================== |
====================================================================== |
------------------------ ®¤äãªæ¨ï 1 - á¡à®á ------------------------ |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
-------------------- ®¤äãªæ¨ï 2 - ¢ë¢¥á⨠¡ ©â --------------------- |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤«ï ¢ë¢®¤ |
®§¢à é ¥¬®¥ § 票¥ (®¤¨ ª®¢® ¤«ï ®¡¥¨å ¯®¤äãªæ¨©): |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«ñ ¡ §®¢ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ®¯à¥¤¥«ñ ¡ §®¢ë© ¯®à⠢맮¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
==== ãªæ¨ï 21, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ¡ §®¢®£® ¯®àâ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡®çë© ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* ®¬¥à ¯®àâ ¤®«¦¥ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF. |
* áâ ®¢ª ¡ §ë 㦠¤«ï à ¡®âë äãªæ¨¨ 20. |
* ®«ãç¨âì ãáâ ®¢«¥ë© ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 26. |
====================================================================== |
===== ãªæ¨ï 21, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ==== |
====================================================================== |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ãáâ ¢«¨¢ âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ ⥫ì à ᪫ ¤ªã - â ¡«¨æã ¤«¨®© 128 ¡ ©â |
Ǭ: |
* ecx = 9 |
* dx = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® |
¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* ®«ãç¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 26. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã. |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¡ §ã CD. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã CD ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 26. |
====================================================================== |
========= ãªæ¨ï 21, ¯®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ï§ëª á¨á⥬ë. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï, ¯®áª®«ìªã ï¤à® íâã |
¯¥à¥¬¥ãî ¥ ¨á¯®«ì§ã¥â. |
* ®«ãç¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 26. |
====================================================================== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 7 - ãáâ ®¢¨âì ¡ §ã HD. =========== |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì ¡ §ã, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 26. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 8. |
====================================================================== |
========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì à §¤¥« HD. ========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = à §¤¥« HD (áç¨â ï á 1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì à §¤¥«, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ë© à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 |
äãªæ¨¨ 26. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 7. |
====================================================================== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 11 ===================== |
=========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 11 äãªæ¨¨ 26. |
====================================================================== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 12 ===================== |
========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 12 äãªæ¨¨ 26. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 1 ============= |
==== ¨æ¨ «¨§¨à®¢ âì + ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤à ©¢¥à¥ vmode.mdr. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 512 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¤à ©¢¥à ¥ § £à㦥 (¨ª®£¤ ¥ ¡ë¢ ¥â ¢ ⥪ã饩 ॠ«¨§ 樨): |
* eax = -1 |
* ebx, ecx à §àãè îâáï |
* ¥á«¨ ¤à ©¢¥à § £à㦥: |
* eax = 'MDAZ' (¢ á⨫¥ fasm' , â.¥. 'M' - ¬« ¤è¨© ¡ ©â, |
'Z' - áâ à訩) - ᨣ âãà |
* ebx = ⥪ãé ï ç áâ®â à §¢ñà⪨ (¢ æ) |
* ecx à §àãè ¥âáï |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â edx, § ¯®«¥ |
®à¬ â ¡ãä¥à : |
* +0: 32*byte: ¨¬ï ¤à ©¢¥à , "Trans VideoDriver" (¡¥§ ª ¢ë祪, |
¤®¯®«¥® ¯à®¡¥« ¬¨) |
* +32 = +0x20: dword: ¢¥àá¨ï ¤à ©¢¥à (¢¥àá¨ï x.y ª®¤¨àã¥âáï ª ª |
y*65536+x), ¤«ï ⥪ã饩 ॠ«¨§ 樨 1 (1.0) |
* +36 = +0x24: 7*dword: § १¥à¢¨à®¢ ® (0 ¢ ⥪ã饩 ॠ«¨§ 樨) |
* +64 = +0x40: 32*word: ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ¢¨¤¥®à¥¦¨¬®¢ (ª ¦¤®¥ |
á«®¢® - ®¬¥à ¢¨¤¥®à¥¦¨¬ , ¯®á«¥ ᮡá⢥® ᯨ᪠¨¤ãâ 㫨) |
* +128 = +0x80: 32*(5*word): ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â à §¢ñà⮪ |
¤«ï ¢¨¤¥®à¥¦¨¬®¢: ¤«ï ª ¦¤®£® ¢¨¤¥®à¥¦¨¬ , 㪠§ ®£® ¢ ¯à¥¤ë¤ã饬 |
¯®«¥, 㪠§ ® ¤® 5 ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â |
(¢ ¥¨á¯®«ì§ã¥¬ëå ¯®§¨æ¨ïå § ¯¨á ë 㫨) |
¬¥ç ¨ï: |
* ãªæ¨ï ¨¨æ¨ «¨§¨àã¥â ¤à ©¢¥à (¥á«¨ ® ¥éñ ¥ ¨¨æ¨ «¨§¨à®¢ ) |
¨ ¤®«¦ ¢ë§ë¢ âìáï ¯¥à¢®©, ¯¥à¥¤ ®áâ «ì묨 (¨ ç¥ ®¨ ¡ã¤ãâ |
¢®§¢à é âì -1, ¨ç¥£® ¥ ¤¥« ï). |
* ⥪ã饩 ॠ«¨§ 樨 ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ®¤ ç áâ®â à §¢ñà⪨ |
¢¨¤¥®à¥¦¨¬. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 2 ============= |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¢¨¤¥®à¥¦¨¬¥. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ ; |
ebx,ecx à §àãè îâáï |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
* ebx = ç áâ®â ¢¥à⨪ «ì®© à §¢ñà⪨ (¢ æ) |
* ecx = ®¬¥à ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ᫨ ã¦ë ⮫쪮 à §¬¥àë íªà , 楫¥á®®¡à §¥© ¨á¯®«ì§®¢ âì |
äãªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ® ¢®§¢à é ¥â à §¬¥àë 1 ¬¥ìè¥. |
====================================================================== |
= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¢¨¤¥®à¥¦¨¬. |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 3 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = [ç áâ®â à §¢ñà⪨]*65536 + [®¬¥à ¢¨¤¥®à¥¦¨¬ ] |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥, ¥ ¨¨æ¨ «¨§¨à®¢ ¨«¨ |
¯à®¨§®è« ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ®¬¥à ¢¨¤¥®à¥¦¨¬ ¨ ç áâ®â ¤®«¦ë ¡ëâì ¢ â ¡«¨æ¥, ¢®§¢à é ¥¬®© |
äãªæ¨¥© ¤à ©¢¥à 1. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 4 ============= |
================= ¥àãâìáï ª ç «ì®¬ã ¢¨¤¥®à¥¦¨¬ã. ================ |
====================================================================== |
®§¢à é ¥â íªà ¢ ¢¨¤¥®à¥¦¨¬, ãáâ ®¢«¥ë© ¯à¨ § £à㧪¥ á¨á⥬ë. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 4 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 5 ============= |
======== ¢¥«¨ç¨âì/㬥ìè¨âì à §¬¥à ¢¨¤¨¬®© ®¡« á⨠¬®¨â®à . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 5 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 0/1 - 㬥ìè¨âì/㢥«¨ç¨âì à §¬¥à ¯® £®à¨§®â «¨ |
®¤ã ¯®§¨æ¨î |
* edx = 2/3 - ¢ ⥪ã饩 ॠ«¨§ 樨 ¥ ¯®¤¤¥à¦¨¢ ¥âáï; ¯« ¨àã¥âáï |
ª ª 㬥ì襨¥/㢥«¨ç¥¨¥ à §¬¥à ¯® ¢¥à⨪ «¨ ®¤ã ¯®§¨æ¨î |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ãªæ¨ï ¢«¨ï¥â ⮫쪮 䨧¨ç¥áª¨© à §¬¥à ¨§®¡à ¦¥¨ï |
¬®¨â®à¥; «®£¨ç¥áª¨© à §¬¥à (ç¨á«® ¯¨ªá¥«¥©) ¥ ¬¥ï¥âáï. |
====================================================================== |
============ ãªæ¨ï 22 - ãáâ ®¢¨âì á¨á⥬ãî ¤ âã/¢à¥¬ï. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 22 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ãáâ ®¢¨âì ¢à¥¬ï |
* ecx = 0x00SSMMHH - ¢à¥¬ï ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* HH=ç á 00..23 |
* MM=¬¨ãâ 00..59 |
* SS=ᥪ㤠00..59 |
* ebx = 1 - ãáâ ®¢¨âì ¤ âã |
* ecx = 0x00DDMMYY - ¤ â ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* DD=¤¥ì 01..31 |
* MM=¬¥áïæ 01..12 |
* YY=£®¤ 00..99 |
* ebx = 2 - ãáâ ®¢¨âì ¤¥ì ¥¤¥«¨ |
* ecx = 1 ¤«ï ¢®áªà¥á¥ìï, ..., 7 ¤«ï áã¡¡®âë |
* ebx = 3 - ãáâ ®¢¨âì ¡ã¤¨«ì¨ª |
* ecx = 0x00SSMMHH |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
* eax = 2 - CMOS-¡ â ३ª¨ à §à廊«¨áì |
¬¥ç ¨ï: |
* ¥®áâì ãáâ ®¢ª¨ ¤ï ¥¤¥«¨ ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©, |
¯®áª®«ìªã ® ¬ «® £¤¥ ¨á¯®«ì§ã¥âáï |
(¤¥ì ¥¤¥«¨ ¬®¦® à ááç¨â âì ¯® ¤ â¥). |
* 㤨«ì¨ª ¬®¦® ãáâ ®¢¨âì áà ¡ âë¢ ¨¥ ¢ § ¤ ®¥ ¢à¥¬ï |
ª ¦¤ë¥ áã⪨. ਠí⮬ ®âª«îç¨âì ¥£® áãé¥áâ¢ãî騬¨ á¨á⥬묨 |
äãªæ¨ï¬¨ ¥«ì§ï. |
* à ¡ âë¢ ¨¥ ¡ã¤¨«ì¨ª § ª«îç ¥âáï ¢ £¥¥à 樨 IRQ8. |
* ®®¡é¥-â® CMOS ¯®¤¤¥à¦¨¢ ¥â ¤«ï ¡ã¤¨«ì¨ª ãáâ ®¢ªã § 票ï |
0xFF ¢ ª ç¥á⢥ ®¤®£® ¨§ ¯ à ¬¥â஢ ¨ ®§ ç ¥â íâ®, çâ® |
ᮮ⢥âáâ¢ãî騩 ¯ à ¬¥âà ¨£®à¨àã¥âáï. ® ¢ ⥪ã饩 ॠ«¨§ 樨 |
íâ® ¥ ¯à®©¤ñâ (¢¥àñâáï § 票¥ 1). |
* 㤨«ì¨ª - £«®¡ «ìë© á¨áâ¥¬ë© à¥áãàá; ãáâ ®¢ª ¡ã¤¨«ì¨ª |
¢â®¬ â¨ç¥áª¨ ®â¬¥ï¥â ¯à¥¤ë¤ãéãî ãáâ ®¢ªã. ¯à®ç¥¬, ¤ ë© |
¬®¬¥â ¨ ®¤ ¯à®£à ¬¬ ¥£® ¥ ¨á¯®«ì§ã¥â. |
====================================================================== |
============== ãªæ¨ï 23 - ®¦¨¤ âì ᮡëâ¨ï á â ©¬ ã⮬. ============= |
====================================================================== |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , ¦¤ñâ ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨, |
® ¥ ¡®«¥¥ 㪠§ ®£® ¢à¥¬¥¨. ⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
à ¬¥âàë: |
* eax = 23 - ®¬¥à äãªæ¨¨ |
* ebx = â ©¬ ãâ (¢ á®âëå ¤®«ïå ᥪã¤ë) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ᪮«ì 㣮¤® ¤®«£®, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
* ¥à¥¤ ç ebx=0 ¯à¨¢®¤¨â ª ¬®¬¥â «ì®¬ã ¢®§¢à 饨î eax=0. |
* ਠ⥪ã饩 ॠ«¨§ 樨 ¯à®¨§®©¤ñâ ¥¬¥¤«¥ë© ¢®§¢à â ¨§ äãªæ¨¨ |
á eax=0, ¥á«¨ á«®¦¥¨¥ ebx á ⥪ã騬 § 票¥¬ áçñâ稪 ¢à¥¬¥¨ |
¢ë§®¢¥â 32-¡¨â®¥ ¯¥à¥¯®«¥¨¥. |
====================================================================== |
======= ãªæ¨ï 24, ¯®¤äãªæ¨ï 1 - ç âì ¯à®¨£àë¢ âì CD-audio. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0x00FRSSMM, £¤¥ |
* MM = ç «ì ï ¬¨ãâ |
* SS = ç «ì ï ᥪ㤠|
* FR = ç «ìë© ä३¬ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ᥪ㤥 75 ä३¬®¢, ¢ ¬¨ã⥠60 ᥪã¤. |
* ãªæ¨ï á¨åà® (¢®§¢à é ¥â ã¯à ¢«¥¨¥, ª®£¤ ç «®áì |
¯à®¨£àë¢ ¨¥). |
====================================================================== |
===== ãªæ¨ï 24, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤®à®¦ª å. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï â ¡«¨æë |
(¬ ªá¨¬ã¬ 8*64h+4 ¡ ©â=100 ¤®à®¦¥ª) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ®à¬ â â ¡«¨æë á ¨ä®à¬ 樥© ® ¤®à®¦ª å â ª®© ¦¥, ª ª ¨ ¤«ï |
ATAPI-CD ª®¬ ¤ë 43h (READ TOC), ®¡ë箩 â ¡«¨æë (¯®¤ª®¬ ¤ 00h). |
¤à¥á ¢®§¢à é îâáï ¢ ä®à¬ ⥠MSF. |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ãªæ¨ï ¢®§¢à é ¥â ¨ä®à¬ æ¨î ⮫쪮 ® ¥ ¡®«¥¥ 祬 100 |
¯¥à¢ëå ¤®à®¦ª å. ¡®«ìè¨á⢥ á«ãç ¥¢ í⮣® ¤®áâ â®ç®. |
====================================================================== |
==== ãªæ¨ï 24, ¯®¤äãªæ¨ï 3 - ®áâ ®¢¨âì ¯à®¨£àë¢ ¥¬®¥ CD-audio. === |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
======= ãªæ¨ï 24, ¯®¤äãªæ¨ï 4 - ¨§¢«¥çì «®â®ª ¯à¨¢®¤ ¤¨áª . ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à CD/DVD-¤¨áª |
(®â 0=Primary Master ¤® 3=Secondary Slave) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD). |
* ਠ¨§¢«¥ç¥¨¨ «®âª ¯à®¨§¢®¤¨âáï à §¡«®ª¨à®¢ª àã箣® ã¯à ¢«¥¨ï |
¬¥å ¨§¬®¬ «®âª . |
* ਠ¨§¢«¥ç¥¨¨ «®âª ª®¤ ¯à®¨§¢®¤¨â ®ç¨áâªã ªíè ᮮ⢥âáâ¢ãî饣® |
ãáâனá⢠. |
* ਬ¥à®¬ ¨á¯®«ì§®¢ ¨ï äãªæ¨¨ ï¥âáï ¯à¨«®¦¥¨¥ CD_tray. |
====================================================================== |
====== ãªæ¨ï 24, ¯®¤äãªæ¨ï 5 - § £à㧨âì «®â®ª ¯à¨¢®¤ ¤¨áª . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à CD/DVD-¤¨áª |
(®â 0=Primary Master ¤® 3=Secondary Slave) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD). |
* ਬ¥à®¬ ¨á¯®«ì§®¢ ¨ï äãªæ¨¨ ï¥âáï ¯à¨«®¦¥¨¥ CD_tray. |
====================================================================== |
===== ãªæ¨ï 26, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* áâ ®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
====== ãªæ¨ï 26, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ===== |
====================================================================== |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ¯®«ãç âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ â¥«ì ¡ãä¥à ¤«¨®© 128 ¡ ©â, ªã¤ ¡ã¤¥â ᪮¯¨à®¢ |
à ᪫ ¤ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
Ǭ: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 9 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® ¨á¯®«ì§ã¥âáï |
à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* áâ ®¢¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 21. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã |
(¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì ¡ §ã CD. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* áâ ®¢¨âì ¡ §ã CD ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ï§ëª á¨á⥬ë. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã (¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* áâ ®¢¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 21. |
====================================================================== |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============ |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* áâ ®¢¨âì ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 21. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 8. |
====================================================================== |
=========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 8 - ¯®«ãç¨âì à §¤¥« HD. =========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¤¥« HD (áç¨â ï á 1) |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* áâ ®¢¨âì à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 äãªæ¨¨ 21. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 7. |
====================================================================== |
=== ãªæ¨ï 26, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì § 票¥ áçñâ稪 ¢à¥¬¥¨. === |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® á®âëå ¤®«¥© ᥪã¤ë, ¯à®è¥¤è¨å á ¬®¬¥â |
§ ¯ã᪠á¨á⥬ë |
¬¥ç ¨ï: |
* çñâ稪 ¡¥àñâáï ¯® ¬®¤ã«î 2^32, ç⮠ᮮ⢥âáâ¢ã¥â ¥¬®£¨¬ ¡®«¥¥ |
497 áã⮪. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ¯®«ãç¨âì äãªæ¨¥© 3. |
====================================================================== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 11 ===================== |
=========== § âì, à §à¥èñ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥éñ/à §à¥èñ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 21. |
====================================================================== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 12 ===================== |
========== § âì, à §à¥èñ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥éñ/à §à¥èñ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 12 äãªæ¨¨ 21. |
====================================================================== |
================ ãªæ¨ï 29 - ¯®«ãç¨âì á¨á⥬ãî ¤ âã. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 29 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00DDMMYY, £¤¥ |
(¨á¯®«ì§ã¥âáï ¤¢®¨ç®-¤¥áïâ¨ç®¥ ª®¤¨à®¢ ¨¥, BCD) |
* YY = ¤¢¥ ¬« ¤è¨¥ æ¨äàë £®¤ (00..99) |
* MM = ¬¥áïæ (01..12) |
* DD = ¤¥ì (01..31) |
¬¥ç ¨ï: |
* ¨á⥬ãî ¤ âã ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
================ ãªæ¨ï 30 - à ¡®â á ⥪ã饩 ¯ ¯ª®©. =============== |
====================================================================== |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . --------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯ãâñ¬ ª ®¢®© ⥪ã饩 ¯ ¯ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . ---------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = - 1 ®é¨¡ª , ¯ ¯ª ⥪ã饣® ¯®â®ª ¨¬¥¥â ¤«¨ã ¡®«¥¥ 祬 4096 ᨬ¢®«®¢. |
* eax = ¤«¨ ¨¬¥¨ ⥪ã饩 ¯ ¯ª¨ (¢ª«îç ï § ¢¥àè î騩 0) |
¬¥ç ¨ï: |
* ᫨ à §¬¥à ¡ãä¥à ¥¤®áâ â®ç® ¤«ï ª®¯¨à®¢ ¨ï ¢á¥£® ¨¬¥¨, |
ª®¯¨àãîâáï ⮫쪮 ¯¥à¢ë¥ (edx-1) ¡ ©â |
¨ ¢ ª®æ¥ áâ ¢¨âáï § ¢¥àè î騩 0. |
====================================================================== |
================ ãªæ¨ï 32 - 㤠«¨âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 32 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 58 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ¥ªãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â ⮫쪮 § 票ï 0(ãᯥå) ¨ |
5(ä ©« ¥ ©¤¥). |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ (¯¥à¢ë¥ |
8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
=============== ãªæ¨ï 33 - § ¯¨á âì ä ©« à ¬¤¨áª. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 33 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* á«¥¤ã¥â ãáâ ¢«¨¢ âì esi=0 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ᫨ 㪠§ âì ¥ã«¥¢®¥ § 票¥ ¢ esi ¨ à ¬¤¨áª¥ 㦥 ¥áâì |
㪠§ ë© ä ©«, â® ¡ã¤¥â ᮧ¤ ¥éñ ®¤¨ ä ©« á ⥬ ¦¥ ¨¬¥¥¬. |
* ¯à®â¨¢®¬ á«ãç ¥ ä ©« ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
============ ãªæ¨ï 35 - ¯à®ç¨â âì 梥â â®çª¨ íªà ¥. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 35 |
* ebx = y*xsize+x, £¤¥ |
* (x,y) = ª®®à¤¨ âë â®çª¨ (áç¨â ï ®â 0) |
* xsize = à §¬¥à íªà ¯® £®à¨§®â «¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 梥â 0x00RRGGBB |
¬¥ç ¨ï: |
* § âì à §¬¥àë íªà ¬®¦® ¢ë§®¢®¬ äãªæ¨¨ 14. ¡à â¨â¥ ¢¨¬ ¨¥, |
çâ® ® ¢ëç¨â ¥â 1 ¨§ ®¡®¨å à §¬¥à®¢. |
* ¢¨¤¥®¯ ¬ï⨠¥áâì â ª¦¥ ¯àאַ© ¤®áâ㯠(¡¥§ ¢ë§®¢®¢ á¨á⥬ëå |
äãªæ¨©) ç¥à¥§ ᥫ¥ªâ®à gs. à ¬¥âàë ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬®¦® ¯®«ãç¨âì äãªæ¨¥© 61. |
====================================================================== |
=============== ãªæ¨ï 36 - ¯à®ç¨â âì ®¡« áâì íªà . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 36 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¯à¥¤¢ à¨â¥«ì® ¢ë¤¥«¥ãî ®¡« áâì ¯ ¬ïâ¨, |
ªã¤ ¡ã¤¥â ¯®¬¥é¥® ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ®¡« á⨠- íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
®¡« á⨠®â®á¨â¥«ì® íªà . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize. |
====================================================================== |
==================== ãªæ¨ï 37 - à ¡®â á ¬ëèìî. ==================== |
====================================================================== |
-------------- ®¤äãªæ¨ï 0 - íªà ë¥ ª®®à¤¨ âë ¬ëè¨ --------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ (áç¨â ï ®â 0) |
---------- ®¤äãªæ¨ï 1 - ª®®à¤¨ âë ¬ëè¨ ®â®á¨â¥«ì® ®ª ---------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ ®â®á¨â¥«ì® |
®ª ¯à¨«®¦¥¨ï (áç¨â ï ®â 0) |
¬¥ç ¨ï: |
* 票¥ ¢ëç¨á«ï¥âáï ¯® ä®à¬ã«¥ (x-xwnd)*65536 + (y-ywnd). |
᫨ y>=ywnd, â® ¬« ¤è¥¥ á«®¢® ¥®âà¨æ â¥«ì® ¨ ᮤ¥à¦¨â |
®â®á¨â¥«ìãî y-ª®®à¤¨ âã, áâ à襥 - ®â®á¨â¥«ìãî x-ª®®à¤¨ âã |
(¯à ¢¨«ì®£® § ª ). ¯à®â¨¢®¬ á«ãç ¥ ¬« ¤è¥¥ á«®¢® ®âà¨æ â¥«ì® |
¨ ¢áñ à ¢® ᮤ¥à¦¨â ®â®á¨â¥«ìãî y-ª®®à¤¨ âã, |
ª áâ à襬ã á«®¢ã á«¥¤ã¥â ¯à¨¡ ¢¨âì 1. |
----------------- ®¤äãªæ¨ï 2 - ¦ âë¥ ª®¯ª¨ ¬ëè¨ ----------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® ¦ âëå ª®¯ª å ¬ëè¨: |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â |
* ¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â |
* ¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
------------------ ®¤äãªæ¨ï 4 - § £à㧨âì ªãàá®à ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* dx = ¨áâ®ç¨ª ¤ ëå: |
* dx = LOAD_FROM_FILE = 0 - ¤ ë¥ ¢ ä ©«¥ |
* ecx = 㪠§ â¥«ì ¯®«ë© ¯ãâì ª ä ©«ã ªãàá®à |
* ä ©« ªãàá®à ¤®«¦¥ ¡ëâì ¢ ä®à¬ ⥠.cur, áâ ¤ à⮬ ¤«ï |
MS Windows, ¯à¨çñ¬ à §¬¥à®¬ 32*32 ¯¨ªá¥«ï |
* dx = LOAD_FROM_MEM = 1 - ¤ ë¥ ä ©« 㦥 § £àã¦¥ë ¢ ¯ ¬ïâì |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä ©« ªãàá®à |
* ä®à¬ â ¤ ëå â ª®© ¦¥, ª ª ¨ ¢ ¯à¥¤ë¤ã饬 á«ãç ¥ |
* dx = LOAD_INDIRECT = 2 - ¤ ë¥ ¢ ¯ ¬ï⨠|
* ecx = 㪠§ â¥«ì ®¡à § ªãàá®à ¢ ä®à¬ ⥠ARGB 32*32 ¯¨ªá¥«ï |
* edx = 0xXXYY0002, £¤¥ |
* XX = x-ª®®à¤¨ â "£®àï祩 â®çª¨" ªãàá®à |
* YY = y-ª®®à¤¨ â |
* 0 <= XX, YY <= 31 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ªãàá®à |
------------------ ®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ªãàá®à ------------------ |
áâ ¢«¨¢ ¥â ®¢ë© ªãàá®à ¤«ï ®ª ⥪ã饣® ¯®â®ª . |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = åí¤« ¯à¥¤ë¤ã饣® ãáâ ®¢«¥®£® ªãàá®à |
¬¥ç ¨ï: |
* ᫨ ¯¥à¥¤ ¥ª®à४âë© åí¤«, â® äãªæ¨ï ¢®ááâ ®¢¨â ªãàá®à |
¯® 㬮«ç ¨î (áâ ¤ àâãî áâ५ªã). ç áâ®áâ¨, ª ¢®ááâ ®¢«¥¨î |
ªãàá®à ¯® 㬮«ç ¨î ¯à¨¢®¤¨â ¯¥à¥¤ ç ecx=0. |
------------------- ®¤äãªæ¨ï 6 - 㤠«¨âì ªãàá®à -------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãàá®à ¤®«¦¥ ¡ë« ¡ëâì à ¥¥ § £à㦥 ⥪ã騬 ¯®â®ª®¬ |
(¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4). ãªæ¨ï ¥ 㤠«ï¥â á¨áâ¥¬ë¥ ªãàá®àë ¨ |
ªãàá®àë, § £àã¦¥ë¥ ¤à㣨¬¨ ¯à¨«®¦¥¨ï¬¨. |
* ᫨ 㤠«ï¥âáï ªâ¨¢ë© (ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 5) ªãàá®à, â® |
¢®ááâ ¢«¨¢ ¥âáï ªãàá®à ¯® 㬮«ç ¨î (áâ ¤ àâ ï áâ५ª ). |
------------------ ®¤äãªæ¨ï 7 - ¤ ë¥ ¯à®ªàã⪨ ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [horizontal offset]*65536 + [vertical offset] |
¬¥ç ¨ï: |
* ë¥ ¤®áâã¯ë ⮫쪮 ªâ¨¢®¬ã ®ªã. |
* ®á«¥ ¯à®çâ¥¨ï § ç¥¨ï ®¡ã«ïîâáï. |
* ë¥ ¨¬¥îâ § ª®¢ë¥ § 票ï. |
====================================================================== |
================== ãªæ¨ï 38 - à¨á®¢ âì ®â१®ª. ================== |
====================================================================== |
à ¬¥âàë: |
* eax = 38 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ç « ¯® ®á¨ x]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ç « ¯® ®á¨ y]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ y] |
* edx = 0x00RRGGBB - 梥â |
edx = 0x01xxxxxx - à¨á®¢ âì ¨¢¥àáë© ®â१®ª |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ®¥ç ï â®çª â ª¦¥ à¨áã¥âáï. |
====================================================================== |
== ãªæ¨ï 39, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. == |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
¬¥ç ¨ï: |
* áâì ¯ à ï ª®¬ ¤ ãáâ ®¢ª¨ à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 15. ®á«¥ ª®â®à®©, à §ã¬¥¥âáï, á«¥¤ã¥â |
§ ®¢® ®¯à¥¤¥«¨âì á ¬® ¨§®¡à ¦¥¨¥. |
====================================================================== |
= ãªæ¨ï 39, ¯®¤äãªæ¨ï 2 - ¯à®ç¨â âì â®çªã á ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00RRGGBB - 梥â â®çª¨, ¥á«¨ ᬥ饨¥ ¤®¯ãá⨬® |
(¬¥ìè¥ 0x160000-16) |
* eax = 2 - ¨ ç¥ |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¢ á«ãç ¥ ¥¢¥à®£® |
ᬥ饨ï, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
* ¬¥é¥¨¥ â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª (x+y*xsize)*3. |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ â®çª¨ ä®®¢®¬ ¨§®¡à ¦¥¨¨ - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 15. |
====================================================================== |
====== ãªæ¨ï 39, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - § ¬®áâ¨âì |
* eax = 2 - à áâïãâì |
¬¥ç ¨ï: |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 15. |
====================================================================== |
======== ãªæ¨ï 40 - ãáâ ®¢¨âì ¬ áªã ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩. ======== |
====================================================================== |
᪠¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩ ¢«¨ï¥â äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ 10, |
11, 23 - ®¨ á®®¡é îâ ⮫쪮 ® ᮡëâ¨ïå, à §à¥èñëå í⮩ ¬ ᪮©. |
à ¬¥âàë: |
* eax = 40 - ®¬¥à äãªæ¨¨ |
* ebx = ¬ ᪠: ¡¨â i ᮮ⢥âáâ¢ã¥â ᮡëâ¨î i+1 (á¬. ᯨ᮪ ᮡë⨩) |
(ãáâ ®¢«¥ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥¨¥ ® ᮡë⨨) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¯à¥¤ë¤ã饥 § 票¥ ¬ ᪨ |
¬¥ç ¨ï: |
* ᪠¯® 㬮«ç ¨î (7=111b) à §à¥è ¥â ¨§¢¥é¥¨ï ® ¯¥à¥à¨á®¢ª¥ |
¨ ¦ â¨ïå ª« ¢¨è ¨ ª®¯®ª. |
⮣® ¤®áâ â®ç® ¤«ï ¡®«ìè¨á⢠¯à¨«®¦¥¨©. |
* ®¡ëâ¨ï, § ¯à¥éñë¥ ¢ ¬ ᪥, ¢áñ à ¢® á®åà ïîâáï, ¥á«¨ |
¯à¨å®¤ïâ; ® ¨å ¯à®áâ® ¥ ¨§¢¥é îâ äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨. |
* ãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ ãç¨âë¢ îâ ¬ áªã ¬®¬¥â |
¢ë§®¢ äãªæ¨¨, ¥ ¬®¬¥â ¯®áâ㯫¥¨ï á®®¡é¥¨ï. |
====================================================================== |
================= ãªæ¨ï 41 - 㧠âì ¢« ¤¥«ìæ IRQ. ================= |
====================================================================== |
à ¬¥âàë: |
* eax = 41 - ®¬¥à äãªæ¨¨ |
* ebx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = PID ¢« ¤¥«ìæ |
* eax = 0, ¥á«¨ ¢« ¤¥«ìæ ¥â |
* eax = -1 ¤«ï ¥ª®à४⮣® ebx |
====================================================================== |
========= ãªæ¨ï 42 - à ¡®â á ¤ 묨, ¯®«ãç¥ë¬¨ ¯® IRQ. ========= |
====================================================================== |
ਠ¢®§¨ª®¢¥¨¨ IRQ á¨á⥬ ¬®¦¥â áç¨âë¢ âì ¤ ë¥ ¨§ 㪠§ ëå |
à ¥¥ äãªæ¨¥© 44 ¯®à⮢ ¨ § ¯¨áë¢ âì í⨠¤ ë¥ ¢ ¡ãä¥à. |
-------------------- ®¤äãªæ¨ï 0 - ç⥨¥ ¤ ëå -------------------- |
à ¬¥âàë: |
* eax = 42 - ®¬¥à äãªæ¨¨ |
* bl = ®¬¥à IRQ, 0..15 |
* bh = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ®áâ «ì ï ç áâì ॣ¨áâà ebx ¤®«¦ ¡ëâì ®¡ã«¥ |
* ecx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ ¥ ¬¥¥¥ 4000 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: (á¨âã æ¨î ¬®¦® à §«¨ç¨âì ¯® § 票î eax) |
* ¥á«¨ ¯®â®ª ¥ ï¥âáï ¢« ¤¥«ì楬 IRQ |
(¨«¨ ®¬¥à IRQ § ¤ ¥¢¥à®): eax = -1 |
* ¥á«¨ ¤ ëå ¥â: eax = 0 |
* ¥á«¨ ¢áñ ¢ ¯®à浪¥ ¨ ¤ ë¥ ¡ë«¨: |
eax = à §¬¥à ¤ ëå, ¯à®ç¨â ëå ¨§ ¡ãä¥à (¢ ¡ ©â å) |
------------ ®¤äãªæ¨ï 1 - 㧠âì à §¬¥à ¤ ëå ¢ ¡ãä¥à¥ ------------ |
à ¬¥âàë: |
* eax = 42 - ®¬¥à äãªæ¨¨ |
* bl = ®¬¥à IRQ, 0..15 |
* bh = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ®áâ «ì ï ç áâì ॣ¨áâà ebx ¤®«¦ ¡ëâì ®¡ã«¥ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¯®â®ª ¥ ï¥âáï ¢« ¤¥«ì楬 IRQ |
(¨«¨ ®¬¥à IRQ § ¤ ¥¢¥à®): eax = -1 |
* ¨ ç¥ eax = à §¬¥à ¤ ëå ¢ ¡ãä¥à¥ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì ¤«ï ᥡï 㪠§ ë© IRQ |
äãªæ¨¥© 45. |
* §¬¥à ¡ãä¥à ¤«ï ¤ ëå - 4000 ¡ ©â, ¯à¨ ¯¥à¥¯®«¥¨¨ |
"ᢥ¦¨¥" ¤ ë¥ ¯¥à¥áâ îâ § ¯¨áë¢ âìáï ¢ ¡ãä¥à. |
====================================================================== |
=================== ãªæ¨ï 43 - ¢¢®¤/¢ë¢®¤ ¢ ¯®àâ. ================== |
====================================================================== |
------------------------ 뢮¤ ¤ ëå ¢ ¯®àâ ------------------------- |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* bl = ¡ ©â ¤«ï ¢ë¢®¤ |
* ecx = ®¬¥à ¯®àâ 0xnnnn (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « 㪠§ ë© ¯®àâ |
------------------------ ¢®¤ ¤ ëå ¨§ ¯®àâ ------------------------ |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* ebx ¨£®à¨àã¥âáï |
* ecx = 0x8000nnnn, £¤¥ nnnn = ®¬¥à ¯®àâ (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¯à¨ í⮬ ebx = ¢¢¥¤ñë© ¡ ©â |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « ¤ ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì § ᮡ®© |
㪠§ ë© ¯®àâ äãªæ¨¥© 46. |
* «ï § १¥à¢¨à®¢ ëå ¯®à⮢ ¢¬¥áâ® ¢ë§®¢ íâ¨å äãªæ¨© |
«ãçè¥ ¨á¯®«ì§®¢ âì ª®¬ ¤ë ¯à®æ¥áá®à in/out - íâ® § ç¨â¥«ì® |
¡ëáâ॥ ¨ ¥áª®«ìª® ª®à®ç¥ ¨ ¯à®é¥. § ¥§ १¥à¢¨à®¢ ëå |
¯®à⮢ ç¨â âì ¢áñ à ¢® ¥«ì§ï. |
====================================================================== |
======== ãªæ¨ï 44 - ®¯à¥¤¥«¨âì ¤¥©áâ¢¨ï ¯à¨ ¯®áâ㯫¥¨¨ IRQ. ======= |
====================================================================== |
ਠ¢®§¨ª®¢¥¨¨ IRQ á¨á⥬ ¬®¦¥â áç¨âë¢ âì ¤ ë¥ ¨§ 㪠§ ëå í⮩ |
äãªæ¨¥© ¯®à⮢ ¨ § ¯¨áë¢ âì í⨠¤ ë¥ ¢ ¡ãä¥à, ®âªã¤ ¨å ¬®¦® |
¯à®ç¨â âì äãªæ¨¥© 42. |
à ¬¥âàë: |
* eax = 44 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¬ áᨢ áâàãªâãà, ®¯¨áë¢ îé¨å ¯® ®¤®¬ã ¯®àâã: |
* +0: word: 0 ®§ ç ¥â ª®¥æ ¬ áᨢ , ¨ ç¥ ®¬¥à ¯®àâ |
* +2: byte: § १¥à¢¨à®¢ ® (¨£®à¨àã¥âáï) |
* +3: byte: 1=áç¨âë¢ âì ¡ ©â ¨§ í⮣® ¯®àâ , 2=áç¨âë¢ âì á«®¢® |
* ecx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯®â®ª ¥ ï¥âáï ¢« ¤¥«ì楬 㪠§ ®£® IRQ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì § ᮡ®© |
㪠§ë¢ ¥¬ë© IRQ äãªæ¨¥© 45. |
* ਨ¬ îâáï ¢® ¢¨¬ ¨¥ ⮫쪮 ¯¥à¢ë¥ 16 ¯®à⮢. |
* ¥ªãé ï ॠ«¨§ æ¨ï à áᬠâਢ ¥â ¥¯à ¢¨«ì®¥ § 票¥ ¯®«ï +3 |
ª ª ᨣ « ¯à¥ªà é¥¨ï ®¡à ¡®âª¨ IRQ. |
====================================================================== |
============ ãªæ¨ï 45 - § १¥à¢¨à®¢ âì/®á¢®¡®¤¨âì IRQ. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 45 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - § १¥à¢¨à®¢ âì, 1 = ®á¢®¡®¤¨âì |
* ecx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª (¥¢¥àë© ®¬¥à IRQ ¨«¨ |
¯®¯ë⪠§ १¥à¢¨à®¢ âì ¥á¢®¡®¤ë© IRQ ¨«¨ ®á¢®¡®¤¨âì IRQ, ¥ |
§ १¥à¢¨à®¢ ë© â¥ªã騬 ¯®â®ª®¬) |
¬¥ç ¨ï: |
* ¥§¥à¢¨à®¢ ¨¥ IRQ 㦮 ¤«ï à ¡®âë äãªæ¨© 42 ¨ 44. |
* ®«ìª® ®¤¨ ¯®â®ª ¬®¦¥â § १¥à¢¨à®¢ âì ª®ªà¥âë© IRQ. |
* IRQ, ®¡à ¡ âë¢ ¥¬ë¥ á¨á⥬®© á ¬®áâ®ï⥫ì®, १¥à¢¨àãîâáï |
á¨á⥬®© (¯®â®ª®¬ 1) ¯à¨ § £à㧪¥. |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï |
¢á¥ § १¥à¢¨à®¢ ë¥ ¨¬ IRQ. |
====================================================================== |
= ãªæ¨ï 46 - § १¥à¢¨à®¢ âì/®á¢®¡®¤¨âì £à㯯㠯®à⮢ ¢¢®¤ /¢ë¢®¤ . |
====================================================================== |
§ १¥à¢¨à®¢ ë¬ ¯®àâ ¬ ¬®¦® ®¡à é âìáï ¯àï¬ãî ¨§ ¯à¨«®¦¥¨ï |
ª®¬ ¤ ¬¨ in/out (४®¬¥¤ã¥¬ë© ᯮᮡ) ¨ ¢ë§®¢®¬ äãªæ¨¨ 43 |
(¥à¥ª®¬¥¤ã¥¬ë© ᯮᮡ). |
à ¬¥âàë: |
* eax = 46 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - § १¥à¢¨à®¢ âì, 1 - ®á¢®¡®¤¨âì |
* ecx = ®¬¥à ç « ¤¨ ¯ §® ¯®à⮢ |
* edx = ®¬¥à ª®æ ¤¨ ¯ §® ¯®à⮢ (¢ª«îç¨â¥«ì®) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
¬¥ç ¨ï: |
* á«ãç ¥ १¥à¢¨à®¢ ¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¢ë¯®«¥¨¥ |
®¤®£® ¨§ ãá«®¢¨©: |
* ç «ìë© ¤à¥á ¡®«ìè¥ ª®¥ç®£®; |
* 㪠§ ë© ¤¨ ¯ §® ᮤ¥à¦¨â ¥ª®à४âë© ®¬¥à ¯®àâ |
(ª®à४âë¥ - ®â 0 ¤® 0xFFFF); |
* ¯à¥¢ë襮 ®£à ¨ç¥¨¥ ®¡é¥¥ ç¨á«® § १¥à¢¨à®¢ ëå ®¡« á⥩ |
- ¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 255; |
* 㪠§ ë© ¤¨ ¯ §® ¯¥à¥á¥ª ¥âáï á ®¤¨¬ ¨§ |
à ¥¥ § १¥à¢¨à®¢ ëå |
* á«ãç ¥ ®á¢®¡®¦¤¥¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¯®¯ë⪠|
®á¢®¡®¦¤¥¨ï ¤¨ ¯ §® , ª®â®àë© à ¥¥ ¥ ¡ë« 楫¨ª®¬ |
§ १¥à¢¨à®¢ í⮩ ¦¥ äãªæ¨¥© (á â ª¨¬¨ ¦¥ § 票ﬨ ecx,edx). |
* ਠ®¡ à㦥¨¨ ®è¨¡ª¨ (¢ ®¡®¨å á«ãç ïå) ¨ª ª¨å ¤¥©á⢨© |
¥ ¯à®¨§¢®¤¨âáï. |
* ਠ§ £à㧪¥ á¨á⥬ १¥à¢¨àã¥â § ᮡ®© ¯®àâë |
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (¢ª«îç¨â¥«ì®). |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥ |
§ १¥à¢¨à®¢ ë¥ ¨¬ ¯®àâë. |
====================================================================== |
================= ãªæ¨ï 47 - ¢ë¢¥á⨠ç¨á«® ¢ ®ª®. ================= |
====================================================================== |
à ¬¥âàë: |
* eax = 47 - ®¬¥à äãªæ¨¨ |
* ebx = ¯ à ¬¥âàë ¯à¥®¡à §®¢ ¨ï ç¨á« ¢ ⥪áâ: |
* bl = 0 - ecx ᮤ¥à¦¨â ç¨á«® |
* bl = 1 - ecx ᮤ¥à¦¨â 㪠§ ⥫ì dword/qword-ç¨á«® |
* bh = 0 - ®â®¡à ¦ âì ¢ ¤¥áïâ¨ç®© á¨á⥬¥ áç¨á«¥¨ï |
* bh = 1 - ®â®¡à ¦ âì ¢ è¥áâ ¤æ â¥à¨ç®© á¨á⥬¥ |
* bh = 2 - ®â®¡à ¦ âì ¢ ¤¢®¨ç®© á¨á⥬¥ |
* ¡¨âë 16-21 = ᪮«ìª® æ¨äà ®â®¡à ¦ âì |
* ¡¨âë 22-29 § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* ¡¨â 30 ãáâ ®¢«¥ = ¢ë¢®¤¨âì qword (64-¡¨â®¥ ç¨á«®); |
¯à¨ í⮬ ¤®«¦® ¡ëâì bl = 1 |
* ¡¨â 31 ãáâ ®¢«¥ = ¥ ¢ë¢®¤¨âì ¢¥¤ã騥 㫨 ç¨á« |
* ecx = ç¨á«® (¯à¨ bl=0) ¨«¨ 㪠§ ⥫ì (¯à¨ bl=1) |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = 0xX0RRGGBB: |
* RR, GG, BB § ¤ îâ 梥â |
* X = ABnn (¡¨âë) |
* nn = èà¨äâ (0/1) |
* A ¨£®à¨àã¥âáï |
* B=1 - § ªà 訢 âì ä® æ¢¥â®¬ edi |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ï ¤«¨ ¥ ¤®«¦ ¯à¥¢®á室¨âì 60. |
* 뢮¤¨âáï ஢® 㪠§ ®¥ ª®«¨ç¥á⢮ æ¨äà. ᫨ ç¨á«® ¬ «® ¨ |
¬®¦¥â ¡ëâì § ¯¨á ® ¬¥ì訬 ª®«¨ç¥á⢮¬ æ¨äà, ®® ¤®¯®«ï¥âáï |
¢¥¤ã騬¨ ã«ï¬¨; ¥á«¨ ç¨á«® ¢¥«¨ª® ¨ ¥ ¬®¦¥â ¡ëâì § ¯¨á ® |
â ª¨¬ ª®«¨ç¥á⢮¬ æ¨äà, "«¨è¨¥" ¢¥¤ã騥 æ¨äàë ®¡à¥§ îâáï. |
* à ¬¥âàë èà¨ä⮢ 㪠§ ë ¢ ®¯¨á ¨¨ äãªæ¨¨ 4 (¢ë¢®¤ ⥪áâ ). |
====================================================================== |
======= ãªæ¨ï 48, ¯®¤äãªæ¨ï 0 - ¯à¨¬¥¨âì áâனª¨ íªà . ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - § १¥à¢¨à®¢ ® |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯¥à¥à¨á®¢ë¢ ¥â íªà ¯®á«¥ ¨§¬¥¥¨ï ¯ à ¬¥â஢ |
¯®¤äãªæ¨ï¬¨ 1 ¨ 2. |
* 맮¢ äãªæ¨¨ ¡¥§ ¯à¥¤è¥áâ¢ãîé¨å ¢ë§®¢®¢ 㪠§ ëå ¯®¤äãªæ¨© |
¨£®à¨àã¥âáï. |
* 맮¢ äãªæ¨¨ á ¥ã«¥¢ë¬ ecx ¨£®à¨àã¥âáï. |
====================================================================== |
========= ãªæ¨ï 48, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì áâ¨«ì ª®¯®ª. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ ª®¯®ª: |
* 0 = ¯«®áª¨¥ |
* 1 = ®¡êñ¬ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¨¯ ª®¯®ª ¢«¨ï¥â ⮫쪮 ¨å ¯à®à¨á®¢ªã äãªæ¨¥© 8. |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì â ¡«¨æã 梥⮢ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®à¬ â â ¡«¨æë 梥⮢ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 3. |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢«¨ï¥â ⮫쪮 ¯à¨«®¦¥¨ï, |
ª®â®àë¥ íâã â ¡«¨æã ï¢ë¬ ®¡à §®¬ ¯®«ãç îâ (¯®¤äãªæ¨¥© 3) ¨ |
¨á¯®«ì§ãîâ (㪠§ë¢ ï 梥⠨§ ¥ñ ¯à¨ ¢ë§®¢ å äãªæ¨© à¨á®¢ ¨ï). |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢å®¤¨â ¢ ᪨ ¨ ãáâ ¢«¨¢ ¥âáï § ®¢® |
¯à¨ ãáâ ®¢ª¥ ᪨ (¯®¤äãªæ¨¨ 8). |
* ¡«¨æã 梥⮢ ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® á ¯®¬®éìî |
¯à¨«®¦¥¨ï desktop. |
====================================================================== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ edx ¡ ©â, |
ªã¤ ¡ã¤¥â § ¯¨á â ¡«¨æ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë 梥⮢: ª ¦¤ë© í«¥¬¥â - |
dword-§ 票¥ 梥â 0x00RRGGBB |
* +0: dword: frames - 梥â à ¬ª¨ |
* +4: dword: grab - 梥⠧ £®«®¢ª |
* +8: dword: grab_button - 梥⠪®¯ª¨ ¯®«®á¥ § £®«®¢ª |
* +12 = +0xC: dword: grab_button_text - 梥â ⥪áâ ª®¯ª¥ |
¯®«®á¥ § £®«®¢ª |
* +16 = +0x10: dword: grab_text - 梥â ⥪áâ § £®«®¢ª¥ |
* +20 = +0x14: dword: work - 梥â à ¡®ç¥© ®¡« á⨠|
* +24 = +0x18: dword: work_button - 梥⠪®¯ª¨ ¢ à ¡®ç¥© ®¡« á⨠|
* +28 = +0x1C: dword: work_button_text - 梥â ⥪áâ ª®¯ª¥ |
¢ à ¡®ç¥© ®¡« á⨠|
* +32 = +0x20: dword: work_text - 梥â ⥪áâ ¢ à ¡®ç¥© ®¡« á⨠|
* +36 = +0x24: dword: work_graph - 梥⠣à 䨪¨ ¢ à ¡®ç¥© ®¡« á⨠|
¬¥ç ¨ï: |
* âàãªâãà â ¡«¨æë 梥⮢ ®¯¨á ¢ áâ ¤ à⮬ ¢ª«îç ¥¬®¬ ä ©«¥ |
macros.inc ¯®¤ §¢ ¨¥¬ system_colors; ¯à¨¬¥à, ¬®¦® ¯¨á âì: |
sc system_colors ; ®¡ê¥¨¥ ¯¥à¥¬¥®© |
... ; £¤¥-â® ¤® ¢ë§¢ âì |
; ®¯¨áë¢ ¥¬ãî äãªæ¨î á ecx=sc |
mov ecx, [sc.work_button_text] ; ç¨â ¥¬ 梥â ⥪áâ |
; ª®¯ª¥ ¢ à ¡®ç¥© ®¡« á⨠|
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ íâ¨å 梥⮢ - ¤¥«® ¨áª«îç¨â¥«ì® |
á ¬®© ¯à®£à ¬¬ë. «ï ¨á¯®«ì§®¢ ¨ï 㦮 ¯à®áâ® ¯à¨ ¢ë§®¢¥ äãªæ¨© |
à¨á®¢ ¨ï 㪠§ë¢ âì 梥â, ¢§ïâë© ¨§ í⮩ â ¡«¨æë. |
* ਠ¨§¬¥¥¨¨ â ¡«¨æë áâ ¤ àâëå 梥⮢ (¯®¤äãªæ¨¥© 2 á |
¯®á«¥¤ãî騬 ¯à¨¬¥¥¨¥¬ ¨§¬¥¥¨© ¯®¤äãªæ¨¥© 0 ¨«¨ |
¯à¨ ãáâ ®¢ª¥ ᪨ ¯®¤äãªæ¨¥© 8) ¢á¥¬ ®ª ¬ ¯®áë« ¥âáï á®®¡é¥¨¥ |
® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ á ª®¤®¬ 1). |
* â ¤ àâë¥ æ¢¥â ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® |
á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
========== ãªæ¨ï 48, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ¢ëá®âã ᪨ . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¢ëá®â ᪨ |
¬¥ç ¨ï: |
* ëá®â®© ᪨ ¯® ®¯à¥¤¥«¥¨î áç¨â ¥âáï ¢ëá®â § £®«®¢ª ®ª®, |
¨á¯®«ì§ãîé¨å ᪨. |
* ¬®âਠ⠪¦¥ ®¡éãî áâàãªâãàã ®ª ¢ ®¯¨á ¨¨ äãªæ¨¨ 0. |
====================================================================== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì à ¡®çãî ®¡« áâì íªà . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* ¡®ç ï ®¡« áâì íªà ¯à¨ ®à¬ «ì®© à ¡®â¥ ¥áâì ¢¥áì íªà |
§ ¢ëç¥â®¬ ¯ ¥«¨ (@panel). |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ à ¡®ç¥© ®¡« á⨠- ¯®¤äãªæ¨ï 6. |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 6 - ãáâ ®¢¨âì à ¡®çãî ®¡« áâì íªà . === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* â äãªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¯à¨«®¦¥¨¥¬ @panel, |
ãáâ ¢«¨¢ î騬 à ¡®ç¥© ®¡« áâìî ¢¥áì íªà § ¢ëç¥â®¬ ¯ ¥«¨. |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ᫨ left>=right, â® x-ª®®à¤¨ âë à ¡®ç¥© ®¡« á⨠¥ ¨§¬¥ïîâáï. |
᫨ left<0, â® left ¥ ãáâ ¢«¨¢ ¥âáï. ᫨ right ¡®«ìè¥ |
¨«¨ à ¢® è¨à¨ë íªà , â® right ¥ ãáâ ¢«¨¢ ¥âáï. |
«®£¨ç® ¯® ®á¨ y. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à ¡®ç¥© ®¡« á⨠- |
¯®¤äãªæ¨ï 5. |
* â äãªæ¨ï ¢â®¬ â¨ç¥áª¨ ¯¥à¥à¨á®¢ë¢ ¥â íªà , ¯® 室㠤¥« |
®¡®¢«ï¥â ª®®à¤¨ âë ¨ à §¬¥àë ¬ ªá¨¬¨§¨à®¢ ëå ®ª®. |
ᥠ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
====================================================================== |
====================== ãªæ¨ï 48, ¯®¤äãªæ¨ï 7 ====================== |
============ ®«ãç¨âì ®¡« áâì ᪨ ¤«ï ⥪áâ § £®«®¢ª . ============ |
====================================================================== |
®§¢à é ¥â ®¡« áâì § £®«®¢ª ®ª ᮠ᪨®¬, ¯à¥¤ § ç¥ãî |
¤«ï ¢ë¢®¤ ⥪áâ § £®«®¢ª . |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
¬¥ç ¨ï: |
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ í⮩ äãªæ¨¨ - |
«¨ç®¥ ¤¥«® ¯à¨«®¦¥¨ï. |
* ¥ª®¬¥¤ã¥âáï ãç¨âë¢ âì § 票ï, ¢®§¢à é ¥¬ë¥ í⮩ äãªæ¨¥©, |
¯à¨ ¢ë¡®à¥ ¬¥áâ ¤«ï à¨á®¢ ¨ï ⥪áâ § £®«®¢ª (äãªæ¨¥© 4) ¨«¨ |
ª ª®£®-¨¡ã¤ì § ¬¥¨â¥«ï ⥪áâ § £®«®¢ª |
(¯® ãᬮâà¥¨î ¯à¨«®¦¥¨ï). |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì ¨á¯®«ì§ã¥¬ë© ᪨ ®ª®. === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¨¬ï ä ©« ᪨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ 㤠«®áì § £à㧨âì ä ©« |
* eax = 2 - ä ©« ¥ ï¥âáï ä ©«®¬ ᪨ |
¬¥ç ¨ï: |
* ਠãᯥ让 § £à㧪¥ ᪨ ¢á¥ ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠|
¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
* ਠ§ £à㧪¥ á¨á⥬ áç¨âë¢ ¥â ᪨ ¨§ ä ©« default.skn |
à ¬¤¨áª¥. |
* ®«ì§®¢ â¥«ì ¬®¦¥â ¨§¬¥ïâì ᪨ áâ â¨ç¥áª¨, ᮧ¤ ¢ ᢮© |
default.skn, ¨«¨ ¤¨ ¬¨ç¥áª¨ á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
============ ãªæ¨ï 49 - Advanced Power Management (APM). =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 49 - ®¬¥à äãªæ¨¨ |
* dx = ®¬¥à äãªæ¨¨ APM ( «®£ ax ¢ ᯥæ¨ä¨ª 樨) |
* bx, cx = ¯ à ¬¥âàë äãªæ¨¨ APM |
®§¢à é ¥¬®¥ § 票¥: |
* 16-¡¨âë¥ à¥£¨áâàë ax, bx, cx, dx, si, di ¨ ä« £ CF |
ãáâ ®¢«¥ë ¢ ᮮ⢥âá⢨¨ ᮠᯥæ¨ä¨ª 樥© APM |
* áâ à訥 ¯®«®¢¨ë 32-¡¨âëå ॣ¨áâ஢ eax, ebx, ecx, |
edx, esi, edi à §àãè îâáï |
¬¥ç ¨ï: |
* ¯¥æ¨ä¨ª æ¨ï APM 1.2 ®¯¨áë¢ ¥âáï ¢ ¤®ªã¬¥â¥ |
"Advanced Power Management (APM) BIOS Specification" |
(Revision 1.2), ¤®áâ㯮¬ |
http://www.microsoft.com/whdc/archive/amp_12.mspx; |
ªà®¬¥ ⮣®, ® ¢ª«îç¥ ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). |
====================================================================== |
================= ãªæ¨ï 50 - ãáâ ®¢ª ä®à¬ë ®ª . ================= |
====================================================================== |
¡ëçë¥ ®ª ¯à¥¤áâ ¢«ïîâ ᮡ®© ¯àאַ㣮«ì¨ª¨. ¯®¬®éìî í⮩ äãªæ¨¨ |
®ªã ¬®¦® ¯à¨¤ âì ¯à®¨§¢®«ìãî ä®à¬ã. ®à¬ § ¤ ñâáï ¡®à®¬ â®ç¥ª |
¢ãâਠ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª , ¯à¨ ¤«¥¦ é¨å ®ªã. ®«®¦¥¨¥ ¨ |
à §¬¥àë ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª § ¤ îâáï äãªæ¨¥© 0 ¨ ¨§¬¥ïîâáï |
äãªæ¨¥© 67. |
--------------- áâ ®¢ª ¤ ëå á ¨ä®à¬ 樥© ® ä®à¬¥ --------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä®à¬ë (¬ áᨢ ¡ ©â 0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------------ áâ ®¢ª ¬ áèâ ¡ ¤ ëå ä®à¬ë ------------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx § ¤ ñâ ¬ áèâ ¡: ª ¦¤ë© ¡ ©â ¤ ëå ®¯à¥¤¥«ï¥â |
(2^scale)*(2^scale) ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* áèâ ¡ ¯® 㬮«ç ¨î à ¢¥ 0 (¬ áèâ ¡¨àãî騩 ¬®¦¨â¥«ì 1). ᫨ ¢ |
¤ ëå ä®à¬ë ®¤¨ ¡ ©â ᮮ⢥âáâ¢ã¥â ®¤®¬ã ¯¨ªá¥«î, â® ¬ áèâ ¡ |
¬®¦® ¥ ãáâ ¢«¨¢ âì. |
* ¡®§ 稬 xsize = è¨à¨ ®ª (¢ ¯¨ªá¥«ïå), ysize = ¢ëá®â ; |
®¡à â¨â¥ ¢¨¬ ¨¥, çâ® ®¨ ¥¤¨¨æã ¡®«ìè¥, 祬 ãáâ ¢«¨¢ ¥¬ë¥ |
äãªæ¨ï¬¨ 0, 67. |
* ® ®¯à¥¤¥«¥¨î ¬ áèâ ¡ xsize ¨ ysize ¤®«¦ë ¤¥«¨âìáï 2^scale. |
* ©â ¤ ëå ¯® ᬥ饨î a ¤®«¦¥ ¡ëâì 0/1 ¨ |
®¯à¥¤¥«ï¥â ¯à¨ ¤«¥¦®áâì ®ªã ª¢ ¤à â á® áâ®à®®© 2^scale |
(¯à¨ scale=0 ¯®«ãç ¥¬ ¯¨ªá¥«ì) ¨ ª®®à¤¨ â ¬¨ «¥¢®£® ¢¥à奣® 㣫 |
(a mod (xsize shr scale), a div (xsize shr scale)) |
* §¬¥à ¤ ëå: (xsize shr scale)*(ysize shr scale). |
* ë¥ ¤®«¦ë ¯à¨áãâá⢮¢ âì ¢ ¯ ¬ï⨠¨ ¥ ¬¥ïâìáï |
¯®á«¥ ãáâ ®¢ª¨ ä®à¬ë. |
* ¨á⥬ ¯à®á¬ âਢ ¥â ¤ ë¥ ® ä®à¬¥ ¯à¨ ª ¦¤®© ¯¥à¥à¨á®¢ª¥ ®ª |
äãªæ¨¥© 0. |
* 맮¢ ¯®¤äãªæ¨¨ 0 á ã«¥¢ë¬ 㪠§ ⥫¥¬ ¯à¨¢®¤¨â ª ¢®§¢à âã |
ª ¯àאַ㣮«ì®© ä®à¬¥. |
====================================================================== |
===================== ãªæ¨ï 51 - ᮧ¤ âì ¯®â®ª. ==================== |
====================================================================== |
à ¬¥âàë: |
* eax = 51 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ¤à¥á â®çª¨ ¢å®¤ ¯®â®ª ( ç «ìë© eip) |
* edx = 㪠§ ⥫ì áâíª ¯®â®ª ( ç «ìë© esp) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (¢ á¨á⥬¥ ᫨誮¬ ¬®£® ¯®â®ª®¢) |
* ¨ ç¥ eax = TID - ¨¤¥â¨ä¨ª â®à ¯®â®ª |
====================================================================== |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨 |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®© ¨ à ¡®â îé¨å á ¥© ¯®¤äãªæ¨© 0 ¨ 2 |
¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
======= ãªæ¨ï 52, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì «®ª «ìë© IP- ¤à¥á. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = IP- ¤à¥á (4 ¡ ©â ) |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ãáâ ¢«¨¢ ¥âáï ¯®¤äãªæ¨¥© 3. |
====================================================================== |
ãªæ¨ï 52, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨; ¥á«¨ ¬« ¤è¨¥ 7 ¡¨â ®¡à §ãîâ |
ç¨á«® 3, íâ® ¢®á¯à¨¨¬ ¥âáï ª ª § ¯à®á [¯¥à¥-]¨¨æ¨ «¨§ æ¨î |
Ethernet-ª àâë, ¢ ¯à®â¨¢®¬ á«ãç ¥ Ethernet ¢ëª«îç ¥âáï |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® ¢®§¢à é ¥âáï eax=2, |
® íâ® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¡ã¤ãé¨å ¢¥àá¨ïå ï¤à |
* ¥á«¨ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® eax=0 ®§ ç ¥â ®è¨¡ªã |
(®âáãâá⢨¥ Ethernet-ª àâë), ¥ã«¥¢®¥ § 票¥ - ãᯥå |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ¯à®ç¨â âì ¯®¤äãªæ¨¥© 0. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®©, ¯®¤äãªæ¨¨ 0 ¨ ç á⨠¯®¤äãªæ¨¨ 2, |
ãáâ ¢«¨¢ î饩 íâã ¯¥à¥¬¥ãî, ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì «®ª «ìë© IP- ¤à¥á. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = IP- ¤à¥á (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=3, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ¬®¦® ¯®«ãç¨âì ¯®¤äãªæ¨¥© 1. |
====================================================================== |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 6 - ¤®¡ ¢¨âì ¤ ë¥ ¢ á⥪ ¢å®¤®© ®ç¥à¥¤¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* edx = à §¬¥à ¤ ëå |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
* §¬¥à ¤ ëå ¥ ¤®«¦¥ ¯à¥¢®á室¨âì 1500 ¡ ©â, |
å®âï ¯à®¢¥à®ª ª®à४â®á⨠¥ ¤¥« ¥âáï. |
====================================================================== |
====================== ãªæ¨ï 52, ¯®¤äãªæ¨ï 8 ====================== |
============= à®ç¨â âì ¤ ë¥ ¨§ á¥â¥¢®© ®ç¥à¥¤¨ ¢ë¢®¤ . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ 1500 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢ ⥪ã饩 ॠ«¨§ 樨 |
«¨¡® 0 = ¥â ¤ ëå, «¨¡® 1500) |
* ¤ ë¥ áª®¯¨à®¢ ë ¢ ¡ãä¥à |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
====================================================================== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì gateway IP. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = gateway IP (4 ¡ ©â ) |
====================================================================== |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì ¬ áªã ¯®¤á¥â¨. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ᪠¯®¤á¥â¨ |
====================================================================== |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 11 - ãáâ ®¢¨âì gateway IP. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = gateway IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=11, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ॠ«¨§ æ¨ïå |
====================================================================== |
======== ãªæ¨ï 52, ¯®¤äãªæ¨ï 12 - ãáâ ®¢¨âì ¬ áªã ¯®¤á¥â¨. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¬ ᪠¯®¤á¥â¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=12, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
====================================================================== |
============ ãªæ¨ï 52, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì DNS IP. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = DNS IP (4 ¡ ©â ) |
====================================================================== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 14 - ãáâ ®¢¨âì DNS IP. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = DNS IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=14, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ á«¥¤ãîé¨å ¢¥àá¨ïå |
====================================================================== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì «®ª «ìë© MAC- ¤à¥á. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ç¨â âì ¯¥à¢ë¥ 4 ¡ ©â , |
ecx = 4 - ç¨â âì ¯®á«¥¤¨¥ 2 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: eax = ¯¥à¢ë¥ 4 ¡ ©â MAC- ¤à¥á |
* ¤«ï ecx=4: ax = ¯®á«¥¤¨¥ 2 ¡ ©â MAC- ¤à¥á , |
áâ àè ï ¯®«®¢¨ eax à §àãè ¥âáï |
* ¤«ï ¤à㣨å ecx: eax = -1 ª ª ¯à¨§ ª ®è¨¡ª¨ |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®), |
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì®£® ¯®àâ |
* edx = 㤠«ñë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«ñë© IP |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 1 - § ªàëâì UDP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¥¢¥àë© åí¤« |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
====================================================================== |
============== ãªæ¨ï 53, ¯®¤äãªæ¨ï 2 - ®¯à®á ᮪¥â . ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯®«ãç¥ëå ¡ ©â, 0 ¤«ï ¥¢¥à®£® åí¤« |
* ebx à §àãè ¥âáï |
====================================================================== |
======== ãªæ¨ï 53, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì ¡ ©â ¨§ ᮪¥â . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥â ¯à¨ïâëå ¤ ëå ¨«¨ 㪠§ ¥¢¥àë© åí¤«: |
eax=0, bl=0, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
* ¥á«¨ ¡ë«¨ ¯à¨ïâë¥ ¤ ë¥: eax=ç¨á«® ®áâ ¢è¨åáï ¡ ©â |
(¢®§¬®¦®, 0), bl=¯à®ç¨â ë© ¡ ©â, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
====================================================================== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ UDP-᮪¥â. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ ¥¤®áâ â®ç® ¯ ¬ïâ¨) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-28, å®âï |
ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 5 - ®âªàëâì TCP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®), |
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì®£® ¯®àâ |
* edx = 㤠«ñë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«ñë© IP |
* edi = ०¨¬ ®âªàëâ¨ï: SOCKET_PASSIVE=0 ¨«¨ SOCKET_ACTIVE=1 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
====== ãªæ¨ï 53, ¯®¤äãªæ¨ï 6 - ¯®«ãç¨âì á®áâ®ï¨¥ TCP-᮪¥â . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ¤«ï ¥¢¥à®£® ᮪¥â ¨«¨ áâ âãá: ®¤® ¨§ |
* TCB_LISTEN = 1 |
* TCB_SYN_SENT = 2 |
* TCB_SYN_RECEIVED = 3 |
* TCB_ESTABLISHED = 4 |
* TCB_FIN_WAIT_1 = 5 |
* TCB_FIN_WAIT_2 = 6 |
* TCB_CLOSE_WAIT = 7 |
* TCB_CLOSING = 8 |
* TCB_LAST_ASK = 9 |
* TCB_TIME_WAIT = 10 |
* TCB_CLOSED = 11 |
* ebx à §àãè ¥âáï |
====================================================================== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ TCP-᮪¥â. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ ¥¤®áâ â®ç® ¯ ¬ïâ¨) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-40, |
å®âï ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 8 - § ªàëâì TCP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ |
¥¤®áâ â®ç® ¯ ¬ï⨠¤«ï ¯ ª¥â § ªàëâ¨ï ᮪¥â ) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
====================================================================== |
== ãªæ¨ï 53, ¯®¤äãªæ¨ï 9 - ¯à®¢¥à¨âì, ᢮¡®¤¥ «¨ «®ª «ìë© ¯®àâ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à «®ª «ì®£® ¯®àâ (¨á¯®«ì§ãîâáï ⮫쪮 ¬« ¤è¨¥ 16 ¡¨â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¯®à⠨ᯮ«ì§ã¥âáï |
* eax = 1 - ¯®àâ ᢮¡®¤¥ |
* ebx à §àãè ¥âáï |
====================================================================== |
==== ãªæ¨ï 53, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì áâ âãá ª ¡¥«ï Ethernet. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* al = -1 - ¤à ©¢¥à á¥â¥¢®© ª àâë ¥ § £à㦥 ¨«¨ |
¥ ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
* al = 0 - ª ¡¥«ì ¥ ¯®¤ª«îçñ |
* al = 1 - ª ¡¥«ì ¯®¤ª«îçñ |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ï¤à ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
⮫쪮 ¤«ï á¥â¥¢ëå ª àâ RTL8139. |
====================================================================== |
==== ãªæ¨ï 53, ¯®¤äãªæ¨ï 11 - ¯à®ç¨â âì ¤ ë¥ á¥â¥¢®£® á⥪ . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = 㪠§ â¥«ì ¡ãä¥à |
* esi = ç¨á«® ¡ ©â ¤«ï ç⥨ï; |
* esi = 0 - ç¨â âì ¢á¥ ¤ ë¥ (¬ ªá¨¬ã¬ 4096 ¡ ©â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (0 ¯à¨ ¥¢¥à®¬ åí¤«¥) |
* ebx à §àãè ¥âáï |
====================================================================== |
ãªæ¨ï 53, ¯®¤äãªæ¨ï 255 - ®â« ¤®ç ï ¨ä®à¬ æ¨ï á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 255 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ § ¯à 訢 ¥¬®© ¨ä®à¬ 樨 (ᬮâਠ¨¦¥) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § ¯à®è¥ ï ¨ä®à¬ æ¨ï |
* ebx à §àãè ¥âáï |
®§¬®¦ë¥ § 票ï ecx: |
* 100: ¤«¨ ®ç¥à¥¤¨ 0 (empty queue) |
* 101: ¤«¨ ®ç¥à¥¤¨ 1 (ip-out queue) |
* 102: ¤«¨ ®ç¥à¥¤¨ 2 (ip-in queue) |
* 103: ¤«¨ ®ç¥à¥¤¨ 3 (net1out queue) |
* 200: ç¨á«® í«¥¬¥â®¢ ¢ â ¡«¨æ¥ ARP |
* 201: à §¬¥à â ¡«¨æë ARP (¢ í«¥¬¥â å) (20 ¢ ⥪ã饩 ¢¥àᨨ) |
* 202: ¯à®ç¨â âì í«¥¬¥â edx â ¡«¨æë ARP ¢® ¢à¥¬¥ë© ¡ãä¥à, ®âªã¤ |
¡¥àãâ ¨ä®à¬ æ¨î 5 ¯®á«¥¤ãîé¨å ⨯®¢; |
¢ í⮬ á«ãç ¥ eax ¥®¯à¥¤¥«ñ |
* 203: IP- ¤à¥á, § ¯®¬¥ë© ⨯®¬ 202 |
* 204: áâ à襥 dword MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 205: ¬« ¤è¥¥ word MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 206: á«®¢® áâ âãá , § ¯®¬¥®¥ ⨯®¬ 202 |
* 207: á«®¢® ttl, § ¯®¬¥®¥ ⨯®¬ 202 |
* 2: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå IP-¯ ª¥â®¢ |
* 3: ®¡é¥¥ ç¨á«® ¯¥à¥¤ ëå IP-¯ ª¥â®¢ |
* 4: ®¡é¥¥ ç¨á«® ᤠ¬¯«¥ëå ¯®«ãç¥ëå ¯ ª¥â®¢ |
* 5: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå ARP-¯ ª¥â®¢ |
* 6: áâ âãá ¤à ©¢¥à ¯ ª¥â®¢, 0=¥ ªâ¨¢¥, |
¥ã«¥¢®¥ § 票¥= ªâ¨¢¥ |
====================================================================== |
====================== ãªæ¨ï 55, ¯®¤äãªæ¨ï 55 ===================== |
========== ç âì ¯à®¨£àë¢ âì ¤ ë¥ ¢áâ஥®¬ ᯨª¥à¥. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 55 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 55 - ®è¨¡ª (ᯨª¥à ®âª«îçñ ¨«¨ § ïâ) |
ë¥ - íâ® ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë. |
®à¬ â ª ¦¤®£® í«¥¬¥â ®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ ¡ ©â®¬: |
* 0 = ª®¥æ ¤ ëå |
* 1..0x80 = § ¤ ñâ ¤«¨â¥«ì®áâì §¢ãç ¨ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®âë, ®¯à¥¤¥«ï¥¬®© ¥¯®á।áâ¢¥ë¬ § 票¥¬ ç áâ®âë |
* á«¥¤ãî饥 á«®¢® (2 ¡ ©â ) ᮤ¥à¦¨â ¤¥«¨â¥«ì ç áâ®âë; |
ç áâ®â ®¯à¥¤¥«ï¥âáï ª ª 1193180/divider |
* 0x81 = invalid |
* 0x82..0xFF = ®â , ®¯à¥¤¥«ï¥¬ ï ®ªâ ¢®© ¨ ®¬¥à®¬: |
* ¤«¨â¥«ì®áâì ¢ á®âëå ¤®«ïå ᥪã¤ë = (¯¥à¢ë© ¡ ©â)-0x81 |
* ¯à¨áãâáâ¢ã¥â ¥éñ ®¤¨ ¡ ©â; |
* (¢â®à®© ¡ ©â)=0xFF - ¯ 㧠|
* ¨ ç¥ ® ¨¬¥¥â ¢¨¤ a*0x10+b, £¤¥ b=®¬¥à ®âë ¢ ®ªâ ¢¥ ®â 1 |
¤® 12, a=®¬¥à ®ªâ ¢ë (áç¨â ï á 0) |
¬¥ç ¨ï: |
* ¨é ¨¥ ᯨª¥à®¬ ¬®¦¥â ¡ëâì § ¯à¥é¥®/à §à¥è¥® ¯®¤äãªæ¨¥© 8 |
äãªæ¨¨ 18. |
* ãªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥¨¥, á®®¡é¨¢ ªã¤ á«¥¤ã¥â ¨ä®à¬ æ¨î |
® § ¯à®á¥. ¬® ¯à®¨£àë¢ ¨¥ ¨¤ñâ ¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë. |
* ë¥ ¤®«¦ë á®åà ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©¥© ¬¥à¥ |
¤® ª®æ ¯à®¨£àë¢ ¨ï. |
====================================================================== |
======================= ãªæ¨ï 57 - PCI BIOS. ======================= |
====================================================================== |
à ¬¥âàë: |
* eax = 57 - ®¬¥à äãªæ¨¨ |
* ebp ᮮ⢥âáâ¢ã¥â ॣ¨áâàã al ¢ ᯥæ¨ä¨ª 樨 PCI BIOS |
* ®áâ «ìë¥ à¥£¨áâàë - ¯® ᯥæ¨ä¨ª 樨 PCI BIOS |
®§¢à é ¥¬®¥ § 票¥: |
* CF ¥ ®¯à¥¤¥«ñ |
* ®áâ «ìë¥ à¥£¨áâàë - ¯® ᯥæ¨ä¨ª 樨 PCI BIOS |
¬¥ç ¨ï: |
* ®£¨å १ã«ìâ ⮢ í⮩ äãªæ¨¨ ¬®¦® â ª¦¥ ¤®¡¨âìáï ¢ë§®¢®¬ |
ᮮ⢥âáâ¢ãîé¨å ¯®¤äãªæ¨© äãªæ¨¨ 62. |
* ãªæ¨ï ¢ë§ë¢ ¥â à áè¨à¥¨¥ PCI32 BIOS, ¤®ªã¬¥â¨à®¢ ®¥, |
¯à¨¬¥à, ¢ http://alpha1.dyns.net/files/PCI/bios21.pdf. |
* ᫨ BIOS ¥ ¯®¤¤¥à¦¨¢ ¥â íâ® à áè¨à¥¨¥, ¯®¢¥¤¥¨¥ äãªæ¨¨ |
í¬ã«¨àã¥âáï (ç¥à¥§ «®£¨ ¯®¤äãªæ¨© äãªæ¨¨ 62 ०¨¬ ï¤à ). |
====================================================================== |
============== ãªæ¨ï 58 - à ¡®â á ä ©«®¢®© á¨á⥬®©. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª |
* +8: dword: à §¬¥à |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¯ ¬ïâì ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã « â¨áª¨å ¡ãª¢, |
àãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì § £« ¢ë¬¨. |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD/x = /HARDDISK/x - ãáâ ॢ訩 ¢ ਠ⠤®áâ㯠ª ¦ñá⪮¬ã ¤¨áªã |
(¢ í⮬ á«ãç ¥ ¡ § ®¯à¥¤¥«ï¥âáï ¯®¤äãªæ¨¥© 7 äãªæ¨¨ 21), |
x - ®¬¥à à §¤¥« (áç¨â ï á 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ãáâனá⢠¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
¬¥ç ¨ï: |
* ¯¥à¢ëå ¤¢ãå á«ãç ïå ¤®¯ã᪠¥âáï ¨á¯®«ì§®¢ ¨¥ FIRST ¢¬¥áâ® 1, |
SECOND ¢¬¥áâ® 2, ® ¨á¯®«ì§®¢ âì íâã ¢®§¬®¦®áâì |
¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï. |
* ª« ¤ë¢ ¥âáï ®£à ¨ç¥¨¥ n<=39. |
* ¬¥ ¯ ¯®ª ¨ ä ©« dir1,...,dirn,file ¤®«¦ë ¡ëâì ¢ ä®à¬ ⥠8.3: |
¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ ¥ ¡®«¥¥ 3 ᨬ¢®«®¢. |
¢®áâ®¢ë¥ ¯à®¡¥«ë ¨£®à¨àãîâáï. àã£¨å ¯à®¡¥«®¢ ¡ëâì ¥ ¤®«¦®. |
᫨ ¨¬ï § ¨¬ ¥â ஢® 8 ᨬ¢®«®¢, â®çªã ¬®¦® ®¯ãáâ¨âì |
(å®âï ¯®«ì§®¢ âìáï í⨬ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ |
¡ã¤ã騥 à áè¨à¥¨ï). |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
ਬ¥àë: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠|
* ¯®¤äãªæ¨ï 15 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«®¢®© á¨á⥬¥ |
====================================================================== |
========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 0 - ¯à®ç¨â âì ä ©«/¯ ¯ªã. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = à §¬¥à ä ©« (¢ ¡ ©â å) ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â. |
* â äãªæ¨ï ãáâ ५ , ¤«ï ç⥨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 0 |
äãªæ¨¨ 70, ¤«ï çâ¥¨ï ¯ ¯®ª - ¯®¤äãªæ¨î 1 äãªæ¨¨ 70. |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ᮤ¥à¦¨¬®¥ ¯ ¯ª¨. § ä ©«®¢ëå á¨á⥬ |
¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT. ®à¬ â FAT-¯ ¯ª¨ ®¯¨á ¢ «î¡®© |
¤®ªã¬¥â 樨 ¯® FAT. |
* §¬¥à ¯ ¯ª¨ ®¯à¥¤¥«ï¥âáï ¯® à §¬¥àã 楯®çª¨ ª« áâ¥à®¢ ¢ FAT. |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ |
eax=6 (EOF). |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ª®à¥¢ë¥ ¯ ¯ª¨ /rd/1,/fd/x,/hd[n]/x, ® |
¢ ¯¥à¢ëå ¤¢ãå á«ãç ïå ⥪ãé ï ॠ«¨§ æ¨ï ¥ á«¥¤ã¥â |
ãáâ ®¢«¥ë¬ ¯à ¢¨« ¬: |
¤«ï /rd/1: |
* ¥á«¨ 㪠§ ® 0 ¡«®ª®¢ ¤«ï ç⥨ï, áç¨â ¥âáï, |
çâ® § ¯à 訢 ¥âáï 1; |
* ¥á«¨ § ¯à 訢 ¥âáï ¡®«ìè¥ 14 ¡«®ª®¢ ¨«¨ ç «ìë© ¡«®ª |
¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï eax=5 (not found) ¨ ebx=-1; |
* à §¬¥à ª®à¥¢®£® ª â «®£ à ¬¤¨áª = 14 ¡«®ª®¢, |
0x1C00=7168 ¡ ©â; ® ¢®§¢à é ¥âáï ebx=0 |
(§ ¨áª«î票¥¬ á«ãç ï ¯à¥¤ë¤ã饣® ¯ãªâ ); |
* ª ª ¨ áâà ®, ¬®¦® ¯à®ç¨â âì 14-© ¡«®ª (â ¬, ¢®®¡é¥ £®¢®àï, |
¬ãá®à - ¯®¬¨ î, áçñâ ¢¥¤ñâáï á 0); |
* ¥á«¨ ¡ë« § ¯à®è¥ å®âï ¡ë ®¤¨ ¡«®ª á ®¬¥à®¬, ¥ ¬¥ì訬 14, |
â® ¢®§¢à é ¥âáï eax=6(EOF); ¨ ç¥ eax=0. |
«ï /fd/x: |
* ¥á«¨ ç «ìë© ¡«®ª ¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï |
eax=5 (not found) ¨ ebx=0; |
* ªáâ ⨠£®¢®àï, ä®à¬ â FAT12 ¤®¯ã᪠¥â ¤¨áª¥âë á à §¬¥à®¬ |
ª®à¥¢®£® ª â «®£ ¬¥ìè¥ ¨«¨ ¡®«ìè¥ 14 ¡«®ª®¢; |
* ¯à®¢¥àª¨ ¤«¨ë ¥ ¤¥« ¥âáï; |
* ¥á«¨ 㤠«®áì ¯à®ç¨â âì ¤ ë¥ á ¤¨áª¥âë, ¢®§¢à é ¥âáï |
eax=0,ebx=0; ¢ ¯à®â¨¢®¬ á«ãç ¥ eax=10 (access denied), ebx=-1. |
* ãªæ¨ï ®¡à ¡ âë¢ ¥â ç⥨¥ á¯¥æ¨ «ìëå ¯ ¯®ª /,/rd,/fd,/hd[n]; |
® १ã«ìâ â ¥ ᮮ⢥âáâ¢ã¥â ®¦¨¤ ¥¬®¬ã |
(¯® à ¡®â¥ á ®¡ëç묨 ä ©« ¬¨/¯ ¯ª ¬¨), ¥ á«¥¤ã¥â ãáâ ®¢«¥ë¬ |
¯à ¢¨« ¬, ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à ¨ ¯®â®¬ã |
¥ ®¯¨áë¢ ¥âáï. «ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ |
¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 11 äãªæ¨¨ 18 ¨«¨ |
ç¨â ©â¥ ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¨ ¯®¤äãªæ¨¥© 1 äãªæ¨¨ 70. |
====================================================================== |
========= ãªæ¨ï 58, ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ¨£®à¨àã¥âáï (ãáâ ¢«¨¢ ©â¥ ¢ 1) |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(512 ¡ ©â) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ãáâனá⢠: ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã, |
®¤® ¨§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - ®¬¥à ãáâனá⢠: 1=IDE0, ..., 4=IDE3. |
¬¥áâ® æ¨äà ¤®¯ã᪠¥âáï, å®âï ¨ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠|
¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï, |
¨á¯®«ì§®¢ ¨¥ 'first','second','third','fourth'. |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ 㪠§ ® ¨¬ï ãáâனá⢠/hd/xxx, £¤¥ xxx ¥ 室¨âáï |
¢ ᯨ᪥ ¢ëè¥: |
* eax = ebx = 1 |
* ¥á«¨ 㪠§ ® ¥¯à ¢¨«ì®¥ ¨¬ï ãáâனá⢠|
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï): |
* eax = 5 |
* ebx ¥ ¬¥ï¥âáï |
* ¥á«¨ LBA-¤®áâ㯠§ ¯à¥éñ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21: |
* eax = 2 |
* ebx à §àãè ¥âáï |
* ¤«ï à ¬¤¨áª : ¯®¯ë⪠çâ¥¨ï ¡«®ª § ¯à¥¤¥« ¬¨ à ¬¤¨áª |
(18*2*80 ¡«®ª®¢) ¯à¨¢®¤¨â ª |
* eax = 3 |
* ebx = 0 |
* ¯à¨ ãᯥ讬 ç⥨¨: |
* eax = ebx = 0 |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â; ç¨â ¥âáï ®¤¨ ¡«®ª. |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥, |
®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå. |
* ॡã¥âáï, çâ®¡ë ¡ë« à §à¥èñ LBA-¤®áâ㯠ª ãáâனá⢠¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21. § âì íâ® ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 26. |
* LBA-ç⥨¥ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
* ãªæ¨ï áç¨âë¢ ¥â ¤ ë¥ ä¨§¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ; |
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨ ¬ ã¦ë ¤ ë¥ ª®ªà¥â®£® à §¤¥« , |
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ç «ìë© á¥ªâ®à í⮣® à §¤¥« |
(«¨¡® ¯àï¬ãî ç¥à¥§ MBR, «¨¡® ¨§ à áè¨à¥®© áâàãªâãàë, |
¢®§¢à é ¥¬®© ⮩ ¦¥ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 18). |
* ãªæ¨ï ¥ ¯à®¢¥àï¥â ª®¤ ®è¨¡ª¨ ¦ñá⪮£® ¤¨áª , â ª çâ® § ¯à®á |
¥áãé¥áâ¢ãî饣® ᥪâ®à ¢áñ à ¢® çâ®-â® ¯à®ç¨â ¥â |
(¢¥à®ï⥥ ¢á¥£®, 㫨, ® íâ® ®¯à¥¤¥«ï¥âáï ãáâனá⢮¬) ¨ |
íâ® ¡ã¤¥â áç¨â âìáï ãᯥ宬 (eax=0). |
====================================================================== |
= ãªæ¨ï 58, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 15 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: ¨£®à¨àã¥âáï |
* +20 = +0x14: (¯à®¢¥àï¥âáï ⮫쪮 ¢â®à®© ᨬ¢®«, áà §ã ¯®á«¥ á«íè ) |
/rd=/RAMDISK ¨«¨ /hd=/HARDDISK |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¢â®à®© ᨬ¢®« ¥ ¯à¨ ¤«¥¦¨â ¬®¦¥áâ¢ã {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* ¤«ï à ¬¤¨áª : |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ = 2847 |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à = 512 |
* ¤«ï ¦ñá⪮£® ¤¨áª : ¡ § ¨ à §¤¥« ®¯à¥¤¥«ïîâáï ¯®¤äãªæ¨ï¬¨ 7 ¨ 8 |
äãªæ¨¨ 21: |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à (¢ ¡ ©â å) |
¬¥ç ¨ï: |
* ¥ 㤨¢«ï©â¥áì áâà ®¬ã à ᯮ«®¦¥¨î 4-£® ¢®§¢à é ¥¬®£® |
¯ à ¬¥âà - ª®£¤ ¯¨á «áï íâ®â ª®¤, ¯à¨ á¨á⥬ëå ¢ë§®¢ å |
¯à¨«®¦¥¨î ¢®§¢à é «¨áì ⮫쪮 ॣ¨áâàë eax,ebx,ecx (¨§ |
pushad-áâàãªâãàë, ¯¥à¥¤ î饩áï ª ª à£ã¬¥â á¨á⥬®© äãªæ¨¨). |
¥¯¥àì íâ® ¨á¯à ¢«¥®, â ª çâ®, ¢®§¬®¦®, ¨¬¥¥â á¬ëá« ¢®§¢à é âì |
à §¬¥à ª« áâ¥à ¢ edx, ¯®ª íâã äãªæ¨î ¥ ç «¨ ¨á¯®«ì§®¢ âì. |
* ®®¡é¥-â® ¥éñ áãé¥áâ¢ã¥â ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18, ¢®§¢à é îé ï |
¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥®© â ¡«¨æ¥ ¤¨áª®¢®© |
¯®¤á¨áâ¥¬ë ¬®¦® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à (â ¬ ® åà ¨âáï |
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦ñáâª¨å ¤¨áª®¢. |
====================================================================== |
=========== ãªæ¨ï 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC ¯à¨¬¥ï¥âáï ¤«ï ¯®áë«®ª á®®¡é¥¨© ®â ®¤®£® ¯à®æ¥áá /¯®â®ª |
¤à㣮¬ã. ਠí⮬ á«¥¤ã¥â ¯à¥¤¢ à¨â¥«ì® ¤®£®¢®à¨âìáï ® ⮬, ª ª |
¨â¥à¯à¥â¨à®¢ âì ª®ªà¥â®¥ á®®¡é¥¨¥. |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ®¡« áâì ¤«ï ¯®«ã票ï IPC --------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¯à¨ñ¬¨ª®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¢á¥£¤ ãá¯¥è® |
®à¬ â IPC-¡ãä¥à : |
* +0: dword: ¥á«¨ §¤¥áì ¥ 0, â® ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬; |
¡«®ª¨àã©â¥/à §¡«®ª¨àã©â¥ ¡ãä¥à, ª®£¤ ¢ë á ¨¬ ªâ¨¢® à ¡®â ¥â¥ |
¨ ¢ ¬ ¤®, çâ®¡ë ¨§¢¥ ¥ ¨§¬¥ï«¨áì ¤ ë¥ ¡ãä¥à |
(¥ ¯®áâ㯠«¨ ®¢ë¥ á®®¡é¥¨ï) |
* +4: dword: § ïâ® ¬¥áâ ¢ ¡ãä¥à¥ (¢ ¡ ©â å) |
* +8: ¯¥à¢®¥ á®®¡é¥¨¥ |
* +8+n: ¢â®à®¥ á®®¡é¥¨¥ |
* ... |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: PID ¯à®æ¥áá /¯®â®ª , ¯®á« ¢è¥£® á®®¡é¥¨¥ |
* +4: dword: ¤«¨ á®®¡é¥¨ï (¥ áç¨â ï íâ®â § £®«®¢®ª) |
* +8: n*byte: ¤ ë¥ á®®¡é¥¨ï |
--------------- ®¤äãªæ¨ï 2 - ¯®á« âì á®®¡é¥¨¥ IPC. ---------------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¨¨æ¨ â®à®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = PID ¯à¨ñ¬¨ª |
* edx = 㪠§ â¥«ì ¤ ë¥ á®®¡é¥¨ï |
* esi = ¤«¨ á®®¡é¥¨ï (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯à¨ñ¬¨ª ¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥¨© |
(¬®¦¥â ¡ëâì, ¥éñ ¥ ãᯥ«, ¬®¦¥â ¡ëâì, íâ® ¥ â®â ¯®â®ª, |
ª®â®àë© ã¦¥) |
* eax = 2 - ¯à¨ñ¬¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à; |
¯®¯à®¡ã©â¥ ¥¬®£® ¯®¤®¦¤ âì |
* eax = 3 - ¯¥à¥¯®«¥¨¥ IPC-¡ãä¥à ¯à¨ñ¬¨ª |
* eax = 4 - ¯à®æ¥áá /¯®â®ª á â ª¨¬ PID ¥ áãé¥áâ¢ã¥â |
¬¥ç ¨ï: |
* ¨á⥬ áà §ã ¯®á«¥ § ¯¨á¨ IPC-á®®¡é¥¨ï ¢ ¡ãä¥à ¯®áë« ¥â |
¯®â®ªã-¯à¨ñ¬¨ªã ᮡë⨥ á ª®¤®¬ 7 (á¬. ª®¤ë ᮡë⨩). |
====================================================================== |
=== ãªæ¨ï 61 - ¯®«ãç¨âì ¯ à ¬¥âàë ¤«ï ¯àאַ£® ¤®áâ㯠ª £à 䨪¥. === |
====================================================================== |
à®£à ¬¬¥ ¤®áâã¯ë ¤ ë¥ £à ä¨ç¥áª®£® íªà (®¡« áâì ¯ ¬ïâ¨, ª®â®à ï |
ᮡá⢥® ¨ ®â®¡à ¦ ¥â ᮤ¥à¦¨¬®¥ íªà ) ¯àï¬ãî ¡¥§ ¢ë§®¢®¢ |
á¨á⥬ëå äãªæ¨© ç¥à¥§ ᥫ¥ªâ®à gs: |
mov eax, [gs:0] |
¯®¬¥áâ¨â ¢ eax ¯¥à¢ë© dword ¡ãä¥à , ᮤ¥à¦ 騩 ¨ä®à¬ æ¨î ® 梥⥠|
«¥¢®© ¢¥à奩 â®çª¨ (¨, ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
mov [gs:0], eax |
¯à¨ à ¡®â¥ ¢ ०¨¬ å VESA c LFB |
ãáâ ®¢¨â 梥⠫¥¢®© ¢¥à奩 â®çª¨ |
(¨ ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
«ï ¨â¥à¯à¥â 樨 ¤ ëå £à ä¨ç¥áª®£® íªà âॡã¥âáï § ¨¥ |
¥ª®â®àëå ¯ à ¬¥â஢, ª®â®àë¥ ¢®§¢à é îâáï í⮩ äãªæ¨¥©. |
¬¥ç ¨ï: |
* à ¬¥âàë £à 䨪¨ ®ç¥ì ।ª® ¬¥ïîâáï ¯à¨ à ¡®â¥ á¨á⥬ë, |
¨¬¥®, ⮫쪮 ¢ á«ãç ïå, ª®£¤ ¯®«ì§®¢ ⥫ì à ¡®â ¥â |
á ¯à®£à ¬¬®© VRR. |
* ਠ¨§¬¥¥¨¨ ¢¨¤¥®à¥¦¨¬ á¨á⥬ ¯¥à¥à¨á®¢ë¢ ¥â ¢á¥ ®ª |
(ᮡë⨥ á ª®¤®¬ 1) ¨ ¯¥à¥à¨á®¢ë¢ ¥â ä® (ᮡë⨥ 5). |
⨠¦¥ ᮡëâ¨ï ¯à®¨á室ïâ ¨ ¢ ¤à㣨å á«ãç ïå, |
ª®â®àë¥ ¢áâà¥ç îâáï § ç¨â¥«ì® ç é¥, 祬 ¨§¬¥¥¨¥ ¢¨¤¥®à¥¦¨¬ . |
* à¨ à ¡®â¥ ¢ ¢¨¤¥®à¥¦¨¬ å á LFB ᥫ¥ªâ®à gs 㪠§ë¢ ¥â |
ᮡá⢥® LFB, â ª çâ® ç⥨¥/§ ¯¨áì ¯® gs ¯à¨¢®¤ïâ |
¥¯®á।á⢥® ª ¨§¬¥¥¨î ᮤ¥à¦¨¬®£® íªà . à¨ à ¡®â¥ ¢ |
¢¨¤¥®à¥¦¨¬ å ¡¥§ LFB gs 㪠§ë¢ ¥â ¥ª®â®àãî ®¡« áâì ¤ ëå |
ï¤à , ¯à¨çñ¬ ¢á¥ äãªæ¨¨ ¢ë¢®¤ íªà ¤®¡à®á®¢¥áâ® ¢ë¯®«ïîâ |
¤¢®©ãî à ¡®âã ¯® § ¯¨á¨ ¥¯®á।á⢥® íªà ¨ ¯® § ¯¨á¨ |
¢ íâ®â ¡ãä¥à. १ã«ìâ ⥠¯à¨ ç⥨¨ ᮤ¥à¦¨¬®£® í⮣® ¡ãä¥à |
१ã«ìâ âë ᮮ⢥âáâ¢ãîâ ᮤ¥à¦¨¬®¬ã íªà |
(á, ¢®®¡é¥ £®¢®àï, ¡®«ì訬 æ¢¥â®¢ë¬ à §à¥è¥¨¥¬), |
§ ¯¨áì ¨£®à¨àã¥âáï. |
᪫î票¥¬ ï¥âáï ०¨¬ 320*200, ¤«ï ª®â®à®£® ¢ £« ¢®¬ 横«¥ |
á¨á⥬®£® ¯®â®ª ¢ë¯®«ï¥âáï ®¡®¢«¥¨¥ íªà ¢ ᮮ⢥âá⢨¨ |
á ¤¢¨¦¥¨ï¬¨ ªãàá®à ¬ëè¨. |
------------------------- §à¥è¥¨¥ íªà -------------------------- |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [à §à¥è¥¨¥ ¯® ®á¨ x]*65536 + [à §à¥è¥¨¥ ¯® ®á¨ y] |
¬¥ç ¨ï: |
* ®¦® ¨á¯®«ì§®¢ âì äãªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ® ¢®§¢à é ¥â |
à §¬¥àë 1 ¬¥ìè¥. â® ¯®«®áâìî íª¢¨¢ «¥âë© á¯®á®¡. |
------------------------ ¨á«® ¡¨â ¯¨ªá¥«ì ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡¨â ¯¨ªá¥«ì (24 ¨«¨ 32) |
------------------------ ¨á«® ¡ ©â áâபã ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡ ©â, ª®â®à®¥ § ¨¬ ¥â ®¤ áâப à §¢ñà⪨ |
(£®à¨§®â «ì ï «¨¨ï íªà ¥) |
====================================================================== |
===== ãªæ¨ï 62, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ¢¥àá¨î PCI-¨â¥à䥩á . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* ah.al = ¢¥àá¨ï PCI-¨â¥à䥩á (ah=¢¥àá¨ï, al=¯®¤¢¥àá¨ï) |
* áâ à襥 á«®¢® eax ®¡ã«¥® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ ax ¥®¯à¥¤¥«¥®. |
====================================================================== |
==== ãªæ¨ï 62, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ®¬¥à ¯®á«¥¤¥© PCI-è¨ë. === |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ®¬¥à ¯®á«¥¤¥© PCI-è¨ë; ®á⠢訥áï ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ al ¥®¯à¥¤¥«¥®. |
====================================================================== |
====================== ãªæ¨ï 62, ¯®¤äãªæ¨ï 2 ====================== |
== ®«ãç¨âì ¬¥å ¨§¬ ®¡à é¥¨ï ª ª®ä¨£ãà 樮®¬ã ¯à®áâà áâ¢ã PCI. = |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ¬¥å ¨§¬ (1 ¨«¨ 2); ¯à®ç¨¥ ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ®¡à é¥¨ï ¢ë¡¨à ¥âáï ¢ ᮮ⢥âá⢨¨ |
á å à ªâ¥à¨á⨪ ¬¨ ®¡®à㤮¢ ¨ï. |
* ®¤äãªæ¨¨ çâ¥¨ï ¨ § ¯¨á¨ ¢â®¬ â¨ç¥áª¨ à ¡®â îâ |
á ¢ë¡à ë¬ ¬¥å ¨§¬®¬. |
====================================================================== |
======== ãªæ¨ï 62, ¯®¤äãªæ¨¨ 4,5,6 - ¯à®ç¨â âì PCI-ॣ¨áâà. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 4 - ç¨â âì ¡ ©â |
* bl = 5 - ç¨â âì á«®¢® |
* bl = 6 - ç¨â âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=5, |
¤¥«¨âìáï 4 ¤«ï bl=6) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë); ¨ ç¥ |
* al/ax/eax (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â ¤ ë¥; |
®áâ ¢è ïáï ç áâì ॣ¨áâà eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
======= ãªæ¨ï 62, ¯®¤äãªæ¨¨ 8,9,10 - § ¯¨á âì ¢ PCI-ॣ¨áâà. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 8 - ¯¨á âì ¡ ©â |
* bl = 9 - ¯¨á âì á«®¢® |
* bl = 10 - ¯¨á âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=9, |
¤¥«¨âìáï 4 ¤«ï bl=10) |
* dl/dx/edx (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â |
¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë) |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown; |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
================ ãªæ¨ï 63 - à ¡®â á ¤®áª®© ®â« ¤ª¨. =============== |
====================================================================== |
®áª ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨áâ¥¬ë© ¡ãä¥à ( 4096 ¡ ©â), |
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬ ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ìë¥) |
¤ ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬ ¬®¦¥â í⨠¤ ë¥ ¯à®ç¨â âì. |
áâì ᮣ« 襨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨áë¢ ¥¬ë¥ ¤ ë¥ - |
⥪áâ®¢ë¥ áâப¨, ¨â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®çë¥ á®®¡é¥¨ï ® 室¥ |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë. ¤à® ¢ ®¯à¥¤¥«ñëå á¨âã æ¨ïå â ª¦¥ § ¯¨áë¢ ¥â |
¤®áªã ®â« ¤ª¨ ᢥ¤¥¨ï ® ¢ë¯®«¥¨¨ ¥ª®â®àëå äãªæ¨©; |
¯® ᮣ« 襨î á®®¡é¥¨ï ï¤à ç¨ îâáï á ¯à¥ä¨ªá "K : ". |
«ï ¯à®á¬®âà ¤®áª¨ ®â« ¤ª¨ ᮧ¤ ® ¯à¨«®¦¥¨¥ board, |
ª®â®à®¥ áç¨âë¢ ¥â ¤ ë¥ ¨§ ¡ãä¥à ¨ ®â®¡à ¦ ¥â ¨å ¢ ᢮ñ¬ ®ª¥. board |
¯®¨¬ ¥â ¯®á«¥¤®¢ ⥫ì®áâì ª®¤®¢ 13,10 ª ª ¯¥à¥å®¤ ®¢ãî áâபã. |
¨¬¢®« á ã«¥¢ë¬ ª®¤®¬ ¢ ª®æ¥ áâப¨ ¥ ®¡ï§ ⥫¥, ® ¨ ¥ ¬¥è ¥â. |
á¢ï§¨ á ¯®ï¢«¥¨¥¬ ®â« ¤ç¨ª 楮áâì ¤®áª¨ ®â« ¤ª¨ ¥áª®«ìª® |
ᨧ¨« áì, ¯®áª®«ìªã ®â« ¤ç¨ª ¯®§¢®«ï¥â ¯®«®áâìî ª®â஫¨à®¢ âì 室 |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë, ¯à¨çñ¬ ¤«ï í⮣® ¥ âॡã¥âáï ¨ª ª¨å ãᨫ¨© |
á® áâ®à®ë á ¬®© ¯à®£à ¬¬ë. ¥¬ ¥ ¬¥¥¥ ¢® ¬®£¨å á«ãç ïå |
¤®áª ®â« ¤ª¨ ¯à®¤®«¦ ¥â ®áâ ¢ âìáï ¯®«¥§®©. |
---------------------------- ¯¨áì ¡ ©â ---------------------------- |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ©â § ¯¨áë¢ ¥âáï ¢ ¡ãä¥à. «¨ ¡ãä¥à - 512 ¡ ©â. |
ਠ¯¥à¥¯®«¥¨¨ ¡ãä¥à ¢á¥ ¯®«ãç¥ë¥ ¤ ë¥ â¥àïîâáï |
¨ § ¯®«¥¨¥ ç¨ ¥âáï ᮢ á ã«ï. |
* «ï ¢ë¢®¤ ¤®áªã ®â« ¤ª¨ ¡®«¥¥ á«®¦ëå ®¡ê¥ªâ®¢ (áâப, ç¨á¥«) |
¤®áâ â®ç® í⮩ äãªæ¨¨, ¢ë§ë¢ ¥¬®© ¢ 横«¥. ®¦® ¥ ¯¨á âì |
¢àãçãî ᮮ⢥âáâ¢ãî騩 ª®¤, ¢®á¯®«ì§®¢ âìáï ä ©«®¬ debug.inc, |
¢å®¤ï騬 ¢ ¤¨áâਡã⨢. |
---------------------------- ⥨¥ ¡ ©â ---------------------------- |
¡¨à ¥â ¡ ©â ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ebx = 0 - ¡ãä¥à ¯ãáâ |
* eax = ¡ ©â, ebx = 1 - ¡ ©â ãá¯¥è® ¯à®ç¨â |
====================================================================== |
========== ãªæ¨ï 64 - ¯¥à¥à á¯à¥¤¥«¨âì ¯ ¬ïâì ¯à¨«®¦¥¨ï. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 64 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ®¢ë© à §¬¥à ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥¤®áâ â®ç® ¯ ¬ï⨠|
¬¥ç ¨ï: |
* áâì ¤à㣮© ᯮᮡ ¢ë¤¥«¥¨ï/®á¢®¡®¦¤¥¨ï ¤¨ ¬¨ç¥áª®© ¯ ¬ï⨠- |
¯®¤äãªæ¨¨ 11, 12, 13 äãªæ¨¨ 68. |
* ãªæ¨ï ¥ ¬®¦¥â ¨á¯®«ì§®¢ âìáï ᮢ¬¥áâ® á 68.11, 68.12, 68.13. |
맮¢ äãªæ¨¨ ¡ã¤¥â ¨£®à¨à®¢ âìáï, ¥á«¨ ¯à¨«®¦¥¨¥ ᮧ¤ áâ |
«®ª «ìãî ªãç㠢맮¢®¬ 68.11. |
====================================================================== |
========= ãªæ¨ï 65 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ á ¯ «¨âன ¢ ®ª®. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 65 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = ç¨á«® ¡¨â ¯¨ªá¥«ì, ¤®«¦® ¡ëâì 1,2,4,8,15,16,24 ¨«¨ 32 |
* edi = 㪠§ â¥«ì ¯ «¨âàã (2 ¢ á⥯¥¨ esi 梥⮢ 0x00RRGGBB); |
¨£®à¨àã¥âáï ¯à¨ esi > 8 |
* ebp = ᬥ饨¥ ¤ ëå ª ¦¤®© á«¥¤ãî饩 áâப¨ ¨§®¡à ¦¥¨ï |
®â®á¨â¥«ì® ¯à¥¤ë¤ã饩 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* ®à¬ â ¨§®¡à ¦¥¨ï á 1 ¡¨â®¬ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â |
¨ä®à¬ æ¨î ® 梥⥠8 ¯¨ªá¥«¥©, áâ à訩 ¡¨â ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã |
¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 2 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â |
¨ä®à¬ æ¨î ® 梥⥠4 ¯¨ªá¥«¥©, áâ à訥 ¤¢ ¡¨â ᮮ⢥âáâ¢ãîâ |
¯¥à¢®¬ã ¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 4 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬ ¯®á«¥¤¨å ¡ ©â®¢ áâப (¥á«¨ è¨à¨ ¨§®¡à ¦¥¨ï |
¥çñâ ), ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® 梥⥠2 ¯¨ªá¥«¥©, áâ àè ï â¥âà ¤ |
ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã ¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 8 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï |
à áᬠâਢ ¥âáï ª ª ¨¤¥ªá ¢ ¯ «¨âà¥. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 15 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï ª ª (¢ ¡¨â®¢®¬ ¯à¥¤áâ ¢«¥¨¨) 0RRRRRGGGGGBBBBB - |
¯® 5 ¯¨ªá¥«¥© ª ¦¤ë© 梥â. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 16 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï ª ª RRRRRGGGGGGBBBBB (á奬 5+6+5). |
* ®à¬ â ¨§®¡à ¦¥¨ï á 24 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï âà¥¬ï ¡ ©â ¬¨ - ¯®á«¥¤®¢ â¥«ì® á¨ïï, §¥«ñ ï, ªà á ï |
á®áâ ¢«ïî騥 梥â . |
* ®à¬ â ¨§®¡à ¦¥¨ï á 32 ¡¨â ¬¨ ¯¨ªá¥«ì: «®£¨ç® 24, ⮫쪮 |
¥áâì ¥éñ ¨£®à¨àã¥¬ë© ç¥â¢ñàâë© ¡ ©â. |
* 맮¢ äãªæ¨¨ 7 íª¢¨¢ «¥â¥ ¢ë§®¢ã í⮩ äãªæ¨¨ á ¯ à ¬¥âà ¬¨ |
esi=24, ebp=0. |
====================================================================== |
================= ãªæ¨ï 66 - à ¡®â á ª« ¢¨ âãன. ================= |
====================================================================== |
¥¦¨¬ ¢¢®¤ ¢«¨ï¥â १ã«ìâ âë çâ¥¨ï ª« ¢¨è äãªæ¨¥© 2. |
ਠ§ £à㧪¥ ¯à®£à ¬¬ë ¤«ï ¥ñ ãáâ ¢«¨¢ ¥âáï ASCII-०¨¬ ¢¢®¤ . |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. --------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬: |
* 0 = ®¡ëçë© (ASCII-ᨬ¢®«ë) |
* 1 = ᪠ª®¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. ---------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ã騩 ०¨¬ |
------- ®¤äãªæ¨ï 3 - ¯®«ãç¨âì á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è. -------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡¨â®¢ ï ¬ ᪠: |
* ¡¨â 0 (¬ ᪠1): «¥¢ë© Shift ¦ â |
* ¡¨â 1 (¬ ᪠2): ¯à ¢ë© Shift ¦ â |
* ¡¨â 2 (¬ ᪠4): «¥¢ë© Ctrl ¦ â |
* ¡¨â 3 (¬ ᪠8): ¯à ¢ë© Ctrl ¦ â |
* ¡¨â 4 (¬ ᪠0x10): «¥¢ë© Alt ¦ â |
* ¡¨â 5 (¬ ᪠0x20): ¯à ¢ë© Alt ¦ â |
* ¡¨â 6 (¬ ᪠0x40): CapsLock ¢ª«îçñ |
* ¡¨â 7 (¬ ᪠0x80): NumLock ¢ª«îçñ |
* ¡¨â 8 (¬ ᪠0x100): ScrollLock ¢ª«îçñ |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
----- ®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ®¡é¥á¨á⥬ãî "£®àïçãî ª« ¢¨èã". ----- |
¦ ⨨ "£®àï祩 ª« ¢¨è¨" ¨§¢¥é îâáï ⮫쪮 ¯à¨«®¦¥¨ï, |
ãáâ ®¢¨¢è¨¥ ¥ñ; ªâ¨¢®¥ ¯à¨«®¦¥¨¥ (ª ª®â®à®¬ã ¯®áâ㯠¥â |
¢¥áì ®à¬ «ìë© ¢¢®¤) â ª¨å ª« ¢¨è ¥ ¯®«ãç ¥â. |
§¢¥é¥¨¥ § ª«îç ¥âáï ¢ ¯®á뫪¥ ᮡëâ¨ï á ª®¤®¬ 2. |
à®ç¨â âì "£®àïçãî ª« ¢¨èã" ¬®¦® â ª ¦¥, ª ª ¨ ®¡ëçãî, - |
äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl § ¤ ñâ ᪠ª®¤ ª« ¢¨è¨; |
¨á¯®«ì§ã©â¥ cl=0 ¤«ï § ¤ ¨ï ª®¬¡¨ 権 ⨯ Ctrl+Shift |
* edx = 0xXYZ § ¤ ñâ ¢®§¬®¦ë¥ á®áâ®ï¨ï ã¯à ¢«ïîé¨å ª« ¢¨è: |
* Z (¬« ¤è¨¥ 4 ¡¨â ) § ¤ ñâ á®áâ®ï¨¥ ª« ¢¨è LShift ¨ RShift: |
* 0 = ¨ ®¤ ¨§ ª« ¢¨è ¥ ¤®«¦ ¡ëâì ¦ â ; |
* 1 = ஢® ®¤ ¨§ ª« ¢¨è ¤®«¦ ¡ëâì ¦ â ; |
* 2 = ®¡¥ ª« ¢¨è¨ ¤®«¦ë ¡ëâì ¦ âë; |
* 3 = ¤®«¦ ¡ëâì ¦ â LShift, ® ¥ RShift; |
* 4 = ¤®«¦ ¡ëâì ¦ â RShift, ® ¥ LShift |
* Y - «®£¨ç® ¤«ï LCtrl ¨ RCtrl; |
* X - «®£¨ç® ¤«ï LAlt ¨ RAlt |
®§¢à é ¥¬®¥ § 票¥: |
* eax=0 - ãá¯¥è® |
* eax=1 - ᫨誮¬ ¬®£® "£®àïç¨å ª« ¢¨è" (¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 256) |
¬¥ç ¨ï: |
* ®àïç ï ª« ¢¨è ¬®¦¥â áà ¡ âë¢ âì «¨¡® ¯à¨ ¦ ⨨, |
«¨¡® ¯à¨ ®â¯ã᪠¨¨. ª ª®¤ ®â¯ã᪠¨ï ª« ¢¨è¨ 128 ¡®«ìè¥, |
祬 ᪠ª®¤ ¦ â¨ï (â.¥. ãáâ ®¢«¥ áâ à訩 ¡¨â). |
* ¥áª®«ìª® ¯à¨«®¦¥¨© ¬®£ãâ ãáâ ®¢¨âì ®¤ã ¨ âã ¦¥ ª®¬¡¨ æ¨î; |
® ¦ ⨨ â ª®© ª®¬¡¨ 樨 ¡ã¤ãâ ¨§¢¥é âìáï ¢á¥ â ª¨¥ ¯à¨«®¦¥¨ï. |
------ ®¤äãªæ¨ï 5 - 㤠«¨âì ãáâ ®¢«¥ãî "£®àïçãî ª« ¢¨èã". ------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ᪠ª®¤ ª« ¢¨è¨ ¨ edx = 0xXYZ â ª¨¥ ¦¥, ª ª ¨ ¢ ¯®¤äãªæ¨¨ 4 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥â â ª®© £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ਠ§ ¢¥à襨¨ ¯à®æ¥áá /¯®â®ª 㤠«ïîâáï ¢á¥ ãáâ ®¢«¥ë¥ ¨¬ |
£®àï稥 ª« ¢¨è¨. |
* 맮¢ äãªæ¨¨ ¥ ¢«¨ï¥â ¤à㣨¥ ¯à¨«®¦¥¨ï. |
᫨ ¤à㣮¥ ¯à¨«®¦¥¨¥ ®¯à¥¤¥«¨«® íâã ¦¥ ª®¬¡¨ æ¨î, |
®® ¯®-¯à¥¦¥¬ã ¡ã¤¥â ¯®«ãç âì 㢥¤®¬«¥¨ï. |
====================================================================== |
============ ãªæ¨ï 67 - ¨§¬¥¨âì ¯®«®¦¥¨¥/à §¬¥àë ®ª . =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 67 - ®¬¥à äãªæ¨¨ |
* ebx = ®¢ ï x-ª®®à¤¨ â ®ª |
* ecx = ®¢ ï y-ª®®à¤¨ â ®ª |
* edx = ®¢ë© x-à §¬¥à ®ª |
* esi = ®¢ë© y-à §¬¥à ®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 票¥ -1 ¤«ï ¯ à ¬¥âà ®§ ç ¥â "¥ ¨§¬¥ïâì"; ¯à¨¬¥à, ¤«ï |
¯¥à¥¬¥é¥¨ï ®ª ¡¥§ ¨§¬¥¥¨ï à §¬¥à®¢ ¬®¦® 㪠§ âì edx=esi=-1. |
* ।¢ à¨â¥«ì® ®ª® ¤®«¦® ¡ëâì ®¯à¥¤¥«¥® äãªæ¨¥© 0. |
¦¥ § ¤ ñâ ç «ìë¥ ª®®à¤¨ âë ¨ à §¬¥àë ®ª . |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ äãªæ¨¨ 0, â.¥. |
®¤¨ ¯¨ªá¥«ì ¬¥ìè¥, 祬 ॠ«ìë¥ à §¬¥àë. |
* 맮¢ äãªæ¨¨ ¤«ï ¬ ªá¨¬¨§¨à®¢ ëå ®ª® ¯à®áâ® ¨£®à¨àã¥âáï. |
* «ï ®ª® ᮮ⢥âáâ¢ãîé¨å á⨫¥© ¯®«®¦¥¨¥ ¨/¨«¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¨§¬¥¥ë ¯®«ì§®¢ ⥫¥¬; ⥪ã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ãªæ¨ï ¯®áë« ¥â ®ªã ᮡë⨥ ¯¥à¥à¨á®¢ª¨ (á ª®¤®¬ 1). |
====================================================================== |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì áçñâ稪 ¯¥à¥ª«î票© § ¤ ç. == |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯¥à¥ª«î票© § ¤ ç á ¬®¬¥â § £à㧪¨ á¨á⥬ë |
(¯® ¬®¤ã«î 2^32) |
====================================================================== |
====================== ãªæ¨ï 68, ¯®¤äãªæ¨ï 1 ====================== |
============ ¥à¥ª«îç¨âìáï á«¥¤ãî騩 ¯®â®ª ¢ë¯®«¥¨ï. ============ |
====================================================================== |
ãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ª¢ ⠢६¥¨, ¢ë¤¥«¥ë© ¯®â®ªã, |
¨ ¯¥à¥ª«îç ¥âáï á«¥¤ãî騩. |
( ª®© ¯®â®ª ª ª®£® ¯à®æ¥áá ¡ã¤¥â á«¥¤ãî騬, ¯à¥¤áª § âì ¥«ì§ï). |
®§¤¥¥, ª®£¤ ¤® ⥪ã饣® ¯®â®ª ¤®©¤ñâ ®ç¥à¥¤ì, |
¢ë¯®«¥¨¥ ¢®§®¡®¢¨âáï. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
=============== ãªæ¨ï 68, ¯®¤äãªæ¨ï 2 - ªíè + rdpmc. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âॡ㥬®¥ ¤¥©á⢨¥: |
* ecx = 0 - à §à¥è¨âì ¢ë¯®«¥¨¥ ¨áâàãªæ¨¨ rdpmc |
(ReaD Performance-Monitoring Counters) |
* ecx = 1 - 㧠âì, ¢ª«îçñ/¢ëª«îç¥ ªíè |
* ecx = 2 - ¢ª«îç¨âì ªíè |
* ecx = 3 - ¢ëª«îç¨âì ªíè |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: |
* eax = § 票¥ cr4 |
* ¤«ï ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - ªíè ¢ª«îçñ |
* eax <> 0 - ªíè ¢ëª«îç¥ |
* ¤«ï ecx=2 ¨ ecx=3: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
®§¢à é ¥¬®¥ § 票¥: |
* ebx:eax = áâ à訩:¬« ¤è¨© dword १ã«ìâ â |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥çñ⠨᪫î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢áñ à ¢® ¯à¨¡ìñâ ¯®â®ª. |
====================================================================== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
* esi:edi = áâ à訩:¬« ¤è¨© dword |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥çñ⠨᪫î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢áñ à ¢® ¯à¨¡ìñâ ¯®â®ª. |
====================================================================== |
===== ãªæ¨ï 68, ¯®¤äãªæ¨ï 11 - ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ãᯥå |
* ¨ ç¥ à §¬¥à ᮧ¤ ®© ªãç¨ |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ¨¨æ¨ «¨§¨àã¥â ªãçã, ¨§ ª®â®à®© ¢¯®á«¥¤á⢨¨ ¬®¦® |
¢ë¤¥«ïâì ¨ ®á¢®¡®¦¤ âì ¡«®ª¨ ¯ ¬ï⨠¯®¤äãªæ¨ï¬¨ 12 ¨ 13. |
§¬¥à ªãç¨ à ¢¥ à §¬¥à㠢ᥩ ᢮¡®¤®© ¯ ¬ï⨠¯à¨«®¦¥¨ï. |
* ਠ¯®¢â®à®¬ ¢ë§®¢¥ äãªæ¨¨ ⥬ ¦¥ ¯à®æ¥áᮬ äãªæ¨ï ¢¥àñâ |
à §¬¥à áãé¥áâ¢ãî饩 ªãç¨. |
* ®á«¥ ᮧ¤ ¨ï ªãç¨ ¢ë§®¢ë äãªæ¨¨ 64 ¨£®à¨àãîâáï. |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 12 - ¢ë¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âà¥¡ã¥¬ë© à §¬¥à ¢ ¡ ©â å |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¢ë¤¥«¥ë© ¡«®ª |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
====================================================================== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 13 - ®á¢®¡®¤¨âì ¡«®ª ¯ ¬ïâ¨. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - ãá¯¥è® |
* eax = 0 - ¥ã¤ ç |
¬¥ç ¨ï: |
* «®ª ¯ ¬ï⨠¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 |
¨«¨ ¯®¤äãªæ¨¥© 20. |
====================================================================== |
==================== ãªæ¨ï 68, ¯®¤äãªæ¨ï 14 ======================= |
===== ¦¨¤ âì ¯®«ã票ï ᨣ « , ®â ¤àã£¨å ¯à¨«®¦¥¨©/¤à ©¢¥à®¢. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¨ä®à¬ 樨 (24 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ¨¤¥â¨ä¨ª â®à ¯®á«¥¤ãîé¨å ¤ ëå ᨣ « |
* +4: ¤ ë¥ ¯à¨ï⮣® ᨣ « (20 ¡ ©â), ä®à¬ â ª®â®àëå |
®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ dword-®¬ |
====================================================================== |
== ãªæ¨ï 68, ¯®¤äãªæ¨ï 15 - ãáâ ®¢¨âì ®¡à ¡®â稪 ¨áª«î票© FPU. = |
====================================================================== |
¤ «¥ (¢ ⥪ã饩 ॠ«¨§ 樨 ¯à®áâ® ¢®§¢à é ¥â 0) |
ᯮ«ì§®¢ âì ¯®¤äãªæ¨¨ 24, 25 |
====================================================================== |
=========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 16 - § £à㧨âì ¤à ©¢¥à. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 16 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ¤à ©¢¥à |
¬¥ç ¨ï: |
* ᫨ ¤à ©¢¥à ¥éñ ¥ § £à㦥, ® § £à㦠¥âáï; |
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥, ¨ç¥£® ¥ ¬¥ï¥âáï. |
* ¬ï ¤à ©¢¥à çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã ᨬ¢®«®¢. |
ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ - 16 ᨬ¢®«®¢, ¢ª«îç ï § ¢¥àè î騩 |
ã«¥¢®© ᨬ¢®«, ®áâ «ìë¥ á¨¬¢®«ë ¨£®à¨àãîâáï. |
* à ©¢¥à á ¨¬¥¥¬ ABC § £à㦠¥âáï ¨§ ä ©« /rd/1/drivers/ABC.obj. |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 17 - ã¯à ¢«¥¨¥ ¤à ©¢¥à®¬. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ã¯à ¢«ïîéãî áâàãªâãàã: |
* +0: dword: åí¤« ¤à ©¢¥à |
* +4: dword: ª®¤ äãªæ¨¨ ¤à ©¢¥à |
* +8: dword: 㪠§ â¥«ì ¢å®¤ë¥ ¤ ë¥ |
* +12 = +0xC: dword: à §¬¥à ¢å®¤ëå ¤ ëå |
* +16 = +0x10: dword: 㪠§ â¥«ì ¢ëå®¤ë¥ ¤ ë¥ |
* +20 = +0x14: dword: à §¬¥à ¢ë室ëå ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¯à¥¤¥«ï¥âáï ¤à ©¢¥à®¬ |
¬¥ç ¨ï: |
* ®¤ë äãªæ¨© ¨ áâàãªâãà ¢å®¤ëå/¢ë室ëå ¤ ëå |
®¯à¥¤¥«ïîâáï ¤à ©¢¥à®¬. |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¯®«ãç¥ åí¤« ¤à ©¢¥à ¯®¤äãªæ¨¥© 16. |
====================================================================== |
== ãªæ¨ï 68, ¯®¤äãªæ¨ï 18 - ãáâ ®¢¨âì ®¡à ¡®â稪 ¨áª«î票© SSE. = |
====================================================================== |
¤ «¥ (¢ ⥪ã饩 ॠ«¨§ 樨 ¯à®áâ® ¢®§¢à é ¥â 0) |
ᯮ«ì§®¢ âì ¯®¤äãªæ¨¨ 24, 25 |
====================================================================== |
============= ãªæ¨ï 68, ¯®¤äãªæ¨ï 19 - § £à㧨âì DLL. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯®«ë¬ ¯ãâñ¬ ª DLL |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = 㪠§ ⥫ì â ¡«¨æã íªá¯®àâ DLL |
¬¥ç ¨ï: |
* ¡«¨æ íªá¯®à⠯।áâ ¢«ï¥â ᮡ®© ¬ áᨢ áâàãªâãà ¯® 2 dword' , |
§ ª 稢 î騩áï ã«ñ¬. ¥à¢ë© dword ¢ áâàãªâãॠï¥âáï |
㪠§ ⥫¥¬ ¨¬ï äãªæ¨¨, ¢â®à®© ᮤ¥à¦¨â ¤à¥á äãªæ¨¨. |
====================================================================== |
====== ãªæ¨ï 68, ¯®¤äãªæ¨ï 20 - ¯¥à¥à á¯à¥¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 20 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¢ë© à §¬¥à ¢ ¡ ©â å |
* edx = 㪠§ ⥫ì 㦥 ¢ë¤¥«¥ë© ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¯¥à¥à á¯à¥¤¥«ñë© ¡«®ª, 0 ¯à¨ ®è¨¡ª¥ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
* ᫨ edx=0, â® ¢ë§®¢ äãªæ¨¨ íª¢¨¢ «¥â¥ ¢ë¤¥«¥¨î ¯ ¬ï⨠|
¯®¤äãªæ¨¥© 12. ¯à®â¨¢®¬ á«ãç ¥ ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx |
¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 ¨«¨ |
®¯¨áë¢ ¥¬®© ¯®¤äãªæ¨¥©. |
* ᫨ ecx=0, â® äãªæ¨ï ®á¢®¡®¦¤ ¥â ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx ¨ |
¢®§¢à é ¥â 0. |
* ®¤¥à¦¨¬®¥ ¯ ¬ï⨠¢¯«®âì ¤® ¨¬¥ì襣® ¨§ áâ ண® ¨ ®¢®£® |
à §¬¥à®¢ á®åà ï¥âáï. |
====================================================================== |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 22 - ®âªàëâì ¨¬¥®¢ ãî ®¡« áâì ¯ ¬ïâ¨. == |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 22 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¬ï ®¡« áâ¨. ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ®«ì |
* edx = à §¬¥à ®¡« á⨠¢ ¡ ©â å ¤«ï SHM_CREATE ¨ SHM_OPEN_ALWAYS |
* esi = ä« £¨ ®âªàëâ¨ï ¨ ¤®áâ㯠: |
* SHM_OPEN = 0x00 - ®âªàëâì áãé¥áâ¢ãîéãî ®¡« áâì ¯ ¬ïâ¨. |
᫨ ®¡« áâì á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥áâ¢ã¥â, |
äãªæ¨ï ¢¥àñâ ª®¤ ®è¨¡ª¨ 5. |
* SHM_OPEN_ALWAYS = 0x04 - ®âªàëâì áãé¥áâ¢ãîéãî ¨«¨ ᮧ¤ âì ®¢ãî |
®¡« áâì ¯ ¬ïâ¨. |
* SHM_CREATE = 0x08 - ᮧ¤ âì ®¢ãî ®¡« áâì ¯ ¬ïâ¨. |
᫨ ®¡« áâì á â ª¨¬ ¨¬¥¥¬ 㦥 áãé¥áâ¢ã¥â, |
äãªæ¨ï ¢¥àñâ ª®¤ ®è¨¡ª¨ 10. |
* SHM_READ = 0x00 - ¤®áâ㯠⮫쪮 ç⥨¥ |
* SHM_WRITE = 0x01 - ¤®áâ㯠ç⥨¥ ¨ § ¯¨áì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ®¡« áâì ¯ ¬ïâ¨, 0 ¯à¨ ®è¨¡ª¥ |
* ¯à¨ ᮧ¤ ¨¨ ®¢®© ®¡« á⨠(SHM_CREATE ¨«¨ SHM_OPEN_ALWAYS): |
edx = 0 - ãᯥå, ¨ ç¥ - ª®¤ ®è¨¡ª¨ |
* ¯à¨ ®âªàë⨨ áãé¥áâ¢ãî饩 ®¡« á⨠(SHM_OPEN ¨«¨ SHM_OPEN_ALWAYS): |
edx = ª®¤ ®è¨¡ª¨ (¯à¨ eax=0) ¨«¨ à §¬¥à ®¡« á⨠¢ ¡ ©â å |
®¤ë ®è¨¡®ª: |
* E_NOTFOUND = 5 |
* E_ACCESS = 10 |
* E_NOMEM = 30 |
* E_PARAM = 33 |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ᫨ ᮧ¤ ñâáï ®¢ ï ®¡« áâì, â® ä« £¨ ¤®áâ㯠ãáâ ¢«¨¢ îâ |
¬ ªá¨¬ «ìë¥ ¯à ¢ ¤®áâ㯠¤«ï ®áâ «ìëå ¯à®æ¥áᮢ. ®¯ë⪠|
®âªàëâ¨ï ¤à㣨¬ ¯®â®ª®¬ á ¥à §à¥èñ묨 ¯à ¢ ¬¨ ¯à®¢ «¨âáï |
á ª®¤®¬ ®è¨¡ª¨ E_ACCESS. |
* à®æ¥áá, ᮧ¤ ¢è¨© ®¡« áâì, ¢á¥£¤ ¨¬¥¥â ¤®áâ㯠§ ¯¨áì. |
====================================================================== |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 23 - § ªàëâì ¨¬¥®¢ ãî ®¡« áâì ¯ ¬ïâ¨. == |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 23 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¬ï ®¡« áâ¨. ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ®«ì |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¡« áâì ¯ ¬ï⨠䨧¨ç¥áª¨ ®á¢®¡®¦¤ ¥âáï (á § ¡ë¢ ¨¥¬ ¢á¥å ¤ ëå |
¨ ¢ë᢮¡®¦¤¥¨¥¬ 䨧¨ç¥áª®© ¯ ¬ïâ¨), ª®£¤ ¥ñ § ªà®îâ |
¢á¥ ®âªàë¢è¨¥ ¯®â®ª¨. |
* ਠ§ ¢¥à襨¨ ¯®â®ª ®á¢®¡®¦¤ îâáï ¢á¥ ®âªàëâë¥ ¨¬ |
®¡« á⨠¯ ¬ïâ¨. |
====================================================================== |
==== ãªæ¨ï 68, ¯®¤äãªæ¨ï 24 - ãáâ ®¢¨âì ®¡à ¡®â稪 ¨áª«î票© === |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 24 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á ®¢®£® ®¡à ¡®â稪 ¨áª«î票© |
* edx = ¬ ᪠®¡à ¡ âë¢ ¥¬ëå ¨áª«î票© |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤à¥á áâ ண® ®¡à ¡®â稪 ¨áª«î票© (0, ¥á«¨ ¥ ãáâ ®¢«¥) |
* ebx = ¬ ᪠áâ ண® ®¡à ¡®â稪 ¨áª«î票© |
¬¥ç ¨ï: |
* ®¬¥à ¡¨â ¢ ¬ ᪥ ¨áª«î票© ᮮ⢥âáâ¢ãîâ ®¬¥à㠨᪫îç¥¨ï ¯® |
ᯥæ¨ä¨ª 樨 ¯à®æ¥áá®à (Intel-PC). ª ¯à¨¬¥à, ¨áª«î票ï FPU |
¨¬¥îâ ®¬¥à 16 (#MF), SSE - 19 (#XF). |
* ¤ ®© ॠ«¨§ 樨 ¨£®à¨àã¥âáï § ¯à®á ¯¥à¥å¢ ⠨᪫î票ï 7 |
- á¨á⥬ ®¡à ¡ âë¢ ¥â #NM á ¬®áâ®ï⥫ì®. |
* ®«ì§®¢ ⥫ì᪨© ®¡à ¡®â稪 ¯®«ãç ¥â ®¬¥à ¨áª«îç¥¨ï ¯ à ¬¥â஬ |
¢ á⥪¥. ®íâ®¬ã ¯à ¢¨«ìë© ¢ë室 ¨§ ®¡à ¡®â稪 : RET 4. ®§¢à â |
¯à¨ í⮬ ¯à®¨§¢®¤¨âáï ª®¬ ¤ã, ¢ë§¢ ¢èãî ¨áª«î票¥. |
* ਠ¯¥à¥¤ ç¥ ã¯à ¢«¥¨ï ®¡à ¡®â稪㠨᪫î票©, á¡à áë¢ ¥âáï |
ᮮ⢥âáâ¢ãî騩 ¡¨â ¢ ¬ ᪥ ¨áª«î票©. ®§¨ª®¢¥¨¥ í⮣® ¦¥ |
¨áª«îç¥¨ï ¢ ¯®á«¥¤á⢨¨ - ¯à¨¢¥¤¥â ª default-®¡à ¡®âª¥ â ª®¢®£®. |
¨¬¥®: ª § ¢¥à襨î à ¡®âë ¯à¨«®¦¥¨ï, ¨«¨ ¯à¨®áâ ®¢ª¥ á |
®â¨ä¨ª 樥© ®â« ¦¨¢ î饬㠯ਫ®¦¥¨î. |
* ®á«¥ § ¢¥àè¥¨ï ªà¨â¨ç¥áª¨å ¤¥©á⢨© ¢ ®¡à ¡®â稪¥ ¯®«ì§®¢ ⥫ï, |
¢®ááâ ®¢«¥¨¥ ¡¨â ¬ ᪨ ¤ ®£® ¨áª«îç¥¨ï ¬®¦® ᤥ« âì |
¯®¤äãªæ¨¥© 25. ¡à®á ä« £®¢ ¨áª«î票© ¢ ¬®¤ã«ïå FPU ¨ XMM - |
â ª¦¥ ¢®§« £ ¥âáï ®¡à ¡®â稪 ¯®«ì§®¢ ⥫ï. |
====================================================================== |
= ãªæ¨ï 68, ¯®¤äãªæ¨ï 25 - ¨§¬¥¥¨¥ á®áâ®ï¨ï ªâ¨¢®á⨠ᨣ « = |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 25 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᨣ « |
* edx = § 票¥ ãáâ ¢«¨¢ ¥¬®© ªâ¨¢®á⨠(0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = áâ ஥ § 票¥ ªâ¨¢®á⨠ᨣ « (0/1) |
¬¥ç ¨ï: |
* ⥪ã饩 ॠ«¨§ 樨 ¨§¬¥ï¥âáï ⮫쪮 ¬ ᪠¯®«ì§®¢ ⥫ì᪮£® |
®¡à ¡®â稪 ¨áª«î票©, ãáâ ®¢«¥®£® ¯®¤äãªæ¨¥© 24. ਠí⮬, |
®¬¥à ᨣ « ᮮ⢥âáâ¢ã¥â ®¬¥à㠨᪫î票ï. |
====================================================================== |
======================== ãªæ¨ï 69 - ®â« ¤ª . ======================= |
====================================================================== |
à®æ¥áá ¬®¦¥â § £à㧨âì ¤à㣮© ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© ãáâ ®¢ª®© |
ᮮ⢥âáâ¢ãî饣® ¡¨â ¯à¨ ¢ë§®¢¥ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 70. |
¯à®æ¥áá ¬®¦¥â ¡ëâì ⮫쪮 ®¤¨ ®â« ¤ç¨ª; ®¤¨ ¯à®æ¥áá ¬®¦¥â |
®â« ¦¨¢ âì ¥áª®«ìª® à §ëå. ¨á⥬ 㢥¤®¬«ï¥â ®â« ¤ç¨ª ® ᮡëâ¨ïå, |
¯à®¨á室ïé¨å á ®â« ¦¨¢ ¥¬ë¬ ¯à®æ¥áᮬ. ®®¡é¥¨ï § ¯¨áë¢ îâáï ¢ ¡ãä¥à, |
®¯à¥¤¥«ñë© ¯®¤äãªæ¨¥© 0. |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: ª®¤ á®®¡é¥¨ï |
* +4: dword: PID ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* +8: ¬®£ãâ ¯à¨áãâá⢮¢ âì ¤®¯®«¨â¥«ìë¥ ¤ ë¥, |
®¯à¥¤¥«ï¥¬ë¥ ª®¤®¬ á®®¡é¥¨ï |
®¤ë á®®¡é¥¨©: |
* 1 = ¨áª«î票¥ |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¬¥à ¨áª«î票ï |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
* 2 = ¯à®æ¥áá § ¢¥à訫áï |
* ¯à¨å®¤¨â ¯à¨ «î¡®¬ § ¢¥à襨¨: ª ª ç¥à¥§ á¨á⥬ãî äãªæ¨î -1, |
â ª ¨ ¯à¨ "㡨©á⢥" «î¡ë¬ ¤à㣨¬ ¯à®æ¥áᮬ |
(¢ ⮬ ç¨á«¥ á ¬¨¬ ®â« ¤ç¨ª®¬) |
* 3 = ®â« ¤®ç®¥ ¨áª«î票¥ int 1 = #DB |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¡à § ॣ¨áâà DR6: |
* ¡¨âë 0-3: ¢ë¯®«¥® ãá«®¢¨¥ ᮮ⢥âáâ¢ãî饩 â®çª¨ ®áâ ®¢ |
(ãáâ ®¢«¥®© ¯®¤äãªæ¨¥© 9) |
* ¡¨â 14: ¨áª«î票¥ ¯à®¨§®è«® ¨§-§ ०¨¬ |
¯®è £®¢®© âà áá¨à®¢ª¨ (ãáâ ®¢«¥ ä« £ TF) |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
ਠ§ ¢¥à襨¨ ®â« ¤ç¨ª ¯à¨¡¨¢ îâáï ¢á¥ ®â« ¦¨¢ ¥¬ë¥ ¯à®æ¥ááë. |
᫨ ®â« ¤ç¨ª í⮣® ¥ å®ç¥â, ® ¤®«¦¥ ¯à¥¤¢ à¨â¥«ì® ®âª«îç¨âìáï |
¯®¤äãªæ¨¥© 3. |
ᥠ¯®¤äãªæ¨¨ ¯à¨¬¥¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ãé¥ë¬ |
¨§ ⥪ã饣® äãªæ¨¥© 70 á ãáâ ®¢«¥ë¬ ä« £®¬ ®â« ¤ª¨. |
â« ¤ª ¬®£®¯®â®çëå ¯à®£à ¬¬ ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
®«ë© ᯨ᮪ ¯®¤äãªæ¨©: |
* ¯®¤äãªæ¨ï 0 - ®¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨© |
* ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 5 - ¢®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 6 - ¯à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 9 - ãáâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 0 ====================== |
========= ¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨©. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì |
®à¬ â ®¡« á⨠¤ ëå: |
* +0: dword: N = à §¬¥à ¡ãä¥à (¥ áç¨â ï í⮣® § £®«®¢ª ) |
* +4: dword: § ïâ® ¢ ¡ãä¥à¥ |
* +8: N*byte: ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯®«¥ à §¬¥à ®âà¨æ ⥫ì®, ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬ |
¨ ¯à¨ ¯®áâ㯫¥¨¨ ®¢®£® á®®¡é¥¨ï á¨á⥬ ¡ã¤¥â ¦¤ âì. |
«ï á¨åந§ 樨 ®¡à ¬«ï©â¥ ¢áî à ¡®âã á ¡ãä¥à®¬ ®¯¥à æ¨ï¬¨ |
¡«®ª¨à®¢ª¨/à §¡«®ª¨à®¢ª¨ |
neg [bufsize] |
* ë¥ ¢ ¡ãä¥à¥ âà ªâãîâáï ª ª ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë - |
á®®¡é¥¨©. ®à¬ â á®®¡é¥¨ï 㪠§ ¢ ®¡é¥¬ ®¯¨á ¨¨. |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 1 ====================== |
========= ®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ : (FPU ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ¢®§¢à é ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 2 ====================== |
======== áâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1. |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ãáâ ¢«¨¢ ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
== ãªæ¨ï 69, ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . = |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá ¡ë« ¯à¨®áâ ®¢«¥, ® ¢®§®¡®¢«ï¥â ¢ë¯®«¥¨¥. |
====================================================================== |
==== ãªæ¨ï 69, ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à ¯à®æ¥áá |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 5 ====================== |
============ ®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 6 ====================== |
============= à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ç¨â âì |
* esi = ¤à¥á ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* edi = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
ãªæ¨ï 69, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ¯¨á âì |
* esi = ¤à¥á ¯ ¬ï⨠¢ ®â« ¦¨¢ ¥¬®¬ ¯à®æ¥áᥠ|
* edi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====== ãªæ¨ï 69, ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ãªæ¨ï «®£¨ç ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 á ¤¢ã¬ï ®â«¨ç¨ï¬¨: |
âॡã¥âáï ¢ë¯®«¥¨¥ ¯¥à¢®£® § ¬¥ç ¨ï ¨ ¯à¨¨¬ ¥âáï PID, |
¥ ®¬¥à á«®â . |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 9 ====================== |
============= áâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* dl = ¨¤¥ªá â®çª¨ ®áâ ®¢ , ®â 0 ¤® 3 ¢ª«îç¨â¥«ì® |
* dh = ä« £¨: |
* ¥á«¨ áâ à訩 ¡¨â á¡à®è¥ - ãáâ ®¢¨âì â®çªã ®áâ ®¢ : |
* ¡¨âë 0-1 - ãá«®¢¨¥: |
* 00 = â®çª ®áâ ®¢ ¢ë¯®«¥¨¥ |
* 01 = â®çª ®áâ ®¢ § ¯¨áì |
* 11 = â®çª ®áâ ®¢ ç⥨¥/§ ¯¨áì |
* ¡¨âë 2-3 - ¤«¨ ; ¤«ï â®ç¥ª ®áâ ®¢ ¨á¯®«¥¨¥ ¤®«¦® ¡ëâì |
00, ¢ ¯à®â¨¢®¬ á«ãç ¥ ®¤® ¨§ |
* 00 = ¡ ©â |
* 01 = á«®¢® |
* 11 = ¤¢®©®¥ á«®¢® |
* esi = ¤à¥á â®çª¨ ®áâ ®¢ ; ¤®«¦¥ ¡ëâì ¢ë஢¥ |
ᮮ⢥âá⢥® ¤«¨¥ (â.¥. ¤®«¦¥ ¡ëâì çñâë¬ ¤«ï |
â®ç¥ª ®áâ ®¢ á«®¢®, ªà ⥠4 ¤«ï ¤¢®©®£® á«®¢ ) |
* ¥á«¨ áâ à訩 ¡¨â ãáâ ®¢«¥ - á¡à®á¨âì â®çªã ®áâ ®¢ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª ¢® ¢å®¤ëå ¤ ëå |
* eax = 2 - (§ १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï |
¢ ⥪ã饩 ॠ«¨§ 樨) á í⨬ ¨¤¥ªá®¬ 㦥 ãáâ ®¢«¥ |
£«®¡ «ì ï â®çª ®áâ ®¢ |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ¯¯ à âë¥ â®çª¨ ®áâ ®¢ ॠ«¨§ãîâáï ç¥à¥§ DRx-ॣ¨áâàë |
¯à®æ¥áá®à , ®âáî¤ ¢á¥ ®£à ¨ç¥¨ï. |
* ãªæ¨ï ¬®¦¥â ¯¥à¥ãáâ ®¢¨âì à ¥¥ ãáâ ®¢«¥ãî ¥© ¦¥ |
â®çªã ®áâ ®¢ (¨ª ª ¥ á®®¡é ï ®¡ í⮬). |
¥¤¨â¥ ᯨ᮪ ãáâ ®¢«¥ëå â®ç¥ª ®áâ ®¢ ¢ ®â« ¤ç¨ª¥. |
* à ¡ âë¢ ¨¥ â®çª¨ ®áâ ®¢ § ª«îç ¥âáï ¢ £¥¥à¨à®¢ ¨¨ |
®â« ¤®ç®£® ¨áª«î票ï #DB, ® ª®â®à®¬ á¨á⥬ á®®¡é ¥â ®â« ¤ç¨ªã. |
* ®çª ®áâ ®¢ § ¯¨áì ¨ ç⥨¥/§ ¯¨áì áà ¡ âë¢ ¥â ¯®á«¥ |
¢ë¯®«¥¨ï ¢ë§¢ ¢è¥© ¥ñ ¨áâàãªæ¨¨. |
====================================================================== |
= ãªæ¨ï 70 - à ¡®â á ä ©«®¢®© á¨á⥬®© á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ᬥ饨¥ ¢ ä ©«¥ |
* +8: dword: áâ à訩 dword ᬥ饨ï (¤®«¦¥ ¡ëâì 0) ¨«¨ ¯®«¥ ä« £®¢ |
* +12 = +0xC: dword: à §¬¥à |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâà㠡㪢. ãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì |
§ ¯¨á ë ¢ ª®¤¨à®¢ª¥ cp866 (DOS). |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ¦ñá⪨¬ ¤¨áª ¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª CD IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
* /SYS - ®¯à¥¤¥«ï¥â á¨á⥬ãî ¯ ¯ªã; ¯à¨ ®¡ë箩 § £à㧪¥ á¨á⥬ë |
á ¤¨áª¥âë íª¢¨¢ «¥â® /RD/1 |
ਬ¥àë: |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
* '/sys/MySuperApp.ini',0 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« |
* ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 2 - ᮧ¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« |
* ¯®¤äãªæ¨ï 3 - § ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©« |
* ¯®¤äãªæ¨ï 4 - ãáâ ®¢ª à §¬¥à ä ©« |
* ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë |
* ¯®¤äãªæ¨ï 8 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨ |
«ï CD-¯à¨¢®¤®¢ ¢ á¢ï§¨ á ¯¯ à â묨 ®£à ¨ç¥¨ï¬¨ ¤®áâã¯ë |
⮫쪮 ¯®¤äãªæ¨¨ 0,1,5 ¨ 7, ¢ë§®¢ ¤àã£¨å ¯®¤äãªæ¨© § ¢¥àè¨âáï |
®è¨¡ª®© á ª®¤®¬ 2. |
ਠ¯¥à¢®¬ ®¡à 饨¨ ¯®¤äãªæ¨© 0,1,5,7 ª ãáâனá⢠¬ ATAPI |
(CD ¨ DVD) ¯à®¨§¢®¤¨âáï ¡«®ª¨à®¢ª àã箣® ã¯à ¢«¥¨ï ¬¥å ¨§¬®¬ |
«®âª . â® á¢ï§ ® á ªíè¨à®¢ ¨¥¬ ¤ ëå, ¯®«ãç¥ëå ®â ¯à¨¢®¤ . |
§¡«®ª¨à®¢ª ®áãé¥á⢫ï¥âáï ¯à¨ ®¡à 饨¨ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 24 |
ª ᮮ⢥âáâ¢ãî饬ã ãáâனáâ¢ã. |
====================================================================== |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ® ¯®¤ áâ à訩 dword ¯®§¨æ¨¨) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ¯à®ç¨â ëå ¡ ©â ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ |
eax=6 (EOF). |
* ãªæ¨ï ¥ ¯®§¢®«ï¥â ç¨â âì ¯ ¯ª¨ |
(¢¥àñâáï eax=10, access denied). |
====================================================================== |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 1 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨¤¥ªá ç «ì®£® ¡«®ª (áç¨â ï á 0) |
* +8: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0 (¬ ᪠1): ¢ ª ª®¬ ä®à¬ ⥠¢®§¢à é âì ¨¬¥ , |
0=ANSI, 1=UNICODE |
* ¯à®ç¨¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®á⨠|
* +12 = +0xC: dword: ᪮«ìª® ¡«®ª®¢ ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë |
¤ ë¥, à §¬¥à ¡ãä¥à ¤®«¦¥ ¡ëâì ¥ ¬¥ìè¥ 32 + [+12]*560 ¡ ©â |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ä ©«®¢, ¨ä®à¬ æ¨ï ® ª®â®àëå ¡ë« § ¯¨á ¢ ¡ãä¥à, |
¨«¨ -1=0xffffffff, ¥á«¨ ¯ ¯ª ¥ ©¤¥ |
âàãªâãà ¡ãä¥à : |
* +0: 32*byte: § £®«®¢®ª |
* +32 = +0x20: n1*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 1 |
* +32+n1: n2*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 2 |
* ... |
âàãªâãà § £®«®¢ª : |
* +0: dword: ¢¥àá¨ï áâàãªâãàë (⥪ãé ï ¢¥àá¨ï = 1) |
* +4: dword: ª®«¨ç¥á⢮ à §¬¥éñëå ¡«®ª®¢; ¥ ¡®«ìè¥, 祬 § ¯à®è¥® |
¢ ¯®«¥ +12 ¨ä®à¬ 樮®© áâàãªâãàë; ¬®¦¥â ¡ëâì ¬¥ìè¥, |
¥á«¨ ¢ ¯ ¯ª¥ ª®ç¨«¨áì ä ©«ë (â® ¦¥ á ¬®¥, çâ® ¨ ¢ ebx) |
* +8: dword: ®¡é¥¥ ç¨á«® ä ©«®¢ ¢ ¯ ¯ª¥ |
* +12 = +0xC: 20*byte: § १¥à¢¨à®¢ ® (㫨) |
âàãªâãà ¡«®ª ¤ ëå ¢å®¤ ª â «®£ (): |
* +0: dword: âਡãâë ä ©« : |
* ¡¨â 0 (¬ ᪠1): ä ©« ⮫쪮 ¤«ï ç⥨ï |
* ¡¨â 1 (¬ ᪠2): ä ©« ï¥âáï áªàëâë¬ |
* ¡¨â 2 (¬ ᪠4): ä ©« ï¥âáï á¨áâ¥¬ë¬ |
* ¡¨â 3 (¬ ᪠8): íâ® ¥ ä ©«, ¬¥âª ⮬ |
( § ¤ ®¬ à §¤¥«¥ ¢áâà¥ç ¥âáï ¥ ¡®«¥¥ ®¤®£® à § ¨ |
⮫쪮 ¢ ª®à¥¢®© ¯ ¯ª¥) |
* ¡¨â 4 (¬ ᪠0x10): íâ® ¯ ¯ª |
* ¡¨â 5 (¬ ᪠0x20): ä ©« ¥ à娢¨à®¢ «áï - ¬®£¨¥ ¯à®£à ¬¬ë |
à娢 樨 ¨¬¥îâ ®¯æ¨î, ¯® ª®â®à®© à娢¨àãîâáï ⮫쪮 ä ©«ë |
á ãáâ ®¢«¥ë¬ í⨬ ¡¨â®¬, ¯®á«¥ 祣® íâ®â ¡¨â á¡à áë¢ ¥âáï - |
íâ® ¬®¦¥â ¡ëâì ¯®«¥§® ¤«ï ¢â®¬ â¨ç¥áª®£® ᮧ¤ ¨ï |
backup- à娢®¢, ¨¡® ¯à¨ § ¯¨á¨ ¡¨â ®¡ëç® ãáâ ¢«¨¢ ¥âáï |
(¥ ¢ Kolibri, ¯à ¢¤ ) |
* +4: byte: ⨯ ¤ ëå ¨¬¥¨: |
(ᮢ¯ ¤ ¥â á ¡¨â®¬ 0 ä« £®¢ ¨ä®à¬ 樮®© áâàãªâãàë) |
* 0 = ASCII = 1-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* 1 = UNICODE = 2-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* +5: 3*byte: § १¥à¢¨à®¢ ® (㫨) |
* +8: 4*byte: ¢à¥¬ï ᮧ¤ ¨ï ä ©« |
* +12 = +0xC: 4*byte: ¤ â ᮧ¤ ¨ï ä ©« |
* +16 = +0x10: 4*byte: ¢à¥¬ï ¯®á«¥¤¥£® ¤®áâ㯠(ç⥨¥ ¨«¨ § ¯¨áì) |
* +20 = +0x14: 4*byte: ¤ â ¯®á«¥¤¥£® ¤®áâ㯠|
* +24 = +0x18: 4*byte: ¢à¥¬ï ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +28 = +0x1C: 4*byte: ¤ â ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +32 = +0x20: qword: à §¬¥à ä ©« ¢ ¡ ©â å (¤® 16777216 ¡) |
* +40 = +0x28: ¨¬ï |
* ¤«ï ä®à¬ â ASCII: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 263 ᨬ¢®« |
(263 ¡ ©â ), ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥¥â § 票¥ 0 |
* ¤«ï ä®à¬ â UNICODE: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 259 ᨬ¢®«®¢ |
(518 ¡ ©â), ¤¢ ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥îâ § 票¥ 0 |
®à¬ ⠢६¥¨: |
* +0: byte: ᥪã¤ë |
* +1: byte: ¬¨ãâë |
* +2: byte: ç áë |
* +3: byte: § १¥à¢¨à®¢ ® (0) |
* ¯à¨¬¥à, 23.59.59 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 3B 3B 17 00 |
®à¬ â ¤ âë: |
* +0: byte: ¤¥ì |
* +1: byte: ¬¥áïæ |
* +2: word: £®¤ |
* ¯à¨¬¥à, 25.11.1979 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 19 0B BB 07 |
¬¥ç ¨ï: |
* ᫨ ¢ ¯à¨áãâáâ¢ã¥â ¨¬ï ¢ ASCII, â® ¤«¨ á®áâ ¢«ï¥â |
304 ¡ ©â , ¥á«¨ ¢ UNICODE - 560 ¡ ©â. 票¥ ¤«¨ë ¢ëà ¢¥® |
楫®¥ ªà ⮥ 16 ¡ ©â |
(¤«ï ãáª®à¥¨ï ®¡à ¡®âª¨ ¢ ªíè-¯ ¬ï⨠CPU). |
* ¥à¢ë© ᨬ¢®« ¯®á«¥ ¨¬¥¨ ã«¥¢®© (ASCIIZ-áâப ). «ì¥©è¨¥ |
¤ ë¥ á®¤¥à¦ â ¬ãá®à. |
* ᫨ ä ©«ë ¢ ¯ ¯ª¥ ª®ç¨«¨áì à ìè¥, 祬 ¡ë«® ¯à®ç¨â ® |
§ ¯à®è¥®¥ ª®«¨ç¥á⢮, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, |
¯®á«¥ 祣® ¢¥àñâ eax=6 (EOF). |
* î¡ ï ¯ ¯ª ¤¨áª¥, ªà®¬¥ ª®à¥¢®©, ᮤ¥à¦¨â ¤¢ á¯¥æ¨ «ìëå |
¢å®¤ "." ¨ "..", ¨¤¥â¨ä¨æ¨àãîé¨å ᮮ⢥âá⢥® á ¬ã ¯ ¯ªã ¨ |
த¨â¥«ìáªãî ¯ ¯ªã. |
* ãªæ¨ï ¯®§¢®«ï¥â â ª¦¥ ç¨â âì ¢¨àâã «ìë¥ ¯ ¯ª¨ "/", "/rd", |
"/fd", "/hd[n]", ¯à¨ í⮬ âਡãâë ¯®¤¯ ¯®ª ¯®« £ îâáï à ¢ë¬¨ |
0x10, ¢à¥¬¥ ¨ ¤ âë ®¡ã«¥ë. «ìâ¥à â¨¢ë© á¯®á®¡ ¯®«ã票ï |
¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ - ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18. |
====================================================================== |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 2 ====================== |
======== ®§¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 2 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ᫨ ä ©« á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥á⢮¢ «, ® ᮧ¤ ñâáï; ¥á«¨ |
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç®, â® äãªæ¨ï § ¯¨è¥â, |
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ ª®¤ ®è¨¡ª¨ 8. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 3 ====================== |
======== ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 3 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å) |
* +8: dword: áâ à訩 dword ¯®§¨æ¨¨ (¤®«¦¥ ¡ëâì 0 ¤«ï FAT) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ©« ¤®«¦¥ 㦥 áãé¥á⢮¢ âì, ¨ ç¥ ¢¥àñâáï eax=5. |
* ¤¨áâ¢¥ë¬ à¥§ã«ìâ ⮬ § ¯¨á¨ 0 ¡ ©â ï¥âáï ãáâ ®¢ª ¢ |
âਡãâ å ä ©« ¤ âë/¢à¥¬¥¨ ¬®¤¨ä¨ª 樨 ¨ ¤®áâ㯠¢ ⥪ãéãî. |
* ᫨ ç «ì ï ¨/¨«¨ ª®¥ç ï ¯®§¨æ¨ï ¢ë室¨â § ¯à¥¤¥«ë ä ©« |
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï), ä ©« à áè¨àï¥âáï ¤® |
¥®¡å®¤¨¬®£® à §¬¥à ã«¥¢ë¬¨ ᨬ¢®« ¬¨. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
========= ãªæ¨ï 70, ¯®¤äãªæ¨ï 4 - ãáâ ®¢ª à §¬¥à ä ©« . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 4 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¬« ¤è¨© dword ®¢®£® à §¬¥à ä ©« |
* +8: dword: áâ à訩 dword ®¢®£® à §¬¥à ä ©« |
(¤®«¦¥ ¡ëâì 0 ¤«ï FAT) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ᫨ ®¢ë© à §¬¥à ä ©« ¬¥ìè¥ áâ ண®, ä ©« ãᥪ ¥âáï. ᫨ |
®¢ë© à §¬¥à ¡®«ìè¥ áâ ண®, ä ©« à áè¨àï¥âáï ã«¥¢ë¬¨ ᨬ¢®« ¬¨. |
᫨ ®¢ë© à §¬¥à à ¢¥ áâ ஬ã, ¥¤¨áâ¢¥ë¬ à¥§ã«ìâ ⮬ ¢ë§®¢ |
ï¥âáï ãáâ ®¢ª ¤ âë/¢à¥¬¥¨ ¬®¤¨ä¨ª 樨 ¨ ¤®áâ㯠¢ ⥪ã騥. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç® ¤«ï à áè¨à¥¨ï ä ©« , |
â® äãªæ¨ï à áè¨à¨â ᪮«ìª® ¢®§¬®¦®, ¯®á«¥ 祣® ¢¥àñâ |
ª®¤ ®è¨¡ª¨ 8. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
=== ãªæ¨ï 70, ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«¥/¯ ¯ª¥. === |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 5 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(40 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
ä®à¬ æ¨ï ® ä ©«¥ ¢®§¢à é ¥âáï ¢ ä®à¬ ⥠|
(¡«®ª ¤ ëå ¢å®¤ ª â «®£ ), 㪠§ ®¬ ¢ ®¯¨á ¨¨ |
¯®¤äãªæ¨¨ 1, ® ¡¥§ ¨¬¥¨ ä ©« |
(â® ¥áâì ¯¥à¢ë¥ 40 = 0x28 ¡ ©â). |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
====================================================================== |
===== ãªæ¨ï 70, ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 6 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à á âਡãâ ¬¨ (32 ¡ ©â ) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
âਡãâë ä ©« - ¯¥à¢ë¥ 32 ¡ ©â ¢ (¡«®ª¥ ¤ ëå ¢å®¤ ª â «®£ ), |
ä®à¬ â ª®â®à®£® 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1 |
(â® ¥áâì ¡¥§ ¨¬¥¨ ¨ à §¬¥à ä ©« ). âਡãâ ä ©«/¯ ¯ª /¬¥âª ⮬ |
(¡¨âë 3,4 ¢ dword'¥ +0) ¥ ¬¥ï¥âáï. |
©â +4 (ä®à¬ â ¨¬¥¨) ¨£®à¨àã¥âáï. |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
============ ãªæ¨ï 70, ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 7 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0: § ¯ãáâ¨âì ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© |
* ®áâ «ìë¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* +8: dword: 0 ¨«¨ 㪠§ ⥫ì ASCIIZ-áâபã á ¯ à ¬¥âà ¬¨ |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax > 0 - ¯à®£à ¬¬ § £à㦥 , eax ᮤ¥à¦¨â PID |
* eax < 0 - ¯à®¨§®è« ®è¨¡ª , -eax ᮤ¥à¦¨â |
ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ®¬ ¤ ï áâப ¤®«¦ § ª 稢 âìáï ᨬ¢®«®¬ á ª®¤®¬ 0 |
(ASCIIZ-áâப ); ãç¨âë¢ îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ã«ï |
¢ª«îç¨â¥«ì®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®, |
çâ® ¬¥ìè¥. |
* ᫨ ¯à®æ¥áá § ¯ã᪠¥âáï ª ª ®â« ¦¨¢ ¥¬ë©, ® ᮧ¤ ñâáï |
¢ § ¬®à®¦¥®¬ á®áâ®ï¨¨; ¤«ï § ¯ã᪠¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 5 äãªæ¨¨ 69. |
====================================================================== |
========== ãªæ¨ï 70, ¯®¤äãªæ¨ï 8 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
* ®¦® 㤠«ïâì ⮫쪮 ¯ãáâë¥ ¯ ¯ª¨ (¯®¯ë⪠㤠«¥¨ï ¥¯ãá⮩ ¯ ¯ª¨ |
¯à¨¢¥¤ñâ ª ®è¨¡ª¥ á ª®¤®¬ 10, "¤®áâ㯠§ ¯à¥éñ"). |
====================================================================== |
============= ãªæ¨ï 70, ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 9 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¯ ¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
* ®¤¨â¥«ìáª ï ¯ ¯ª ¤®«¦ 㦥 áãé¥á⢮¢ âì. |
* ᫨ ¯ ¯ª 㦥 áãé¥áâ¢ã¥â, äãªæ¨ï § ¢¥àè¨âáï ãá¯¥è® (eax=0). |
====================================================================== |
=== ãªæ¨ï 71, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì § £®«®¢®ª ®ª ¯à®£à ¬¬ë. == |
====================================================================== |
à ¬¥âàë: |
* eax = 71 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á áâப¨ § £®«®¢ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* âப § £®«®¢ª ¤®«¦ ¡ëâì ¢ ä®à¬ ⥠ASCIIZ. § £®«®¢ª¥ |
®â®¡à ¦ ¥âáï ¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ¥§ ¢¨á¨¬® ®â ¯®«®© ¤«¨ë |
áâப¨. |
* ⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx. |
====================================================================== |
================ ãªæ¨ï 72 - ¯®á« âì á®®¡é¥¨¥ ®ªã. ================ |
====================================================================== |
--- ®¤äãªæ¨ï 1 - ¯®á« âì á®®¡é¥¨¥ á ¯ à ¬¥â஬ ªâ¨¢®¬ã ®ªã. ---- |
à ¬¥âàë: |
* eax = 72 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª®¤ ᮡëâ¨ï: 2 ¨«¨ 3 |
* edx = ª®¤ ª« ¢¨è¨ ¤«ï ecx=2, ¨¤¥â¨ä¨ª â®à ª®¯ª¨ ¤«ï ecx=3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¡ãä¥à § ¯®«¥ |
====================================================================== |
========== ãªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«¥¨¥ ¯®â®ª /¯à®æ¥áá ========= |
====================================================================== |
à ¬¥âàë: |
* eax = -1 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â ¨ § 票ï, ¨ ã¯à ¢«¥¨ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá  ¥ ᮧ¤ ¢ « ¯®â®ª®¢, â® ã ¥£® ¥áâì ⮫쪮 |
®¤¨ ¯®â®ª, § ¢¥à襨¥ ª®â®à®£® ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* ᫨ ⥪ã騩 ¯®â®ª - ¯®á«¥¤¨© ¢ ¯à®æ¥áá¥, â® ¥£® § ¢¥à襨¥ |
â ª¦¥ ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* â äãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ¯®â®ª. à㣮© ¯®â®ª ¬®¦® ¯à¨¡¨âì |
¢ë§®¢®¬ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18. |
====================================================================== |
=========================== ¯¨á®ª ᮡë⨩ =========================== |
====================================================================== |
ç¥à¥¤®¥ ᮡë⨥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ®¤®© ¨§ äãªæ¨© 10 |
(®¦¨¤ âì ᮡëâ¨ï), 11 (¯à®¢¥à¨âì ¡¥§ ®¦¨¤ ¨ï), 23 |
(®¦¨¤ âì ¢ â¥ç¥¨¥ § ¤ ®£® ¢à¥¬¥¨). |
⨠äãªæ¨¨ ¢®§¢à é îâ ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î íâ® ¯¥à¢ë¥ âà¨, 祣® |
¢¯®«¥ ¤®áâ â®ç® ¤«ï ¬®£¨å ¯à¨«®¦¥¨©. |
®¤ë ᮡë⨩: |
* 1 = á®®¡é¥¨¥ ® ¯¥à¥à¨á®¢ª¥ (á¡à áë¢ ¥âáï ¯à¨ ¢ë§®¢¥ äãªæ¨¨ 0) |
* 2 = ¦ â ª« ¢¨è ª« ¢¨ âãॠ(¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® |
ªâ¨¢®) ¨«¨ ¦ â "£®àïç ï ª« ¢¨è "; |
á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ ª« ¢¨è¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 2 |
* 3 = ¦ â ª®¯ª , ®¯à¥¤¥«ñ ï à ¥¥ äãªæ¨¥© 8 (¨«¨ ª®¯ª |
§ ªàëâ¨ï, ᮧ¤ ï ¥ï¢® äãªæ¨¥© 0; ª®¯ª ¬¨¨¬¨§ 樨 |
®¡à ¡ âë¢ ¥âáï á¨á⥬®© ¨ ® ¥© á®®¡é¥¨ï ¥ ¯à¨å®¤¨â; |
¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® ªâ¨¢®; á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ |
ª®¯ª¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 17) |
* 4 = § १¥à¢¨à®¢ ® (¢ ⥪ã饩 ॠ«¨§ 樨 ¨ª®£¤ ¥ ¯à¨å®¤¨â ¤ ¦¥ |
¯à¨ à §¬ ᪨஢ª¥ äãªæ¨¥© 40) |
* 5 = ¯¥à¥à¨á®¢ë¢ ¥âáï ä® à ¡®ç¥£® á⮫ (á¡à áë¢ ¥âáï |
¢â®¬ â¨ç¥áª¨ ¯®á«¥ ¯¥à¥à¨á®¢ª¨, â ª çâ® ¥á«¨ ¢® ¢à¥¬ï ¯¥à¥à¨á®¢ª¨ |
ä® ¯à®£à ¬¬ ¥ ¦¤ñâ ¨ ¥ ¯à®¢¥àï¥â ᮡëâ¨ï, â® í⮣® ᮡëâ¨ï |
® ¥ § ¬¥â¨â) |
* 6 = ᮡë⨥ ®â ¬ëè¨ (çâ®-â® á«ã稫®áì - ¦ ⨥ ª®¯ªã ¬ëè¨ |
¨«¨ ¯¥à¥¬¥é¥¨¥; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 7 = ¯à®¨§®è«® ᮡë⨥ IPC (ᬮâਠäãªæ¨î 60 - Inter Process |
Communication; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 8 = ¯à®¨§®è«® á¥â¥¢®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâà¨ à ¡®âã á á¥âìî) |
* 9 = ¯à®¨§®è«® ®â« ¤®ç®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâਠ®â« ¤®çãî ¯®¤á¨á⥬ã) |
* 16..31 = ¯à®¨§®è«® ᮡë⨥ á ᮮ⢥âáâ¢ãî騬 IRQ |
(16=IRQ0, 31=IRQ15) (á¡à áë¢ ¥âáï ¯à¨ áç¨âë¢ ¨¨ ¢á¥å ¤ ëå IRQ) |
====================================================================== |
==================== ®¤ë ®è¨¡®ª ä ©«®¢®© á¨á⥬ë ==================== |
====================================================================== |
* 0 = ãá¯¥è® |
* 1 = ¥ ®¯à¥¤¥«¥ ¡ § ¨/¨«¨ à §¤¥« ¦ñá⪮£® ¤¨áª (¯®¤äãªæ¨ï¬¨ |
7, 8 äãªæ¨¨ 21) |
* 2 = äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ®© ä ©«®¢®© á¨á⥬ë |
* 3 = ¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬ |
* 4 = § १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï ¢ ⥪ã饩 ॠ«¨§ 樨 |
* 5 = ä ©« ¥ ©¤¥ |
* 6 = ä ©« § ª®ç¨«áï |
* 7 = 㪠§ â¥«ì ¢¥ ¯ ¬ï⨠¯à¨«®¦¥¨ï |
* 8 = ¤¨áª § ¯®«¥ |
* 9 = â ¡«¨æ FAT à §àãè¥ |
* 10 = ¤®áâ㯠§ ¯à¥éñ |
* 11 = ®è¨¡ª ãáâனá⢠|
ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: |
* 30 = 0x1E = ¥¤®áâ â®ç® ¯ ¬ï⨠|
* 31 = 0x1F = ä ©« ¥ ï¥âáï ¨á¯®«¨¬ë¬ |
* 32 = 0x20 = ᫨誮¬ ¬®£® ¯à®æ¥áᮢ |
/kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt |
---|
0,0 → 1,4529 |
SYSTEM FUNCTIONS of OS Kolibri 0.7.5.0 |
Number of the function is located in the register eax. |
The call of the system function is executed by "int 0x40" command. |
All registers except explicitly declared in the returned value, |
including eflags, are preserved. |
====================================================================== |
============== Function 0 - define and draw the window. ============== |
====================================================================== |
Defines an application window. Draws a frame of the window, header and |
working area. For skinned windows defines standard close and minimize |
buttons. |
Parameters: |
* eax = 0 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = 0xXYRRGGBB, where: |
* Y = style of the window: |
* Y=0 - type I - fixed-size window |
* Y=1 - only define window area, draw nothing |
* Y=2 - type II - variable-size window |
* Y=3 - skinned window |
* Y=4 - skinned fixed-size window |
* other possible values (from 5 up to 15) are reserved, |
function call with such Y is ignored |
* RR, GG, BB = accordingly red, green, blue components of a color |
of the working area of the window (are ignored for style Y=2) |
* X = DCBA (bits) |
* A = 1 - window has caption; for styles Y=3,4 caption string |
must be passed in edi, for other styles use |
subfunction 1 of function 71 |
* B = 1 - coordinates of all graphics primitives are relative to |
window client area |
* C = 1 - don't fill working area on window draw |
* D = 0 - normal filling of the working area, 1 - gradient |
The following parameters are intended for windows |
of a type I and II, and ignored for styles Y=1,3: |
* esi = 0xXYRRGGBB - color of the header |
* RR, GG, BB define color |
* Y=0 - usual window, Y=1 - unmovable window |
* X defines a gradient of header: X=0 - no gradient, |
X=8 - usual gradient, |
for windows of a type II X=4 - negative gradient |
* other values of X and Y are reserved |
* edi = 0x00RRGGBB - color of the frame |
Returned value: |
* function does not return value |
Remarks: |
* Position and sizes of the window are installed by the first |
call of this function and are ignored at subsequent; to change |
position and/or sizes of already created window use function 67. |
* For windows with styles Y=3,4 and caption (A=1) caption string |
is set by the first call of this function and is ignored |
at subsequent (strictly speaking, is ignored after a call to |
subfunction 2 of function 12 - end redraw); to change caption of |
already created window use subfunction 1 of function 71. |
* If the window has appropriate styles, position and/or sizes can be |
changed by user. Current position and sizes can be obtained |
by function 9. |
* The window must fit on the screen. If the transferred |
coordinates and sizes do not satisfy to this condition, |
appropriate coordinate (or, probably, both) is considered as zero, |
and if it does not help too, the appropriate size |
(or, probably, both) is installed in a size of the screen. |
Further let us designate xpos,ypos,xsize,ysize - values passed |
in ebx,ecx. The coordinates are resulted concerning |
the left upper corner of the window, which, thus, is set as (0,0), |
coordinates of the right lower corner essence (xsize,ysize). |
* The sizes of the window are understood in sence of coordinates |
of the right lower corner. This concerns all other functions too. |
It means, that the real sizes are on 1 pixel more. |
* The window of type I looks as follows: |
* draw external frame of color indicated in edi, 1 pixel in width |
* draw header - rectangle with the left upper corner (1,1) and |
right lower (xsize-1,min(25,ysize)) color indicated in esi |
(taking a gradient into account) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (1,21) and right lower |
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color |
indicated in edx (taking a gradient into account) |
* if A=1 and caption has been already set by subfunction 1 |
of function 71, it is drawn in the corresponding place of header |
* The window of style Y=1 looks as follows: |
* completely defined by the application |
* The window of type II looks as follows: |
* draw external frame of width 1 pixel with the "shaded" color |
edi (all components of the color decrease twice) |
* draw intermediate frame of width 3 pixels with color edi |
* draw internal frame of width 1 pixel with the "shaded" color edi |
* draw header - rectangle with the left upper corner (4,4) |
and right lower (xsize-4,min(20,ysize)) color, indicated in esi |
(taking a gradient into account) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (5,20) and right lower |
(xsize-5,ysize-5) with color indicated in edx |
(taking a gradient into account) |
* if A=1 and caption has been already set by subfunction 1 |
of function 71, it is drawn in the corresponding place of header |
* The skinned window looks as follows: |
* draw external frame of width 1 pixel |
with color 'outer' from the skin |
* draw intermediate frame of width 3 pixel |
with color 'frame' from the skin |
* draw internal frame of width 1 pixel |
with color 'inner' from the skin |
* draw header (on bitmaps from the skin) in a rectangle |
(0,0) - (xsize,_skinh-1) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (5,_skinh) and right lower |
(xsize-5,ysize-5) with color indicated in edx |
(taking a gradient into account) |
* define two standard buttons: close and minimize |
(see function 8) |
* if A=1 and edi contains (nonzero) pointer to caption string, |
it is drawn in place in header defined in the skin |
* value _skinh is accessible as the result of call |
subfunction 4 of function 48 |
====================================================================== |
================ Function 1 - put pixel in the window. =============== |
====================================================================== |
Parameters: |
* eax = 1 - function number |
* ebx = x-coordinate (relative to the window) |
* ecx = y-coordinate (relative to the window) |
* edx = 0x00RRGGBB - color of a pixel |
edx = 0x01xxxxxx - invert color of a pixel |
(low 24 bits are ignored) |
Returned value: |
* function does not return value |
====================================================================== |
============ Function 2 - get the code of the pressed key. =========== |
====================================================================== |
Takes away the code of the pressed key from the buffer. |
Parameters: |
* eax = 2 - function number |
Returned value: |
* if the buffer is empty, function returns eax=1 |
* if the buffer is not empty, function returns al=0, |
ah=code of the pressed key, high word of eax is zero |
* if there is "hotkey", function returns al=2, |
ah=scancode of the pressed key (0 for control keys), |
high word of eax contains a status of control keys at the moment |
of pressing a hotkey |
Remarks: |
* There is a common system buffer of the pressed keys |
by a size of 120 bytes, organized as queue. |
* There is one more common system buffer on 120 "hotkeys". |
* If the application with the inactive window calls this function, |
the buffer of the pressed keys is considered to be empty. |
* By default this function returns ASCII-codes; to switch |
to the scancodes mode (and back) use function 66. |
However, hotkeys are always notificated as scancodes. |
* To find out, what keys correspond to what codes, start |
the application keyascii and scancode. |
* Scancodes come directly from keyboard and are fixed; |
ASCII-codes turn out with usage of the conversion tables, |
which can be set by subfunction 2 of function 21 |
and get by subfunction 2 of function 26. |
* As a consequence, ASCII-codes take into account current |
keyboard layout (rus/en) as opposed to scancodes. |
* This function notifies only about those hotkeys, which were |
defined by this thread by subfunction 4 of function 66. |
====================================================================== |
==================== Function 3 - get system time. =================== |
====================================================================== |
Parameters: |
* eax = 3 - function number |
Returned value: |
* eax = 0x00SSMMHH, where HH:MM:SS = Hours:Minutes:Seconds |
* each item is BCD-number, for example, |
for time 23:59:59 function returns 0x00595923 |
Remarks: |
* See also subfunction 9 of function 26 - get time from |
the moment of start of the system; it is more convenient, because |
returns simply DWORD-value of the time counter. |
* System time can be set by function 22. |
====================================================================== |
============ Function 4 - draw text string in the window. ============ |
====================================================================== |
Parameters: |
* eax = 4 - function number |
* ebx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* ecx = 0xX0RRGGBB, where |
* RR, GG, BB specify text color |
* X=ABnn (bits): |
* nn specifies the used font: 0=system monospaced, |
1=system font of variable width |
* A=0 - output esi characters, A=1 - output ASCIIZ-string |
* B=1 - fill background with the color edi |
* edx = pointer to the beginning of the string |
* esi = for A=0 length of the string, must not exceed 255; |
for A=1 is ignored |
Returned value: |
* function does not return value |
Remarks: |
* First system font is read out at loading from the file char.mt, |
second - from char2.mt. |
* Both fonts have height 9 pixels, width of the monospaced font |
is equal to 6 pixels. |
====================================================================== |
========================= Function 5 - delay. ======================== |
====================================================================== |
Delays execution of the program on the given time. |
Parameters: |
* eax = 5 - function number |
* ebx = time in the 1/100 of second |
Returned value: |
* function does not return value |
Remarks: |
* Passing ebx=0 does not transfer control to the next process |
and does not make any operations at all. If it is really required |
to transfer control to the next process (to complete a current |
time slice), use subfunction 1 of function 68. |
====================================================================== |
============== Function 6 - read the file from ramdisk. ============== |
====================================================================== |
Parameters: |
* eax = 6 - function number |
* ebx = pointer to the filename |
* ecx = number of start block, beginning from 1; |
ecx=0 - read from the beginning of the file (same as ecx=1) |
* edx = number of blocks to read; |
edx=0 - read one block (same as edx=1) |
* esi = pointer to memory area for the data |
Returned value: |
* eax = file size in bytes, if the file was successfully read |
* eax = -1, if the file was not found |
Remarks: |
* This function is out-of-date; function 70 allows |
to fulfil the same operations with the extended possibilities. |
* Block = 512 bytes. |
* For reading all file you can specify the certainly large value |
in edx, for example, edx = -1; but in this case be ready that |
the program will "fall", if the file will appear too large and can |
not be placed in the program memory. |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
=============== Function 7 - draw image in the window. =============== |
====================================================================== |
Paramters: |
* eax = 7 - function number |
* ebx = pointer to the image in the format BBGGRRBBGGRR... |
* ecx = [size on axis x]*65536 + [size on axis y] |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates of the image are coordinates of the upper left corner |
of the image relative to the window. |
* Size of the image in bytes is 3*xsize*ysize. |
====================================================================== |
=============== Function 8 - define/delete the button. =============== |
====================================================================== |
Parameters for button definition: |
* eax = 8 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = 0xXYnnnnnn, where: |
* nnnnnn = identifier of the button |
* high (31st) bit of edx is cleared |
* if 30th bit of edx is set - do not draw the button |
* if 29th bit of edx is set - do not draw a frame |
at pressing the button |
* esi = 0x00RRGGBB - color of the button |
Parameters for button deleting: |
* eax = 8 - function number |
* edx = 0x80nnnnnn, where nnnnnn - identifier of the button |
Returned value: |
* function does not return value |
Remarks: |
* Sizes of the button must be more than 0 and less than 0x8000. |
* For skinned windows definition of the window |
(call of 0th function) creates two standard buttons - |
for close of the window with identifier 1 and |
for minimize of the window with identifier 0xffff. |
* The creation of two buttons with same identifiers is admitted. |
* The button with the identifier 0xffff at pressing is interpreted |
by the system as the button of minimization, the system handles |
such pressing independently, not accessing to the application. |
In rest it is usual button. |
* Total number of buttons for all applications is limited to 4095. |
====================================================================== |
============ Function 9 - information on execution thread. =========== |
====================================================================== |
Parameters: |
* eax = 9 - function number |
* ebx = pointer to 1-Kb buffer |
* ecx = number of the slot of the thread |
ecx = -1 - get information on the current thread |
Returned value: |
* eax = maximum number of the slot of a thread |
* buffer pointed to by ebx contains the following information: |
* +0: dword: usage of the processor (how many time units |
per second leaves on execution of this thread) |
* +4: word: position of the window of thread in the window stack |
* +6: word: (has no relation to the specified thread) |
number of the thread slot, which window has in the window stack |
position ecx |
* +8: word: reserved |
* +10 = +0xA: 11 bytes: name of the process |
(name of corresponding executable file in the format 8+3) |
* +21 = +0x15: byte: reserved, this byte is not changed |
* +22 = +0x16: dword: address of the process in memory |
* +26 = +0x1A: dword: size of used memory - 1 |
* +30 = +0x1E: dword: identifier (PID/TID) |
* +34 = +0x22: dword: coordinate of the thread window on axis x |
* +38 = +0x26: dword: coordinate of the thread window on axis y |
* +42 = +0x2A: dword: size of the thread window on axis x |
* +46 = +0x2E: dword: size of the thread window on axis y |
* +50 = +0x32: word: status of the thread slot: |
* 0 = thread is running |
* 1 = thread is suspended |
* 2 = thread is suspended while waiting for event |
* 3 = thread is terminating as a result of call to function -1 |
or under duress as a result of call to subfunction 2 |
of function 18 or termination of the system |
* 4 = thread is terminating as a result of exception |
* 5 = thread waits for event |
* 9 = requested slot is free, all other information on the slot |
is not meaningful |
* +52 = +0x34: word: reserved, this word is not changed |
* +54 = +0x36: dword: coordinate of the client area on axis x |
* +58 = +0x3A: dword: coordinate of the client area on axis y |
* +62 = +0x3E: dword: width of the client area |
* +66 = +0x42: dword: height of the client area |
* +70 = +0x46: byte: state of the window - bitfield |
* bit 0 (mask 1): window is maximized |
* bit 1 (mask 2): window is minimized to panel |
* bit 2 (mask 4): window is rolled up |
Remarks: |
* Slots are numbered starting from 1. |
* Returned value is not a total number of threads, because there |
can be free slots. |
* When process is starting, system automatically creates |
execution thread. |
* Function gives information on the thread. Each process has |
at least one thread. One process can create many threads, |
in this case each thread has its own slot and the fields |
+10, +22, +26 in these slots coincide. |
Applications have no common way to define whether two threads |
belong to one process. |
* The active window - window on top of the window stack - |
receives the messages on a keyboard input. For such window |
the position in the window stack coincides with returned value. |
* Slot 1 corresponds to special system thread, for which: |
* the window is in the bottom of the window stack, the fields |
+4 and +6 contain value 1 |
* name of the process - "OS/IDLE" (supplemented by spaces) |
* address of the process in memory is 0, size of used memory is |
16 Mb (0x1000000) |
* PID=1 |
* coordinates and sizes of the window and the client area are by |
convention set to 0 |
* status of the slot is always 0 (running) |
* the execution time adds of time leaving on operations itself |
and idle time in waiting for interrupt (which can be got by call |
to subfunction 4 of function 18). |
* Beginning from slot 2, the normal applications are placed. |
* The normal applications are placed in memory at the address |
0x60400000 (kernel constant 'std_application_base_address'). |
There is no intersection, as each process has its own page table. |
* At creation of the thread it is assigned the slot |
in the system table and identifier (Process/Thread IDentifier = |
PID/TID), which do not vary with time for given thread. |
After completion of the thread its slot can be anew used |
for another thread. The thread identifier can not be assigned |
to other thread even after completion of this thread. |
Identifiers, assigned to new threads, grow monotonously. |
* If the thread has not yet defined the window by call to |
function 0, the position and the sizes |
of its window are considered to be zero. |
* Coordinates of the client area are relative to the window. |
* At the moment only the part of the buffer by a size |
71 = 0x37 bytes is used. Nevertheless it is recommended to use |
1-Kb buffer for the future compatibility, in the future |
some fields can be added. |
====================================================================== |
==================== Function 10 - wait for event. =================== |
====================================================================== |
If the message queue is empty, waits for appearance of the message |
in queue. In this state thread does not consume CPU time. |
Then reads out the message from queue. |
Parameters: |
* eax = 10 - function number |
Returned value: |
* eax = event (see the list of events) |
Remarks: |
* Those events are taken into account only which enter into |
a mask set by function 40. By default it is |
redraw, key and button events. |
* To check, whether there is a message in queue, use function 11. |
To wait for no more than given time, use function 23. |
====================================================================== |
=============== Function 11 - check for event, no wait. ============== |
====================================================================== |
If the message queue contains event, function reads out |
and return it. If the queue is empty, function returns 0. |
Parameters: |
* eax = 11 - function number |
Returned value: |
* eax = 0 - message queue is empty |
* else eax = event (see the list of events) |
Remarks: |
* Those events are taken into account only, which enter into |
a mask set by function 40. By default it is |
redraw, key and button events. |
* To wait for event, use function 10. |
To wait for no more than given time, use function 23. |
====================================================================== |
=============== Function 12 - begin/end window redraw. =============== |
====================================================================== |
---------------- Subfunction 1 - begin window redraw. ---------------- |
Parameters: |
* eax = 12 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
----------------- Subfunction 2 - end window redraw. ----------------- |
Parameters: |
* eax = 12 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* function does not return value |
Remarks: |
* Subfunction 1 deletes all buttons defined with |
function 8, they must be defined again. |
====================================================================== |
============ Function 13 - draw a rectangle in the window. =========== |
====================================================================== |
Parameters: |
* eax = 13 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = color 0xRRGGBB or 0x80RRGGBB for gradient fill |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates are understood as coordinates of the left upper corner |
of a rectangle relative to the window. |
====================================================================== |
=================== Function 14 - get screen size. =================== |
====================================================================== |
Parameters: |
* eax = 14 - function number |
Returned value: |
* eax = [xsize]*65536 + [ysize], where |
* xsize = x-coordinate of the right lower corner of the screen = |
horizontal size - 1 |
* ysize = y-coordinate of the right lower corner of the screen = |
vertical size - 1 |
Remarks: |
* See also subfunction 5 of function 48 - get sizes of |
working area of the screen. |
====================================================================== |
== Function 15, subfunction 1 - set a size of the background image. == |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 1 - subfunction number |
* ecx = width of the image |
* edx = height of the image |
Returned value: |
* function does not return value |
Remarks: |
* Before calling subfunctions 2 and 5 you should call this function |
to set image size! |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get size of the background image - |
subfunction 1 of function 39. |
====================================================================== |
=== Function 15, subfunction 2 - put pixel on the background image. == |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
* edx = color of a pixel 0xRRGGBB |
Returned value: |
* function does not return value |
Remarks: |
* Offset for a pixel with coordinates (x,y) is calculated as |
(x+y*xsize)*3. |
* If the given offset exceeds size set by subfunction 1, |
the call is ignored. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get pixel on the background image - |
subfunction 2 of function 39. |
====================================================================== |
=========== Function 15, subfunction 3 - redraw background. ========== |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
== Function 15, subfunction 4 - set drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 4 - subfunction number |
* ecx = drawing mode: |
* 1 = tile |
* 2 = stretch |
Returned value: |
* function does not return value |
Remarks: |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get drawing mode of the background - |
subfunction 4 of function 39. |
====================================================================== |
===================== Function 15, subfunction 5 ===================== |
============ Put block of pixels on the background image. ============ |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 5 - subfunction number |
* ecx = pointer to the data in the format BBGGRRBBGGRR... |
* edx = offset in data of the background image |
* esi = size of data in bytes = 3 * number of pixels |
Returned value: |
* function does not return value |
Remarks: |
* Offset and size are not checked for correctness. |
* Color of each pixel is stored as 3-bytes value BBGGRR. |
* Pixels of the background image are written sequentially |
from left to right, from up to down. |
* Offset of pixel with coordinates (x,y) is (x+y*xsize)*3. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
====================================================================== |
===================== Function 15, subfunction 6 ===================== |
======== Map background data to the address space of process. ======== |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 6 - subfunction number |
Returned value: |
* eax = pointer to background data, 0 if error |
Remarks: |
* Mapped data are available for read and write. |
* Size of background data is 3*xsize*ysize. The system blocks |
changes of background sizes while process works with mapped data. |
* Color of each pixel is stored as 3-bytes value BBGGRR. |
* Pixels of the background image are written sequentially |
from left to right, from up to down. |
====================================================================== |
===== Function 15, subfunction 7 - close mapped background data. ===== |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 7 - subfunction number |
* ecx = pointer to mapped data |
Returned value: |
* eax = 1 - success, 0 - error |
====================================================================== |
=============== Function 16 - save ramdisk on a floppy. ============== |
====================================================================== |
Parameters: |
* eax = 16 - function number |
* ebx = 1 or ebx = 2 - on which floppy save |
Returned value: |
* eax = 0 - success |
* eax = 1 - error |
====================================================================== |
======= Function 17 - get the identifier of the pressed button. ====== |
====================================================================== |
Takes away the code of the pressed button from the buffer. |
Parameters: |
* eax = 17 - function number |
Returned value: |
* if the buffer is empty, function returns eax=1 |
* if the buffer is not empty: |
* high 24 bits of eax contain button identifier (in particular, |
ah contains low byte of the identifier; if all buttons have |
the identifier less than 256, ah is enough to distinguish) |
* al = 0 - the button was pressed with left mouse button |
* al = bit corresponding to used mouse button otherwise |
Remarks: |
* "Buffer" keeps only one button, at pressing the new button the |
information about old is lost. |
* The call of this function by an application with inactive window |
will return answer "buffer is empty". |
* Returned value for al corresponds to the state of mouse buttons |
as in subfunction 2 of function 37 at the beginning |
of button press, excluding lower bit, which is cleared. |
====================================================================== |
= Function 18, subfunction 2 - terminate process/thread by the slot. = |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 2 - subfunction number |
* ecx = number of the slot of process/thread |
Returned value: |
* function does not return value |
Remarks: |
* It is impossible to terminate system thread OS/IDLE (with |
number of the slot 1), |
it is possible to terminate any normal process/thread. |
* See also subfunction 18 - terminate |
process/thread by the identifier. |
====================================================================== |
===================== Function 18, subfunction 3 ===================== |
============= Make active the window of the given thread. ============ |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 3 - subfunction number |
* ecx = number of the thread slot |
Returned value: |
* function does not return value |
Remarks: |
* If correct, but nonexistent slot is given, |
some window is made active. |
* To find out, which window is active, use subfunction 7. |
====================================================================== |
===================== Function 18, subfunction 4 ===================== |
=========== Get counter of idle time units per one second. =========== |
====================================================================== |
Idle time units are units, in which the processor stands idle |
in waiting for interrupt (in the command 'hlt'). |
Parameters: |
* eax = 18 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = value of the counter of idle time units per one second |
====================================================================== |
========== Function 18, subfunction 5 - get CPU clock rate. ========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = clock rate (modulo 2^32 clock ticks = 4GHz) |
====================================================================== |
Function 18, subfunction 6 - save ramdisk to the file on hard drive. |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 6 - subfunction number |
* ecx = pointer to the full path to file |
(for example, "/hd0/1/kolibri/kolibri.img") |
Returned value: |
* eax = 0 - success |
* else eax = error code of the file system |
Remarks: |
* All folders in the given path must exist, otherwise function |
returns value 5, "file not found". |
====================================================================== |
=========== Function 18, subfunction 7 - get active window. ========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = number of the active window |
(number of the slot of the thread with active window) |
Remarks: |
* Active window is at the top of the window stack and receives |
messages on all keyboard input. |
* To make a window active, use subfunction 3. |
====================================================================== |
== Function 18, subfunction 8 - disable/enable the internal speaker. = |
====================================================================== |
If speaker sound is disabled, all calls to subfunction 55 of |
function 55 are ignored. If speaker sound is enabled, |
they are routed on builtin speaker. |
------------------- Subsubfunction 1 - get status. ------------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 1 - number of the subsubfunction |
Returned value: |
* eax = 0 - speaker sound is enabled; 1 - disabled |
----------------- Subsubfunction 2 - toggle status. ------------------ |
Toggles states of disable/enable. |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 2 - number of the subsubfunction |
Returned value: |
* function does not return value |
====================================================================== |
== Function 18, subfunction 9 - system shutdown with the parameter. == |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 9 - subfunction number |
* ecx = parameter: |
* 2 = turn off computer |
* 3 = reboot computer |
* 4 = restart the kernel from the file 'kernel.mnt' on ramdisk |
Returned value: |
* at incorrect ecx the registers do not change (i.e. eax=18) |
* by correct call function always returns eax=0 |
as the tag of success |
Remarks: |
* Do not rely on returned value by incorrect call, it can be |
changed in future versions of the kernel. |
====================================================================== |
===== Function 18, subfunction 10 - minimize application window. ===== |
====================================================================== |
Minimizes the own window. |
Parameters: |
* eax = 18 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* function does not return value |
Remarks: |
* The minimized window from the point of view of function 9 |
keeps position and sizes. |
* Restoring of an application window occurs at its activation by |
subfunction 3. |
* Usually there is no necessity to minimize/restire a window |
obviously: minimization of a window is carried out by the system |
at pressing the minimization button (for skinned windows |
it is defined automatically by function 0, |
for other windows it can be defined manually by function 8), |
restore of a window is done by the application '@panel'. |
====================================================================== |
Function 18, subfunction 11 - get information on the disk subsystem. |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 11 - subfunction number |
* ecx = type of the table: |
* 1 = short version, 10 bytes |
* 2 = full version, 65536 bytes |
* edx = pointer to the buffer (in the application) for the table |
Returned value: |
* function does not return value |
Format of the table: short version: |
* +0: byte: information about FDD's (drives for floppies), |
AAAABBBB, where AAAA gives type of the first drive, BBBB - |
of the second regarding to the following list: |
* 0 = there is no drive |
* 1 = 360Kb, 5.25'' |
* 2 = 1.2Mb, 5.25'' |
* 3 = 720Kb, 3.5'' |
* 4 = 1.44Mb, 3.5'' |
* 5 = 2.88Mb, 3.5'' (such drives are not used anymore) |
For example, for the standard configuration from one 1.44-drive |
here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B: |
the value is 24h. |
* +1: byte: information about hard disks and CD-drives, AABBCCDD, |
where AA corresponds to the controller IDE0, ..., DD - IDE3: |
* 0 = device is absent |
* 1 = hard drive |
* 2 = CD-drive |
For example, in the case HD on IDE0 and CD on IDE2 |
this field contains 48h. |
* +2: 4 db: number of the retrieved partitions on hard disks |
at accordingly IDE0,...,IDE3. |
If the hard disk on IDEx is absent, appropriate byte is zero, |
otherwise it shows number of the recognized partitions, which |
can be not presented (if the drive is not formatted or if |
the file system is not supported). Current version of the kernel |
supports only FAT16, FAT32 and NTFS for hard disks. |
* +6: 4 db: reserved |
Format of the table: full version: |
* +0: 10 db: same as for the short version |
* +10: 100 db: data for the first partition |
* +110: 100 db: data for the second partition |
* ... |
* +10+100*(n-1): 100 db: data for the last partition |
The partitions are located as follows: at first sequentially all |
recoginzed partitions on HD on IDE0 (if present), |
then on HD on IDE1 (if present) and so on up to IDE3. |
Format of the information about partition |
(at moment only FAT is supported): |
* +0: dword: first physical sector of the partition |
* +4: dword: last physical sector of the partition |
(belongs to the partition) |
* +8: byte: file system type: |
16=FAT16, 32=FAT32, 1=NTFS |
* other data are dependent on file system, are modified with |
kernel modifications and therefore are not described |
Remarks: |
* The short table can be used for obtaining the information about |
available devices. |
====================================================================== |
========== Function 18, subfunction 13 - get kernel version. ========= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 13 - subfunction number |
* ecx = pointer to the buffer (not less than 16 bytes), where |
the information will be placed |
Returned value: |
* function does not return value |
Structure of the buffer: |
db a,b,c,d for version a.b.c.d |
db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
dd REV - kernel SVN revision number |
For Kolibri 0.7.1.0 kernel: |
db 0,7,0,0 |
db 2 |
dd 638 |
====================================================================== |
======= Function 18, subfunction 14 - wait for screen retrace. ======= |
====================================================================== |
Waits for the beginning of retrace of the scanning ray of the screen |
monitor. |
Parameters: |
* eax = 18 - function number |
* ebx = 14 - subfunction number |
Returned value: |
* eax = 0 as the tag of success |
Remarks: |
* Function is intended only for active high-efficiency graphics |
applications; is used for smooth output of a graphics. |
====================================================================== |
== Function 18, subfunction 15 - center mouse cursor on the screen. == |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 15 - subfunction number |
Returned value: |
* eax = 0 as the tag of success |
====================================================================== |
========= Function 18, subfunction 16 - get size of free RAM. ======== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 16 - subfunction number |
Returned value: |
* eax = size of free memory in kilobytes |
====================================================================== |
======== Function 18, subfunction 17 - get full amount of RAM. ======= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 17 - subfunction number |
Returned value: |
* eax = total size of existing memory in kilobytes |
====================================================================== |
===================== Function 18, subfunction 18 ==================== |
============= Terminate process/thread by the identifier. ============ |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 18 - subfunction number |
* ecx = identifer of process/thread (PID/TID) |
Returned value: |
* eax = 0 - success |
* eax = -1 - error (process is not found or is system) |
Remarks: |
* It is impossible to terminate system thread OS/IDLE (identifier |
1), it is possible to terminate any normal process/thread. |
* See also subfunction 2 - terminate |
process/thread by given slot. |
====================================================================== |
======== Function 18, subfunction 19 - get/set mouse features. ======= |
====================================================================== |
---------------- Subsubfunction 0 - get mouse speed. ----------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 0 - subsubfunction number |
Returned value: |
* eax = current mouse speed |
---------------- Subsubfunction 1 - set mouse speed. ----------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 1 - subsubfunction number |
* edx = new value for speed |
Returned value: |
* function does not return value |
---------------- Subsubfunction 2 - get mouse delay. ----------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 2 - subsubfunction number |
Returned value: |
* eax = current mouse delay |
---------------- Subsubfunction 3 - set mouse delay. ----------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 3 - subsubfunction number |
* edx = new value for mouse delay |
Returned value: |
* function does not return value |
----------- Subsubfunction 4 - set mouse pointer position. ----------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 4 - subsubfunction number |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
Returned value: |
* function does not return value |
-------- Subsubfunction 5 - simulate state of mouse buttons. --------- |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = 5 - subsubfunction number |
* edx = information about emulated state of mouse buttons: |
(same as return value in subfunction 2 of function 37) |
* bit 0 is set = left button is pressed |
* bit 1 is set = right button is pressed |
* bit 2 is set = middle button is pressed |
* bit 3 is set = 4th button is pressed |
* bit 4 is set = 5th button is pressed |
Returned value: |
* function does not return value |
Remarks: |
* It is recommended to set speed of the mouse (in subsubfunction 1) |
from 1 up to 9. The installed value is not inspected by the kernel |
code, so set it carefully, at incorrect value the cursor |
can "freeze". Speed of the mouse can be regulated through the |
application SETUP. |
* Recommended delay of the mouse (in subsubfunction 3) = 10. Lower |
value is not handled by COM mice. At the very large values the |
movement of the mouse on 1 pixel is impossible and the cursor will |
jump on the value of installed speed (subsubfunction 1). The |
installed value is not inspected by the kernel code. |
Mouse delay can be regulated through the application SETUP. |
* The subsubfunction 4 does not check the passed value. Before |
its call find out current screen resolution (with function 14) |
and check that the value of position is inside the limits of the |
screen. |
====================================================================== |
======== Function 18, subfunction 20 - get information on RAM. ======= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 20 - subfunction number |
* ecx = pointer to the buffer for information (36 bytes) |
Returned value: |
* eax = total size of existing RAM in pages |
or -1 if error has occured |
* buffer pointed to by ecx contains the following information: |
* +0: dword: total size of existing RAM in pages |
* +4: dword: size of free RAM in pages |
* +8: dword: number of page faults (exceptions #PF) |
in applications |
* +12: dword: size of kernel heap in bytes |
* +16: dword: free in kernel heap in bytes |
* +20: dword: total number of memory blocks in kernel heap |
* +24: dword: number of free memory blocks in kernel heap |
* +28: dword: size of maximum free block in kernel heap |
(reserved) |
* +32: dword: size of maximum allocated block in kernel heap |
(reserved) |
====================================================================== |
===================== Function 18, subfunction 21 ==================== |
======== Get slot number of process/thread by the identifier. ======== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 21 - subfunction number |
* ecx = identifer of process/thread (PID/TID) |
Returned value: |
* eax = 0 - error (invalid identifier) |
* otherwise eax = slot number |
====================================================================== |
===================== Function 18, subfunction 22 ==================== |
============== Operations with window of another thread. ============= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 22 - subfunction number |
* ecx = operation type: |
* 0 = minimize window of the thread with given slot number |
* 1 = minimize window of the thread with given identifier |
* 2 = restore window of the thread with given slot number |
* 3 = restore window of the thread with given identifier |
* edx = parameter (slot number or PID/TID) |
Returned value: |
* eax = 0 - success |
* eax = -1 - error (invalid identifier) |
Remarks: |
* The thread can minimize its window with subfunction 10. |
* One can restore and activate window simultaneously with |
subfunction 3 (which requires slot number). |
====================================================================== |
==================== Function 20 - MIDI interface. =================== |
====================================================================== |
----------------------- Subfunction 1 - reset ------------------------ |
Parameters: |
* eax = 20 - function number |
* ebx = 1 - subfunction number |
-------------------- Subfunction 2 - output byte --------------------- |
Parameters: |
* eax = 20 - function number |
* ebx = 2 - subfunction number |
* cl = byte for output |
Returned value (is the same for both subfunctions): |
* eax = 0 - success |
* eax = 1 - base port is not defined |
Remarks: |
* Previously the base port must be defined by |
subfunction 1 of function 21. |
====================================================================== |
======== Function 21, subfunction 1 - set MPU MIDI base port. ======== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 1 - subfunction number |
* ecx = number of base port |
Returned value |
* eax = 0 - success |
* eax = -1 - erratic number of a port |
Remarks: |
* Number of a port must satisfy to conditions 0x100<=ecx<=0xFFFF. |
* The installation of base is necessary for function 20. |
* To get base port use subfunction 1 of function 26. |
====================================================================== |
========== Function 21, subfunction 2 - set keyboard layout. ========= |
====================================================================== |
Keyboard layout is used to convert keyboard scancodes to ASCII-codes, |
which will be read by function 2. |
Parameters: |
* eax = 21 - function number |
* ebx = 2 - subfunction number |
* ecx = which layout to set: |
* 1 = normal layout |
* 2 = layout at pressed Shift |
* 3 = layout at pressed Alt |
* edx = pointer to layout - table of length 128 bytes |
Or: |
* ecx = 9 |
* dx = country identifier (1=eng, 2=fi, 3=ger, 4=rus) |
Returned value: |
* eax = 0 - success |
* eax = 1 - incorrect parameter |
Remarks: |
* If Alt is pressed, the layout with Alt is used; |
if Alt is not pressed, but Shift is pressed, |
the layout with Shift is used; |
if Alt and Shift are not pressed, but Ctrl is pressed, the normal |
layout is used and then from the code is subtracted 0x60; |
if no control key is pressed, the normal layout is used. |
* To get layout and country identifier use |
subfunction 2 of function 26. |
* Country identifier is global system variable, which is not used |
by the kernel itself; however the application '@panel' displays |
the corresponding icon. |
* The application @panel switches layouts on user request. |
====================================================================== |
============== Function 21, subfunction 3 - set CD base. ============= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 3 - subfunction number |
* ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Returned value: |
* eax = 0 |
Remarks: |
* CD base is used by function 24. |
* To get CD base use subfunction 3 of function 26. |
====================================================================== |
========== Function 21, subfunction 5 - set system language. ========= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 5 - subfunction number |
* ecx = system language (1=eng, 2=fi, 3=ger, 4=rus) |
Returned value: |
* eax = 0 |
Remarks: |
* System language is global system variable and is not used |
by the kernel itself, however application @panel draws the |
appropriate icon. |
* Function does not check for correctness, as the kernel does not |
use this variable. |
* To get system language use subfunction 5 of function 26. |
====================================================================== |
============== Function 21, subfunction 7 - set HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
syntax /HD in obsolete function 58; at usage of modern syntax |
/HD0,/HD1,/HD2,/HD3 base is set automatically. |
Parameters: |
* eax = 21 - function number |
* ebx = 7 - subfunction number |
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Returned value: |
* eax = 0 |
Remarks: |
* Any application at any time can change the base. |
* Do not change base, when any application works with hard disk. |
If you do not want system bugs. |
* To get HD base use subfunction 7 of function 26. |
* It is also necessary to define used partition of hard disk by |
subfunction 8. |
====================================================================== |
========= Function 21, subfunction 8 - set used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete syntax /HD and obsolete function 58; |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
base and partition are set automatically. |
Parameters: |
* eax = 21 - function number |
* ebx = 8 - subfunction number |
* ecx = HD partition (beginning from 1) |
Return value: |
* eax = 0 |
Remarks: |
* Any application at any time can change partition. |
* Do not change partition when any application works with hard disk. |
If you do not want system bugs. |
* To get used partition use subfunction 8 of function 26. |
* There is no correctness checks. |
* To get the number of partitions of a hard disk use |
subfunction 11 of function 18. |
* It is also necessary to define used HD base by subfunction 7. |
====================================================================== |
Function 21, subfunction 11 - enable/disable low-level access to HD. |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 11 - subfunction number |
* ecx = 0/1 - disable/enable |
Returned value: |
* eax = 0 |
Remarks: |
* Is used in LBA-read (subfunction 8 of function 58). |
* The current implementation uses only low bit of ecx. |
* To get current status use subfunction 11 of function 26. |
====================================================================== |
Function 21, subfunction 12 - enable/disable low-level access to PCI. |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 12 - subfunction number |
* ecx = 0/1 - disable/enable |
Returned value: |
* eax = 0 |
Remarks: |
* Is used in operations with PCI bus (function 62). |
* The current implementation uses only low bit of ecx. |
* To get current status use subfunction 12 of function 26. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 1 =========== |
======== Initialize + get information on the driver vmode.mdr. ======= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 1 - number of the driver function |
* edx = pointer to 512-bytes buffer |
Returned value: |
* if driver is not loaded |
(never happens in the current implementation): |
* eax = -1 |
* ebx, ecx destroyed |
* if driver is loaded: |
* eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high) |
- signature |
* ebx = current frequency of the scanning (in Hz) |
* ecx destroyed |
* buffer pointed to by edx is filled |
Format of the buffer: |
* +0: 32*byte: driver name, "Trans VideoDriver" |
(without quotes, supplemented by spaces) |
* +32 = +0x20: dword: driver version (version x.y is encoded as |
y*65536+x), for the current implementation is 1 (1.0) |
* +36 = +0x24: 7*dword: reserved (0 in the current implementation) |
* +64 = +0x40: 32*word: list of supported videomodes (each word |
is number of a videomode, after list itself there are zeroes) |
* +128 = +0x80: 32*(5*word): list of supported frequences of the |
scannings for videomodes: for each videomode listed in the |
previous field up to 5 supported frequences are given |
(unused positions contain zeroes) |
Remarks: |
* Function initializes the driver (if it is not initialized yet) |
and must be called first, before others (otherwise they will do |
nothing and return -1). |
* The current implementation supports only one frequency |
of the scanning on videomode. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 2 =========== |
================ Get information on current videomode. =============== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 2 - number of the driver function |
Returned value: |
* eax = -1 - driver is not loaded or not initialized; |
ebx,ecx are destroyed |
* eax = [width]*65536 + [height] |
* ebx = frequency of the vertical scanning (in Hz) |
* ecx = number of current videomode |
Remarks: |
* Driver must be initialized by call to |
driver function 1. |
* If only screen sizes are required, it is more expedient to use |
function 14 taking into account that it |
returns sizes on 1 less. |
====================================================================== |
=== Function 21, subfunction 13, subsubfunction 3 - set videomode. === |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 3 - number of the driver function |
* edx = [scanning frequency]*65536 + [videomode number] |
Returned value: |
* eax = -1 - driver is not loaded, not initialized or |
an error has occured |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by driver function 1. |
* The videomode number and frequency must be in the table |
returned by driver function 1. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 4 =========== |
================== Return to the initial videomode. ================== |
====================================================================== |
Returns the screen to the videomode set at system boot. |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 4 - number of the driver function |
Returned value: |
* eax = -1 - driver is not loaded or not initialized |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by call to driver function 1. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 5 =========== |
===== Increase/decrease the size of the visible area of monitor. ===== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 5 - number of the driver function |
* edx = 0/1 - decrease/increase horizontal size on 1 position |
* edx = 2/3 - is not supported in the current implementation; |
is planned as decrease/increase vertical size on 1 position |
Returned value: |
* eax = -1 - driver is not loaded or not initialized |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by call to driver function 1. |
* Function influences only the physical size of the screen image; |
the logical size (number of pixels) does not change. |
====================================================================== |
================= Function 22 - set system date/time. ================ |
====================================================================== |
Parameters: |
* eax = 22 - function number |
* ebx = 0 - set time |
* ecx = 0x00SSMMHH - time in the binary-decimal code (BCD): |
* HH=hour 00..23 |
* MM=minute 00..59 |
* SS=second 00..59 |
* ebx = 1 - set date |
* ecx = 0x00DDMMYY - date in the binary-decimal code (BCD): |
* DD=day 01..31 |
* MM=month 01..12 |
* YY=year 00..99 |
* ebx = 2 - set day of week |
* ecx = 1 for Sunday, ..., 7 for Saturday |
* ebx = 3 - set alarm clock |
* ecx = 0x00SSMMHH |
Returned value: |
* eax = 0 - success |
* eax = 1 - incorrect parameter |
* eax = 2 - CMOS-battery was unloaded |
Remarks: |
* Value of installation of day of week seems to be doubtful, |
as it a little where is used |
(day of week can be calculated by date). |
* Alarm clock can be set on operation in the given time every day. |
But there is no existing system function to disable it. |
* Operation of alarm clock consists in generation IRQ8. |
* Generally CMOS supports for alarm clock set of value 0xFF |
as one of parameters and it means that the appropriate parameter |
is ignored. But current implementation does not allow this |
(will return 1). |
* Alarm clock is a global system resource; the set of |
an alarm clock cancels automatically the previous set. |
However, at moment no program uses it. |
====================================================================== |
============= Function 23 - wait for event with timeout. ============= |
====================================================================== |
If the message queue is empty, waits for new message in the queue, |
but no more than given time. Then reads out a message from the queue. |
Parameters: |
* eax = 23 - function number |
* ebx = timeout (in 1/100 of second) |
Returned value: |
* eax = 0 - the message queue is empty |
* otherwise eax = event (see the list of events) |
Remarks: |
* Only those events are taken into account, which enter into |
the mask set by function 40. By default it is |
redraw, key and button events. |
* To check for presence of a message in the queue use function 11. |
To wait without timeout use function 10. |
* Transmission ebx=0 results in immediate returning eax=0. |
* Current implementation returns immediately with eax=0, |
if the addition of ebx with the current value of time counter |
makes 32-bit overflow. |
====================================================================== |
======== Function 24, subfunction 1 - begin to play CD-audio. ======== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 1 - subfunction number |
* ecx = 0x00FRSSMM, where |
* MM = starting minute |
* SS = starting second |
* FR = starting frame |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Remarks: |
* Previously CD base must be defined by the call to |
subfunction 3 of function 21. |
* One second includes 75 frames, one minute includes 60 seconds. |
* The function is asynchronous (returns control, when play begins). |
====================================================================== |
======= Function 24, subfunction 2 - get information on tracks. ====== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to the buffer for the table |
(maximum 8*64h+4 bytes=100 tracks) |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Remarks: |
* The format of the table with tracks information is the same as |
for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h). |
Function returns addresses in MSF. |
* Previously CD base port must be set by call to |
subfunction 3 of function 21. |
* Function returns information only about no more than 100 |
first tracks. In most cases it is enough. |
====================================================================== |
========== Function 24, subfunction 3 - stop play CD-audio. ========== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Remarks: |
* Previously CD base port must be defined by call to |
subfunction 3 of function 21. |
====================================================================== |
======= Function 24, subfunction 4 - eject tray of disk drive. ======= |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 4 - subfunction number |
* ecx = position of CD/DVD-drive |
(from 0=Primary Master to 3=Secondary Slave) |
Returned value: |
* function does not return value |
Remarks: |
* The function is supported only for ATAPI devices (CD and DVD). |
* When the tray is being ejected, |
manual control of tray is unlocked. |
* When the tray is being ejected, the code clears the cache for |
corresponding device. |
* An example of usage of the function is the application CD_tray. |
====================================================================== |
======== Function 24, subfunction 5 - load tray of disk drive. ======= |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 5 - subfunction number |
* ecx = position of CD/DVD-drive |
(from 0=Primary Master to 3=Secondary Slave) |
Returned value: |
* function does not return value |
Remarks: |
* The function is supported only for ATAPI devices (CD and DVD). |
* An example of usage of the function is the application CD_tray. |
====================================================================== |
======== Function 26, subfunction 1 - get MPU MIDI base port. ======== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = port number |
Parameters: |
* To set base port use subfunction 1 of function 21. |
====================================================================== |
========== Function 26, subfunction 2 - get keyboard layout. ========= |
====================================================================== |
The keyboard layout is used to convert keyboard scancodes to |
ASCII-codes for function 2. |
Parameters: |
* eax = 26 - function number |
* ebx = 2 - subfunction number |
* ecx = what layout to get: |
* 1 = normal layout |
* 2 = layout with pressed Shift |
* 3 = layout with pressed Alt |
* edx = pointer to the 128-bytes buffer, where the layout will be |
copied |
Returned value: |
* function does not return value |
Or: |
* eax = 26 - function number |
* ebx = 2 - subfunction number |
* ecx = 9 |
Returned value: |
* eax = country identifier (1=eng, 2=fi, 3=ger, 4=rus) |
Remarks: |
* If Alt is pressed, the layout with Alt is used; |
if Alt is not pressed, but Shift is pressed, |
the layout with Shift is used; |
if Alt and Shift are not pressed, but Ctrl is pressed, the normal |
layout is used and then from the code is subtracted 0x60; |
if no control key is pressed, the normal layout is used. |
* To set layout and country identifier use |
subfunction 2 of function 21. |
* Country identifier is global system variable, which is not used |
by the kernel itself; however the application '@panel' displays |
the corresponding icon (using this function). |
* The application @panel switches layouts on user request. |
====================================================================== |
============== Function 26, subfunction 3 - get CD base. ============= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Remarks: |
* CD base is used by function 24. |
* To set CD base use subfunction 3 of function 21. |
====================================================================== |
========== Function 26, subfunction 5 - get system language. ========= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = system language (1=eng, 2=fi, 3=ger, 4=rus) |
Remarks: |
* System language is global system variable and is not used |
by the kernel itself, however application @panel draws the |
appropriate icon (using this function). |
* To set system language use subfunction 5 of function 21. |
====================================================================== |
============== Function 26, subfunction 7 - get HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
syntax /HD in obsolete function 58; at usage of modern syntax |
/HD0,/HD1,/HD2,/HD3 base is set automatically. |
Parameters: |
* eax = 26 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Remarks: |
* Any application in any time can change HD base. |
* To set base use subfunction 7 of function 21. |
* To get used partition of hard disk use subfunction 8. |
====================================================================== |
========= Function 26, subfunction 8 - get used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete syntax /HD in obsolete function 58; |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
base and partition are set automatically. |
Parameters: |
* eax = 26 - function number |
* ebx = 8 - subfunction number |
Returned value: |
* eax = HD partition (beginning from 1) |
Remarks: |
* Any application in any time can change partition. |
* To set partition use subfunction 8 of function 21. |
* To get number of partitions on a hard disk use |
subfunction 11 of function 18. |
* To get base of used hard disk, use subfunction 7. |
====================================================================== |
=== Function 26, subfunction 9 - get the value of the time counter. == |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 9 - subfunction number |
Returned value: |
* eax = number of 1/100s of second, past from the system boot time |
Remarks: |
* Counter takes modulo 2^32, that correspond to a little more |
than 497 days. |
* To get system time use function 3. |
====================================================================== |
===================== Function 26, subfunction 11 ==================== |
========== Find out whether low-level HD access is enabled. ========== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 11 - subfunction number |
Returned value: |
* eax = 0/1 - disabled/enabled |
Remarks: |
* Is used in LBA read (subfunction 8 of function 58). |
* To set current state use subfunction 11 of function 21. |
====================================================================== |
===================== Function 26, subfunction 12 ==================== |
========== Find out whether low-level PCI access is enabled. ========= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 12 - subfunction number |
Returned value: |
* eax = 0/1 - disabled/enabled |
Remarks: |
* Is used by operations with PCI bus (function 62). |
* The current implementation uses only low bit of ecx. |
* To set the current state use subfunction 12 of function 21. |
====================================================================== |
=================== Function 29 - get system date. =================== |
====================================================================== |
Parameters: |
* eax = 29 - function number |
Returned value: |
* eax = 0x00DDMMYY, where |
(binary-decimal coding, BCD, is used) |
* YY = two low digits of year (00..99) |
* MM = month (01..12) |
* DD = day (01..31) |
Remarks: |
* To set system date use function 22. |
====================================================================== |
============= Function 30 - work with the current folder. ============ |
====================================================================== |
--------- Subfunction 1 - set current folder for the thread. --------- |
Parameters: |
* eax = 30 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to ASCIIZ-string with the path to new current folder |
Returned value: |
* function does not return value |
--------- Subfunction 2 - get current folder for the thread. --------- |
Parameters: |
* eax = 30 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to buffer |
* edx = size of buffer |
Returned value: |
* eax = size of the current folder's name (including terminating 0) |
Remarks: |
* If the buffer is too small to hold all data, only first (edx-1) |
bytes are copied and than terminating 0 is inserted. |
====================================================================== |
=============== Function 32 - delete file from ramdisk. ============== |
====================================================================== |
Parameters: |
* eax = 32 - function number |
* ebx = pointer to the filename |
Returned value: |
* eax = 0 - success; otherwise file system error code |
Remarks: |
* This function is obsolete; function 58 allows to fulfill |
the same operations with the extended possibilities. |
* The current implementation returns only values 0(success) and |
5(file not found). |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
================ Function 33 - write file to ramdisk. ================ |
====================================================================== |
Parameters: |
* eax = 33 - function number |
* ebx = pointer to the filename |
* ecx = pointer to data for writing |
* edx = number of bytes for writing |
* should be set esi=0 |
Returned value: |
* eax = 0 - success, otherwise file system error code |
Remarks: |
* This function is obsolete; function 70 allows to fulfil |
the same operations with extended possibilities. |
* If esi contains non-zero value and selected file already exists, |
one more file with the same name will be created. |
* Otherwise file will be overwritten. |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
======= Function 35 - read the color of a pixel on the screen. ======= |
====================================================================== |
Parameters: |
* eax = 35 |
* ebx = y*xsize+x, where |
* (x,y) = coordinates of a pixel (beginning from 0) |
* xsize = horizontal screen size |
Returned value: |
* eax = color 0x00RRGGBB |
Remarks: |
* To get screen sizes use function 14. Pay attention, |
that it subtracts 1 from both sizes. |
* There is also direct access (without any system calls) |
to videomemory through the selector gs. To get parameters of |
the current videomode, use function 61. |
====================================================================== |
=================== Function 36 - read screen area. ================== |
====================================================================== |
Paramters: |
* eax = 36 - function number |
* ebx = pointer to the previously allocated memory area, |
where will be placed the image in the format BBGGRRBBGGRR... |
* ecx = [size on axis x]*65536 + [size on axis y] |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates of the image are coordinates of the upper left corner |
of the image relative to the screen. |
* Size of the image in bytes is 3*xsize*ysize. |
====================================================================== |
=================== Function 37 - work with mouse. =================== |
====================================================================== |
---------- Subfunction 0 - screen coordinates of the mouse ----------- |
Parameters: |
* eax = 37 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
(beginning from 0) |
-- Subfunction 1 - coordinates of the mouse relative to the window --- |
Parameters: |
* eax = 37 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
relative to the application window (beginning from 0) |
Remarks: |
* The value is calculated by formula (x-xwnd)*65536 + (y-ywnd). |
If y>=ywnd, the low word is non-negative and contains |
relative y-coordinate, and the high word - relative x-coordinate |
(with correct sign). Otherwise the low word is negative and still |
contains relative y-coordinate, and to the high word |
1 should be added. |
------------ Subfunction 2 - pressed buttons of the mouse ------------ |
Parameters: |
* eax = 37 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax contains information on the pressed mouse buttons: |
* bit 0 is set = left button is pressed |
* bit 1 is set = right button is pressed |
* bit 2 is set = middle button is pressed |
* bit 3 is set = 4th button is pressed |
* bit 4 is set = 5th button is pressed |
* other bits are cleared |
-------------------- Subfunction 4 - load cursor --------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 4 - subfunction number |
* dx = data source: |
* dx = LOAD_FROM_FILE = 0 - data in a file |
* ecx = pointer to full path to the cursor file |
* the file must be in the format .cur, which is standard for |
MS Windows, at that of the size 32*32 pixels |
* dx = LOAD_FROM_MEM = 1 - data of file are already loaded in memory |
* ecx = pointer to data of the cursor file |
* the data format is the same as in the previous case |
* dx = LOAD_INDIRECT = 2 - data in memory |
* ecx = pointer to cursor image in the format ARGB 32*32 pixels |
* edx = 0xXXYY0002, where |
* XX = x-coordinate of cursor hotspot |
* YY = y-coordinate |
* 0 <= XX, YY <= 31 |
Returned value: |
* eax = 0 - failed |
* otherwise eax = cursor handle |
--------------------- Subfunction 5 - set cursor --------------------- |
Sets new cursor for the window of the current thread. |
Parameters: |
* eax = 37 - function number |
* ebx = 5 - subfunction number |
* ecx = cursor handle |
Returned value: |
* eax = handle of previous cursor |
Remarks: |
* If the handle is incorrect, the function restores the default |
cursor (standard arrow). In particular, ecx=0 restores it. |
------------------- Subfunction 6 - delete cursor -------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 6 - subfunction number |
* ecx = cursor handle |
Returned value: |
* eax destroyed |
Remarks: |
* The cursor must be loaded previously by the current thread |
(with the call to subfunction 4). The function does not delete |
system cursors and cursors, loaded by another applications. |
* If the active cursor (set by subfunction 5) is deleted, |
the system restores the default cursor (standard arrow). |
------------------ Subfunction 7 - get scroll data ------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = [horizontal offset]*65536 + [vertical offset] |
Remarks: |
* Scroll data is available for active window only. |
* Values are zeroed after reading. |
* Values are signed. |
====================================================================== |
====================== Function 38 - draw line. ====================== |
====================================================================== |
Parameters: |
* eax = 38 - function number |
* ebx = [start coordinate on axis x]*65536 + |
[end coordinate on axis x] |
* ecx = [start coordinate on axis y]*65536 + |
[end coordinate on axis y] |
* edx = 0x00RRGGBB - color |
edx = 0x01xxxxxx - draw inversed line |
(low 24 bits are ignored) |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates are relative to the window. |
* End point is also drawn. |
====================================================================== |
== Function 39, subfunction 1 - get a size of the background image. == |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [width]*65536 + [height] |
Remarks: |
* There is a pair function to set sizes of background image - |
subfunction 1 of function 15. After which it is necessary, |
of course, anew to define image. |
====================================================================== |
== Function 39, subfunction 2 - get pixel from the background image. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
Returned value: |
* eax = 0x00RRGGBB - pixel color, if offset is valid |
(less than 0x160000-16) |
* eax = 2 otherwise |
Remarks: |
* Do not rely on returned value for invalid offsets, it may be |
changed in future kernel versions. |
* Offset for pixel with coordinates (x,y) |
is calculated as (x+y*xsize)*3. |
* There is a pair function to set pixel on the background image - |
subfunction 2 of function 15. |
====================================================================== |
== Function 39, subfunction 4 - get drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = 1 - tile |
* eax = 2 - stretch |
Remarks: |
* There is a pair function to set drawing mode - |
subfunction 4 of function 15. |
====================================================================== |
=========== Function 40 - set the mask for expected events. ========== |
====================================================================== |
The mask for expected events affects function working with events |
10, 11, 23 - they notify only about events allowed by this mask. |
Parameters: |
* eax = 40 - function number |
* ebx = mask: bit i corresponds to event i+1 (see list of events) |
(set bit permits notice on event) |
Returned value: |
* eax = previous value of mask |
Remarks: |
* Default mask (7=111b) enables nofices about redraw, |
keys and buttons. This is enough for many applications. |
* Events prohibited in the mask are saved anyway, when come; |
they are simply not informed with event functions. |
* Event functions take into account the mask on moment of |
function call, not on moment of event arrival. |
====================================================================== |
==================== Function 41 - get IRQ owner. ==================== |
====================================================================== |
Parameters: |
* eax = 41 - function number |
* ebx = IRQ number, 0..15 |
Returned value: |
* eax = owner PID |
* eax = 0, if there is no owner |
* eax = -1 for incorrect ebx |
====================================================================== |
================== Function 42 - work with IRQ data. ================= |
====================================================================== |
When an IRQ occurs, the system reads data from ports indicated |
earlier by function 44 and writes this data to |
internal buffer. This function reads out data from that buffer. |
--------------------- Subfunction 0 - read data ---------------------- |
Parameters: |
* eax = 42 - function number |
* bl = IRQ number, 0..15 |
* bh = 0 - subfunction number |
* rest of ebx must be zeroed |
* ecx = pointer to a buffer with size not less than 4000 bytes |
Returned value: (use value of eax to distinguish) |
* if the thread is not IRQ owner |
(or IRQ number is incorrect): eax = -1 |
* if there is no data: eax = 0 |
* if all is ok: |
eax = size of data read (in bytes) |
------------- Subfunction 1 - get size of data in buffer ------------- |
Parameters: |
* eax = 42 - function number |
* bl = IRQ number, 0..15 |
* bh = 0 - subfunction number |
* rest of ebx must be zeroed |
Returned value: |
* if the thread is not IRQ owner |
(or IRQ number is incorrect): eax = -1 |
* otherwise eax = size of data in buffer |
Remarks: |
* Previously the thread must reserve indicated IRQ for itself |
by function 45. |
* The size of data buffer is 4000 bytes, on overflow |
"fresh" data cease to be written in the buffer. |
====================================================================== |
================ Function 43 - input/output to a port. =============== |
====================================================================== |
------------------------ Output data to port ------------------------- |
Parameters: |
* eax = 43 - function number |
* bl = byte for output |
* ecx = port number 0xnnnn (from 0 to 0xFFFF) |
Returned value: |
* eax = 0 - success |
* eax = 1 - the thread has not reserved the selected port |
------------------------ Input data from port ------------------------ |
Parameters: |
* eax = 43 - function number |
* ebx is ignored |
* ecx = 0x8000nnnn, where nnnn = port number (from 0 to 0xFFFF) |
Returned value: |
* eax = 0 - success, thus ebx = entered byte |
* eax = 1 - the thread has not reserved the selected port |
Remarks: |
* Previously the thread must reserve the selected port |
for itself by function 46. |
* Instead of call to this function it is better to use |
processor instructions in/out - this is much |
faster and a bit shorter and easier. |
====================================================================== |
=========== Function 44 - define operations at IRQ arrival. ========== |
====================================================================== |
At IRQ arrival the system can read the data from ports defined |
by this function and write these data to internal buffer, whence |
they can be read by ôóíêöèåé 42. |
Parameters: |
* eax = 44 - function number |
* ebx = pointer to the array of structures each describing one port: |
* +0: word: 0 means end of array, otherwise port number |
* +2: byte: reserved (ignored) |
* +3: byte: 1=read byte from this port, 2=read word |
* ecx = IRQ number, 0..15 |
Returned value: |
* eax = 0 - success |
* eax = 1 - the thread is not owner of selected IRQ |
Remarks: |
* Previously the thread must reserve for itself selected IRQ |
by function 45. |
* First 16 ports are considered only. |
* The current implementation considers incorrect value of field +3 |
as a signal to terminate IRQ processing. |
====================================================================== |
=================== Function 45 - reserve/free IRQ. ================== |
====================================================================== |
Parameters: |
* eax = 45 - function number |
* ebx = 0 - reserve, 1 = free |
* ecx = IRQ number, 0..15 |
Returned value: |
* eax = 0 - success |
* eax = 1 - error (invalid IRQ number |
or attempt to reserve not free IRQ |
or to free IRQ, not reserved by this thread) |
Remarks: |
* IRQ reservation is required for functions 42 and 44. |
* Only one thread can reserve the specific IRQ. |
* IRQs, handled by the system itself, are reserved by the system |
(thread 1) at booting. |
* When a thread terminates, all reserved by it IRQs |
are freed automatically. |
====================================================================== |
====== Function 46 - reserve/free a group of input/output ports. ===== |
====================================================================== |
To work with reserved ports an application can access directly by |
commands in/out (recommended way) and can use function 43 |
(not recommended way). |
Parameters: |
* eax = 46 - function number |
* ebx = 0 - reserve, 1 - free |
* ecx = start port number |
* edx = end port number (inclusive) |
Returned value: |
* eax = 0 - success |
* eax = 1 - error |
Remarks: |
* For ports reservation: an error occurs if and only if |
one from the following condition satisfies: |
* start port is more than end port; |
* the selected range contains incorrect port number |
(correct are from 0 to 0xFFFF); |
* limit for the total number of reserved areas is exceeded |
(maximum 255 are allowed); |
* the selected range intersects with any of earlier reserved |
* For ports free: an error is an attempt to free range, |
that was not earlier reserved by this function |
(with same ecx,edx). |
* If an error occurs (for both cases) function performs no action. |
* At booting the system reserves for itself ports |
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (inclusively). |
* When a thread terminates, all reserved by it ports |
are freed automatically. |
====================================================================== |
============= Function 47 - draw a number in the window. ============= |
====================================================================== |
Parameters: |
* eax = 47 - function number |
* ebx = parameters of conversion number to text: |
* bl = 0 - ecx contains number |
* bl = 1 - ecx contains pointer to dword/qword-number |
* bh = 0 - display in decimal number system |
* bh = 1 - display in hexadecimal system |
* bh = 2 - display in binary system |
* bits 16-21 = how many digits to display |
* bits 22-29 reserved and must be set to 0 |
* bit 30 set = display qword (64-bit) number (must be bl=1) |
* bit 31 set = do not display leading zeroes of the number |
* ecx = number (if bl=0) or pointer (if bl=1) |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* esi = 0xX0RRGGBB: |
* RR, GG, BB specify the color |
* X = ABnn (bits) |
* nn = font (0/1) |
* A is ignored |
* B=1 - fill background with the color edi |
Returned value: |
* function does not return value |
Remarks: |
* The given length must not exceed 60. |
* The exactly given amount of digits is output. If number is small |
and can be written by smaller amount of digits, it is supplemented |
by leading zeroes; if the number is big and can not be written by |
given amount of digits, extra digits are not drawn. |
* Parameters of fonts are shown in the description of function 4 |
(text output). |
====================================================================== |
========= Function 48, subfunction 0 - apply screen settings. ======== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 0 - subfunction number |
* ecx = 0 - reserved |
Returned value: |
* function does not return value |
Remarks: |
* Function redraws the screen after parameters change by |
subfunctions 1 and 2. |
* Function call without prior call to one of indicated subfunctions |
is ignored. |
* Function call with nonzero ecx is ignored. |
====================================================================== |
=========== Function 48, subfunction 1 - set button style. =========== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 1 - subfunction number |
* ecx = button style: |
* 0 = flat |
* 1 = 3d |
Returned value: |
* function does not return value |
Remarks: |
* After call to this function one should redraw the screen by |
subfunction 0. |
* Button style influences only to their draw of function 8. |
====================================================================== |
====== Function 48, subfunction 2 - set standard window colors. ====== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to the color table |
* edx = size of the color table |
(must be 40 bytes for future compatibility) |
Format of the color table is shown in description of subfunction 3. |
Returned value: |
* function does not return value |
Remarks: |
* After call to this function one should redraw the screen by |
subfunction 0. |
* Table of standard colors influences only to applications, |
which receive this table obviously (by subfunction 3) |
and use it (specifying colors from it to drawing functions). |
* Table of standard colors is included in skin and is installed |
anew with skin installation (by subfunction 8). |
* Color table can be viewed/changed interactively with |
the application 'desktop'. |
====================================================================== |
====== Function 48, subfunction 3 - get standard window colors. ====== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 3 - subfunction number |
* ecx = pointer to the buffer with size edx bytes, |
where table will be written |
* edx = size of color table |
(must be 40 bytes for future compatibility) |
Returned value: |
* function does not return value |
Format of the color table: |
each item is dword-value for color 0x00RRGGBB |
* +0: dword: frames - color of frame |
* +4: dword: grab - color of header |
* +8: dword: grab_button - color of button on header bar |
* +12 = +0xC: dword: grab_button_text - color of text on button |
on header bar |
* +16 = +0x10: dword: grab_text - color of text on header |
* +20 = +0x14: dword: work - color of working area |
* +24 = +0x18: dword: work_button - color of button in working area |
* +28 = +0x1C: dword: work_button_text - color of text on button |
in working area |
* +32 = +0x20: dword: work_text - color of text in working area |
* +36 = +0x24: dword: work_graph - color of graphics in working area |
Remarks: |
* Structure of the color table is described in the standard |
include file 'macros.inc' as 'system_colors'; for example, |
it is possible to write: |
sc system_colors ; variable declaration |
... ; somewhere one must call |
; this function with ecx=sc |
mov ecx, [sc.work_button_text] ; read text color on |
; buttin in working area |
* A program itself desides to use or not to use color table. |
For usage program must simply at calls to drawing functions select |
color taken from the table. |
* At change of the table of standard colors (by subfunction 2 with |
the subsequent application of changes by subfunction 0 or |
at skin set by subfunction 8) the system sends to all windows |
redraw message (the event with code 1). |
* Color table can be viewed/changed interactively with |
the application 'desktop'. |
====================================================================== |
============ Function 48, subfunction 4 - get skin height. =========== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = skin height |
Remarks: |
* Skin height is defined as the height of a header |
of skinned windows. |
* See also general structure of window in the description |
of function 0. |
====================================================================== |
======== Function 48, subfunction 5 - get screen working area. ======= |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Remarks: |
* The screen working area defines position and coordinates of |
a maximized window. |
* The screen working area in view of normal work is all screen |
without system panel (the application '@panel'). |
* (left,top) are coordinates of the left upper corner, |
(right,bottom) are coordinates of the right lower one. |
Thus the size of working area on x axis can be calculated by |
formula right-left+1, on y axis - by formula bottom-right+1. |
* See also function 14, |
to get sizes of all screen. |
* There is a pair function to set working area - subfunction 6. |
====================================================================== |
======== Function 48, subfunction 6 - set screen working area. ======= |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 6 - subfunction number |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
Returned value: |
* function does not return value |
Remarks: |
* The screen working area defines position and coordinates of |
a maximized window. |
* This function is used only by the application '@panel', |
which set working area to all screen without system panel. |
* (left,top) are coordinates of the left upper corner, |
(right,bottom) are coordinates of the right lower one. |
Thus the size of working area on x axis can be calculated by |
formula right-left+1, on y axis - by formula bottom-right+1. |
* If 'left'>='right', x-coordinate of working area is not changed. |
If 'left'<0, 'left' will not be set. If 'right' is greater than or |
equal to screen width, 'right' will not be set. |
Similarly on y axis. |
* See also function 14, |
to get sizes of all screen. |
* There is a pair function to get working area - subfunction 5. |
* This function redraws the screen automatically, |
updating coordinates and sizes of maximized windows. |
The system sends to all windows redraw message (the event 1). |
====================================================================== |
=========== Function 48, subfunction 7 - get skin margins. =========== |
====================================================================== |
Returns the area of a header of a skinned window, intended for |
a text of a header. |
Parameters: |
* eax = 48 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Remarks: |
* An application decides itself to use or not to use this function. |
* It is recommended to take into account returned value |
of this function for choice of a place for drawing header text |
(by function 4) or a substitute of header text |
(at the discretion of an application). |
====================================================================== |
============= Function 48, subfunction 8 - set used skin. ============ |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 8 - subfunction number |
* ecx = pointer to a block for function 58, in |
which the fields of intermediate buffer and file name are filled |
Returned value: |
* eax = 0 - success |
* otherwise eax = file system error code; if file does not |
contain valid skin, function returns error 3 |
(unknown file system). |
Remarks: |
* After successful skin loading the system sends to all windows |
redraw message (the event 1). |
* At booting the system reads skin from file 'default.skn' |
on ramdisk. |
* User can change the skin statically by creating hisself |
'default.skn' or dynamically with the application 'desktop'. |
====================================================================== |
=========== Function 49 - Advanced Power Management (APM). =========== |
====================================================================== |
Parameters: |
* eax = 49 - function number |
* dx = number of the APM function |
(analogue of ax in APM specification) |
* bx, cx = parameters of the APM function |
Returned value: |
* 16-bit registers ax, bx, cx, dx, si, di and carry flag CF |
are set according to the APM specification |
* high halves of 32-bit registers eax, ebx, ecx, |
edx, esi, edi are destroyed |
Remarks: |
* APM 1.2 specification is described in the document |
"Advanced Power Management (APM) BIOS Specification" |
(Revision 1.2), available at |
http://www.microsoft.com/whdc/archive/amp_12.mspx; |
besides it is included in famous Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). |
====================================================================== |
=================== Function 50 - set window shape. ================== |
====================================================================== |
Normal windows have rectangular shape. This function can give to |
a window any shape. The shape is given by a set of points inside |
the base rectangle belonging to a window. Position and coordinates |
of the base rectangle are set by function 0 |
and changed by function 67. |
--------------------------- Set shape data --------------------------- |
Parameters: |
* eax = 50 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer to shape data (array of bytes 0/1) |
Returned value: |
* function does not return value |
-------------------------- Set shape scale --------------------------- |
Parameters: |
* eax = 50 - function number |
* ebx = 1 - subfunction number |
* ecx sets a scale: each byte of data defines |
(2^scale)*(2^scale) pixels |
Returned value: |
* function does not return value |
Remarks: |
* Default scale is 0 (scale factor is 1). If in the shape data |
one byte corresponds to one pixel, there is no necessity |
to set scale. |
* Let's designate xsize = window width (in pixels), ysize = height; |
pay attention, that they are one pixel more than defined by |
functions 0, 67. |
* On definition of scale xsize and ysize must be divisible |
on 2^scale. |
* Byte of data on offset 'a' must be 0/1 and defines belonging |
to a window of square with the side 2^scale (if scale=0, |
this is one pixel) and coordinates of the left upper corner |
(a mod (xsize shr scale), a div (xsize shr scale)) |
* Data size: (xsize shr scale)*(ysize shr scale). |
* Data must be presented in the memory and not change |
after set of shape. |
* The system views the shape data at every window redraw by |
function 0. |
* The call of subfunction 0 with NULL pointer results in return |
to the rectangular shape. |
====================================================================== |
==================== Function 51 - create thread. ==================== |
====================================================================== |
Parameters: |
* eax = 51 - function number |
* ebx = 1 - unique subfunction |
* ecx = address of thread entry point (starting eip) |
* edx = pointer to thread stack (starting esp) |
Returned value: |
* eax = -1 - error (there is too many threads) |
* otherwise eax = TID - thread identifier |
</UL> |
====================================================================== |
=== Function 52, subfunction 0 - get network driver configuration. === |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = configuration dword |
Remarks: |
* Configuration dword can be set by subfunction 2. |
* The kernel does not use this variable. The value of this |
variable and working with it subfunctions 0 and 2 is represented |
doubtful. |
====================================================================== |
========= Function 52, subfunction 1 - get local IP-address. ========= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = IP-address (4 bytes) |
Remarks: |
* Local IP-address is set by subfunction 3. |
====================================================================== |
=== Function 52, subfunction 2 - set network driver configuration. === |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 2 - subfunction number |
* ecx = configuration dword; if low 7 bits derivate the number 3, |
function [re-]initializes Ethernet-card, otherwise |
Ethernet turns off |
Returned value: |
* if Ethernet-interface is not requested, function returns eax=2, |
but this can be changed in future kernel versions |
* if Ethernet-interface is requested, eax=0 means error |
(absence of Ethernet-card), and nonzero value - success |
Remarks: |
* Configuration dword can be read by subfunction 0. |
* The kernel does not use this variable. The value of this |
variable, subfunction 0 and part of subfunction 2, which set it, |
is represented doubtful. |
====================================================================== |
========= Function 52, subfunction 3 - set local IP-address. ========= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 3 - subfunction number |
* ecx = IP-address (4 bytes) |
Returned value: |
* the current implementation returns eax=3, but this can be changed |
in future versions |
Remarks: |
* Local IP-address can be get by subfunction 1. |
====================================================================== |
= Function 52, subfunction 6 - add data to the stack of input queue. = |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 6 - subfunction number |
* edx = data size |
* esi = data pointer |
Returned value: |
* eax = -1 - error |
* eax = 0 - success |
Remarks: |
* This function is intended only for slow network drivers |
(PPP, SLIP). |
* Data size must not exceed 1500 bytes, though function |
performs no checks on correctness. |
====================================================================== |
Function 52, subfunction 8 - read data from the network output queue. |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 8 - subfunction number |
* esi = pointer to 1500-byte buffer |
Returned value: |
* eax = number of read bytes (in the current implementation |
either 0 = no data or 1500) |
* data was copied in buffer |
Remarks: |
* This function is intended only for slow network drivers |
(PPP, SLIP). |
====================================================================== |
============ Function 52, subfunction 9 - get gateway IP. ============ |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 9 - subfunction number |
Returned value: |
* eax = gateway IP (4 bytes) |
====================================================================== |
=========== Function 52, subfunction 10 - get subnet mask. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* eax = subnet mask |
====================================================================== |
============ Function 52, subfunction 11 - set gateway IP. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 11 - subfunction number |
* ecx = gateway IP (4 bytes) |
Returned value: |
* the current implementation returns eax=11, but this can be changed |
in future versions |
====================================================================== |
=========== Function 52, subfunction 12 - set subnet mask. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 12 - subfunction number |
* ecx = subnet mask |
Returned value: |
* the current implementation returns eax=12, but this can be changed |
in future versions |
====================================================================== |
============== Function 52, subfunction 13 - get DNS IP. ============= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 13 - subfunction number |
Returned value: |
* eax = DNS IP (4 bytes) |
====================================================================== |
============== Function 52, subfunction 14 - set DNS IP. ============= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 14 - subfunction number |
* ecx = DNS IP (4 bytes) |
Returned value: |
* the current implementation returns eax=14, but this can be changed |
in future versions |
====================================================================== |
======== Function 52, subfunction 15 - get local MAC address. ======== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 15 - subfunction number |
* ecx = 0 - read first 4 bytes, |
ecx = 4 - read last 2 bytes |
Returned value: |
* for ecx=0: eax = first 4 bytes of MAC address |
* for ecx=4: ax = last 2 bytes of MAC address, |
high half of eax is destroyed |
* for other ecx: eax = -1 indicates an error |
====================================================================== |
============ Function 53, subfunction 0 - open UDP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 0 - subfunction number |
* ecx = local port (only low word is taken into account), |
ecx = 0 - let the system choose a port |
* edx = remote port (only low word is taken into account) |
* esi = remote IP |
Returned value: |
* eax = -1 = 0xFFFFFFFF - error; ebx destroyed |
* eax = socket handle (some number which unambiguously identifies |
socket and have sense only for the system) - success; |
ebx destroyed |
====================================================================== |
=========== Function 53, subfunction 1 - close UDP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 1 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = -1 - incorrect handle |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* The current implementation does not close automatically all |
sockets of a thread at termination. In particular, one should not |
kill a thread with many opened sockets - there will be an outflow |
of resources. |
====================================================================== |
============== Function 53, subfunction 2 - poll socket. ============= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 2 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = number of read bytes, 0 for incorrect handle |
* ebx destroyed |
====================================================================== |
========= Function 53, subfunction 3 - read byte from socket. ======== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 3 - subfunction number |
* ecx = socket handle |
Returned value: |
* if there is no read data or handle is incorrect: eax=0, bl=0, |
other bytes of ebx are destroyed |
* if there are read data: eax=number of rest bytes |
(possibly 0), bl=read byte, other bytes of ebx are destroyed |
====================================================================== |
========== Function 53, subfunction 4 - write to UDP-socket. ========= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 4 - subfunction number |
* ecx = socket handle |
* edx = number of bytes to write |
* esi = pointer to data to write |
Returned value: |
* eax = 0xffffffff - error (invalid handle or not enough memory) |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* Number of bytes to write must not exceed 1500-28, though |
the appropriate check is not made. |
====================================================================== |
============ Function 53, subfunction 5 - open TCP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 5 - subfunction number |
* ecx = local port (only low word is taken into account), |
ecx = 0 - let the system choose a port |
* edx = remote port (only low word is taken into account) |
* esi = remote IP |
* edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1 |
Returned value: |
* eax = -1 = 0xFFFFFFFF - error; ebx destroys |
* eax = socket handle (some number which unambiguously identifies |
socket and have sense only for the system) - success; |
ebx destroyed |
====================================================================== |
========= Function 53, subfunction 6 - get TCP-socket status. ======== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 6 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = 0 for incorrect handle or socket status: one of |
* TCB_LISTEN = 1 |
* TCB_SYN_SENT = 2 |
* TCB_SYN_RECEIVED = 3 |
* TCB_ESTABLISHED = 4 |
* TCB_FIN_WAIT_1 = 5 |
* TCB_FIN_WAIT_2 = 6 |
* TCB_CLOSE_WAIT = 7 |
* TCB_CLOSING = 8 |
* TCB_LAST_ASK = 9 |
* TCB_TIME_WAIT = 10 |
* TCB_CLOSED = 11 |
* ebx destroyed |
====================================================================== |
========== Function 53, subfunction 7 - write to TCP-socket. ========= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 7 - subfunction number |
* ecx = socket handle |
* edx = number of bytes to write |
* esi = pointer to data to write |
Returned value: |
* eax = 0xffffffff - error (invalid handle or not enough memory) |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* Number of bytes to write must not exceed 1500-40, though |
the appropriate check is not made. |
====================================================================== |
=========== Function 53, subfunction 8 - close TCP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 8 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = -1 - error (invalid handle or |
not enough memory for socket close packet) |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* The current implementation does not close automatically all |
sockets of a thread at termination. In particular, one should not |
kill a thread with many opened sockets - there will be an outflow |
of resources. |
====================================================================== |
=== Function 53, subfunction 9 - check whether local port is free. === |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 9 - subfunction number |
* ecx = local port number (low 16 bits are used only) |
Returned value: |
* eax = 0 - port is used |
* eax = 1 - port is free |
* ebx destroyed |
====================================================================== |
===== Function 53, subfunction 10 - query Ethernet cable status. ===== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* al = -1 - a network driver is not loaded or |
does not support this function |
* al = 0 - Ethernet cable is unplugged |
* al = 1 - Ethernet cable is plugged |
* ebx destroyed |
Remarks: |
* The current kernel implementation supports this function |
only for RTL8139 network cards. |
====================================================================== |
======= Function 53, subfunction 11 - read network stack data. ======= |
====================================================================== |
Paramters: |
* eax = 53 - function number |
* ebx = 11 - subfunction number |
* ecx = socket handle |
* edx = pointer to buffer |
* esi = number of bytes to read; |
* esi = 0 - read all data (maximum 4096 bytes) |
Returned value: |
* eax = number of bytes read (0 for incorrect handle) |
* ebx destroyed |
====================================================================== |
= Function 53, subfunction 255 - debug information of network driver. |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 255 - subfunction number |
* ecx = type of requested information (see below) |
Returned value: |
* eax = requested information |
* ebx destroyed |
Possible values for ecx: |
* 100: length of queue 0 (empty queue) |
* 101: length of queue 1 (ip-out queue) |
* 102: length of queue 2 (ip-in queue) |
* 103: length of queue 3 (net1out queue) |
* 200: number of items in the ARP table |
* 201: size of the ARP table (in items) (20 for current version) |
* 202: read item at edx of the ARP table to the temporary buffer, |
whence 5 following types take information; |
in this case eax is not defined |
* 203: IP-address saved by type 202 |
* 204: high dword of MAC-address saved by type 202 |
* 205: low word of MAC-address saved by type 202 |
* 206: status word saved by type 202 |
* 207: ttl word saved by type 202 |
* 2: total number of received IP-packets |
* 3: total number of transferred IP-packets |
* 4: total number of dumped received packets |
* 5: total number of received ARP-packets |
* 6: status of packet driver, 0=inactive, nonzero=active |
====================================================================== |
Function 55, subfunction 55 - begin to play data on built-in speaker. |
====================================================================== |
Parameters: |
* eax = 55 - function number |
* ebx = 55 - subfunction number |
* esi = pointer to data |
Returned value: |
* eax = 0 - success |
* eax = 55 - error (speaker is off or busy) |
Data is an array of items with variable length. |
Format of each item is defined by first byte: |
* 0 = end of data |
* 1..0x80 = sets sound duration on 1/100 of second; sound note |
is defined by immediate value of frequency |
* following word (2 bytes) contains frequency divider; |
frequency is defined as 1193180/divider |
* 0x81 = invalid |
* 0x82..0xFF = note is defined by octave and number: |
* duration in 1/100 of second = (first byte)-0x81 |
* there is one more byte; |
* (second byte)=0xFF - delay |
* otherwise it looks like a*0x10+b, where b=number of the note in |
an octave from 1 to 12, a=number of octave (beginning from 0) |
Remarks: |
* Speaker play can be disabled/enabled by |
subfunction 8 of function 18. |
* Function returns control, having informed the system |
an information on request. Play itself goes independently from |
the program. |
* The data must be kept in the memory at least up to the end |
of play. |
====================================================================== |
======================= Function 57 - PCI BIOS. ====================== |
====================================================================== |
Parameters: |
* eax = 57 - function number |
* ebp corresponds to al in PCI BIOS specification |
* other registers are set according to PCI BIOS specification |
Returned value: |
* CF is undefined |
* other registers are set according to PCI BIOS specification |
Remarks: |
* Many effects of this function can be also achieved with |
corresponding subfunctions of function 62. |
* The function calls PCI32 BIOS extension, documented e.g. in |
http://alpha1.dyns.net/files/PCI/bios21.pdf. |
* If BIOS does not support this extension, its behavior is emulated |
(through kernel-mode analogues of subfunctions of function 62). |
====================================================================== |
================ Function 58 - work with file system. ================ |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: number of block |
* +8: dword: size |
* +12 = +0xC: dword: pointer to data |
* +16 = +0x10: dword: pointer to a memory for system operations |
(4096 bytes) |
* +20 = +0x14: n db: ASCIIZ-string with the file name |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive for latin letters, russian letters |
must be capital. |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk |
(in this case base is defined by subfunction 7 of function 21), |
x - partition number (beginning from 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
Remarks: |
* In the first two cases it is also possible to use FIRST |
instead of 1, SECOND instead of 2, but it is not recommended |
for convenience of transition to the future extensions. |
* Limitation n<=39 is imposed. |
* Names of folders and file dir1,...,dirn,file must have the |
format 8.3: name no more than 8 characters, dot, extension no |
more than 3 characters. Trailing spaces are ignored, no other |
spaces is allowed. If name occupies equally 8 characters, |
dot may be omitted (though it is not recommended to use this |
feature for convenience of transition to the future extensions). |
* This function does not support folders on ramdisk. |
Examples: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
Existing subfunctions: |
* subfunction 0 - read file/folder |
* subfunction 8 - LBA-read from device |
* subfunction 15 - get file system information |
====================================================================== |
=========== Function 58, subfunction 0 - read file/folder. =========== |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: first block to read (beginning from 0) |
* +8: dword: amount of blocks to read |
* +12 = +0xC: dword: pointer to buffer for data |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found |
Remarks: |
* Block size is 512 bytes. |
* This function is obsolete, for reading files use subfunction 0 |
of function 70, for reading folders - subfunction 1 of |
function 70. |
* Function can read contents of a folder. Only FAT file system is |
supported. The format of FAT-folder is described |
in any FAT documentation. |
* Size of a folder is determined by size of FAT clusters chain. |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but |
in the first two cases the current implementation does not follow |
to the declared rules: |
for /rd/1: |
* if one want to read 0 blocks, function considers, |
that he requested 1; |
* if one requests more than 14 blocks or starting block is |
not less than 14, function returns eax=5 (not found) è ebx=-1; |
* size of ramdisk root folder is 14 blocks, |
0x1C00=7168 áàéò; but function returns ebx=0 |
(except of the case of previous item); |
* strangely enough, it is possible to read 14th block (which |
generally contains a garbage - I remind, the indexing begins |
from 0); |
* if some block with the number not less than 14 was requested, |
function returns eax=6(EOF); otherwise eax=0. |
For /fd/x: |
* if the start block is not less than 14, function returns |
eax=5 (not found) and ebx=0; |
* note that format of FAT12 allows floppies with the root size |
more or less than 14 blocks; |
* check for length is not performed; |
* if data was successful read, function returns |
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1. |
* The function handles reading of special folders /,/rd,/fd,/hd[n]; |
but the result does not correspond to expected (on operations with |
normal files/folders), does not follow the declared rules, |
may be changed in future versions of the kernel and consequently |
is not described. To obtain the information about the equipment |
use subfunction 11 of function 18 or |
read corresponding folder with subfunction 1 of function 70. |
====================================================================== |
========= Function 58, subfunction 8 - LBA-read from device. ========= |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 8 = subfunction number |
* +4: dword: number of block to read (beginning from 0) |
* +8: dword: ignored (set to 1) |
* +12 = +0xC: dword: pointer to buffer for data (512 bytes) |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of |
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3. |
Instead of digits it is allowed, though not recommended for |
convenience of transition to future extensions, to use |
'first','second','third','fourth'. |
Returned value: |
* for device name /hd/xxx, where xxx is not in the list above: |
* eax = ebx = 1 |
* for invalid device name (except for the previous case): |
* eax = 5 |
* ebx does not change |
* if LBA-access is disabled by subfunction 11 of function 21: |
* eax = 2 |
* ebx destroyed |
* for ramdisk: attempt to read block outside ramdisk |
(18*2*80 blocks) results in |
* eax = 3 |
* ebx = 0 |
* for successful read: |
* eax = ebx = 0 |
Remarks: |
* Block size is 512 bytes; function reads one block. |
* Do not depend on returned value, it can be changed |
in future versions. |
* Function requires that LBA-access to devices is enabled by |
subfunction 11 of function 21. To check this one can use |
subfunction 11 of function 26. |
* LBA-read of floppy is not supported. |
* Function reads data on physical hard drive; if for any reason |
data of the concrete partition are required, application must |
define starting sector of this partition (either directly |
through MBR, or from the full structure returned by |
ïîäôóíêöèåé 11 ôóíêöèè 18). |
* Function does not check error code of hard disk, so request of |
nonexisting sector reads something (most probably it will be |
zeroes, but this is defined by device) and this is considered |
as success (eax=0). |
====================================================================== |
==== Function 58, subfunction 15 - get information on file system. === |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 15 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: ignored |
* +20 = +0x14: (only second character is checked) |
/rd=/RAMDISK or /hd=/HARDDISK |
Returned value: |
* if the second character does not belong to set {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* for ramdisk: |
* eax = 0 (success) |
* ebx = total number of clusters = 2847 |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size = 512 |
* for hard disk: base and partition are defined by subfunctions |
7 and 8 of function 21: |
* eax = 0 (success) |
* ebx = total number of clusters |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size (in bytes) |
Remarks: |
* Be not surprised to strange layout of 4th returned parameter |
- when this code was writing, at system calls application got |
only registers eax,ebx,ecx (from pushad-structure transmitted |
as argument to the system function). Now it is corrected, so, |
probably, it is meaningful to return cluster size in edx, while |
this function is not used yet. |
* There exists also subfunction 11 of function 18, |
which returns information on file system. From the full table |
of disk subsystem it is possible to deduce cluster size (there |
it is stored in sectors) and total number of clusters |
for hard disks. |
====================================================================== |
========== Function 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC is used for message dispatching from one process/thread to |
another. Previously it is necessary to agree how to interpret |
the concrete message. |
----------- Subfunction 1 - set the area for IPC receiving ----------- |
Is called by process-receiver. |
Parameters: |
* eax = 60 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to the buffer |
* edx = size of the buffer |
Returned value: |
* eax = 0 - always success |
Format of IPC-buffer: |
* +0: dword: if nonzero, buffer is considered locked; |
lock/unlock the buffer, when you work with it and need that |
buffer data are not changed from outside (no new messages) |
* +4: dword: occupied place in the buffer (in bytes) |
* +8: first message |
* +8+n: second message |
* ... |
Format of a message: |
* +0: dword: PID of sender |
* +4: dword: message length (not including this header) |
* +8: n*byte: message data |
------------------ Subfunction 2 - send IPC message ------------------ |
Is called by process-sender. |
Parameters: |
* eax = 60 - function number |
* ebx = 2 - subfunction number |
* ecx = PID of receiver |
* edx = pointer to the message data |
* esi = message length (in bytes) |
Returned value: |
* eax = 0 - success |
* eax = 1 - the receiver has not defined buffer for IPC messages |
(can be, still have no time, |
and can be, this is not right process) |
* eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit |
* eax = 3 - overflow of IPC-buffer of the receiver |
* eax = 4 - process/thread with such PID does not exist |
Remarks: |
* Immediately after writing of IPC-message to the buffer the system |
sends to the receiver the event with code 7 (see event codes). |
====================================================================== |
==== Function 61 - get parameters for the direct graphics access. ==== |
====================================================================== |
The data of the graphics screen (the memory area which displays |
screen contents) are accessible to a program directly, without |
any system calls, through the selector gs: |
mov eax, [gs:0] |
places in eax the first dword of the buffer, which contains |
information on color of the left upper point (and, possibly, colors |
of several following). |
mov [gs:0], eax |
by work in VESA modes with LFB sets color of the left upper point |
(and, possibly, colors of several following). |
To interpret the data of graphics screen program needs to know |
some parameters, returning by this function. |
Remarks: |
* Graphics parameters changes very seldom at work, |
namely, only in cases, when user works with the application VRR. |
* At videomode change the system redraws all windows (event |
with code 1) and redraws the background (event 5). |
Same events occur in other cases too, which meet much more often, |
than videomode change. |
* By operation in videomodes with LFB the selector gs points to |
LFB itself, so reading/writing on gs result directly in |
change of screen contents. By operation in videomodes without |
LFB gs points to some data area in the kernel, and all functions |
of screen output fulfil honesty double operation on writing |
directly to the screen and writing to this buffer. In result |
at reading contents of this buffer the results correspond to |
screen contents (with, generally speaking, large color |
resolution), and writing is ignored. |
One exception is the mode 320*200, for which main loop of the |
system thread updates the screen according to mouse movements. |
------------------------- Screen resolution -------------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [resolution on x axis]*65536 + [resolution on y axis] |
Remarks: |
* One can use function 14 paying attention that |
it returns sizes on 1 pixel less. It is fully equivalent way. |
---------------------- Number of bits per pixel ---------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = number of bits per pixel (24 or 32) |
-------------------- Number of bytes per scanline -------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = number of bytes occupied by one scanline |
(horizontal line on the screen) |
====================================================================== |
===== Function 62, subfunction 0 - get version of PCI-interface. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 0 - subfunction number |
Returned value: |
* eax = -1 - PCI access is disabled; otherwise |
* ah.al = version of PCI-interface (ah=version, al=subversion) |
* high word of eax is zeroed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
==== Function 62, subfunction 1 - get number of the last PCI-bus. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 1 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = number of the last PCI-bus; other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
===================== Function 62, subfunction 2 ===================== |
===== Get mechanism of addressing to the PCI configuration space. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 2 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = mechanism (1 or 2); other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Addressing mechanism is selected depending on |
equipment characteristics. |
* Subfunctions of read and write work automatically |
with the selected mechanism. |
====================================================================== |
======== Function 62, subfunctions 4,5,6 - read PCI-register. ======== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 4 - read byte |
* bl = 5 - read word |
* bl = 6 - read dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=5, |
divisible by 4 for bl=6) |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported); otherwise |
* al/ax/eax (depending on requested size) contains the data; |
the other part of register eax is destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous |
Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
registers of the second type must be listed |
in the device documentation. |
====================================================================== |
====== Function 62, subfunctions 8,9,10 - write to PCI-register. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 8 - write byte |
* bl = 9 - write word |
* bl = 10 - write dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=9, |
divisible by 4 for bl=10) |
* dl/dx/edx (depending on requested size) contatins |
the data to write |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported) |
* eax = 0 - success |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous Interrupt List by |
Ralf Brown; registers of the second type must be listed |
in the device documentation. |
====================================================================== |
============== Function 63 - work with the debug board. ============== |
====================================================================== |
The debug board is the global system buffer (with the size |
1024 bytes), to which any program can write (generally speaking, |
arbitrary) data and from which other program can read these data. |
By the agreement written data are text strings interpreted as |
debug messages on a course of program execution. The kernel in |
some situations also writes to the debug board information on |
execution of some functions; by the agreement kernel messages |
begins from the prefix "K : ". |
For view of the debug board the application 'board' was created, |
which reads data from the buffer and displays them in its window. |
'board' interpretes the sequence of codes 13,10 as newline. |
A character with null code in an end of line is not necessary, |
but also does not prevent. |
Because debugger has been written, the value of the debug board |
has decreased, as debugger allows to inspect completely a course of |
program execution without any efforts from the direction of program |
itself. Nevertheless in some cases the debug board is still useful. |
----------------------------- Write byte ----------------------------- |
Parameters: |
* eax = 63 - function number |
* ebx = 1 - subfunction number |
* cl = data byte |
Returned value: |
* function does not return value |
Remarks: |
* Byte is written to the buffer. Buffer size is 512 bytes. |
At buffer overflow all obtained data are lost. |
* For output to the debug board of more complicated objects |
(strings, numbers) it is enough to call this function in cycle. |
It is possible not to write the appropriate code manually and use |
file 'debug.inc', which is included into the distributive. |
----------------------------- Read byte ------------------------------ |
Takes away byte from the buffer. |
Parameters: |
* eax = 63 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = ebx = 0 - the buffer is empty |
* eax = byte, ebx = 1 - byte was successfully read |
====================================================================== |
============== Function 64 - resize application memory. ============== |
====================================================================== |
Parameters: |
* eax = 64 - function number |
* ebx = 1 - unique subfunction |
* ecx = new memory size |
Returned value: |
* eax = 0 - success |
* eax = 1 - not enough memory |
Remarks: |
* There is another way to dynamically allocate/free memory - |
subfunctions 11, 12, 13 of function 68. |
* The function cannot be used together with 68.11, 68.12, 68.13. |
The function call will be ignored after creation of process heap |
with function 68.11. |
====================================================================== |
======== Function 65 - draw image with palette in the window. ======== |
====================================================================== |
Parameters: |
* eax = 65 - function number |
* ebx = pointer to the image |
* ecx = [size on axis x]*65536 + [size on axis y] |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* esi = number of bits per pixel, must be 1,2,4,8,15,16,24 or 32 |
* edi = pointer to palette (2 to the power esi colors 0x00RRGGBB); |
ignored when esi > 8 |
* ebp = offset of next row data relative to previous row data |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates of the image are coordinates of the upper left corner |
of the image relative to the window. |
* Format of image with 1 bit per pixel: each byte of image |
(possibly excluding last bytes in rows), contains information on |
the color of 8 pixels, MSB corresponds to first pixel. |
* Format of image with 2 bits per pixel: each byte of image |
(possibly excluding last bytes in rows), contains information on |
the color of 4 pixels, two MSBs correspond to first pixel. |
* Format of image with 4 bits per pixel: each byte of image |
excluding last bytes in rows (if width is odd) contains |
information on the color of 2 pixels, high-order tetrad |
corresponds to first pixel. |
* Format of image with 8 bits per pixel: each byte of image is |
index in the palette. |
* Format of image with 15 bits per pixel: the color of each pixel |
is coded as (bit representation) 0RRRRRGGGGGBBBBB - 5 bits per |
each color. |
* Format of image with 16 bits per pixel: the color of each pixel |
is coded as RRRRRGGGGGGBBBBB (5+6+5). |
* Format of image with 24 bits per pixel: the color of each pixel |
is coded as 3 bytes - sequentially blue, green, red components. |
* Format of image with 32 bits per pixel: similar to 24, but |
one additional ignored byte is present. |
* The call to function 7 is equivalent to call to this function |
with esi=24, ebp=0. |
====================================================================== |
================== Function 66 - work with keyboard. ================= |
====================================================================== |
The input mode influences results of reading keys by function 2. |
When a program loads, ASCII input mode is set for it. |
-------------- Subfunction 1 - set keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 1 - subfunction number |
* ecx = mode: |
* 0 = normal (ASCII-characters) |
* 1 = scancodes |
Returned value: |
* function does not return value |
-------------- Subfunction 2 - get keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = current mode |
------------ Subfunction 3 - get status of control keys. ------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = bit mask: |
* bit 0 (mask 1): left Shift is pressed |
* bit 1 (mask 2): right Shift is pressed |
* bit 2 (mask 4): left Ctrl is pressed |
* bit 3 (mask 8): right Ctrl is pressed |
* bit 4 (mask 0x10): left Alt is pressed |
* bit 5 (mask 0x20): right Alt is pressed |
* bit 6 (mask 0x40): CapsLock is on |
* bit 7 (mask 0x80): NumLock is on |
* bit 8 (mask 0x100): ScrollLock is on |
* other bits are cleared |
-------------- Subfunction 4 - set system-wide hotkey. --------------- |
When hotkey is pressed, the system notifies only those applications, |
which have installed it; the active application (which receives |
all normal input) does not receive such keys. |
The notification consists in sending event with the code 2. |
Reading hotkey is the same as reading normal key - by function 2. |
Parameters: |
* eax = 66 - function number |
* ebx = 4 - subfunction number |
* cl determines key scancode; |
use cl=0 to give combinations such as Ctrl+Shift |
* edx = 0xXYZ determines possible states of control keys: |
* Z (low 4 bits) determines state of LShift and RShift: |
* 0 = no key must be pressed; |
* 1 = exactly one key must be pressed; |
* 2 = both keys must be pressed; |
* 3 = must be pressed LShift, but not RShift; |
* 4 = must be pressed RShift, but not LShift |
* Y - similar for LCtrl and RCtrl; |
* X - similar for LAlt and RAlt |
Returned value: |
* eax=0 - success |
* eax=1 - too mant hotkeys (maximum 256 are allowed) |
Remarks: |
* Hotkey can work either at pressing or at release. Release |
scancode of a key is more on 128 than pressing scancode |
(i.e. high bit is set). |
* Several applications can set the same combination; |
all such applications will be informed on pressing |
such combination. |
-------------- Subfunction 5 - delete installed hotkey. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 5 - subfunction number |
* cl = scancode of key and edx = 0xXYZ the same as in subfunction 4 |
Returned value: |
* eax = 0 - success |
* eax = 1 - there is no such hotkey |
Remarks: |
* When a process/thread terminates, all hotkey installed by it are |
deleted. |
* The call to this subfunction does not affect other applications. |
If other application has defined the same combination, it will |
still receive notices. |
====================================================================== |
========= Function 67 - change position/sizes of the window. ========= |
====================================================================== |
Parameters: |
* eax = 67 - function number |
* ebx = new x-coordinate of the window |
* ecx = new y-coordinate of the window |
* edx = new x-size of the window |
* esi = new y-size of the window |
Returned value: |
* function does not return value |
Remarks: |
* The value -1 for a parameter means "do not change"; e.g. to move |
the window without resizing it is possible to specify edx=esi=-1. |
* Previously the window must be defined by function 0. |
It sets initial coordinates and sizes of the window. |
* Sizes of the window are understood in sense of function 0, |
that is one pixel less than real sizes. |
* The function call for maximized windows is simply ignored. |
* For windows of appropriate styles position and/or sizes can be |
changed by user; current position and sizes can be obtained by |
call to function 9. |
* The function sends to the window redraw event (with the code 1). |
====================================================================== |
====== Function 68, subfunction 0 - get the task switch counter. ===== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = number of task switches from the system booting |
(modulo 2^32) |
====================================================================== |
======= Function 68, subfunction 1 - switch to the next thread. ====== |
====================================================================== |
The function completes the current time slice allocated to the |
thread and switches to the next. (Which thread in which process |
will be next, is unpredictable). Later, when execution queue |
will reach the current thread, execution will be continued. |
Parameters: |
* eax = 68 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
============= Function 68, subfunction 2 - cache + rdpmc. ============ |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 2 - subfunction number |
* ecx = required action: |
* ecx = 0 - enable instruction 'rdpmc' |
(ReaD Performance-Monitoring Counters) for applications |
* ecx = 1 - find out whether cache is disabled/enabled |
* ecx = 2 - enable cache |
* ecx = 3 - disable cache |
Returned value: |
* for ecx=0: |
* eax = the value of cr4 |
* for ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - cache is on |
* eax <> 0 - cache is off |
* for ecx=2 and ecx=3: |
* function does not return value |
====================================================================== |
=========== Function 68, subfunction 3 - read MSR-register. ========== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 3 - subfunction number |
* ecx is ignored |
* edx = MSR address |
Returned value: |
* ebx:eax = high:low dword of the result |
Remarks: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
========= Function 68, subfunction 4 - write to MSR-register. ======== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 4 - subfunction number |
* ecx is ignored |
* edx = MSR address |
* esi:edi = high:low dword |
Returned value: |
* function does not return value |
Remarks: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
======= Function 68, subfunction 11 - initialize process heap. ======= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 11 - subfunction number |
Returned value: |
* eax = 0 - failed |
* otherwise size of created heap |
Remarks: |
* The function call initializes heap, from which one can in future |
allocate and free memory blocks with subfunctions 12 and 13. |
Heap size is equal to total amount of free application memory. |
* The second function call from the same process results in |
returning the size of the existing heap. |
* After creation of the heap calls to function 64 will be ignored. |
====================================================================== |
======== Function 68, subfunction 12 - allocate memory block. ======== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 12 - subfunction number |
* ecx = required size in bytes |
Returned value: |
* eax = pointer to the allocated block |
Remarks: |
* Before this call one must initialize process heap by call to |
subfunction 11. |
* The function allocates an integer number of pages (4 Kb) in such |
way that the real size of allocated block is more than or equal to |
requested size. |
====================================================================== |
========== Function 68, subfunction 13 - free memory block. ========== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 13 - subfunction number |
* ecx = pointer to the memory block |
Returned value: |
* eax = 1 - success |
* eax = 0 - failed |
Remarks: |
* The memory block must have been allocated by subfunction 12 |
or subfunction 20. |
====================================================================== |
===================== Function 68, subfunction 14 ==================== |
====== Waiting delivering of signal from another program/driver ====== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 14 - subfunction number |
* ecx = pointer to the buffer for information (24 bytes) |
Returned value: |
* buffer pointed to by ecx contains the following information: |
* +0: dword: identifier for underlying data of signal |
* +4: data of signal (20 bytes), format of which is defining by |
first dword |
====================================================================== |
====== Function 68, subfunction 15 - set FPU exception handler. ====== |
====================================================================== |
Deleted (in current implementation only 0 is returned). |
Using subfunctions 24, 25 is true. |
====================================================================== |
============= Function 68, subfunction 16 - load driver. ============= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 16 - subfunction number |
* ecx = pointer to ASCIIZ-string with driver name |
Returned value: |
* eax = 0 - failed |
* otherwise eax = driver handle |
Remarks: |
* If the driver was not loaded yet, it is loaded; |
if the driver was loaded yet, nothing happens. |
* Driver name is case-sensitive. |
Maximum length of the name is 16 characters, including |
terminating null character, the rest is ignored. |
* Driver ABC is loaded from file /rd/1/drivers/ABC.obj. |
====================================================================== |
============ Function 68, subfunction 17 - driver control. =========== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 17 - subfunction number |
* ecx = pointer to the control structure: |
* +0: dword: handle of driver |
* +4: dword: code of driver function |
* +8: dword: pointer to input data |
* +12 = +0xC: dword: size of input data |
* +16 = +0x10: dword: pointer to output data |
* +20 = +0x14: dword: size of output data |
Returned value: |
* eax = error code |
0 - successful call |
-1 - any error. |
-2, -3, -4, etc. reserved for kernel error codes |
1, 2, 3, etc driver specific error codes |
Remarks: |
* Function codes and the structure of input/output data |
are defined by driver. |
* Previously one must obtain driver handle by subfunction 16. |
====================================================================== |
====== Function 68, subfunction 18 - set SSE exception handler. ====== |
====================================================================== |
Deleted (in current implementation only 0 is returned). |
Using subfunctions 24, 25 is true. |
====================================================================== |
=============== Function 68, subfunction 19 - load DLL. ============== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 19 - subfunction number |
* ecx = pointer to ASCIIZ-string with the full path to DLL |
Returned value: |
* eax = 0 - failed |
* otherwise eax = pointer to DLL export table |
Remarks: |
* Export table is an array of structures of 2 dword's, terminated |
by zero. The first dword in structure points to function name, |
the second dword contains address of function. |
====================================================================== |
======= Function 68, subfunction 20 - reallocate memory block. ======= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 20 - subfunction number |
* ecx = new size in bytes |
* edx = pointer to already allocated block |
Returned value: |
* eax = pointer to the reallocated block, 0 = error |
Remarks: |
* Before this call one must initialize process heap by call to |
subfunction 11. |
* The function allocates an integer number of pages (4 Kb) in such |
way that the real size of allocated block is more than or equal to |
requested size. |
* If edx=0, the function call is equivalent to memory allocation |
with subfunction 12. Otherwise the block at edx |
must be allocated earlier with subfunction 12 or this subfunction. |
* If ecx=0, the function frees memory block at edx and returns 0. |
* The contents of the block are unchanged up to the shorter of |
the new and old sizes. |
====================================================================== |
====== Function 68, subfunction 24 - set new exceptions handler ====== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 24 - subfunction number |
* ecx = address of the new exception handler |
* edx = the mask of processing exceptions |
Returned value: |
* eax = address of the old exception handler (0, if it was not set) |
* ebx = the old mask of exception handler |
Remarks: |
* Bit number in mask of exceptions is correspond to exception number |
by CPU-specification (Intel-PC). For example, FPU-exception have |
number 16 (#MF), and SSE-exception - 19 (#XF) |
* The current implementation ignore the inquiry for hook of 7 |
exception - system process #NM by one's own. |
* User handler get exception number in stack parameter. So, correct |
exit from handler is: RET 4. Return from handler is to the same |
instruction, that was cause the exception |
* When control is transfering to user handler, corresponding bit in |
exception mask is clearing. Rising this exception in consequence |
- reduce to default-handling. Exactly: terminating the application, |
or suspending with debug-notify to owner. |
* After completion of critical operations in user handler, it may be |
rising corresponding bit in exception mask by using subfunction 25 |
Clearing exceptions flags in FPU and/or XMM modules - is |
responsibility of user handler too. |
====================================================================== |
==== Function 68, subfunction 25 - change state of signal activity === |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 25 - subfunction number |
* ecx = signal number |
* edx = value of activity (0/1) |
Returned value: |
* eax = value of old activity for this signal (0/1) |
Remarks: |
* In current implementation, it is changed only exception mask for |
user exception handler, wich was previously set by subfunction 24. |
At that, number of signal correspond to exception number. |
====================================================================== |
====================== Fucntion 69 - debugging. ====================== |
====================================================================== |
A process can load other process as debugged by set of corresponding |
bit by call to subfunction 7 of function 70. |
A process can have only one debugger; one process can debug some |
others. The system notifies debugger on events occuring with |
debugged process. Messages are written to the buffer defined by |
subfunction 0. |
Format of a message: |
* +0: dword: message code |
* +4: dword: PID of debugged process |
* +8: there can be additional data depending on message code |
Message codes: |
* 1 = exception |
* in addition dword-number of the exception is given |
* process is suspended |
* 2 = process has terminated |
* comes at any termination: both through the system function -1, |
and at "murder" by any other process (including debugger itself) |
* 3 = debug exception int 1 = #DB |
* in addition dword-image of the register DR6 is given: |
* bits 0-3: condition of the corresponding breakpoint (set by |
subfunction 9) is satisfied |
* áèò 14: exception has occured because of the trace mode |
(flag TF is set TF) |
* process is suspended |
When debugger terminates, all debugged processes are killed. |
If debugger does not want this, it must previously detach by |
subfunction 3. |
All subfunctions are applicable only to processes/threads started |
from the current by function 70 with set debugging flag. |
Debugging of multithreaded programs is not supported yet. |
The full list of subfunctions: |
* subfunction 0 - define data area for debug messages |
* subfunction 1 - get contents of registers of debugged thread |
* subfunction 2 - set contents of registers of debugged thread |
* subfunction 3 - detach from debugged process |
* subfunction 4 - suspend debugged thread |
* subfunction 5 - resume debugged thread |
* subfunction 6 - read from the memory of debugged process |
* subfunction 7 - write to the memory of debugged process |
* subfunction 8 - terminate debugged thread |
* subfunction 9 - set/clear hardware breakpoint |
====================================================================== |
= Function 69, subfunction 0 - define data area fror debug messages. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer |
Format of data area: |
* +0: dword: N = buffer size (not including this header) |
* +4: dword: occupied place |
* +8: N*byte: buffer |
Returned value: |
* function does not return value |
Remarks: |
* If the size field is negative, the buffer is considered locked |
and at arrival of new message the system will wait. |
For synchronization frame all work with the buffer by operations |
lock/unlock |
neg [bufsize] |
* Data in the buffer are considered as array of items with variable |
length - messages. Format of a message is explained in |
general description. |
====================================================================== |
===================== Function 69, subfunction 1 ===================== |
============ Get contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 1 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
* esi = pointer to context structure |
Returned value: |
* function does not return value |
Format of context structure: (FPU is not supported yet) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===================== Function 69, subfunction 2 ===================== |
============ Set contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 2 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
Returned value: |
* function does not return value |
Format of context structure is shown in the description of |
subfunction 1. |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===== Function 69, subfunction 3 - detach from debugged process. ===== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 3 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* If the process was suspended, it resumes execution. |
====================================================================== |
======== Function 69, subfunction 4 - suspend debugged thread. ======= |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 4 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======== Function 69, subfunction 5 - resume debugged thread. ======== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 5 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
= Fucntion 69, subfunction 6 - read from memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 6 - subfunction number |
* ecx = identifier |
* edx = number of bytes to read |
* esi = address in the memory of debugged process |
* edi = pointer to buffer for data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of read bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
== Function 69, subfunction 7 - write to memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 7 - subfunction number |
* ecx = identifier |
* edx = number of bytes to write |
* esi = address of memory in debugged process |
* edi = pointer to data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of written bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======= Function 69, subfunction 8 - terminate debugged thread. ====== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 8 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* The function is similar to subfunction 2 of function 18 |
with two differences: it requires first remark and |
accepts PID rather than slot number. |
====================================================================== |
===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 9 - subfunction number |
* ecx = thread identifier |
* dl = index of breakpoint, from 0 to 3 inclusively |
* dh = flags: |
* if high bit is cleared - set breakpoint: |
* bits 0-1 - condition: |
* 00 = breakpoint on execution |
* 01 = breakpoint on read |
* 11 = breakpoint on read/write |
* bits 2-3 - length; for breakpoints on exception it must be |
00, otherwise one of |
* 00 = byte |
* 01 = word |
* 11 = dword |
* esi = breakpoint address; must be aligned according to |
the length (i.e. must be even for word breakpoints, |
divisible by 4 for dword) |
* if high bit is set - clear breakpoint |
Returned value: |
* eax = 0 - success |
* eax = 1 - error in the input data |
* eax = 2 - (reserved, is never returned in the current |
implementation) a global breakpoint with that index is already set |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* Hardware breakpoints are implemented through DRx-registers of |
the processor, all limitations results from this. |
* The function can reinstall the breakpoint, previously set |
by it (and it does not inform on this). |
Carry on the list of set breakpoints in the debugger. |
* Breakpoints generate debug exception #DB, on which the system |
notifies debugger. |
* Breakpoints on write and read/write act after |
execution of the caused it instruction. |
====================================================================== |
==== Function 70 - work with file system with long names support. ==== |
====================================================================== |
Parameters: |
* eax = 70 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: file offset |
* +8: dword: high dword of offset (must be 0) or flags field |
* +12 = +0xC: dword: size |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: n db: ASCIIZ-string with the filename |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with the filename |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive. Russian letters must be written in |
the encoding cp866 (DOS). |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to |
CD on IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
* /SYS means system folder; with the usual boot (from floppy) |
is equivalent to /RD/1 |
Examples: |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
* '/sys/MySuperApp.ini',0 |
Available subfunctions: |
* subfunction 0 - read file |
* subfunction 1 - read folder |
* subfunction 2 - create/rewrite file |
* subfunction 3 - write to existing file |
* subfunction 4 - set file size |
* subfunction 5 - get attributes of file/folder |
* subfunction 6 - set attributes of file/folder |
* subfunction 7 - start application |
* subfunction 8 - delete file/folder |
* subfunction 9 - create folder |
For CD-drives due to hardware limitations only subfunctions |
0,1,5 and 7 are available, other subfunctions return error |
with code 2. |
At the first call of subfunctions 0,1,5,7 to ATAPI devices |
(CD and DVD) the manual control of tray is locked due to caching |
drive data. Unlocking is made when subfunction 4 of function 24 |
is called for corresponding device. |
====================================================================== |
=== Function 70, subfunction 0 - read file with long names support. == |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: file offset (in bytes) |
* +8: dword: 0 (reserved for high dword of offset) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to buffer for data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of read bytes or -1=0xffffffff if file was not found |
Remarks: |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* The function does not allow to read folder (returns eax=10, |
access denied). |
====================================================================== |
== Function 70, subfunction 1 - read folder with long names support. = |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 1 = subfunction number |
* +4: dword: index of starting block (beginning from 0) |
* +8: dword: flags field: |
* bit 0 (mask 1): in what format to return names, |
0=ANSI, 1=UNICODE |
* other bits are reserved and must be set to 0 for the future |
compatibility |
* +12 = +0xC: dword: number of blocks to read |
* +16 = +0x10: dword: pointer to buffer for data, buffer size |
must be not less than 32 + [+12]*560 bytes |
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of files, information on which was written to |
the buffer, or -1=0xffffffff, if folder was not found |
Structure of the buffer: |
* +0: 32*byte: header |
* +32 = +0x20: n1*byte: block with information on file 1 |
* +32+n1: n2*byte: block with information on file 2 |
* ... |
Structure of header: |
* +0: dword: version of structure (current is 1) |
* +4: dword: number of placed blocks; is not greater than requested |
in the field +12 of information structure; can be less, if |
there are no more files in folder (the same as in ebx) |
* +8: dword: total number of files in folder |
* +12 = +0xC: 20*byte: reserved (zeroed) |
Structure of block of data for folder entry (BDFE): |
* +0: dword: attributes of file: |
* bit 0 (mask 1): file is read-only |
* bit 1 (mask 2): file is hidden |
* bit 2 (mask 4): file is system |
* bit 3 (mask 8): this is not a file but volume label |
(for one partition meets no more than once and |
only in root folder) |
* bit 4 (mask 0x10): this is a folder |
* bit 5 (mask 0x20): file was not archived - many archivation |
programs have an option to archive only files with this bit set, |
and after archiving this bit is cleared - it can be useful |
for automatically creating of backup-archives as at writing |
this bit is usually set |
* +4: byte: type of name data: |
(coincides with bit 0 of flags in the information structure) |
* 0 = ASCII = 1-byte representation of each character |
* 1 = UNICODE = 2-byte representation of each character |
* +5: 3*byte: reserved (zero) |
* +8: 4*byte: time of file creation |
* +12 = +0xC: 4*byte: date of file creation |
* +16 = +0x10: 4*byte: time of last access (read or write) |
* +20 = +0x14: 4*byte: date of last access |
* +24 = +0x18: 4*byte: time of last modification |
* +28 = +0x1C: 4*byte: date of last modification |
* +32 = +0x20: qword: file size in bytes (up to 16777216 Tb) |
* +40 = +0x28: name |
* for ASCII format: maximum length is 263 characters |
(263 bytes), byte after the name has value 0 |
* for UNICODE format: maximum length is 259 characters |
(518 bytes), 2 bytes after the name have value 0 |
Time format: |
* +0: byte: seconds |
* +1: byte: minutes |
* +2: byte: hours |
* +3: byte: reserved (0) |
* for example, 23.59.59 is written as (in hex) 3B 3B 17 00 |
Date format: |
* +0: byte: day |
* +1: byte: month |
* +2: word: year |
* for example, 25.11.1979 is written as (in hex) 19 0B BB 07 |
Remarks: |
* If BDFE contains ASCII name, the length of BDFE is 304 bytes, |
if UNICODE name - 560 bytes. Value of length is aligned |
on 16-byte bound (to accelerate processing in CPU cache). |
* First character after a name is zero (ASCIIZ-string). The further |
data contain garbage. |
* If files in folder were ended before requested number was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Any folder on the disk, except for root, contains two special |
entries "." and "..", identifying accordingly the folder itself |
and the parent folder. |
* The function allows also to read virtual folders "/", "/rd", |
"/fd", "/hd[n]", thus attributes of subfolders are set to 0x10, |
and times and dates are zeroed. An alternative way to get the |
equipment information - subfunction 11 of function 18. |
====================================================================== |
===================== Function 70, subfunction 2 ===================== |
============ Create/rewrite file with long names support. ============ |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 2 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of written bytes (possibly 0) |
Remarks: |
* If a file with given name did not exist, it is created; |
if it existed, it is rewritten. |
* If there is not enough free space on disk, the function will |
write as many as can and then return error code 8. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
===================== Function 70, subfunction 3 ===================== |
=========== Write to existing file with long names support. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 3 = subfunction number |
* +4: dword: file offset (in bytes) |
* +8: dword: high dword of offset (must be 0 for FAT) |
* +12 = +0xC: dword: number of bytes to write |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of written bytes (possibly 0) |
Remarks: |
* The file must already exist, otherwise function returns eax=5. |
* The only result of write 0 bytes is update in the file attributes |
date/time of modification and access to the current date/time. |
* If beginning and/or ending position is greater than file size |
(except for the previous case), the file is expanded to needed |
size with zero characters. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
============ Function 70, subfunction 4 - set end of file. =========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 4 = subfunction number |
* +4: dword: low dword of new file size |
* +8: dword: high dword of new file size (must be 0 for FAT) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* If the new file size is less than old one, file is truncated. |
If the new size is greater than old one, file is expanded with |
characters with code 0. If the new size is equal to old one, |
the only result of call is set date/time of modification and |
access to the current date/time. |
* If there is not enough free space on disk for expansion, the |
function will expand to maximum possible size and then return |
error code 8. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
==== Function 70, subfunction 5 - get information on file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 5 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer for data (40 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Information on file is returned in the BDFE format (block of data |
for folder entry), explained in the description of |
subfunction 1, but without filename |
(i.e. only first 40 = 0x28 bytes). |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
====================================================================== |
===== Function 70, subfunction 6 - set attributes of file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 6 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer with attributes (32 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
File attributes are first 32 bytes in BDFE (block of data |
for folder entry), explained in the description of subfunction 1 |
(that is, without name and size of file). Attribute |
file/folder/volume label (bits 3,4 in dword +0) is not changed. |
Byte +4 (name format) is ignored. |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
=========== Function 70, subfunction 7 - start application. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 7 = subfunction number |
* +4: dword: flags field: |
* áèò 0: start process as debugged |
* other bits are reserved and must be set to 0 |
* +8: dword: 0 or pointer to ASCIIZ-string with parameters |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax > 0 - program is loaded, eax contains PID |
* eax < 0 - an error has occured, -eax contains |
file system error code |
* ebx destroyed |
Remarks: |
* Command line must be terminated by the character with the code 0 |
(ASCIIZ-string); function takes into account either all characters |
up to terminating zero inclusively or first 256 character |
regarding what is less. |
* If the process is started as debugged, it is created in |
the suspended state; to run use subfunction 5 of function 69. |
====================================================================== |
========== Function 70, subfunction 8 - delete file/folder. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 8 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* The function is not supported for CD (returns error code 2). |
* The function can delete only empty folders (attempt to delete |
nonempty folder results in error with code 10, "access denied"). |
====================================================================== |
============= Function 70, subfunction 9 - create folder. ============ |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 9 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with folder name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* The function is not supported for CD (returns error code 2). |
* The parent folder must already exist. |
* If target folder already exists, function returns success (eax=0). |
====================================================================== |
========== Function 71, subfunction 1 - set window caption. ========== |
====================================================================== |
Parameters: |
* eax = 71 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to caption string |
Returned value: |
* function does not return value |
Remarks: |
* String must be in the ASCIIZ-format. Disregarding real string |
length, no more than 255 characters are drawn. |
* Pass NULL in ecx to remove caption. |
====================================================================== |
=============== Function 72 - send message to a window. ============== |
====================================================================== |
- Subfunction 1 - send message with parameter to the active window. -- |
Parameters: |
* eax = 72 - function number |
* ebx = 1 - subfunction number |
* ecx = event code: 2 or 3 |
* edx = parameter: key code for ecx=2, button identifier for ecx=3 |
Returned value: |
* eax = 0 - success |
* eax = 1 - buffer is full |
====================================================================== |
=============== Function -1 - terminate thread/process =============== |
====================================================================== |
Parameters: |
* eax = -1 - function number |
Returned value: |
* function does not return neither value nor control |
Remarks: |
* If the process did not create threads obviously, it has only |
one thread, which termination results in process termination. |
* If the current thread is last in the process, its termination |
also results in process terminates. |
* This function terminates the current thread. Other thread can be |
killed by call to subfunction 2 of function 18. |
====================================================================== |
=========================== List of events =========================== |
====================================================================== |
Next event can be retrieved by the call of one from functions 10 |
(to wait for event), 11 (to check without waiting), 23 |
(to wait during the given time). |
These functions return only those events, which enter into a mask set |
by function 40. By default it is first three, |
there is enough for most applications. |
Codes of events: |
* 1 = redraw event (is reset by call to function 0) |
* 2 = key on keyboard is pressed (acts, only when the window is |
active) or hotkey is pressed; is reset, when all keys from |
the buffer are read out by function 2 |
* 3 = button is pressed, defined earlier by function 8 |
(or close button, created implicitly by function 0; |
minimize button is handled by the system and sends no message; |
acts, only when the window is active; |
is reset when all buttons from the buffer |
are read out by function 17) |
* 4 = reserved (in current implementation never comes even after |
unmasking by function 40) |
* 5 = the desktop background is redrawed (is reset automatically |
after redraw, so if in redraw time program does not wait and |
does not check events, it will not remark this event) |
* 6 = mouse event (something happened - button pressing or moving; |
is reset at reading) |
* 7 = IPC event (see function 60 - |
Inter Process Communication; is reset at reading) |
* 8 = network event (is reset at reading) |
* 9 = debug event (is reset at reading; see |
debug subsystem) |
* 16..31 = event with appropriate IRQ |
(16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data) |
====================================================================== |
=================== Error codes of the file system =================== |
====================================================================== |
* 0 = success |
* 1 = base and/or partition of a hard disk is not defined |
(by subfunctions 7, 8 of function 21) |
* 2 = function is not supported for the given file system |
* 3 = unknown file system |
* 4 = reserved, is never returned in the current implementation |
* 5 = file not found |
* 6 = end of file, EOF |
* 7 = pointer lies outside of application memory |
* 8 = disk is full |
* 9 = FAT table is destroyed |
* 10 = access denied |
* 11 = device error |
Application start functions can return also following errors: |
* 30 = 0x1E = not enough memory |
* 31 = 0x1F = file is not executable |
* 32 = 0x20 = too many processes |
/kernel/tags/kolibri0.7.7.0/docs/loader_doc.txt |
---|
0,0 → 1,88 |
; (english text below) |
;------------------------------------------ |
; Èíòåðôåéñ ñîõðàíåíèÿ ïàðàìåòðîâ |
;------------------------------------------ |
Åñëè ïðè ïåðåäà÷å óïðàâëåíèÿ ÿäðó çàãðóç÷èê óñòàíàâëèâàåò AX='KL', |
òî â DS:SI ÿäðî îæèäàåò äàëüíåãî óêàçàòåëÿ íà ñëåäóþùóþ ñòðóêòóðó: |
db âåðñèÿ ñòðóêòóðû, äîëæíà áûòü 1 |
dw ôëàãè: |
áèò 0 óñòàíîâëåí = ïðèñóòñòâóåò îáðàç ðàìäèñêà â ïàìÿòè |
dd äàëüíèé óêàçàòåëü íà ïðîöåäóðó ñîõðàíåíèÿ ïàðàìåòðîâ |
ìîæåò áûòü 0, åñëè çàãðóç÷èê íå ïîääåðæèâàåò |
Ïðîöåäóðà ñîõðàíåíèÿ ïàðàìåòðîâ äîëæíà çàïèñàòü ïåðâûé ñåêòîð ÿäðà |
kernel.mnt íàçàä íà òî ìåñòî, îòêóäà îíà åãî ñ÷èòàëà; âîçâðàò èç |
ïðîöåäóðû îñóùåñòâëÿåòñÿ ïî retf. |
;------------------------------------------ |
; Óêàçàíèå çàãðóç÷èêîì ñèñòåìíîãî êàòàëîãà |
;------------------------------------------ |
Ïåðåä ïåðåäà÷åé óïðàâëåíèÿ ÿäðó ìîãóò áûòü óñòàíîâëåíû ñëåäóþùèå ðåãèñòðû: |
CX='HA' |
DX='RD' |
Ýòî óêàçûâàåò íà òî, ÷òî ðåãèñòð BX óêàçûâàåò íà ñèñòåìíûé ðàçäåë. Êàòàëîã /kolibri/ íà |
ýòîì ðàçäåëå ÿâëÿåòñÿ ñèñòåìíûì, ê íåìó ìîæíî îáðàùàòüñÿ êàê ê /sys/ |
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BL (óêàçûâàåò íà óñòðîéñòâî): |
'a' - Primary Master |
'b' - Primary Slave |
'c' - Secondary Master |
'd' - Secondary Slave |
'r' - RAM äèñê |
'm' - Ïðèâîäû CD-ROM |
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BH (óêàçûâàåò íà ðàçäåë): |
äëÿ BL='a','b','c','d','r' - óêàçûâàåò íà ðàçäåë, ãäå ðàñïîëîæåí ñèñòåìíûé êàòàëîã |
äëÿ BL='m',óêàçûâàåò íà íîìåð ôèçè÷åñêîãî óñòðîéñòâà, ñ êîòîðîãî íàäî íà÷èíàòü ïîèñê ñèñòåìíîãî êàòàëîãà. |
ïðèìåðû çíà÷åíèé ðåãèñòðà BX: |
'a1' - /hd0/1/ |
'a2' - /hd0/2/ |
'b1' - /hd1/1/ |
'd4' - /hd3/4/ |
'm0' - ïîèñê ïî ñèäþêàì êàòàëîãà kolibri |
'r1' - /rd/1/ |
;------------------------------------------ |
; Interface for saving boot-screen settings |
;------------------------------------------ |
If a loader sets AX='KL' when transferring control to the kernel, |
the kernel expects in DS:SI far pointer to the following structure: |
db structure version, must be 1 |
dw flags |
bit 0 set = ramdisk image in memory is present |
dd far pointer to save settings procedure |
may be 0 if such procedure is not supported by loader |
Procedure for saving settings must write the first sector of the kernel |
kernel.mnt back to the place, from where it has been read; return from |
this procedure must be with retf. |
;------------------------------------------ |
; System directory information from loader |
;------------------------------------------ |
Before transfer of control to the kernel following registers can be set: |
CX = 'HA' |
DX = 'RD' |
This indicates that the register BX identifies system partition. The folder /kolibri/ in |
this partition is system folder, it can be referenced as /sys/ |
Possible values for register BL (indicates the device): |
'a' - Primary Master |
'b' - Primary Slave |
'c' - Secondary Master |
'd' - Secondary Slave |
'r' - RAM disc |
'm' - ROM drives |
Possible values for register BH (indicates section): |
for BL = 'a', 'b', 'c', 'd', 'r' to denote partition where the system folder |
for BL = 'm', indicates the number of physical devices, which must begin a systematic search directory. |
Examples of register BX: |
'a1' - /hd0/1/ |
'a2' - /hd0/2/ |
'b1' - /hd1/1/ |
'd4' - /hd3/4/ |
'm0' - search directory 'kolibri' by all CD-ROMs |
'r1' - /rd/1/ |
/kernel/tags/kolibri0.7.7.0/docs/apm.txt |
---|
0,0 → 1,518 |
--------p-155300----------------------------- |
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK |
AX = 5300h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AH = major version (BCD) |
AL = minor version (BCD) |
BX = 504Dh ("PM") |
CX = flags (see #00472) |
CF set on error |
AH = error code (06h,09h,86h) (see #00473) |
BUG: early versions of the Award Modular BIOS with built-in APM support |
reportedly do not set BX on return |
Bitfields for APM flags: |
Bit(s) Description (Table 00472) |
0 16-bit protected mode interface supported |
1 32-bit protected mode interface supported |
2 CPU idle call reduces processor speed |
3 BIOS power management disabled |
4 BIOS power management disengaged (APM v1.1) |
5-7 reserved |
(Table 00473) |
Values for APM error code: |
01h power management functionality disabled |
02h interface connection already in effect |
03h interface not connected |
04h real-mode interface not connected |
05h 16-bit protected-mode interface already connected |
06h 16-bit protected-mode interface not supported |
07h 32-bit protected-mode interface already connected |
08h 32-bit protected-mode interface not supported |
09h unrecognized device ID |
0Ah invalid parameter value in CX |
0Bh (APM v1.1) interface not engaged |
0Ch (APM v1.2) function not supported |
0Dh (APM v1.2) Resume Timer disabled |
0Eh-1Fh reserved for other interface and general errors |
20h-3Fh reserved for CPU errors |
40h-5Fh reserved for device errors |
60h can't enter requested state |
61h-7Fh reserved for other system errors |
80h no power management events pending |
81h-85h reserved for other power management event errors |
86h APM not present |
87h-9Fh reserved for other power management event errors |
A0h-FEh reserved |
FFh undefined |
--------p-155301----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE |
AX = 5301h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (02h,05h,07h,09h) (see #00473) |
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5302h,AX=5303h,AX=5304h |
--------p-155302----------------------------- |
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE |
AX = 5302h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 16-bit code |
segment |
BX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,06h,07h,09h) (see #00473) |
Notes: the caller must initialize two consecutive descriptors with the |
returned segment base addresses; these descriptors must be valid |
whenever the protected-mode interface is called, and will have |
their limits arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call with the |
same register values as for INT 15; it must be invoked while CPL=0, |
the code segment descriptor must have a DPL of 0, the stack must be |
in a 16-bit segment and have enough room for BIOS use and possible |
interrupts, and the current I/O permission bit map must allow access |
to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5303h,AX=5304h |
--------p-155303----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE |
AX = 5303h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 32-bit code |
segment |
EBX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit code |
segment |
DX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,07h,08h,09h) (see #00473) |
Notes: the caller must initialize three consecutive descriptors with the |
returned segment base addresses for 32-bit code, 16-bit code, and |
16-bit data, respectively; these descriptors must be valid whenever |
the protected-mode interface is called, and will have their limits |
arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call to the |
32-bit code segment with the same register values as for INT 15; it |
must be invoked while CPL=0, the code segment descriptor must have a |
DPL of 0, the stack must be in a 32-bit segment and have enough room |
for BIOS use and possible interrupts, and the current I/O permission |
bit map must allow access to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5302h,AX=5304h |
--------p-155304----------------------------- |
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE |
AX = 5304h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h) (see #00473) |
SeeAlso: AX=5301h,AX=5302h,AX=5303h |
--------p-155305----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU IDLE |
AX = 5305h |
Return: CF clear if successful (after system leaves idle state) |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: call when the system is idle and should be suspended until the next |
system event or interrupt |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
if an interrupt causes the system to resume normal processing, the |
interrupt may or may not have been handled when the BIOS returns |
from this call; thus, the caller should allow interrupts on return |
interrupt handlers may not retain control if the BIOS allows |
interrupts while in idle mode even if they are able to determine |
that they were called from idle mode |
the caller should issue this call continuously in a loop until it needs |
to perform some processing of its own |
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h |
--------p-155306----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU BUSY |
AX = 5306h |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: called to ensure that the system runs at full speed even on systems |
where the BIOS is unable to recognize increased activity (especially |
if interrupts are hooked by other programs and not chained to the |
BIOS) |
this call may be made even when the system is already running at full |
speed, but it will create unnecessary overhead |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5305h |
--------p-155307----------------------------- |
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE |
AX = 5307h |
BX = device ID (see #00474) |
CX = system state ID (see #00475) |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=530Ch |
(Table 00474) |
Values for APM device IDs: |
0000h system BIOS |
0001h all devices for which the system BIOS manages power |
01xxh display (01FFh for all attached display devices) |
02xxh secondary storage (02FFh for all attached secondary storage devices) |
03xxh parallel ports (03FFh for all attached parallel ports) |
04xxh serial ports (04FFh for all attached serial ports) |
---APM v1.1+ --- |
05xxh network adapters (05FFh for all attached network adapters) |
06xxh PCMCIA sockets (06FFh for all) |
0700h-7FFFh reserved |
80xxh system battery devices (APM v1.2) |
8100h-DFFFh reserved |
Exxxh OEM-defined power device IDs |
F000h-FFFFh reserved |
(Table 00475) |
Values for system state ID: |
0000h ready (not supported for device ID 0001h) |
0001h stand-by |
0002h suspend |
0003h off (not supported for device ID 0001h in APM v1.0) |
---APM v1.1--- |
0004h last request processing notification (only for device ID 0001h) |
0005h last request rejected (only for device ID 0001h) |
0006h-001Fh reserved system states |
0020h-003Fh OEM-defined system states |
0040h-007Fh OEM-defined device states |
0080h-FFFFh reserved device states |
--------p-155307CX0001----------------------- |
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY |
AX = 5307h |
CX = 0001h |
BX = 0001h (device ID for all power-managed devices) |
Return: CF clear |
Notes: puts the entire system into stand-by mode; normally called in response |
to a System Stand-by Request notification after any necessary |
processing, but may also be invoked at the caller's discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the stand-by state is typically exited on an interrupt |
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh |
--------p-155307CX0002----------------------- |
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM |
AX = 5307h |
CX = 0002h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: puts the entire system into a low-power suspended state; normally |
called in response to a Suspend System Request notification after |
any necessary processing, but may also be invoked at the caller's |
discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the caller may need to update its date and time values because the |
system could have been suspended for a long period of time |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155307CX0003----------------------- |
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM |
AX = 5307h |
CX = 0003h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: if supported by the system's power supply, turns off the system power |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155308----------------------------- |
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT |
AX = 5308h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1+) |
FFFFh (APM v1.0) |
CX = new state |
0000h disabled |
0001h enabled |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Notes: when power management is disabled, the system BIOS will not |
automatically power down devices, enter stand-by or suspended mode, |
or perform any power-saving actions in response to AX=5305h calls |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the APM BIOS should never be both disabled and disengaged at the same |
time |
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh |
--------p-155309----------------------------- |
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS |
AX = 5309h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1) |
FFFFh (APM v1.0) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5308h |
--------p-15530A----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS |
AX = 530Ah |
BX = device ID |
0001h all devices power-managed by APM |
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) |
Return: CF clear if successful |
BH = AC line status |
00h off-line |
01h on-line |
02h on backup power (APM v1.1) |
FFh unknown |
other reserved |
BL = battery status (see #00476) |
CH = battery flag (APM v1.1+) (see #00477) |
CL = remaining battery life, percentage |
00h-64h (0-100) percentage of full charge |
FFh unknown |
DX = remaining battery life, time (APM v1.1) (see #00478) |
---if specific battery unit specified--- |
SI = number of battery units currently installed |
CF set on error |
AH = error code (09h,0Ah) (see #00473) |
Notes: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
supported in real mode (INT 15) and both 16-bit and 32-bit protected |
mode |
(Table 00476) |
Values for APM v1.0+ battery status: |
00h high |
01h low |
02h critical |
03h charging |
FFh unknown |
other reserved |
SeeAlso: #00477,#00478 |
Bitfields for APM v1.1+ battery flag: |
Bit(s) Description (Table 00477) |
0 high |
1 low |
2 critical |
3 charging |
4 selected battery not present (APM v1.2) |
5-6 reserved (0) |
7 no system battery |
Note: all bits set (FFh) if unknown |
SeeAlso: #00476,#00478 |
Bitfields for APM v1.1+ remaining battery life: |
Bit(s) Description (Table 00478) |
15 time units: 0=seconds, 1=minutes |
14-0 battery life in minutes or seconds |
Note: all bits set (FFFFh) if unknown |
SeeAlso: #00476,#00477 |
--------p-15530B----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT |
AX = 530Bh |
Return: CF clear if successful |
BX = event code (see #00479) |
CX = event information (APM v1.2) if BX=0003h or BX=0004h |
bit 0: PCMCIA socket was powered down in suspend state |
CF set on error |
AH = error code (03h,0Bh,80h) (see #00473) |
Notes: although power management events are often asynchronous, notification |
will not be made until polled via this call to permit software to |
only receive event notification when it is prepared to process |
power management events; since these events are not very time- |
critical, it should be sufficient to poll once or twice per second |
the critical resume notification is made after the system resumes |
from an emergency suspension; normally, the system BIOS only notifies |
its partner that it wishes to suspend and relies on the partner to |
actually request the suspension, but no notification is made on an |
emergency suspension |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" |
(Table 00479) |
Values for APM event code: |
0001h system stand-by request |
0002h system suspend request |
0003h normal resume system notification |
0004h critical resume system notification |
0005h battery low notification |
---APM v1.1--- |
0006h power status change notification |
0007h update time notification |
0008h critical system suspend notification |
0009h user system standby request notification |
000Ah user system suspend request notification |
000Bh system standby resume notification |
---APM v1.2--- |
000Ch capabilities change notification (see AX=5310h) |
------ |
000Dh-00FFh reserved system events |
01xxh reserved device events |
02xxh OEM-defined APM events |
0300h-FFFFh reserved |
--------p-15530C----------------------------- |
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE |
AX = 530Ch |
BX = device ID (see #00474) |
Return: CF clear if successful |
CX = system state ID (see #00475) |
CF set on error |
AH = error code (01h,09h) (see #00473) |
SeeAlso: AX=5307h |
--------p-15530D----------------------------- |
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT |
AX = 530Dh |
BX = device ID (see #00474) |
CX = function |
0000h disable power management |
0001h enable power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Desc: specify whether automatic power management should be active for a |
given device |
SeeAlso: AX=5308h,AX=530Fh |
--------p-15530E----------------------------- |
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION |
AX = 530Eh |
BX = device ID of system BIOS (0000h) |
CH = APM driver major version (BCD) |
CL = APM driver minor version (BCD) (02h for APM v1.2) |
Return: CF clear if successful |
AH = APM connection major version (BCD) |
AL = APM connection minor version (BCD) |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
SeeAlso: AX=5300h,AX=5303h |
--------p-15530F----------------------------- |
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT |
AX = 530Fh |
BX = device ID (see #00474) |
CX = function |
0000h disengage power management |
0001h engage power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,09h) (see #00473) |
Notes: unlike AX=5308h, this call does not affect the functioning of the APM |
BIOS |
when cooperative power management is disengaged, the APM BIOS performs |
automatic power management of the system or device |
SeeAlso: AX=5308h,AX=530Dh |
--------p-155310----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES |
AX = 5310h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
Return: CF clear if successful |
BL = number of battery units supported (00h if no system batteries) |
CX = capabilities flags (see #00480) |
CF set on error |
AH = error code (01h,09h,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces; it does not require that a |
connection be established prior to use |
this function will return the capabilities currently in effect, not |
any new settings which have been made but do not take effect until |
a system restart |
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h |
Bitfields for APM v1.2 capabilities flags: |
Bit(s) Description (Table 00480) |
15-8 reserved |
7 PCMCIA Ring Indicator will wake up system from suspend mode |
6 PCMCIA Ring Indicator will wake up system from standby mode |
5 Resume on Ring Indicator will wake up system from suspend mode |
4 Resume on Ring Indicator will wake up system from standby mode |
3 resume timer will wake up system from suspend mode |
2 resume timer will wake up system from standby mode |
1 can enter global suspend state |
0 can enter global standby state |
--------p-155311----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER |
AX = 5311h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume Timer |
01h get Resume Timer |
02h set Resume Timer |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
Return: CF clear if successful |
---if getting timer--- |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h |
--------p-155312----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING |
AX = 5312h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume on Ring Indicator |
01h enable Resume on Ring Indicator |
02h get Resume on Ring Indicator status |
Return: CF clear if successful |
CX = resume status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h |
--------p-155313----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS |
AX = 5313h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable timer-based requests |
01h enable timer-based requests |
02h get timer-based requests status |
Return: CF clear if successful |
CX = timer-based requests status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
some BIOSes set AH on return even when successful |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h |
/kernel/tags/kolibri0.7.7.0/docs |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/gui/button.inc |
---|
0,0 → 1,643 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
max_buttons=4095 |
dececx: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0x20 |
jae @f |
mov [esp+edx],byte 0x20 |
@@: |
sub [esp+edx],byte 0x20 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
incecx: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0xdf |
jbe @f |
mov [esp+edx],byte 0xdf |
@@: |
add [esp+edx],byte 0x20 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
incecx2: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0xeb |
jbe @f |
mov [esp+edx],byte 0xeb |
@@: |
add [esp+edx],byte 0x14 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
drawbuttonframes: |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
shr ebx,16 |
shr ecx,16 |
mov eax,[TASK_BASE] |
add ebx,[eax-twdw + WDATA.box.left] |
add ecx,[eax-twdw + WDATA.box.top] |
mov eax, ebx |
shl eax, 16 |
mov ax, bx |
add ax, word [esp+8] |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
push ebx |
xor edi, edi |
mov ecx, esi |
call incecx |
call [draw_line] |
movzx edx,word [esp+4+4] |
add ebx,edx |
shl edx,16 |
add ebx,edx |
mov ecx,esi |
call dececx |
call [draw_line] |
pop ebx |
push edx |
mov edx,eax |
shr edx,16 |
mov ax,dx |
mov edx,ebx |
shr edx,16 |
mov bx,dx |
mov dx,[esp+4+4] |
add bx,dx |
pop edx |
mov ecx,esi |
call incecx |
call [draw_line] |
mov dx,[esp+8] |
add ax,dx |
shl edx,16 |
add eax,edx |
add ebx,1*65536 |
mov ecx,esi |
call dececx |
call [draw_line] |
pop edx |
pop ecx |
pop ebx |
pop eax |
pop edi |
pop esi |
ret |
button_dececx: |
cmp [buttontype],dword 1 |
jne .finish |
; je bdece |
; ret |
; bdece: |
push eax |
mov eax,0x01 |
cmp edi,20 |
jg @f |
mov eax,0x02 |
@@: |
test ecx,0xff |
jz @f |
sub ecx,eax |
@@: |
shl eax,8 |
test ecx,0xff00 |
jz @f |
sub ecx,eax |
@@: |
shl eax,8 |
test ecx,0xff0000 |
jz @f |
sub ecx,eax |
@@: |
pop eax |
.finish: |
ret |
sys_button: |
mov eax, [current_slot] |
rol ebx, 16 |
add bx, word [eax+APPDATA.wnd_clientbox.left] |
rol ebx, 16 |
rol ecx, 16 |
add cx, word [eax+APPDATA.wnd_clientbox.top] |
rol ecx, 16 |
.forced: |
test edx, 0x80000000 |
jnz remove_button |
or bx, bx |
jle noaddbutt |
or cx, cx |
jle noaddbutt |
test edx, 0x40000000 |
jnz button_no_draw |
pushad ; button body |
movzx edi, cx |
shr ebx, 16 |
shr ecx, 16 |
mov eax, [TASK_BASE] |
add ebx, [eax-twdw + WDATA.box.left] |
add ecx, [eax-twdw + WDATA.box.top] |
mov eax, ebx |
shl eax, 16 |
mov ax, bx |
add ax, word [esp+16] |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov ecx, esi |
cmp [buttontype], 0 |
je @f |
call incecx2 |
@@: |
mov edx, edi |
.newline: |
call button_dececx |
push edi |
xor edi, edi |
call [draw_line] |
pop edi |
add ebx, 1*65536+1 ; [ y start | y end ] |
dec edx |
jnz .newline |
popad |
call drawbuttonframes |
button_no_draw: |
mov edi, [BTN_ADDR] |
movzx eax, word [edi] |
cmp eax, max_buttons |
jge noaddbutt |
inc eax |
mov [edi], ax |
shl eax, 4 |
add edi, eax |
mov ax, [CURRENT_TASK] |
stosw |
mov ax, dx |
stosw ; button id number: bits 0-15 |
mov eax, ebx |
rol eax, 16 |
stosd ; x start | x size |
mov eax, ecx |
rol eax, 16 |
stosd ; y start | y size |
mov eax, edx |
shr eax, 16 |
stosw ; button id number: bits 16-31 |
noaddbutt: |
ret |
remove_button: |
and edx, 0x7fffffff |
rnewba2: |
mov edi, [BTN_ADDR] |
mov eax, edi |
movzx ebx, word [edi] |
inc ebx |
rnewba: |
dec ebx |
jz rnmba |
add eax, 0x10 |
mov cx, [CURRENT_TASK] |
cmp cx, [eax] |
jnz rnewba |
cmp dx, [eax+2] |
jnz rnewba |
lea ecx, [ebx+1] |
shl ecx, 4 |
mov ebx, eax |
add eax, 0x10 |
call memmove |
dec dword [edi] |
jmp rnewba2 |
rnmba: |
ret |
find_pressed_button_frames: |
pushad |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+ WDATA.box.left] ; window x start |
movzx edx,word [eax+4] ; button x start |
add ecx,edx |
push ecx |
mov dx,[eax+6] ; button x size |
add cx,dx |
mov esi,ecx |
inc esi |
mov ecx, [ebx+WDATA.box.top] ; window y start |
mov dx,[eax+8] ; button y start |
add ecx,edx |
mov ebx,ecx |
mov dx,[eax+10] ; button y size |
add dx,cx |
inc dx |
pop eax |
; eax x beginning |
; ebx y beginning |
; esi x end |
; edx y end |
; ecx color |
mov [pressed_button_eax],eax |
mov [pressed_button_ebx],ebx |
mov [pressed_button_ecx],ecx |
mov [pressed_button_edx],edx |
mov [pressed_button_esi],esi |
popad |
ret |
uglobal |
pressed_button_eax dd 0 |
pressed_button_ebx dd 0 |
pressed_button_ecx dd 0 |
pressed_button_edx dd 0 |
pressed_button_esi dd 0 |
endg |
; negative button image |
negativebutton: |
; If requested, do not display button |
; boarder on press. |
test ebx,0x20000000 |
jz draw_negative_button |
ret |
draw_negative_button: |
pushad |
mov eax,[pressed_button_eax] |
mov ebx,[pressed_button_ebx] |
mov ecx,[pressed_button_ecx] |
mov edx,[pressed_button_edx] |
mov esi,[pressed_button_esi] |
mov ecx,0x01000000 |
dec edx |
push edx |
inc edx |
dec esi |
push esi |
inc esi |
push eax |
push ebx |
push ecx |
push edx |
push edi |
call [_display.disable_mouse] |
bdbnewline: |
mov edi,1 ; force |
cmp eax,[esp+16] |
jz bneg |
cmp eax,[esp+20] |
jz bneg |
cmp ebx,[esp+12] |
jz bneg |
cmp ebx,[esp+24] |
jnz nbneg |
; jz bneg |
; jmp nbneg |
bneg: |
call [putpixel] |
nbneg: |
inc eax |
cmp eax,esi |
jnz bdbnewline |
mov eax,[esp+16] |
inc ebx |
cmp ebx,edx |
jnz bdbnewline |
add esp,28 |
popad |
ret |
; check buttons |
; 0000 word process number |
; 0002 word button id number : bits 0-15 |
; 0004 word x start |
; 0006 word x size |
; 0008 word y start |
; 000A word y size |
; 000C word button id number : bits 16-31 |
; |
; button table in 0x10 increments |
; |
; first at 0x10 |
align 4 |
checkbuttons: |
cmp [BTN_DOWN],byte 0 ; mouse buttons pressed |
jnz @f |
;..................................... start 1/5 : modified by vhanla ............................. |
mov [bPressedMouseXY_B],0 |
;..................................... end 1/5 : modified by vhanla ............................. |
ret |
@@: |
pushad |
xor esi, esi |
mov edi, [BTN_ADDR] |
movzx edx, word [edi] |
test edx, edx |
jne @f |
popad |
ret |
@@: |
;..................................... start 2/5 : modified by vhanla ............................. |
;here i catch the coordinates when the mouse's button is clicked |
push ax |
cmp [bPressedMouseXY_B],0;FALSE |
jnz @f |
mov [bPressedMouseXY_B],1;TRUE - it was already clicked |
mov ax,[MOUSE_X] |
mov [mx],ax |
mov ax,[MOUSE_Y] |
mov [my],ax |
@@: |
pop ax |
;and it is only refreshed after the mouse's button release |
;..................................... end 2/5 : modified by vhanla ............................. |
push esi |
inc edx |
push edx |
buttonnewcheck: |
pop edx |
pop esi |
inc esi |
cmp edx,esi |
jge bch |
popad ; no button pressed |
ret |
bch: |
push esi |
push edx |
mov eax,esi |
shl eax,4 |
add eax,edi |
; check that button is at top of windowing stack |
movzx ebx,word [eax] |
movzx ecx,word [WIN_STACK + ebx * 2] |
cmp ecx,[TASK_COUNT] |
jne buttonnewcheck |
; check that button start is inside window x/y end |
movzx ebx,word [eax+0] |
shl ebx,5 |
test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED |
jnz buttonnewcheck |
; add ebx,window_data |
; mov ecx,[window_data+ebx+8] ; window end X |
movzx edx,word [eax+4] ; button start X |
cmp edx, [window_data+ebx+WDATA.box.width] ;ecx |
jge buttonnewcheck |
; mov ecx,[window_data+ebx+12] ; window end Y |
movzx edx, word [eax+8] ; button start Y |
cmp edx, [window_data+ebx+WDATA.box.height] ;ecx |
jge buttonnewcheck |
; check coordinates |
; mouse x >= button x ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.left] ; window x start |
movzx edx,word [eax+4] ; button x start |
add edx,ecx |
;..................................... start 3/5 : modified by vhanla ............................. |
mov cx,[mx] ;mov cx,[MOUSE_X] |
;..................................... end 3/5 : modified by vhanla ............................. |
cmp edx,ecx |
jg buttonnewcheck |
movzx ebx,word [eax+6] ; button x size |
add edx,ebx |
cmp ecx,edx |
jg buttonnewcheck |
; mouse y >= button y ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.top] ; window y start |
movzx edx,word [eax+8] ; button y start |
add edx,ecx |
;..................................... start 4/5 : modified by vhanla ............................. |
mov cx,[my] ;mov cx,[MOUSE_Y] |
;..................................... start 4/5 : modified by vhanla ............................. |
cmp edx,ecx |
jg buttonnewcheck |
movzx ebx,word [eax+10] ; button y size |
add edx,ebx |
cmp ecx,edx |
jg buttonnewcheck |
; mouse on button |
pop edx |
pop esi |
mov bx,[eax+0xc] ; button id : bits 16-31 |
shl ebx,16 |
mov bx,[eax+2] ; button id : bits 00-16 |
push ebx |
mov [MOUSE_DOWN],byte 1 ; no mouse down checks |
call find_pressed_button_frames |
call negativebutton |
pushad |
; // Alver 22.06.2008 // { |
push eax |
mov al, byte [BTN_DOWN] |
mov byte [btn_down_determ], al |
pop eax |
; } \\ Alver \\ |
cbwaitmouseup: |
call checkidle |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? |
jnz cbwaitmouseup |
popad |
call negativebutton |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
;..................................... start 5/5 : modified by vhanla ............................. |
; check coordinates |
iglobal |
mx dw 0x0 ; keeps the x mouse's position when it was clicked |
my dw 0x0 ; keeps the y mouse's position when it was clicked |
bPressedMouseXY_B db 0x0 |
btn_down_determ db 0x0 ; << // Alver 22.06.2008// << |
endg |
pusha |
; mouse x >= button x ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.left] ; window x start |
movzx edx,word [eax+4] ; button x start |
add edx,ecx |
mov cx,[MOUSE_X] |
cmp edx,ecx |
jg no_on_button ;if we release the pointer out of the button area |
movzx ebx,word [eax+6] ; button x size |
add edx,ebx |
cmp ecx,edx |
jg no_on_button |
; mouse y >= button y ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.top] ; window y start |
movzx edx,word [eax+8] ; button y start |
add edx,ecx |
mov cx,[MOUSE_Y] |
cmp edx,ecx |
jg no_on_button |
movzx ebx,word [eax+10] ; button y size |
add edx,ebx |
cmp ecx,edx |
jg no_on_button |
popa |
mov [BTN_COUNT],byte 1 ; no of buttons in buffer |
pop ebx |
mov [BTN_BUFF],ebx ; lets put the button id in buffer |
push ebx |
pusha |
jmp yes_on_button |
no_on_button: |
mov [BTN_COUNT],byte 0 ; no of buttons in buffer |
yes_on_button: |
mov [MOUSE_DOWN],byte 0 ; mouse down -> do not draw |
popa |
pop ebx |
popa |
ret |
;..................................... end 5/5 : modified by vhanla ................................ |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/font.inc |
---|
0,0 → 1,132 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; // Alver 22.06.2008 // { |
align 4 |
dtext_asciiz_esi: ; for skins title out |
push eax |
xor eax, eax |
inc eax |
jmp dtext.1 |
; } \\ Alver \\ |
align 4 |
dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) |
; ebx x & y |
; ecx style ( 0xX0000000 ) & color ( 0x00RRGGBB ) |
; X = ABnnb: |
; nn = font |
; A = 0 <=> output esi characters; otherwise output ASCIIZ string |
; B = 1 <=> fill background with color eax |
; edx start of text |
; edi 1 force |
; // Alver 22.06.2008 // { |
push eax |
xor eax, eax |
.1: |
; } \\ Alver \\ |
pushad |
call [_display.disable_mouse] |
movsx eax, bx ; eax=y |
sar ebx, 16 ; ebx=x |
xchg eax, ebx ; eax=x, ebx=y |
cmp esi, 255 |
jb .loop |
mov esi, 255 |
.loop: |
test ecx, ecx |
js .test_asciiz |
dec esi |
js .end |
jmp @f |
.test_asciiz: |
cmp byte [edx], 0 |
jz .end |
; // Alver 22.06.2008 // { |
cmp byte [esp+28], 1 |
jne @f |
dec esi |
js .end |
; } \\ Alver \\ |
@@: |
inc edx |
pushad |
movzx edx, byte [edx-1] |
test ecx, 0x10000000 |
jnz .font2 |
mov esi, 9 |
lea ebp, [FONT_I+8*edx+edx] |
.symloop1: |
mov dl, byte [ebp] |
or dl, 1 shl 6 |
.pixloop1: |
shr dl, 1 |
jz .pixloop1end |
jnc .nopix |
call [putpixel] |
jmp .pixloop1cont |
.nopix: |
test ecx, 0x40000000 |
jz .pixloop1cont |
push ecx |
mov ecx, [esp+4+20h+20h] |
call [putpixel] |
pop ecx |
.pixloop1cont: |
inc eax |
jmp .pixloop1 |
.pixloop1end: |
sub eax, 6 |
inc ebx |
inc ebp |
dec esi |
jnz .symloop1 |
popad |
add eax, 6 |
jmp .loop |
.font2: |
add edx, edx |
lea ebp, [FONT_II+4*edx+edx+1] |
push 9 |
movzx esi, byte [ebp-1] |
.symloop2: |
mov dl, byte [ebp] |
push esi |
.pixloop2: |
shr dl, 1 |
jnc .nopix2 |
call [putpixel] |
jmp .pixloop2cont |
.nopix2: |
test ecx, 0x40000000 |
jz .pixloop2cont |
push ecx |
mov ecx, [esp+12+20h+20h] |
call [putpixel] |
pop ecx |
.pixloop2cont: |
inc eax |
dec esi |
jnz .pixloop2 |
pop esi |
sub eax, esi |
inc ebx |
inc ebp |
dec dword [esp] |
jnz .symloop2 |
pop eax |
add dword [esp+28], esi |
popad |
jmp .loop |
.end: |
popad |
pop eax ; << // Alver 22.06.2008 // << |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/window.inc |
---|
0,0 → 1,1823 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
get_titlebar_height: ; edi = window draw_data pointer |
mov al,[edi+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,0x03 |
jne @f |
mov eax,[_skinh] |
ret |
@@: mov eax,21 |
ret |
get_rolledup_height: ; edi = window draw_data pointer |
mov al,[edi+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,0x03 |
jb @f |
mov eax,[_skinh] |
add eax,3 |
ret |
@@: or al,al |
jnz @f |
mov eax,21 |
ret |
@@: mov eax,21+2 |
ret |
setwindowdefaults: |
pushad |
xor eax,eax |
mov ecx,WIN_STACK |
@@: |
inc eax |
add ecx,2 |
mov [ecx+0x000],ax ; process no |
mov [ecx+0x400],ax ; positions in stack |
cmp ecx,WIN_POS-2 ; the more high, the more surface |
jnz @b |
popad |
ret |
; eax = cx |
; ebx = cy |
; ecx = ex |
; edx = ey |
; èäåÿ: ïåðåáðàòü âñå îêíà, íà÷èíàÿ ñ ñàìîãî íèæíåãî, |
; è äëÿ ïîïàâøèõ â çàäàííóþ îáëàñòü |
; ÷àñòåé îêîí âûçâàòü setscreen |
align 4 |
calculatescreen: |
pushad |
pushfd |
cli |
push edx ecx ebx eax |
mov esi, 1 |
call setscreen |
mov ebp, [TASK_COUNT] ; number of processes |
cmp ebp, 1 |
jbe .finish |
align 4 |
.new_wnd: |
movzx edi, word [WIN_POS + esi * 2] |
shl edi, 5 |
cmp [CURRENT_TASK+edi+TASKDATA.state], byte 9 |
je .not_wnd |
add edi, window_data |
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .not_wnd |
mov eax,[edi+WDATA.box.left] |
cmp eax, [esp+RECT.right] |
ja .out_of_bounds |
mov ebx,[edi+WDATA.box.top] |
cmp ebx, [esp+RECT.bottom] |
ja .out_of_bounds |
mov ecx,[edi+WDATA.box.width] |
add ecx, eax |
cmp ecx, [esp+RECT.left] |
jb .out_of_bounds |
mov edx,[edi+WDATA.box.height] |
add edx, ebx |
cmp edx, [esp+RECT.top] |
jb .out_of_bounds |
cmp eax, [esp+RECT.left] |
jae @f |
mov eax, [esp+RECT.left] |
@@: |
cmp ebx, [esp+RECT.top] |
jae @f |
mov ebx, [esp+RECT.top] |
@@: |
cmp ecx, [esp+RECT.right] |
jbe @f |
mov ecx, [esp+RECT.right] |
@@: |
cmp edx, [esp+RECT.bottom] |
jbe @f |
mov edx, [esp+RECT.bottom] |
@@: |
push esi |
movzx esi, word [WIN_POS + esi * 2] |
call setscreen |
pop esi |
.not_wnd: |
.out_of_bounds: |
inc esi |
dec ebp |
jnz .new_wnd |
.finish: |
pop eax ebx ecx edx |
popfd |
popad |
ret |
virtual at esp |
ff_x dd ? |
ff_y dd ? |
ff_width dd ? |
ff_xsz dd ? |
ff_ysz dd ? |
ff_scale dd ? |
end virtual |
align 4 |
; ðåçåðâèðóåò ìåñòî ïîä îêíî çàäàííîãî ïðîöåññà |
setscreen: |
; eax x start |
; ebx y start |
; ecx x end |
; edx y end |
; esi process number |
pushad |
; \begin{diamond}[29.08.2006] |
cmp esi, 1 |
jz @f |
mov edi, esi |
shl edi, 5 |
cmp [edi+window_data+WDATA.box.width], 0 |
jnz @f |
cmp [edi+window_data+WDATA.box.height], 0 |
jz .ret |
@@: |
; \end{diamond}[29.08.2006] |
mov edi, esi ;;;word [esi*2+WIN_POS] |
shl edi, 8 |
add edi, SLOT_BASE ; address of random shaped window area |
cmp [edi+APPDATA.wnd_shape], dword 0 |
jne .free_form |
; get x&y size |
sub ecx, eax |
sub edx, ebx |
inc ecx |
inc edx |
; get WinMap start |
mov edi, [Screen_Max_X] ; screen_sx |
inc edi |
imul edi, ebx |
add edi, eax |
add edi, [_WinMapAddress] |
.new_y: |
push ecx ; sx |
push edx |
mov edx, esi |
align 4 |
.new_x: |
mov byte [edi], dl |
inc edi |
dec ecx |
jnz .new_x |
pop edx |
pop ecx |
add edi, [Screen_Max_X] |
inc edi |
sub edi, ecx |
dec edx |
jnz .new_y |
.ret: |
popad |
ret |
.read_byte: |
;eax - address |
;esi - slot |
push eax |
push ebx |
push ecx |
push edx |
mov edx,eax |
mov eax,esi |
lea ebx,[esp+12] |
mov ecx,1 |
call read_process_memory |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
.free_form: |
; for (y=0; y <= x_size; y++) |
; for (x=0; x <= x_size; x++) |
; if (shape[coord(x,y,scale)]==1) |
; set_pixel(x, y, process_number); |
sub ecx, eax |
sub edx, ebx |
inc ecx |
inc edx |
push dword [edi+APPDATA.wnd_shape_scale] ; push scale first -> for loop |
; get WinMap start -> ebp |
push eax |
mov eax, [Screen_Max_X] ; screen_sx |
inc eax |
imul eax, ebx |
add eax, [esp] |
add eax, [_WinMapAddress] |
mov ebp, eax |
mov edi, [edi+APPDATA.wnd_shape] |
pop eax |
; eax = x_start |
; ebx = y_start |
; ecx = x_size |
; edx = y_size |
; esi = process_number |
; edi = &shape |
; [scale] |
push edx ecx ; for loop - x,y size |
mov ecx, esi |
shl ecx, 5 |
mov edx, [window_data+ecx+WDATA.box.top] |
push [window_data+ecx+WDATA.box.width] ; for loop - width |
mov ecx, [window_data+ecx+WDATA.box.left] |
sub ebx, edx |
sub eax, ecx |
push ebx eax ; for loop - x,y |
add [ff_xsz], eax |
add [ff_ysz], ebx |
mov ebx, [ff_y] |
.ff_new_y: |
mov edx, [ff_x] |
.ff_new_x: |
; -- body -- |
mov ecx, [ff_scale] |
mov eax, [ff_width] |
inc eax |
shr eax, cl |
push ebx edx |
shr ebx, cl |
shr edx, cl |
imul eax, ebx |
add eax, edx |
pop edx ebx |
add eax, edi |
call .read_byte |
test al,al |
jz @f |
mov eax, esi |
mov [ebp], al |
@@: |
; -- end body -- |
inc ebp |
inc edx |
cmp edx, [ff_xsz] |
jb .ff_new_x |
sub ebp, [ff_xsz] |
add ebp, [ff_x] |
add ebp, [Screen_Max_X] ; screen.x |
inc ebp |
inc ebx |
cmp ebx, [ff_ysz] |
jb .ff_new_y |
add esp, 24 |
popad |
ret |
display_settings: |
; eax = 0 ; DISPLAY redraw |
; ebx = 0 ; all |
; |
; eax = 1 ; BUTTON type |
; ebx = 0 ; flat |
; ebx = 1 ; 3D |
; eax = 2 ; set WINDOW colours |
; ebx = pointer to table |
; ecx = number of bytes define |
; eax = 3 ; get WINDOW colours |
; ebx = pointer to table |
; ecx = number of bytes wanted |
; eax = 4 ; get skin height |
; input : nothing |
; output : eax = skin height in pixel |
; eax = 5 ; get screen workarea |
; input : nothing |
; output : eax = [left]*65536+[right] |
; ebx = [top]*65536+[bottom] |
; eax = 6 ; set screen workarea |
; input : ecx = [left]*65536+[right] |
; edx = [top]*65536+[bottom] |
; output : nothing |
; eax = 7 ; get skin margins |
; input : nothing |
; output : eax = [left]*65536+[right] |
; ebx = [top]*65536+[bottom] |
; eax = 8 ; set window skin |
; input : ecx = pointer to file info block |
; output : eax = FS error code |
pushad |
test eax, eax ; redraw display |
jnz dspl0 |
test ebx, ebx |
jnz dspl0 |
cmp [windowtypechanged],dword 1 |
jne dspl00 |
mov [windowtypechanged],dword 0 |
redraw_screen_direct: |
mov [dlx],dword 0 |
mov [dly],dword 0 |
mov eax,[Screen_Max_X] |
mov [dlxe],eax |
mov eax,[Screen_Max_Y] |
mov [dlye],eax |
mov eax,window_data |
call redrawscreen |
dspl00: |
popad |
ret |
dspl0: |
cmp eax,1 ; button type |
jne dspl1 |
and ebx,1 |
cmp ebx,[buttontype] |
je dspl9 |
mov [buttontype],ebx |
mov [windowtypechanged],dword 1 |
dspl9: |
popad |
ret |
dspl1: |
cmp eax,2 ; set common window colours |
jne no_com_colours |
mov [windowtypechanged],dword 1 |
mov esi,[TASK_BASE] |
add esi,TASKDATA.mem_start |
add ebx,[esi] |
mov esi,ebx |
mov edi,common_colours |
and ecx,127 |
cld |
rep movsb |
popad |
ret |
no_com_colours: |
cmp eax,3 ; get common window colours |
jne no_get_com |
mov esi,[TASK_BASE] |
add esi,TASKDATA.mem_start |
add ebx,[esi] |
mov edi,ebx |
mov esi,common_colours |
and ecx,127 |
cld |
rep movsb |
popad |
ret |
no_get_com: |
cmp eax,4 ; get skin height |
jne no_skin_height |
popad |
mov eax,[_skinh] |
mov [esp+36],eax |
ret |
no_skin_height: |
cmp eax,5 ; get screen workarea |
jne no_get_workarea |
popad |
mov eax,[screen_workarea.left-2] |
mov ax,word[screen_workarea.right] |
mov [esp+36],eax |
mov eax,[screen_workarea.top-2] |
mov ax,word[screen_workarea.bottom] |
mov [esp+24],eax |
ret |
no_get_workarea: |
cmp eax,6 ; set screen workarea |
jne no_set_workarea |
movsx eax,word[esp+16+2] |
movsx ebx,word[esp+16] |
cmp eax,ebx |
jge .lp1 |
or eax,eax;[Screen_Max_X] |
jl @f |
mov [screen_workarea.left],eax |
@@: cmp ebx,[Screen_Max_X] |
jg .lp1 |
mov [screen_workarea.right],ebx |
.lp1: movsx eax,word[esp+24+2] |
movsx ebx,word[esp+24] |
cmp eax,ebx |
jge .lp2 |
or eax,eax;[0xFE04] |
jl @f |
mov [screen_workarea.top],eax |
@@: cmp ebx,[Screen_Max_Y] |
jg .lp2 |
mov [screen_workarea.bottom],ebx |
.lp2: call repos_windows |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [Screen_Max_X] |
mov edx, [Screen_Max_Y] |
call calculatescreen |
; jmp redraw_screen_direct |
.exit: |
popad |
ret |
no_set_workarea: |
cmp eax,7 ; get skin margins |
jne no_get_skinmargins |
popad |
mov eax,dword[_skinmargins+0] |
mov [esp+36],eax |
mov eax,dword[_skinmargins+4] |
mov [esp+24],eax |
ret |
no_get_skinmargins: |
cmp eax,8 ; set window skin |
jne no_set_skin |
call read_skin_file |
mov [esp+32+36], eax |
test eax, eax |
jnz .ret |
xor eax, eax |
xor ebx, ebx |
mov ecx, [Screen_Max_X] |
mov edx, [Screen_Max_Y] |
call calculatescreen |
jmp redraw_screen_direct |
.ret: |
popad |
ret |
no_set_skin: |
popad |
ret |
repos_windows: |
mov ecx,[TASK_COUNT] |
mov edi, window_data+0x20*2 |
call force_redraw_background |
dec ecx |
jge @f |
ret |
@@: mov [edi+WDATA.fl_redraw],1 |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jz .lp2 |
mov eax,[screen_workarea.left] |
mov [edi+WDATA.box.left],eax |
sub eax,[screen_workarea.right] |
neg eax |
mov [edi+WDATA.box.width],eax |
mov eax,[screen_workarea.top] |
mov [edi+WDATA.box.top],eax |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .lp1 |
sub eax,[screen_workarea.bottom] |
neg eax |
mov [edi+WDATA.box.height],eax |
.lp1: |
call set_window_clientbox |
add edi,0x20 |
loop @b |
ret |
.lp2: mov eax,[edi+WDATA.box.left] |
add eax,[edi+WDATA.box.width] |
mov ebx,[Screen_Max_X] |
; inc ebx |
cmp eax,ebx |
jle .lp4 |
mov eax,[edi+WDATA.box.width] |
sub eax,ebx |
jle .lp3 |
mov [edi+WDATA.box.width],ebx |
.lp3: sub ebx,[edi+WDATA.box.width] |
mov [edi+WDATA.box.left],ebx |
.lp4: mov eax,[edi+WDATA.box.top] |
add eax,[edi+WDATA.box.height] |
mov ebx,[Screen_Max_Y] |
; inc ebx |
cmp eax,ebx |
jle .lp6 |
mov eax,[edi+WDATA.box.height] |
sub eax,ebx |
jle .lp5 |
mov [edi+WDATA.box.height],ebx |
.lp5: sub ebx,[edi+WDATA.box.height] |
mov [edi+WDATA.box.top],ebx |
.lp6: jmp .lp1 |
uglobal |
common_colours: |
times 128 db 0x0 |
endg |
check_window_position: |
pushad ; window inside screen ? |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, [edi+WDATA.box.width] |
mov edx, [edi+WDATA.box.height] |
cmp ecx,[Screen_Max_X] ; check x size |
jbe x_size_ok |
mov ecx,[Screen_Max_X] |
mov [edi+WDATA.box.width],ecx |
x_size_ok: |
cmp edx,[Screen_Max_Y] ; check y size |
jbe y_size_ok |
mov edx,[Screen_Max_Y] |
mov [edi+WDATA.box.height],edx |
y_size_ok: |
cmp eax,0 ; check x pos |
jnle @f |
xor eax,eax |
mov [edi+WDATA.box.left],eax |
jmp x_pos_ok |
@@: |
add eax,ecx |
cmp eax,[Screen_Max_X] |
jbe x_pos_ok |
mov eax,[Screen_Max_X] |
sub eax,ecx |
mov [edi+WDATA.box.left],eax |
x_pos_ok: |
cmp ebx,0 ; check x pos |
jnle @f |
xor ebx,ebx |
mov [edi+WDATA.box.top],ebx |
jmp y_pos_ok |
@@: |
add ebx,edx |
cmp ebx,[Screen_Max_Y] |
jbe y_pos_ok |
mov ebx,[Screen_Max_Y] |
sub ebx,edx |
mov [edi+WDATA.box.top],ebx |
y_pos_ok: |
popad |
ret |
uglobal |
new_window_starting dd 0 |
endg |
sys_window_mouse: |
push eax |
mov eax,[timer_ticks] |
cmp [new_window_starting],eax |
jb swml1 |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
mov [new_window_starting],eax |
swml1: |
pop eax |
ret |
drawwindow_I_caption: |
mov ecx,[edx+WDATA.cl_titlebar] ; grab bar |
push ecx |
mov esi,edx |
mov edx,[esi+WDATA.box.top] |
add edx,1 |
mov ebx,[esi+WDATA.box.top] |
add ebx,21 |
mov eax,[esi+WDATA.box.top] |
add eax,[esi+WDATA.box.height] |
cmp ebx,eax |
jb .wdsizeok |
mov ebx,eax |
.wdsizeok: |
push ebx |
.drwi: |
mov ebx,edx |
shl ebx,16 |
add ebx,edx |
mov eax,[esi+WDATA.box.left] |
inc eax |
shl eax,16 |
add eax,[esi+WDATA.box.left] |
add eax,[esi+WDATA.box.width] |
sub eax,1 |
push edx |
mov edx,0x80000000 |
mov ecx,[esi+WDATA.cl_titlebar] |
and ecx,edx |
cmp ecx,edx |
jnz .nofa |
mov ecx,[esi+WDATA.cl_titlebar] |
sub ecx,0x00040404 |
mov [esi+WDATA.cl_titlebar],ecx |
and ecx,0x00ffffff |
jmp .faj |
.nofa: |
mov ecx,[esi+WDATA.cl_titlebar] |
and ecx,0x00ffffff |
.faj: |
pop edx |
mov edi,0 |
call [draw_line] |
inc edx |
cmp edx,[esp] |
jb .drwi |
add esp,4 |
pop ecx |
mov [esi+WDATA.cl_titlebar],ecx |
ret |
drawwindow_I: |
pushad |
or [edx+WDATA.fl_wdrawn], 4 |
mov esi,[edx+WDATA.cl_frames] ; rectangle |
mov eax,[edx+WDATA.box.left] |
shl eax,16 |
add eax,[edx+WDATA.box.left] |
add eax,[edx+WDATA.box.width] |
mov ebx,[edx+WDATA.box.top] |
shl ebx,16 |
add ebx,[edx+WDATA.box.top] |
add ebx,[edx+WDATA.box.height] |
call draw_rectangle |
and [edx+WDATA.fl_wdrawn], not 4 |
test [edx+WDATA.fl_wdrawn], 2 |
jz @f |
call drawwindowframes2 |
@@: |
call drawwindow_I_caption |
mov edx,[esi+WDATA.box.top] ; inside work area |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg noinside |
mov eax,1 |
mov ebx,21 |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
mov edi,[esi+WDATA.cl_workarea] |
test edi,0x40000000 |
jnz noinside |
call [drawbar] |
noinside: |
popad |
ret |
draw_rectangle: |
r_eax equ [esp+28] ; x start |
r_ax equ [esp+30] ; x end |
r_ebx equ [esp+16] ; y start |
r_bx equ [esp+18] ; y end |
;esi ; color |
pushad |
mov ecx,esi ; yb,xb -> yb,xe |
mov eax, r_eax |
rol eax, 16 |
mov ebx,r_ebx |
shl ebx,16 |
mov bx,r_ebx |
xor edi, edi |
call [draw_line] |
mov ebx,r_bx ; ye,xb -> ye,xe |
shl ebx,16 |
mov bx,r_bx |
call [draw_line] |
mov ecx,esi ; ya,xa -> ye,xa |
mov eax,r_eax |
shl eax,16 |
mov ax,r_eax |
mov ebx,r_ebx |
shl ebx,16 |
mov bx,r_bx |
mov edi,0 |
call [draw_line] |
mov eax,r_ax ; ya,xe -> ye,xe |
shl eax,16 |
mov ax,r_ax |
call [draw_line] |
popad |
ret |
drawwindow_III_caption: |
mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR |
push ecx |
mov esi,edx |
mov edx,[esi+WDATA.box.top] |
add edx,4 |
mov ebx,[esi+WDATA.box.top] |
add ebx,20 |
mov eax,[esi+WDATA.box.top] |
add eax,[esi+WDATA.box.height] |
cmp ebx,eax |
jb .wdsizeok |
mov ebx,eax |
.wdsizeok: |
push ebx |
.drwi: |
mov ebx,edx |
shl ebx,16 |
add ebx,edx |
mov eax,[esi+WDATA.box.left] |
shl eax,16 |
add eax,[esi+WDATA.box.left] |
add eax,[esi+WDATA.box.width] |
add eax,4*65536-4 |
mov ecx,[esi+WDATA.cl_titlebar] |
test ecx,0x40000000 |
jz .nofa |
add ecx,0x040404 |
.nofa: |
test ecx,0x80000000 |
jz .nofa2 |
sub ecx,0x040404 |
.nofa2: |
mov [esi+WDATA.cl_titlebar],ecx |
and ecx,0xffffff |
xor edi, edi |
call [draw_line] |
inc edx |
cmp edx,[esp] |
jb .drwi |
add esp,4 |
pop ecx |
mov [esi+WDATA.cl_titlebar],ecx |
ret |
drawwindow_III: |
pushad |
mov edi,edx ; RECTANGLE |
mov eax,[edi+WDATA.box.left] |
shl eax,16 |
mov ax, word [edi+WDATA.box.left] |
add ax, word [edi+WDATA.box.width] |
mov ebx,[edi+WDATA.box.top] |
shl ebx,16 |
mov bx, word [edi+WDATA.box.top] |
add bx, word [edi+WDATA.box.height] |
mov esi,[edi+WDATA.cl_frames] |
shr esi,1 |
and esi,0x007f7f7f |
push esi |
or [edi+WDATA.fl_wdrawn], 4 |
call draw_rectangle |
and [edi+WDATA.fl_wdrawn], not 4 |
test [edi+WDATA.fl_wdrawn], 2 |
jz @f |
call drawwindowframes2 |
@@: |
mov ecx,3 |
dw3l: |
add eax,1*65536-1 |
add ebx,1*65536-1 |
mov esi,[edi+WDATA.cl_frames] |
call draw_rectangle |
dec ecx |
jnz dw3l |
pop esi |
add eax,1*65536-1 |
add ebx,1*65536-1 |
call draw_rectangle |
call drawwindow_III_caption |
mov edx,[esi+WDATA.box.top] ; WORK AREA |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg noinside2 |
mov eax,5 |
mov ebx,20 |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
sub ecx,4 |
sub edx,4 |
mov edi,[esi+WDATA.cl_workarea] |
test edi,0x40000000 |
jnz noinside2 |
call [drawbar] |
noinside2: |
popad |
ret |
; activate window |
align 4 |
windowactivate: |
; esi = abs mem position in stack 0xC400+ |
pushad |
; if type of current active window is 3, |
; it must be redrawn |
mov eax, [TASK_COUNT] |
movzx eax, word [WIN_POS + eax*2] |
shl eax, 5 |
add eax, window_data |
mov ebx, [eax + WDATA.cl_workarea] |
and ebx, 0x0f000000 |
cmp ebx, 0x03000000 |
je .set_WDATA_fl_redraw ; for 3 and 4 style |
cmp ebx, 0x04000000 |
je .set_WDATA_fl_redraw |
jmp @f |
.set_WDATA_fl_redraw: |
mov [eax + WDATA.fl_redraw], byte 1 |
@@: |
push esi |
movzx eax, word [esi] ; ax <- process no |
movzx eax, word [WIN_STACK+eax*2] ; ax <- position in window stack |
xor esi, esi ; drop others |
waloop: |
cmp esi, dword [TASK_COUNT] |
jae wacont |
inc esi |
lea edi, [WIN_STACK + esi*2] |
mov bx, [edi] ; position of the current process |
cmp bx, ax |
jbe @f |
dec bx ; upper? => drop! |
mov [edi], bx |
@@: |
jmp waloop |
wacont: |
; set to no 1 |
pop esi ; esi = pointer at 0xC400 |
movzx eax, word [esi] |
mov bx, [TASK_COUNT] ; number of processes |
mov [WIN_STACK+eax*2], bx ; this is the last (and the upper) |
; update on screen -window stack |
xor esi, esi |
waloop2: |
mov edi, [TASK_COUNT] |
cmp esi, edi |
jae wacont2 |
inc esi |
movzx ebx, word [esi*2 + WIN_STACK] |
mov [ebx*2 + WIN_POS], si |
jmp waloop2 |
wacont2: |
mov [KEY_COUNT], byte 0 ; empty keyboard buffer |
mov [BTN_COUNT], byte 0 ; empty button buffer |
mov [MOUSE_SCROLL_H], word 0 ; zero mouse z-index |
mov [MOUSE_SCROLL_V], word 0 ; zero mouse z-index |
popad |
ret |
; check if window is necessary to draw |
checkwindowdraw: |
; edi = position in window_data+ |
mov eax, [edi + WDATA.cl_workarea] |
and eax, 0x0f000000 |
cmp eax, 0x03000000 |
je .return_yes ; window type 3 |
cmp eax, 0x04000000 |
je .return_yes ; window type 4 |
mov esi, edi |
sub esi, window_data |
shr esi, 5 |
; esi = process number |
movzx eax, word [WIN_STACK + esi * 2] ; get value of the curr process |
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 |
push esi |
.new_check: |
pop esi |
add esi, 2 |
push esi |
mov eax, [TASK_COUNT] |
lea eax, word [WIN_POS + eax * 2] ; number of the upper window |
cmp esi, eax |
ja .all_wnds_to_top |
movzx eax, word [esi] |
shl eax, 5 |
cmp [CURRENT_TASK + eax + TASKDATA.state], byte 9 |
je .new_check ; skip dead windows |
lea esi, [eax+window_data] |
mov ebx, [edi+WDATA.box.top] ; y0 |
mov edx, [edi+WDATA.box.height] |
add edx, ebx ; y0e |
mov ecx, [esi+WDATA.box.top] ; y ; y check |
cmp ecx, edx |
jae .new_check ; y < y0e |
mov eax, [esi+WDATA.box.height] |
add ecx, eax ; ye |
cmp ebx, ecx ; y0 >= ye |
ja .new_check |
mov eax, [edi+WDATA.box.left] ; x0 |
mov ecx, [edi+WDATA.box.width] |
add ecx, eax ; x0e |
mov edx, [esi+WDATA.box.left] ; x ; x check |
cmp edx, ecx |
jae .new_check ; x < x0e |
mov ecx, [esi+WDATA.box.width] |
add edx, ecx |
cmp eax, edx |
ja .new_check |
pop esi |
.return_yes: |
mov ecx,1 ; overlap some window |
ret |
.all_wnds_to_top: |
pop esi |
xor ecx, ecx ; passed all windows to top |
ret |
waredraw: ; if redraw necessary at activate |
pushad |
call checkwindowdraw ; draw window on activation ? |
test ecx, ecx |
jz .do_not_draw |
popad |
mov [MOUSE_DOWN], byte 1 ; do draw mouse |
call windowactivate |
; update screen info |
pushad |
mov edi, [TASK_COUNT] ; the last process (number) |
movzx esi, word [WIN_POS + edi * 2] |
shl esi, 5 |
add esi, window_data |
; coordinates of the upper window |
mov eax, [esi + WDATA.box.left] ; cx |
mov ebx, [esi + WDATA.box.top] ; cy |
mov ecx, [esi + WDATA.box.width] ; sx |
mov edx, [esi + WDATA.box.height] ; sy |
add ecx, eax ; ecx = x_end |
add edx, ebx ; edx = y_end |
mov edi, [TASK_COUNT] |
movzx esi, word [WIN_POS + edi * 2] |
call setscreen |
popad |
mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app |
mov [MOUSE_DOWN],byte 0 ; mouse down checks |
ret |
.do_not_draw: |
popad |
call windowactivate |
mov [MOUSE_DOWN],byte 0 ; mouse down checks |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
ret |
; eax = window number on screen |
; corrupts registers and [dl*] |
minimize_window: |
movzx eax, word [WIN_POS+eax*2] |
shl eax, 5 |
add eax, window_data |
test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .skip_redrawings |
pushfd |
cli |
or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED |
mov edi, eax |
;call calculatescreen |
mov eax, [edi+WDATA.box.left] |
mov [dlx], eax |
mov ecx, eax |
add ecx, [edi+WDATA.box.width] |
mov [dlxe], ecx |
mov ebx, [edi+WDATA.box.top] |
mov [dly], ebx |
mov edx, ebx |
add edx, [edi+WDATA.box.height] |
mov [dlye], edx |
call calculatescreen |
xor esi, esi |
xor eax, eax |
call redrawscreen |
popfd |
.skip_redrawings: |
ret |
; eax = window number on screen |
; corrupts registers and [dl*] |
restore_minimized_window: |
pushfd |
cli |
movzx esi, word [WIN_POS+eax*2] |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED |
jz .skip_redrawings |
mov [edi+WDATA.fl_redraw], 1 |
and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED |
cmp eax, [TASK_COUNT] ; the uppermost window |
jnz .no_uppermost |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, eax |
mov edx, ebx |
add ecx, [edi+WDATA.box.width] |
add edx, [edi+WDATA.box.height] |
call setscreen |
jmp .done |
.no_uppermost: |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, eax |
mov edx, ebx |
add ecx, [edi+WDATA.box.width] |
add edx, [edi+WDATA.box.height] |
call calculatescreen |
.done: |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
.skip_redrawings: |
popfd |
ret |
;iglobal |
; window_moving db 'K : Window - move/resize',13,10,0 |
; window_moved db 'K : Window - done',13,10,0 |
;endg |
; check window touch |
align 4 |
checkwindows: |
pushad |
cmp [window_minimize], 0 |
je .no_minimizing |
mov eax, [TASK_COUNT] ; the uppermost window |
mov bl, 0 |
xchg [window_minimize], bl |
cmp bl, 1 |
jne .restore |
call minimize_window |
jmp .continue |
.restore: |
call restore_minimized_window |
.continue: |
.no_minimizing: |
cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? |
jne .mouse_buttons_pressed |
;..................................... start 1/4 : modified by vhanla ................. |
mov [bPressedMouseXY_W],0 |
;..................................... end 1/4 : modified by vhanla ................... |
popad |
ret |
.mouse_buttons_pressed: |
;..................................... start 2/4 : modified by vhanla ................. |
uglobal |
bPressedMouseXY_W db 0x0 |
endg |
;..................................... end 2/4 : modified by vhanla ................... |
mov esi,[TASK_COUNT] |
inc esi |
;..................................... start 3/4 : modified by vhanla ................. |
cmp [bPressedMouseXY_W],1 |
ja @f |
inc [bPressedMouseXY_W] |
jnc @f |
;mov ax,[MOUSE_X] |
;mov [mx],ax |
;mov ax,[MOUSE_Y] |
;mov [my],ax |
mov eax,dword[MOUSE_X] |
mov dword[mx],eax |
@@: |
;..................................... end 3/4 : modified by vhanla ................... |
cwloop: |
cmp esi,2 |
jb .exit |
dec esi |
movzx edi, word [WIN_POS + esi * 2] ; ebx |
shl edi, 5 |
add edi, window_data |
; mov edi, ebx |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
mov eax,ecx |
mov ebx,edx |
test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED |
jnz cwloop |
;..................................... start 4/4 : modified by vhanla ................. |
movzx eax, word [mx]; movzx eax,word[MOUSE_X] |
movzx ebx, word [my]; movzx ebx,word[MOUSE_Y] |
;..................................... endt 4/4 : modified by vhanla .................. |
cmp ecx, eax |
jae cwloop |
cmp edx, ebx |
jae cwloop |
add ecx, [edi + WDATA.box.width] |
add edx, [edi + WDATA.box.height] |
cmp eax, ecx |
jae cwloop |
cmp ebx, edx |
jae cwloop |
pushad |
mov eax, esi |
mov ebx, [TASK_COUNT] |
cmp eax, ebx ; is this window active? |
jz .move_resize_window |
cmp [bPressedMouseXY_W], 1 |
ja .exit_popa |
; eax = position in windowing stack |
; redraw must ? |
lea esi, [WIN_POS + esi * 2] |
call waredraw |
.exit_popa: |
add esp, 32 |
.exit: |
popad |
ret |
.move_resize_window: ; MOVE OR RESIZE WINDOW |
popad |
; Check for user enabled fixed window |
mov edx, [edi + WDATA.cl_titlebar] |
and edx, 0x0f000000 |
cmp edx, 0x01000000 |
jne .window_move_enabled_for_user |
popad |
ret |
.window_move_enabled_for_user: |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .no_resize_2 |
mov [do_resize_from_corner],byte 0 ; resize for skinned window |
mov edx, [edi + WDATA.cl_workarea] |
and edx, 0x0f000000 |
cmp edx, 0x00000000 ;{test for resized} |
je .no_resize_2 |
cmp edx, 0x01000000 ;{test for resized} |
je .no_resize_2 |
cmp edx, 0x04000000 ;{test for resized} |
je .no_resize_2 |
; jb .no_resize_2 ; not type 2 wnd |
mov edx, [edi + WDATA.box.top] |
add edx, [edi + WDATA.box.height] |
sub edx, 6 ; edx = y_end - 6 |
cmp ebx, edx ; ebx = mouse_y |
jb .no_resize_2 |
mov [do_resize_from_corner],byte 1 |
jmp .continue |
.no_resize_2: |
push eax |
call get_titlebar_height |
add eax,[edi + WDATA.box.top] |
cmp ebx,eax |
pop eax |
jae .exit |
.continue: |
; push esi |
; mov esi, window_moving |
; call sys_msg_board_str |
; pop esi |
mov ecx, [timer_ticks] ; double-click ? |
mov edx, ecx |
sub edx, [latest_window_touch] |
mov [latest_window_touch], ecx |
mov [latest_window_touch_delta], edx |
mov cl, [BTN_DOWN] ; save for shade check |
mov [do_resize], cl |
no_emulation_righ_button: |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
push eax ecx edx |
mov [dlx], ecx ; save for drawlimits |
mov [dly], edx |
mov eax, [edi + WDATA.box.width] |
add ecx, eax |
mov eax, [edi + WDATA.box.height] |
add edx, eax |
mov [dlxe], ecx |
mov [dlye], edx |
pop edx ecx eax |
sub eax, ecx |
sub ebx, edx |
mov esi, [MOUSE_X] |
mov [WIN_TEMP_XY], esi |
pushad ; wait for putimages to finish |
; mov ebx,5 |
; call delay_hs |
mov eax,[edi + WDATA.box.left] |
mov [npx],eax |
mov eax,[edi + WDATA.box.top] |
mov [npy],eax |
popad |
push eax ; save old coordinates |
mov ax, word [edi + WDATA.box.left] |
mov word [oldc+BOX.left],ax |
mov ax, word [edi + WDATA.box.top] |
mov word [oldc+BOX.top],ax |
mov ax, word [edi + WDATA.box.width] |
mov word [oldc+BOX.width],ax |
mov word [npxe],ax |
mov ax, word [edi + WDATA.box.height] |
mov word [oldc+BOX.height],ax |
mov word [npye],ax |
pop eax |
call drawwindowframes |
mov [reposition],0 |
mov [MOUSE_DOWN],byte 1 ; no reaction to mouse up/down |
; move window |
newchm: |
mov [DONT_DRAW_MOUSE],byte 1 |
call checkidle |
call checkVga_N13 |
mov [MOUSE_BACKGROUND],byte 0 |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
mov esi,[WIN_TEMP_XY] |
cmp esi,[MOUSE_X] |
je cwb |
mov cx,[MOUSE_X] |
mov dx,[MOUSE_Y] |
sub cx,ax |
sub dx,bx |
push ax |
push bx |
call drawwindowframes |
mov ax,[Screen_Max_X] |
mov bx,[Screen_Max_Y] |
cmp [do_resize_from_corner],1 |
je no_new_position |
mov word [npx],word 0 ; x repos ? |
cmp ax,cx |
jb noreposx |
mov [reposition],1 |
sub ax,word [npxe] |
mov word [npx],ax |
cmp ax,cx |
jb noreposx |
mov word [npx],cx |
noreposx: |
mov word [npy],word 0 ; y repos ? |
cmp bx,dx |
jb noreposy |
mov [reposition],1 |
sub bx,word [npye] |
mov word [npy],bx |
cmp bx,dx |
jb noreposy |
mov word [npy],dx |
noreposy: |
no_new_position: |
cmp [do_resize_from_corner],0 ; resize from right corner |
je norepos_size |
pushad |
mov edx,edi |
sub edx,window_data |
;shr edx,5 |
;shl edx,8 |
;add edx,0x80000 ; process base at 0x80000+ |
lea edx, [SLOT_BASE + edx*8] |
movzx eax,word [MOUSE_X] |
cmp eax,[edi + WDATA.box.left] |
jb nnepx |
sub eax,[edi + WDATA.box.left] |
cmp eax,32 ; [edx+0x90+8] |
jge nnepx2 |
mov eax,32 ; [edx+0x90+8] |
nnepx2: |
mov [npxe],eax |
nnepx: |
call get_rolledup_height |
mov ebx,eax |
movzx eax,word [MOUSE_Y] |
cmp eax,[edi + WDATA.box.top] |
jb nnepy |
sub eax,[edi + WDATA.box.top] |
cmp eax,ebx ; [edx+0x90+12] |
jge nnepy2 |
mov eax,ebx ; [edx+0x90+12] |
nnepy2: |
mov [npye],eax |
nnepy: |
mov [reposition],1 |
popad |
norepos_size: |
pop bx |
pop ax |
call drawwindowframes |
mov esi,[MOUSE_X] |
mov [WIN_TEMP_XY],esi |
cwb: |
cmp [BTN_DOWN],byte 0 |
jne newchm |
; new position done |
mov [DONT_DRAW_MOUSE],byte 1 |
mov cl,0 |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz @f |
mov cl,[reposition] |
call drawwindowframes |
mov eax,[npx] |
mov [edi + WDATA.box.left],eax |
mov eax,[npy] |
mov [edi + WDATA.box.top],eax |
mov eax,[npxe] |
mov [edi + WDATA.box.width],eax |
mov eax,[npye] |
mov [edi + WDATA.box.height],eax |
call set_window_clientbox |
@@: mov [reposition],cl |
cmp [reposition],1 ; save new position and size |
jne no_bounds_save |
push esi edi ecx |
mov esi,edi |
mov ecx,2 |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED |
jnz @f |
add ecx,2 |
@@: sub edi,window_data |
shr edi,5 |
shl edi,8 |
add edi,SLOT_BASE+APPDATA.saved_box |
cld |
rep movsd |
pop ecx edi esi |
no_bounds_save: |
pushad ; WINDOW SHADE/FULLSCREEN |
;{doule click not worked for 4 type window} |
mov edx, [edi + WDATA.cl_workarea] |
and edx, 0x0f000000 |
cmp edx, 0x00000000 |
je no_fullscreen_restore |
cmp edx, 0x01000000 |
je no_fullscreen_restore |
cmp [reposition],1 |
je no_window_sizing |
mov edx,edi |
sub edx,window_data |
shr edx,5 |
shl edx,8 |
add edx,SLOT_BASE ; process base at 0x80000+ |
cmp [do_resize],2 ; window shade ? |
jne no_window_shade |
mov [reposition],1 |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz wnd_rolldown |
wnd_rollup: |
or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
call get_rolledup_height |
jmp @f |
wnd_rolldown: |
and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP |
mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jz @f |
mov eax,[screen_workarea.bottom] |
sub eax,[screen_workarea.top] |
@@: mov [edi+WDATA.box.height],eax |
add eax, [edi+WDATA.box.top] |
cmp eax, [Screen_Max_Y] |
jbe @f |
mov eax, [Screen_Max_Y] |
sub eax, [edi+WDATA.box.height] |
mov [edi+WDATA.box.top], eax |
@@: call check_window_position |
call set_window_clientbox |
no_window_shade: |
push edx |
mov edx, [edi + WDATA.cl_workarea] |
and edx, 0x0f000000 |
cmp edx, 0x04000000 |
pop edx |
je no_fullscreen_restore |
cmp [do_resize],1 ; fullscreen/restore ? |
jne no_fullscreen_restore |
cmp [latest_window_touch_delta],dword 50 |
jg no_fullscreen_restore |
mov [reposition],1 |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz restore_from_fullscreen |
or [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
mov eax,[screen_workarea.left] |
mov [edi+WDATA.box.left],eax |
sub eax,[screen_workarea.right] |
neg eax |
mov [edi+WDATA.box.width],eax |
mov eax,[screen_workarea.top] |
mov [edi+WDATA.box.top],eax |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz @f |
sub eax,[screen_workarea.bottom] |
neg eax |
mov [edi+WDATA.box.height],eax |
@@: |
jmp restore_from_fullscreen.clientbox |
restore_from_fullscreen: |
and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED |
push [edi+WDATA.box.height] |
push edi ; restore |
lea esi, [edx + APPDATA.saved_box] |
mov ecx,4 |
cld |
rep movsd |
pop edi |
pop eax |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jz @f |
mov [edi+WDATA.box.height],eax |
@@: |
.clientbox: |
call set_window_clientbox |
no_fullscreen_restore: |
mov eax,[edi+WDATA.box.top] ; check Y inside screen |
add eax,[edi+WDATA.box.height] |
cmp eax,[Screen_Max_Y] |
jbe no_window_sizing |
mov eax,[edi+WDATA.box.left] ; check X inside screen |
add eax,[edi+WDATA.box.width] |
cmp eax,[Screen_Max_X] |
jbe no_window_sizing |
mov eax,[Screen_Max_X] |
sub eax,[edi+WDATA.box.width] |
mov [edi+WDATA.box.left],eax |
mov eax,[Screen_Max_Y] |
sub eax,[edi+WDATA.box.height] |
mov [edi+WDATA.box.top],eax |
call set_window_clientbox |
no_window_sizing: |
popad |
cmp [reposition],0 |
je retwm |
mov [DONT_DRAW_MOUSE],byte 1 ; no mouse |
push eax ebx ecx edx |
mov eax,[edi+WDATA.box.left] |
mov ebx,[edi+WDATA.box.top] |
mov ecx,[edi+WDATA.box.width] |
mov edx,[edi+WDATA.box.height] |
add ecx,eax |
add edx,ebx |
call calculatescreen |
mov eax,[oldc+BOX.left] |
mov ebx,[oldc+BOX.top] |
mov ecx,[oldc+BOX.width] |
mov edx,[oldc+BOX.height] |
add ecx,eax |
add edx,ebx |
call calculatescreen |
pop edx ecx ebx eax |
mov eax,edi |
call redrawscreen |
mov [edi+WDATA.fl_redraw],1 |
mov ecx,100 ; wait to avoid mouse residuals |
waitre2: |
mov [DONT_DRAW_MOUSE],byte 1 |
call checkidle |
cmp [edi+WDATA.fl_redraw],0 |
jz retwm |
loop waitre2 |
retwm: |
mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
mov [MOUSE_DOWN],byte 0 ; react to mouse up/down |
; mov esi,window_moved |
; call sys_msg_board_str |
popad |
ret |
uglobal |
add_window_data dd 0 |
do_resize_from_corner db 0x0 |
reposition db 0x0 |
latest_window_touch dd 0x0 |
latest_window_touch_delta dd 0x0 |
do_resize db 0x0 |
oldc dd 0x0,0x0,0x0,0x0 |
dlx dd 0x0 |
dly dd 0x0 |
dlxe dd 0x0 |
dlye dd 0x0 |
npx dd 0x0 |
npy dd 0x0 |
npxe dd 0x0 |
npye dd 0x0 |
mpx dd 0x0 |
mpy dd 0x0 |
endg |
; draw negative window frames |
drawwindowframes2: |
pushad |
cli |
jmp drawwindowframes.do |
drawwindowframes: |
pushad |
cli |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz .ret |
mov eax, [npx] |
cmp eax, [edi+WDATA.box.left] |
jnz .nowndframe |
mov eax, [npxe] |
cmp eax, [edi+WDATA.box.width] |
jnz .nowndframe |
mov eax, [npy] |
cmp eax, [edi+WDATA.box.top] |
jnz .nowndframe |
mov eax, [npye] |
cmp eax, [edi+WDATA.box.height] |
jnz .nowndframe |
xor [edi+WDATA.fl_wdrawn], 2 |
test [edi+WDATA.fl_wdrawn], 4 |
jnz .ret |
.nowndframe: |
.do: |
mov edi, 1 |
mov ecx, 0x01000000 |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
add eax,65536*1-1 |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
call [draw_line] |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
add eax,65536*1-1 |
mov ebx,[npy] |
add ebx,[npye] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
call [draw_line] |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
call [draw_line] |
mov eax,[npx] |
add eax,[npxe] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
call [draw_line] |
.ret: |
sti |
popad |
ret |
random_shaped_window: |
; |
; eax = 0 giving address of data area |
; ebx address |
; eax = 1 shape area scale |
; ebx 2^ebx scale |
test eax, eax |
jne rsw_no_address |
mov eax,[current_slot] |
mov [eax+APPDATA.wnd_shape],ebx |
rsw_no_address: |
cmp eax,1 |
jne rsw_no_scale |
mov eax,[current_slot] |
mov byte [eax+APPDATA.wnd_shape_scale], bl |
rsw_no_scale: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/event.inc |
---|
0,0 → 1,487 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
uglobal |
align 4 |
event_start dd ? |
event_end dd ? |
event_uid dd 0 |
endg |
EV_SPACE = 512 |
FreeEvents = event_start-EVENT.fd ; "âèðòóàëüíûé" event, èñïîëüçóþòñÿ òîëüêî ïîëÿ: |
; FreeEvents.fd=event_start è FreeEvents.bk=event_end |
align 4 |
init_events: ;; used from kernel.asm |
stdcall kernel_alloc,EV_SPACE*EVENT.size |
or eax,eax |
jz .fail |
; eax - current event, ebx - previos event below |
mov ecx,EV_SPACE ; current - in allocated space |
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà |
push ebx ; îíî æå è êîíåö ïîòîì áóäåò |
@@: mov [ebx+EVENT.fd],eax |
mov [eax+EVENT.bk],ebx |
mov ebx,eax ; previos <- current |
add eax,EVENT.size ; new current |
loop @b |
pop eax ; âîò îíî êîíöîì è ñòàëî |
mov [ebx+EVENT.fd],eax |
mov [eax+EVENT.bk],ebx |
.fail: ret |
EVENT_WATCHED equ 0x10000000 ;áèò 28 |
EVENT_SIGNALED equ 0x20000000 ;áèò 29 |
MANUAL_RESET equ 0x40000000 ;áèò 30 |
MANUAL_DESTROY equ 0x80000000 ;áèò 31 |
align 4 |
create_event: ;; EXPORT use |
;info: |
; Ïåðåíîñèì EVENT èç ñïèñêà FreeEvents â ñïèñîê ObjList òåêóùåãî ñëîòà |
; EVENT.state óñòàíàâëèâàåì èç ecx, EVENT.code êîñâåííî èç esi (åñëè esi<>0) |
;param: |
; esi - event data |
; ecx - flags |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;scratched: ebx,ecx,esi,edi |
mov ebx,[current_slot] |
add ebx,APP_OBJ_OFFSET |
mov edx,[TASK_BASE] |
mov edx,[edx+TASKDATA.pid] |
pushfd |
cli |
set_event: ;; INTERNAL use !!! don't use for Call |
;info: |
; Áåðåì íîâûé event èç FreeEvents, çàïîëíÿåì åãî ïîëÿ, êàê óêàçàíî â ecx,edx,esi |
; è óñòàíàâëèâàåì â ñïèñîê, óêàçàííûé â ebx. |
; Âîçâðàùàåì ñàì event (â eax), è åãî uid (â edx) |
;param: |
; ebx - start-chain "virtual" event for entry new event Right of him |
; ecx - flags (copied to EVENT.state) |
; edx - pid (copied to EVENT.pid) |
; esi - event data (copied to EVENT.code indirect, =0 => skip) |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;scratched: ebx,ecx,esi,edi |
mov eax,FreeEvents |
cmp eax,[eax+EVENT.fd] |
jne @f ; not empty ??? |
pushad |
call init_events |
popad |
jz RemoveEventTo.break ; POPF+RET |
@@: mov eax,[eax+EVENT.fd] |
mov [eax+EVENT.magic],'EVNT' |
mov [eax+EVENT.destroy],destroy_event.internal |
mov [eax+EVENT.state],ecx |
mov [eax+EVENT.pid],edx |
inc [event_uid] |
Mov [eax+EVENT.id],edx,[event_uid] |
or esi,esi |
jz RemoveEventTo |
lea edi,[eax+EVENT.code] |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
RemoveEventTo: ;; INTERNAL use !!! don't use for Call |
;param: |
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì |
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì |
;scratched: ebx,ecx |
mov ecx,eax ; ecx=eax=Self, ebx=NewLeft |
xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight |
cmp eax,ecx ; ñòîï, ñåáå äóìàþ... |
je .break ; - à íå äóðàê ëè ÿ? |
mov [ecx+EVENT.bk],eax ; NewRight.bk=Self |
xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft |
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight |
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight |
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft |
.break: popfd |
ret |
align 4 |
NotDummyTest: ;; INTERNAL use (not returned for fail !!!) |
pop edi |
call DummyTest ; not returned for fail !!! |
mov ebx,eax |
mov eax,[ebx+EVENT.pid] |
push edi |
.small: ; êðèâî êàê-òî... |
pop edi |
pushfd |
cli |
call pid_to_slot ; saved all registers (eax - retval) |
shl eax,8 |
jz RemoveEventTo.break ; POPF+RET |
jmp edi ; øòàòíûé âîçâðàò |
align 4 |
raise_event: ;; EXPORT use |
;info: |
; Óñòàíàâëèâàåì äàííûå EVENT.code |
; Åñëè òàì ôëàã EVENT_SIGNALED óæå àêòèâåí - áîëüøå íè÷åãî |
; Èíà÷å: ýòîò ôëàã âçâîäèòñÿ, çà èñêëþ÷åíèåì ñëó÷àÿ íàëè÷èÿ ôëàãà EVENT_WATCHED â edx |
;  ýòîì ñëó÷àå EVENT_SIGNALED âçâîäèòñÿ ëèøü ïðè íàëè÷èå EVENT_WATCHED â ñàìîì ñîáûòèè |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
; edx - flags |
; esi - event data (=0 => skip) |
;scratched: ebx,ecx,esi,edi |
call NotDummyTest ; not returned for fail !!! |
or esi,esi |
jz @f |
lea edi,[ebx+EVENT.code] |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
@@: |
test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz RemoveEventTo.break ; POPF+RET |
bt edx, 28 ;EVENT_WATCHED |
jnc @f |
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24 |
jz RemoveEventTo.break ; POPF+RET |
@@: |
or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 |
add eax,SLOT_BASE+APP_EV_OFFSET |
xchg eax,ebx |
jmp RemoveEventTo |
align 4 |
clear_event: ;; EXPORT use |
;info: |
; |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;scratched: ebx,ecx |
call NotDummyTest ; not returned for fail !!! |
add eax,SLOT_BASE+APP_OBJ_OFFSET |
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) |
xchg eax,ebx |
jmp RemoveEventTo |
align 4 |
send_event: ;; EXPORT use |
;info: |
; Ñîçäàåò íîâûé EVENT (âûòàñêèâàåò èç ñïèñêà FreeEvents) â ñïèñêå EventList |
; öåëåâîãî ñëîòà (eax=pid), ñ äàííûìè èç esi êîñâåííî, è state=EVENT_SIGNALED |
;param: |
; eax - slots pid, to sending new event |
; esi - pointer to sending data (in code field of new event) |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;warning: |
; may be used as CDECL with such prefix... |
; mov esi,[esp+8] |
; mov eax,[esp+4] |
; but not as STDCALL :( |
;scratched: ebx,ecx,esi,edi |
mov edx,eax |
call NotDummyTest.small ; not returned for fail !!! |
lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET] |
mov ecx,EVENT_SIGNALED |
jmp set_event |
align 4 |
DummyTest: ;; INTERNAL use (not returned for fail !!!) |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
cmp [eax+EVENT.magic],'EVNT' |
jne @f |
cmp [eax+EVENT.id],ebx |
je .ret |
@@: pop eax |
xor eax,eax |
.ret: ret |
align 4 |
Wait_events: |
or ebx,-1 ; infinite timeout |
Wait_events_ex: |
;info: |
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ. |
; Àáñòðàêòíîñòü çàêëþ÷åíà â òîì, ÷òî ôàêò ñîáûòèÿ îïðåäåëÿåòñÿ ôóíêöèåé APPDATA.wait_test, |
; êîòîðàÿ çàäàåòñÿ êëèåíòîì è ìîæåò áûòü ôàêòè÷åñêè ëþáîé. |
; Ýòî ïîçâîëÿåò shed-ó íàäåæíî îïðåäåëèòü ôàêò ñîáûòèÿ, è íå ñîâåðøàòü "õîëîñòûõ" ïåðåêëþ÷åíèé, |
; ïðåäíàçíà÷åííûõ äëÿ ðàçáîðîê òèïà "ñâîé/÷óæîé" âíóòðè çàäà÷è. |
;param: |
; edx - wait_test, êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ (àäðåñ êîäà) |
; ecx - wait_param, äîïîëíèòåëüíûé ïàðàìåòð, âîçìîæíî íåîáõîäèìûé äëÿ [wait_test] |
; ebx - wait_timeout |
;retval: |
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout) |
;scratched: esi |
mov esi,[current_slot] |
mov [esi+APPDATA.wait_param],ecx |
pushad |
mov ebx,esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call edx |
popfd |
mov [esp+28],eax |
popad |
or eax,eax |
jnz @f ;RET |
mov [esi+APPDATA.wait_test],edx |
mov [esi+APPDATA.wait_timeout],ebx |
Mov [esi+APPDATA.wait_begin],eax,[timer_ticks] |
mov eax,[TASK_BASE] |
mov [eax+TASKDATA.state], 5 |
call change_task |
mov eax,[esi+APPDATA.wait_param] |
@@: ret |
align 4 |
wait_event: ;; EXPORT use |
;info: |
; Îæèäàíèå ôëàãà EVENT_SIGNALED â ñîâåðøåííî êîíêðåòíîì Event |
; (óñòàíàâëèâàåìîãî, íàäî ïîëàãàòü, ÷åðåç raise_event) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;scratched: ecx,edx,esi |
call DummyTest |
mov ecx,eax ; wait_param |
mov edx, get_event_alone ; wait_test |
call Wait_events ; timeout ignored |
jmp wait_finish |
align 4 |
get_event_ex: ;; f68:14 |
;info: |
; Îæèäàíèå ëþáîãî ñîáûòèÿ â î÷åðåäè EventList òåêóùåãî ñëîòà |
; Äàííûå ñîáûòèÿ code - êîïèðóþòñÿ â ïàìÿòü ïðèëîæåíèÿ (êîñâåííî ïî edi) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; edi - àäðåñ â êîäå ïðèëîæåíèÿ äëÿ êîïèðîâàíèÿ äàííûõ èç EVENT.code |
;retval: |
; eax - ñîáñòâåííî EVENT (áóäåì íàçûâàòü ýòî åãî õýíäëîì) |
;scratched: ebx,ecx,edx,esi,edi |
mov edx, get_event_queue ; wait_test |
call Wait_events ; timeout ignored |
lea esi,[eax+EVENT.code] |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
mov [edi-EVENT.codesize+2],cl ;clear priority field |
wait_finish: |
test byte[eax+EVENT.state+3], MANUAL_RESET shr 24 |
jnz get_event_queue.ret ; RET |
and byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) |
test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24 |
jz destroy_event.internal |
mov ebx,[current_slot] |
add ebx,APP_OBJ_OFFSET |
pushfd |
cli |
jmp RemoveEventTo |
align 4 |
destroy_event: ;; EXPORT use |
;info: |
; Ïåðåíîñèì EVENT â ñïèñîê FreeEvents, ÷èñòèì ïîëÿ magic,destroy,pid,id |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
;scratched: ebx,ecx |
call DummyTest ; not returned for fail !!! |
.internal: |
xor ecx,ecx ; clear common header |
pushfd |
cli |
mov [eax+EVENT.magic],ecx |
mov [eax+EVENT.destroy],ecx |
mov [eax+EVENT.pid],ecx |
mov [eax+EVENT.id],ecx |
mov ebx,FreeEvents |
jmp RemoveEventTo |
align 4 |
get_event_queue: |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ get_event_ex |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
add ebx,APP_EV_OFFSET |
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO |
cmp eax,ebx ; empty ??? |
je get_event_alone.ret0 |
.ret: ret |
align 4 |
get_event_alone: |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ wait_event |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
mov eax,[ebx+APPDATA.wait_param] |
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz .ret |
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24 |
.ret0: xor eax,eax ; NO event!!! |
.ret: ret |
align 4 |
sys_sendwindowmsg: ;; f72 |
dec ebx |
jnz .ret ;subfunction==1 ? |
;pushfd ;à íàôèãà? |
cli |
sub ecx,2 |
je .sendkey |
loop .retf |
.sendbtn: |
cmp byte[BTN_COUNT],1 |
jae .result ;overflow |
inc byte[BTN_COUNT] |
mov [BTN_BUFF],edx |
jmp .result |
.sendkey: |
movzx eax,byte[KEY_COUNT] |
cmp al,120 |
jae .result ;overflow |
inc byte[KEY_COUNT] |
mov [KEY_COUNT+1+eax],dl |
.result: |
setae byte[esp+32] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32]==72 |
.retf: ;popfd |
.ret: ret |
align 4 |
sys_getevent: ;; f11 |
mov ebx,[current_slot] ;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call get_event_for_app |
popfd |
mov [esp+32],eax |
ret |
align 4 |
sys_waitforevent: ;; f10 |
or ebx,-1 ; infinite timeout |
sys_wait_event_timeout: ;; f23 |
mov edx,get_event_for_app ; wait_test |
call Wait_events_ex ; ebx - timeout |
mov [esp+32],eax |
ret |
align 4 |
get_event_for_app: ;; used from f10,f11,f23 |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ ïðèëîæåíèé (f10,f23) |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - íîìåð ñîáûòèÿ (=0 => no events) |
movzx edi,bh ; bh is assumed as [CURRENT_TASK] |
shl edi,5 |
add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE] |
mov ecx,[edi+TASKDATA.event_mask] |
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè |
bsr eax,ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0) |
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ??? |
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè |
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà |
cmp eax,16 |
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15 |
cmp eax,9 |
jae .loop ; eax=[9..15], ignored |
cmp eax,3 |
je .loop ; eax=3, ignored |
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1 |
cmp eax,1 |
jae .BtKy ; eax=[1,2], retvals=eax+1 |
.WndRedraw: ; eax=0, retval WndRedraw=1 |
cmp [edi-twdw+WDATA.fl_redraw],al ;al==0 |
jne .result |
jmp .loop |
.no_events: |
xor eax,eax |
ret |
.IRQ: |
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) |
mov edx,[irq_owner+eax*4-64] ; eax==16+irq |
cmp edx,[edi+TASKDATA.pid] |
jne .loop |
mov edx,eax |
shl edx,12 |
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000 |
je .loop ; empty ??? |
ret ; retval = eax |
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9 |
btr [ebx+APPDATA.event_mask],eax |
jnc .loop |
.result: ; retval = eax+1 |
inc eax |
ret |
.BtKy: |
movzx edx,bh |
movzx edx, word[WIN_STACK+edx*2] |
je .Keys ; eax=1, retval Keys=2 |
.Buttons: ; eax=2, retval Buttons=3 |
cmp byte[BTN_COUNT],0 |
je .loop ; empty ??? |
cmp edx,[TASK_COUNT] |
jne .loop ; not Top ??? |
cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form |
jne .result |
mov [window_minimize],1 |
dec byte[BTN_COUNT] |
jmp .loop |
.Keys: ; eax==1 |
cmp edx,[TASK_COUNT] |
jne @f ; not Top ??? |
cmp [KEY_COUNT],al ; al==1 |
jae .result ; not empty ??? |
@@: mov edx, hotkey_buffer |
@@: cmp [edx],bh ; bh - slot for testing |
je .result |
add edx,8 |
cmp edx, hotkey_buffer+120*8 |
jb @b |
jmp .loop |
;end. |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/mouse.inc |
---|
0,0 → 1,250 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
align 4 |
mousepointer: |
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f |
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 |
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 |
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 |
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 |
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 |
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f |
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 |
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e |
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a |
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 |
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 |
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 |
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c |
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 |
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d |
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 |
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e |
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 |
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 |
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d |
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 |
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a |
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c |
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 |
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 |
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 |
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 |
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 |
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 |
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d |
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a |
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff |
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 |
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 |
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 |
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 |
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 |
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f |
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 |
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e |
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f |
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 |
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 |
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 |
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b |
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f |
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 |
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 |
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 |
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b |
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a |
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f |
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e |
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80 |
mousepointer1: |
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a |
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 |
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e |
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f |
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 |
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 |
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c |
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c |
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c |
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 |
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 |
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 |
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 |
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 |
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 |
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 |
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e |
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 |
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 |
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a |
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 |
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 |
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d |
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 |
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 |
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00 |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/skincode.inc |
---|
0,0 → 1,467 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
include "skindata.inc" |
;skin_data = 0x00778000 |
read_skin_file: |
stdcall load_file, ebx |
test eax, eax |
jz .notfound |
cmp dword [eax], 'SKIN' |
jnz .noskin |
cmp ebx, 32*1024 |
jb @f |
mov ebx, 32*1024 |
@@: |
lea ecx, [ebx+3] |
shr ecx, 2 |
mov esi, eax |
mov edi, skin_data |
rep movsd |
stdcall kernel_free, eax |
call parse_skin_data |
xor eax, eax |
ret |
.notfound: |
xor eax, eax |
inc eax |
ret |
.noskin: |
stdcall kernel_free, eax |
push 2 |
pop eax |
ret |
struct SKIN_HEADER |
.ident dd ? |
.version dd ? |
.params dd ? |
.buttons dd ? |
.bitmaps dd ? |
ends |
struct SKIN_PARAMS |
.skin_height dd ? |
.margin.right dw ? |
.margin.left dw ? |
.margin.bottom dw ? |
.margin.top dw ? |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.colors_1.inner dd ? |
.colors_1.outer dd ? |
.colors_1.frame dd ? |
.dtp.size dd ? |
.dtp.data db 40 dup (?) |
ends |
struct SKIN_BUTTONS |
.type dd ? |
.pos: |
.left dw ? |
.top dw ? |
.size: |
.width dw ? |
.height dw ? |
ends |
struct SKIN_BITMAPS |
.kind dw ? |
.type dw ? |
.data dd ? |
ends |
load_default_skin: |
mov [_skinh],22 |
mov ebx,_skin_file_default |
call read_skin_file |
ret |
parse_skin_data: |
mov ebp,skin_data |
cmp [ebp+SKIN_HEADER.ident],'SKIN' |
jne .exit |
mov edi,skin_udata |
mov ecx,(skin_udata.end-skin_udata)/4 |
xor eax,eax |
cld |
rep stosd |
mov ebx,[ebp+SKIN_HEADER.params] |
add ebx,skin_data |
mov eax,[ebx+SKIN_PARAMS.skin_height] |
mov [_skinh],eax |
mov eax,[ebx+SKIN_PARAMS.colors.inner] |
mov [skin_active.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors.outer] |
mov [skin_active.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors.frame] |
mov [skin_active.colors.frame],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.inner] |
mov [skin_inactive.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.outer] |
mov [skin_inactive.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.frame] |
mov [skin_inactive.colors.frame],eax |
lea esi,[ebx+SKIN_PARAMS.dtp.data] |
mov edi,common_colours |
mov ecx,[ebx+SKIN_PARAMS.dtp.size] |
and ecx,127 |
rep movsb |
mov eax,dword[ebx+SKIN_PARAMS.margin.right] |
mov dword[_skinmargins+0],eax |
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] |
mov dword[_skinmargins+4],eax |
mov ebx,[ebp+SKIN_HEADER.bitmaps] |
add ebx,skin_data |
.lp1: cmp dword[ebx],0 |
je .end_bitmaps |
movzx eax,[ebx+SKIN_BITMAPS.kind] |
movzx ecx,[ebx+SKIN_BITMAPS.type] |
dec eax |
jnz .not_left |
xor eax,eax |
mov edx,skin_active.left.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.left.data |
@@: jmp .next_bitmap |
.not_left: |
dec eax |
jnz .not_oper |
mov esi,[ebx+SKIN_BITMAPS.data] |
add esi,skin_data |
mov eax,[esi+0] |
neg eax |
mov edx,skin_active.oper.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.oper.data |
@@: jmp .next_bitmap |
.not_oper: |
dec eax |
jnz .not_base |
mov eax,[skin_active.left.width] |
mov edx,skin_active.base.data |
or ecx,ecx |
jnz @f |
mov eax,[skin_inactive.left.width] |
mov edx,skin_inactive.base.data |
@@: jmp .next_bitmap |
.not_base: |
add ebx,8 |
jmp .lp1 |
.next_bitmap: |
mov ecx,[ebx+SKIN_BITMAPS.data] |
add ecx,skin_data |
mov [edx+4],eax |
mov eax,[ecx+0] |
mov [edx+8],eax |
add ecx,8 |
mov [edx+0],ecx |
add ebx,8 |
jmp .lp1 |
.end_bitmaps: |
mov ebx,[ebp+SKIN_HEADER.buttons] |
add ebx,skin_data |
.lp2: cmp dword[ebx],0 |
je .end_buttons |
mov eax,[ebx+SKIN_BUTTONS.type] |
dec eax |
jnz .not_close |
mov edx,skin_btn_close |
jmp .next_button |
.not_close: |
dec eax |
jnz .not_minimize |
mov edx,skin_btn_minimize |
jmp .next_button |
.not_minimize: |
add ebx,12 |
jmp .lp2 |
.next_button: |
movsx eax,[ebx+SKIN_BUTTONS.left] |
mov [edx+SKIN_BUTTON.left],eax |
movsx eax,[ebx+SKIN_BUTTONS.top] |
mov [edx+SKIN_BUTTON.top],eax |
movsx eax,[ebx+SKIN_BUTTONS.width] |
mov [edx+SKIN_BUTTON.width],eax |
movsx eax,[ebx+SKIN_BUTTONS.height] |
mov [edx+SKIN_BUTTON.height],eax |
add ebx,12 |
jmp .lp2 |
.end_buttons: |
.exit: |
ret |
sys_putimage_with_check: |
or ebx,ebx |
jz @f |
call sys_putimage.forced |
@@: ret |
drawwindow_IV_caption: |
mov ebp,skin_active |
or al,al |
jnz @f |
mov ebp,skin_inactive |
@@: |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] ; window width |
mov edx,[ebp+SKIN_DATA.left.left] |
shl edx,16 |
mov ecx,[ebp+SKIN_DATA.left.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov ebx, [ebp+SKIN_DATA.left.data] |
call sys_putimage_with_check |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] |
sub eax,[ebp+SKIN_DATA.left.width] |
sub eax,[ebp+SKIN_DATA.oper.width] |
cmp eax,[ebp+SKIN_DATA.base.left] |
jng .non_base |
xor edx,edx |
mov ecx,[ebp+SKIN_DATA.base.width] |
jecxz .non_base |
div ecx |
inc eax |
mov ebx,[ebp+SKIN_DATA.base.data] |
mov ecx,[ebp+SKIN_DATA.base.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov edx,[ebp+SKIN_DATA.base.left] |
sub edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
.baseskinloop: |
shr edx,16 |
add edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
push eax ebx ecx edx |
call sys_putimage_with_check |
pop edx ecx ebx eax |
dec eax |
jnz .baseskinloop |
.non_base: |
mov esi,[esp+4] |
mov edx,[esi+WDATA.box.width] |
sub edx,[ebp+SKIN_DATA.oper.width] |
inc edx |
shl edx,16 |
mov ebx,[ebp+SKIN_DATA.oper.data] |
mov ecx,[ebp+SKIN_DATA.oper.width] |
shl ecx,16 |
add ecx,[_skinh] |
call sys_putimage_with_check |
ret |
;//mike.dld, 2006-08-02 ] |
drawwindow_IV: |
;param1 - aw_yes |
pusha |
push edx |
mov edi,edx |
mov ebp,skin_active |
cmp byte [esp+32+4+4],0 |
jne @f |
mov ebp,skin_inactive |
@@: |
mov eax,[edi+WDATA.box.left] |
shl eax,16 |
mov ax,word [edi+WDATA.box.left] |
add ax,word [edi+WDATA.box.width] |
mov ebx,[edi+WDATA.box.top] |
shl ebx,16 |
mov bx,word [edi+WDATA.box.top] |
add bx,word [edi+WDATA.box.height] |
; mov esi,[edi+24] |
; shr esi,1 |
; and esi,0x007f7f7f |
mov esi,[ebp+SKIN_DATA.colors.outer] |
or [edi+WDATA.fl_wdrawn], 4 |
call draw_rectangle |
mov ecx,3 |
_dw3l: |
add eax,1*65536-1 |
add ebx,1*65536-1 |
test ax,ax |
js no_skin_add_button |
test bx,bx |
js no_skin_add_button |
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24] |
call draw_rectangle |
dec ecx |
jnz _dw3l |
mov esi,[ebp+SKIN_DATA.colors.inner] |
add eax,1*65536-1 |
add ebx,1*65536-1 |
test ax,ax |
js no_skin_add_button |
test bx,bx |
js no_skin_add_button |
call draw_rectangle |
cmp dword[skin_data],'SKIN' |
je @f |
xor eax,eax |
xor ebx,ebx |
mov esi,[esp] |
mov ecx,[esi+WDATA.box.width] |
inc ecx |
mov edx,[_skinh] |
mov edi,[common_colours+4] ; standard grab color |
call [drawbar] |
jmp draw_clientbar |
@@: |
mov al,[esp+32+4+4] |
call drawwindow_IV_caption |
draw_clientbar: |
mov esi,[esp] |
mov edx,[esi+WDATA.box.top] ; WORK AREA |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg _noinside2 |
mov eax,5 |
mov ebx,[_skinh] |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
sub ecx,4 |
sub edx,4 |
mov edi,[esi+WDATA.cl_workarea] |
test edi,0x40000000 |
jnz _noinside2 |
call [drawbar] |
_noinside2: |
cmp dword[skin_data],'SKIN' |
jne no_skin_add_button |
;* close button |
mov edi,[BTN_ADDR] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[CURRENT_TASK] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,1 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_close.left],0 |
jge _bCx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bCx_at_right: |
add ebx,[skin_btn_close.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_close.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_close.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_close.height] |
dec ebx |
mov [eax],bx |
;* minimize button |
mov edi,[BTN_ADDR] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[CURRENT_TASK] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,65535 ;999 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_minimize.left],0 |
jge _bMx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bMx_at_right: |
add ebx,[skin_btn_minimize.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_minimize.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_minimize.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_minimize.height] |
dec ebx |
mov [eax],bx |
no_skin_add_button: |
pop edi |
and [edi+WDATA.fl_wdrawn], not 4 |
test [edi+WDATA.fl_wdrawn], 2 |
jz @f |
call drawwindowframes2 |
@@: |
popa |
ret 4 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui/skindata.inc |
---|
0,0 → 1,64 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; |
; WINDOW SKIN DATA |
; |
iglobal |
_skin_file_default db '/sys/DEFAULT.SKN',0 |
endg |
struct SKIN_DATA |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.left.data dd ? |
.left.left dd ? |
.left.width dd ? |
.oper.data dd ? |
.oper.left dd ? |
.oper.width dd ? |
.base.data dd ? |
.base.left dd ? |
.base.width dd ? |
ends |
struct SKIN_BUTTON |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
ends |
uglobal |
align 4 |
skin_udata: |
_skinh dd ? |
_skinmargins: ; rw 4 |
.right dw ? |
.left dw ? |
.bottom dw ? |
.top dw ? |
skin_btn_close SKIN_BUTTON |
skin_btn_minimize SKIN_BUTTON |
skin_active SKIN_DATA |
skin_inactive SKIN_DATA |
align 4 |
skin_udata.end: |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/gui |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/3c59x.inc |
---|
0,0 → 1,2378 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;; Copyright (c) 2004, Endre Kozma <endre.kozma@axelero.hu> |
;; All rights reserved. |
;; |
;; Redistribution and use in source and binary forms, with or without |
;; modification, are permitted provided that the following conditions are |
;; met: |
;; |
;; 1. Redistributions of source code must retain the above copyright notice, |
;; this list of conditions and the following disclaimer. |
;; |
;; 2. 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. |
;; |
;; 3. The name of the author may not be used to endorse or promote products |
;; derived from this software without specific prior written permission. |
;; |
;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 3C59X.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Driver for 3Com fast etherlink 3c59x and ;; |
;; etherlink XL 3c900 and 3c905 cards ;; |
;; References: ;; |
;; www.3Com.com - data sheets ;; |
;; DP83840A.pdf - ethernet physical layer ;; |
;; 3c59x.c - linux driver ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; Credits ;; |
;; Mike Hibbett, ;; |
;; who kindly supplied me with a 3Com905C-TX-M card ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; History |
;; ======= |
;; $Log: 3C59X.INC,v $ |
;; Revision 1.3 2004/07/11 12:21:12 kozma |
;; Support of vortex chips (3c59x) added. |
;; Support of 3c920 and 3c982 added. |
;; Corrections. |
;; |
;; Revision 1.2 2004/06/12 19:40:20 kozma |
;; Function e3c59x_set_available_media added in order to set |
;; the default media in case auto detection finds no valid link. |
;; Incorrect mii check removed (3c900 Cyclone works now). |
;; Cleanups. |
;; |
;; Revision 1.1 2004/06/12 18:27:15 kozma |
;; Initial revision |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; comment the next line out if you don't want debug info printed |
; on the debug board. This option adds a lot of bytes to the driver |
; so it's worth to comment it out. |
; E3C59X_DEBUG equ 1 |
; forcing full duplex mode makes sense at some cards and link types |
E3C59X_FORCE_FD equ 1 |
macro virt_to_dma reg |
{ |
sub reg, OS_BASE |
} |
macro dma_to_virt reg |
{ |
add reg, OS_BASE |
} |
macro zero_to_virt reg |
{ |
} |
macro virt_to_zero reg |
{ |
} |
macro zero_to_dma reg |
{ |
sub reg, OS_BASE |
} |
macro dma_to_zero reg |
{ |
add reg, OS_BASE |
} |
macro strtbl name, [string] |
{ |
common |
label name dword |
forward |
local label |
dd label |
forward |
label db string, 0 |
} |
; Ethernet frame symbols |
ETH_ALEN equ 6 |
ETH_HLEN equ (2*ETH_ALEN+2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
; PCI programming |
PCI_REG_COMMAND equ 0x4 ; command register |
PCI_REG_STATUS equ 0x6 ; status register |
PCI_REG_LATENCY equ 0xd ; latency timer register |
PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer |
PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block |
PCI_REG_PM_STATUS equ 0x4 ; power management status register |
PCI_REG_PM_CTRL equ 0x4 ; power management control register |
PCI_BIT_PIO equ 0 ; bit0: io space control |
PCI_BIT_MMIO equ 1 ; bit1: memory space control |
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
; Registers |
E3C59X_REG_POWER_MGMT_CTRL equ 0x7c |
E3C59X_REG_UP_LIST_PTR equ 0x38 |
E3C59X_REG_UP_PKT_STATUS equ 0x30 |
E3C59X_REG_TX_FREE_THRESH equ 0x2f |
E3C59X_REG_DN_LIST_PTR equ 0x24 |
E3C59X_REG_DMA_CTRL equ 0x20 |
E3C59X_REG_TX_STATUS equ 0x1b |
E3C59X_REG_RX_STATUS equ 0x18 |
E3C59X_REG_TX_DATA equ 0x10 |
; Common window registers |
E3C59X_REG_INT_STATUS equ 0xe |
E3C59X_REG_COMMAND equ 0xe |
; Register window 7 |
E3C59X_REG_MASTER_STATUS equ 0xc |
E3C59X_REG_POWER_MGMT_EVENT equ 0xc |
E3C59X_REG_MASTER_LEN equ 0x6 |
E3C59X_REG_VLAN_ETHER_TYPE equ 0x4 |
E3C59X_REG_VLAN_MASK equ 0x0 |
E3C59X_REG_MASTER_ADDRESS equ 0x0 |
; Register window 6 |
E3C59X_REG_BYTES_XMITTED_OK equ 0xc |
E3C59X_REG_BYTES_RCVD_OK equ 0xa |
E3C59X_REG_UPPER_FRAMES_OK equ 0x9 |
E3C59X_REG_FRAMES_DEFERRED equ 0x8 |
E3C59X_REG_FRAMES_RCVD_OK equ 0x7 |
E3C59X_REG_FRAMES_XMITTED_OK equ 0x6 |
E3C59X_REG_RX_OVERRUNS equ 0x5 |
E3C59X_REG_LATE_COLLISIONS equ 0x4 |
E3C59X_REG_SINGLE_COLLISIONS equ 0x3 |
E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2 |
E3C59X_REG_SQE_ERRORS equ 0x1 |
E3C59X_REG_CARRIER_LOST equ 0x0 |
; Register window 5 |
E3C59X_REG_INDICATION_ENABLE equ 0xc |
E3C59X_REG_INTERRUPT_ENABLE equ 0xa |
E3C59X_REG_TX_RECLAIM_THRESH equ 0x9 |
E3C59X_REG_RX_FILTER equ 0x8 |
E3C59X_REG_RX_EARLY_THRESH equ 0x6 |
E3C59X_REG_TX_START_THRESH equ 0x0 |
; Register window 4 |
E3C59X_REG_UPPER_BYTES_OK equ 0xe |
E3C59X_REG_BAD_SSD equ 0xc |
E3C59X_REG_MEDIA_STATUS equ 0xa |
E3C59X_REG_PHYSICAL_MGMT equ 0x8 |
E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6 |
E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4 |
E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported |
; Bits in register window 4 |
E3C59X_BIT_AUTOSELECT equ 24 |
; Register window 3 |
E3C59X_REG_TX_FREE equ 0xc |
E3C59X_REG_RX_FREE equ 0xa |
E3C59X_REG_MEDIA_OPTIONS equ 0x8 |
E3C59X_REG_MAC_CONTROL equ 0x6 |
E3C59X_REG_MAX_PKT_SIZE equ 0x4 |
E3C59X_REG_INTERNAL_CONFIG equ 0x0 |
; Register window 2 |
E3C59X_REG_RESET_OPTIONS equ 0xc |
E3C59X_REG_STATION_MASK_HI equ 0xa |
E3C59X_REG_STATION_MASK_MID equ 0x8 |
E3C59X_REG_STATION_MASK_LO equ 0x6 |
E3C59X_REG_STATION_ADDRESS_HI equ 0x4 |
E3C59X_REG_STATION_ADDRESS_MID equ 0x2 |
E3C59X_REG_STATION_ADDRESS_LO equ 0x0 |
; Register window 1 |
E3C59X_REG_TRIGGER_BITS equ 0xc |
E3C59X_REG_SOS_BITS equ 0xa |
E3C59X_REG_WAKE_ON_TIMER equ 0x8 |
E3C59X_REG_SMB_RXBYTES equ 0x7 |
E3C59X_REG_SMB_DIAG equ 0x5 |
E3C59X_REG_SMB_ARB equ 0x4 |
E3C59X_REG_SMB_STATUS equ 0x2 |
E3C59X_REG_SMB_ADDRESS equ 0x1 |
E3C59X_REG_SMB_FIFO_DATA equ 0x0 |
; Register window 0 |
E3C59X_REG_EEPROM_DATA equ 0xc |
E3C59X_REG_EEPROM_COMMAND equ 0xa |
E3C59X_REG_BIOS_ROM_DATA equ 0x8 |
E3C59X_REG_BIOS_ROM_ADDR equ 0x4 |
; Physical management bits |
E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData |
E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit |
E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock |
; MII commands |
E3C59X_MII_CMD_MASK equ (1111b shl 10) |
E3C59X_MII_CMD_READ equ (0110b shl 10) |
E3C59X_MII_CMD_WRITE equ (0101b shl 10) |
; MII registers |
E3C59X_REG_MII_BMCR equ 0 ; basic mode control register |
E3C59X_REG_MII_BMSR equ 1 ; basic mode status register |
E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register |
E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register |
E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register |
; MII bits |
E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete |
E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6 |
; eeprom bits and commands |
E3C59X_EEPROM_CMD_READ equ 0x80 |
E3C59X_EEPROM_BIT_BUSY equ 15 |
; eeprom registers |
E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa |
E3C59X_EEPROM_REG_CAPABILITIES equ 0x10 |
; Commands for command register |
E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11) |
IS_VORTEX equ 0x1 |
IS_BOOMERANG equ 0x2 |
IS_CYCLONE equ 0x4 |
IS_TORNADO equ 0x8 |
EEPROM_8BIT equ 0x10 |
HAS_PWR_CTRL equ 0x20 |
HAS_MII equ 0x40 |
HAS_NWAY equ 0x80 |
HAS_CB_FNS equ 0x100 |
INVERT_MII_PWR equ 0x200 |
INVERT_LED_PWR equ 0x400 |
MAX_COLLISION_RESET equ 0x800 |
EEPROM_OFFSET equ 0x1000 |
HAS_HWCKSM equ 0x2000 |
EXTRA_PREAMBLE equ 0x4000 |
iglobal |
align 4 |
e3c59x_hw_versions: |
dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps |
dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex |
dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex |
dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx |
dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4 |
dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII |
dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT |
dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo |
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO |
dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo |
dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC |
dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL |
dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx |
dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4 |
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx |
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC |
dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx |
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado |
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone |
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone |
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane |
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane |
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \ |
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado |
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \ |
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane |
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus |
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus |
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus |
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus |
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus |
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus |
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus |
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado |
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado |
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A |
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B |
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4 |
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado |
E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions |
endg |
; RX/TX buffers sizes |
E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size |
E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number |
E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number |
E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC) |
E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC) |
; Download Packet Descriptor |
E3C59X_DPD_DN_NEXT_PTR equ 0 |
E3C59X_DPD_FRAME_START_HDR equ 4 |
E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data |
E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data |
E3C59X_DPD_SIZE equ 16 ; a power of 2 number |
; Upload Packet Descriptor |
E3C59X_UPD_UP_NEXT_PTR equ 0 |
E3C59X_UPD_PKT_STATUS equ 4 |
E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data |
E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data |
E3C59X_UPD_SIZE equ 16 |
; RX/TX buffers |
if defined E3C59X_LINUX |
E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment |
e3c59x_rx_buff = 0 |
else |
E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment |
e3c59x_rx_buff = eth_data_start |
end if |
e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE |
e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE |
e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC) |
uglobal |
e3c59x_curr_upd: dd 0 |
e3c59x_prev_dpd: dd 0 |
e3c59x_prev_tx_frame: dd 0 |
e3c59x_transmit_function: dd 0 |
e3c59x_receive_function: dd 0 |
endg |
iglobal |
e3c59x_ver_id: db 17 |
endg |
uglobal |
e3c59x_full_bus_master: db 0 |
e3c59x_has_hwcksm: db 0 |
e3c59x_preamble: db 0 |
e3c59x_dn_list_ptr_cleared: db 0 |
e3c59x_self_directed_packet: rb 6 |
endg |
if defined E3C59X_DEBUG |
e3c59x_hw_type_str: db "Detected hardware type : ", 0 |
e3c59x_device_str: db "Device ID : 0x" |
e3c59x_device_id_str: db "ffff", 13, 10, 0 |
e3c59x_vendor_str: db "Vendor ID : 0x" |
e3c59x_vendor_id_str: db "ffff", 13, 10, 0 |
e3c59x_io_info_str: db "IO address : 0x" |
e3c59x_io_addr_str: db "ffff", 13, 10, 0 |
e3c59x_mac_info_str: db "MAC address : " |
e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0 |
e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0 |
e3c59x_vortex_str: db " (vortex)", 13, 10, 0 |
e3c59x_link_type_str: db "Established link type : ", 0 |
e3c59x_new_line_str: db 13, 10, 0 |
e3c59x_link_type: dd 0 |
e3c59x_charset: db '0123456789abcdef' |
strtbl e3c59x_link_str, \ |
"No valid link type detected", \ |
"10BASE-T half duplex", \ |
"10BASE-T full-duplex", \ |
"100BASE-TX half duplex", \ |
"100BASE-TX full duplex", \ |
"100BASE-T4", \ |
"100BASE-FX", \ |
"10Mbps AUI", \ |
"10Mbps COAX (BNC)", \ |
"miiDevice - not supported" |
strtbl e3c59x_hw_str, \ |
"3c590 Vortex 10Mbps", \ |
"3c592 EISA 10Mbps Demon/Vortex", \ |
"3c597 EISA Fast Demon/Vortex", \ |
"3c595 Vortex 100baseTx", \ |
"3c595 Vortex 100baseT4", \ |
"3c595 Vortex 100base-MII", \ |
"3c900 Boomerang 10baseT", \ |
"3c900 Boomerang 10Mbps Combo", \ |
"3c900 Cyclone 10Mbps TPO", \ |
"3c900 Cyclone 10Mbps Combo", \ |
"3c900 Cyclone 10Mbps TPC", \ |
"3c900B-FL Cyclone 10base-FL", \ |
"3c905 Boomerang 100baseTx", \ |
"3c905 Boomerang 100baseT4", \ |
"3c905B Cyclone 100baseTx", \ |
"3c905B Cyclone 10/100/BNC", \ |
"3c905B-FX Cyclone 100baseFx", \ |
"3c905C Tornado", \ |
"3c980 Cyclone", \ |
"3c982 Dual Port Server Cyclone", \ |
"3cSOHO100-TX Hurricane", \ |
"3c555 Laptop Hurricane", \ |
"3c556 Laptop Tornado", \ |
"3c556B Laptop Hurricane", \ |
"3c575 [Megahertz] 10/100 LAN CardBus", \ |
"3c575 Boomerang CardBus", \ |
"3CCFE575BT Cyclone CardBus", \ |
"3CCFE575CT Tornado CardBus", \ |
"3CCFE656 Cyclone CardBus", \ |
"3CCFEM656B Cyclone+Winmodem CardBus", \ |
"3CXFEM656C Tornado+Winmodem CardBus", \ |
"3c450 HomePNA Tornado", \ |
"3c920 Tornado", \ |
"3c982 Hydra Dual Port A", \ |
"3c982 Hydra Dual Port B", \ |
"3c905B-T4", \ |
"3c920B-EMB-WNM Tornado" |
end if ; defined E3C59X_DEBUG |
;*************************************************************************** |
; Function |
; e3c59x_debug |
; Description |
; prints debug info to the debug board |
; Parameters |
; ebp - io_addr |
; Return value |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
if defined E3C59X_DEBUG |
align 4 |
e3c59x_debug: |
pushad |
; print device type |
mov esi, e3c59x_hw_type_str |
call sys_msg_board_str |
movzx ecx, byte [e3c59x_ver_id] |
mov esi, [e3c59x_hw_str+ecx*4] |
call sys_msg_board_str |
mov esi, e3c59x_boomerang_str |
cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit |
jz .boomerang |
mov esi, e3c59x_vortex_str |
.boomerang: |
call sys_msg_board_str |
; print device/vendor |
mov ax, [pci_data+2] |
mov cl, 2 |
mov ebx, e3c59x_device_id_str |
call e3c59x_print_hex |
mov esi, e3c59x_device_str |
call sys_msg_board_str |
mov ax, [pci_data] |
mov cl, 2 |
mov ebx, e3c59x_vendor_id_str |
call e3c59x_print_hex |
mov esi, e3c59x_vendor_str |
call sys_msg_board_str |
; print io address |
mov ax, [io_addr] |
mov ebx, e3c59x_io_addr_str |
mov cl, 2 |
call e3c59x_print_hex |
mov esi, e3c59x_io_info_str |
call sys_msg_board_str |
; print MAC address |
mov ebx, e3c59x_mac_addr_str |
xor ecx, ecx |
.mac_loop: |
push ecx |
mov al, [node_addr+ecx] |
mov cl, 1 |
call e3c59x_print_hex |
inc ebx |
pop ecx |
inc cl |
cmp cl, 6 |
jne .mac_loop |
mov esi, e3c59x_mac_info_str |
call sys_msg_board_str |
; print link type |
mov esi, e3c59x_link_type_str |
call sys_msg_board_str |
xor eax, eax |
bsr ax, word [e3c59x_link_type] |
jz @f |
sub ax, 4 |
@@: |
mov esi, [e3c59x_link_str+eax*4] |
call sys_msg_board_str |
mov esi, e3c59x_new_line_str |
call sys_msg_board_str |
popad |
ret |
;*************************************************************************** |
; Function |
; e3c59x_print_hex |
; Description |
; prints a hexadecimal value |
; Parameters |
; eax - value to be printed out |
; ebx - where to print |
; cl - value size (1, 2, 4) |
; Return value |
; ebx - end address after the print |
; Destroyed registers |
; eax, ebx |
; |
;*************************************************************************** |
align 4 |
e3c59x_print_hex: |
cmp cl, 1 |
je .print_byte |
cmp cl, 2 |
jz .print_word |
.print_dword: |
push eax |
bswap eax |
xchg ah, al |
call .print_word |
pop eax |
.print_word: |
push eax |
xchg ah, al |
call .print_byte |
pop eax |
.print_byte: |
movzx eax, al |
push eax |
and al, 0xf0 |
shr al, 4 |
mov al, byte [eax+e3c59x_charset] |
mov [ebx], al |
inc ebx |
pop eax |
and al, 0x0f |
mov al, byte [eax+e3c59x_charset] |
mov [ebx], al |
inc ebx |
ret |
end if ; defined E3C59X_DEBUG |
;*************************************************************************** |
; Function |
; e3c59x_try_link_detect |
; Description |
; e3c59x_try_link_detect checks if link exists |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no link detected |
; al - 1 ; link detected |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_link_detect: |
; download self-directed packet |
mov edi, node_addr |
mov bx, 0x0608 ; packet type |
mov esi, e3c59x_self_directed_packet |
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes |
call dword [e3c59x_transmit_function] |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; program RxFilter for promiscuous operation |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1111b |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; switch to register window 4 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; check loop |
xor ebx, ebx |
mov ecx, 0xffff ; 65535 tries |
.loop: |
push ecx ebx |
call dword [e3c59x_receive_function] |
pop ebx ecx |
test al, al |
jnz .finish |
.no_packet_received: |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; read linkbeatdetect |
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] |
in ax, dx |
test ah, 1000b ; test linkBeatDetect |
jnz .link_detected |
xor al, al |
jmp .finish |
.link_detected: |
; test carrierSense |
test al, 100000b |
jz .no_carrier_sense |
inc ebx |
.no_carrier_sense: |
dec ecx |
jns .loop |
; assume the link is good if 0 < ebx < 25 % |
test ebx, ebx |
setnz al |
jz .finish |
cmp ebx, 16384 ; 25% |
setb al |
.finish: |
if defined E3C59X_DEBUG |
test al, al |
jz @f |
or byte [e3c59x_link_type+1], 100b |
@@: |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_phy |
; Description |
; e3c59x_try_phy checks the auto-negotiation function |
; in the PHY at PHY index. It can also be extended to |
; include link detection for non-IEEE 802.3u |
; auto-negotiation devices, for instance the BCM5000. |
; Parameters |
; ah - PHY index |
; ebp - io_addr |
; Return value |
; al - 0 link is auto-negotiated |
; al - 1 no link is auto-negotiated |
; Destroyed registers |
; eax, ebx, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_phy: |
mov al, E3C59X_REG_MII_BMCR |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
or ah, 0x80 ; software reset |
mov ebx, eax |
pop eax |
push eax |
call e3c59x_mdio_write ; returns with window #4 |
; wait for reset to complete |
mov esi, 2000 ; 2000ms = 2s |
call delay_ms |
pop eax |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
test ah, 0x80 |
jnz .fail_finish |
pop eax |
push eax |
; wait for a while after reset |
mov esi, 20 ; 20ms |
call delay_ms |
pop eax |
push eax |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read ; returns with window #4 |
test al, 1 ; extended capability supported? |
jz .no_ext_cap |
; auto-neg capable? |
test al, 1000b |
jz .fail_finish ; not auto-negotiation capable |
; auto-neg complete? |
test al, 100000b |
jnz .auto_neg_ok |
; restart auto-negotiation |
pop eax |
push eax |
mov al, E3C59X_REG_MII_ANAR |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX |
mov ebx, eax |
pop eax |
call e3c59x_mdio_write ; returns with window #4 |
pop eax |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
mov ebx, eax |
or bh, 10010b ; restart auto-negotiation |
pop eax |
push eax |
call e3c59x_mdio_write ; returns with window #4 |
mov esi, 4000 ; 4000ms = 4 seconds |
call delay_ms |
pop eax |
push eax |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read ; returns with window #4 |
test al, 100000b ; auto-neg complete? |
jnz .auto_neg_ok |
jmp .fail_finish |
.auto_neg_ok: |
; compare advertisement and link partner ability registers |
pop eax |
push eax |
mov al, E3C59X_REG_MII_ANAR |
call e3c59x_mdio_read ; returns with window #4 |
xchg eax, [esp] |
mov al, E3C59X_REG_MII_ANLPAR |
call e3c59x_mdio_read ; returns with window #4 |
pop ebx |
and eax, ebx |
and eax, 1111100000b |
push eax |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], ax |
end if ; defined E3C59X_DEBUG |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; set full-duplex mode |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
and ax, not 0x120 ; clear full duplex and flow control |
pop ebx |
test ebx, (1010b shl 5) ; check for full-duplex |
jz .half_duplex |
or ax, 0x120 ; set full duplex and flow control |
.half_duplex: |
out dx, ax |
mov al, 1 |
ret |
.no_ext_cap: |
; not yet implemented BCM5000 |
.fail_finish: |
pop eax |
xor al, al |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_mii |
; Description |
; e3c59x_try_MII checks the on-chip auto-negotiation logic |
; or an off-chip MII PHY, depending upon what is set in |
; xcvrSelect by the caller. |
; It exits when it finds the first device with a good link. |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_mii: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, (1111b shl 20) |
cmp eax, (1000b shl 20) ; is auto-negotiation set? |
jne .mii_device |
; auto-negotiation is set |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; PHY==24 is the on-chip auto-negotiation logic |
; it supports only 10base-T and 100base-TX |
mov ah, 24 |
call e3c59x_try_phy |
test al, al |
jz .fail_finish |
mov cl, 24 |
jmp .check_preamble |
.mii_device: |
cmp eax, (0110b shl 20) |
jne .fail_finish |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
in ax, dx |
and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA) |
cmp al, (1 shl E3C59X_BIT_MGMT_DATA) |
je .serch_for_phy |
xor al, al |
ret |
.serch_for_phy: |
; search for PHY |
mov cl, 31 |
.search_phy_loop: |
cmp cl, 24 |
je .next_phy |
mov ah, cl ; ah = phy |
mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register |
push ecx |
call e3c59x_mdio_read |
pop ecx |
test ax, ax |
jz .next_phy |
cmp ax, 0xffff |
je .next_phy |
mov ah, cl ; ah = phy |
push ecx |
call e3c59x_try_phy |
pop ecx |
test al, al |
jnz .check_preamble |
.next_phy: |
dec cl |
jns .search_phy_loop |
.fail_finish: |
xor al, al |
ret |
; epilog |
.check_preamble: |
push eax ; eax contains the return value of e3c59x_try_phy |
; check hard coded preamble forcing |
movzx eax, byte [e3c59x_ver_id] |
test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE |
setnz [e3c59x_preamble] ; force preamble |
jnz .finish |
; check mii for preamble suppression |
mov ah, cl |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read |
test al, 1000000b ; preamble suppression? |
setz [e3c59x_preamble] ; no |
.finish: |
pop eax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_test_packet |
; Description |
; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_test_packet: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; set fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
or ax, 0x120 |
out dx, ax |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; set RxFilter to enable individual address matches |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; issue RxEnable and TxEnable |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
; download a self-directed test packet |
mov edi, node_addr |
mov bx, 0x0608 ; packet type |
mov esi, e3c59x_self_directed_packet |
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes |
call dword [e3c59x_transmit_function] |
; wait for 2s |
mov esi, 2000 ; 2000ms = 2s |
call delay_ms |
; check if self-directed packet is received |
call dword [e3c59x_receive_function] |
test al, al |
jnz .finish |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; clear fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
and ax, not 0x120 |
out dx, ax |
xor al, al |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_loopback |
; Description |
; tries a loopback packet for 10BASE2 or AUI port |
; Parameters |
; al - 0: 10Mbps AUI connector |
; 1: 10BASE-2 |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_loopback: |
push eax |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
pop eax |
push eax |
if defined E3C59X_DEBUG |
mov bl, al |
inc bl |
shl bl, 3 |
or byte [e3c59x_link_type+1], bl |
end if ; defined E3C59X_DEBUG |
test al, al ; aui or coax? |
jz .complete_loopback |
; enable 100BASE-2 DC-DC converter |
mov ax, (10b shl 11) ; EnableDcConverter |
out dx, ax |
.complete_loopback: |
mov cl, 2 ; give a port 3 chances to complete a loopback |
.next_try: |
push ecx |
call e3c59x_test_packet |
pop ecx |
test al, al |
jnz .finish |
dec cl |
jns .next_try |
.finish: |
xchg eax, [esp] |
test al, al |
jz .aui_finish |
; issue DisableDcConverter command |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10111b shl 11) |
out dx, ax |
.aui_finish: |
pop eax ; al contains the result of operation |
if defined E3C59X_DEBUG |
test al, al |
jnz @f |
and byte [e3c59x_link_type+1], not 11000b |
@@: |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_set_available_media |
; Description |
; sets the first available media |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_set_available_media: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
push eax |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 10b |
jz @f |
; baseTXAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (100b shl 20) |
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD |
mov word [e3c59x_link_type], (1 shl 8) |
else if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 7) |
end if |
jmp .set_media |
@@: |
test al, 100b |
jz @f |
; baseFXAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (101b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 10) |
end if |
jmp .set_media |
@@: |
test al, 1000000b |
jz @f |
; miiDevice |
pop eax |
and eax, not (1111b shl 20) |
or eax, (0110b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 13) |
end if |
jmp .set_media |
@@: |
test al, 1000b |
jz @f |
.set_default: |
; 10bTAvailable |
pop eax |
and eax, not (1111b shl 20) |
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD |
mov word [e3c59x_link_type], (1 shl 6) |
else if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 5) |
end if ; E3C59X_FORCE_FD |
jmp .set_media |
@@: |
test al, 10000b |
jz @f |
; coaxAvailable |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10b shl 11) ; EnableDcConverter |
out dx, ax |
pop eax |
and eax, not (1111b shl 20) |
or eax, (11b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 12) |
end if ; defined E3C59X_DEBUG |
jmp .set_media |
@@: |
test al, 10000b |
jz .set_default |
; auiAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (1 shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 11) |
end if ; defined E3C59X_DEBUG |
.set_media: |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
out dx, eax |
if defined E3C59X_FORCE_FD |
; set fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
or ax, 0x120 |
out dx, ax |
end if ; E3C59X_FORCE_FD |
mov al, 1 |
ret |
;*************************************************************************** |
; Function |
; e3c59x_set_active_port |
; Description |
; It selects the media port (transceiver) to be used |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_set_active_port: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
test eax, (1 shl 24) ; check if autoselect enable |
jz .set_first_available_media |
; check 100BASE-TX and 10BASE-T |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 1010b ; check whether 100BASE-TX or 10BASE-T available |
jz .mii_device ; they are not available |
; set auto-negotiation |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (1000b shl 20) |
out dx, eax |
call e3c59x_try_mii |
test al, al |
jz .mii_device |
ret |
.mii_device: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for off-chip mii device |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 1000000b ; check miiDevice |
jz .base_fx |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0110b shl 20) ; set MIIDevice |
out dx, eax |
call e3c59x_try_mii |
test al, al |
jz .base_fx |
ret |
.base_fx: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for 100BASE-FX |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 100b ; check 100BASE-FX |
jz .aui_enable |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0101b shl 20) ; set 100base-FX |
out dx, eax |
call e3c59x_try_link_detect |
test al, al |
jz .aui_enable |
ret |
.aui_enable: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for 10Mbps AUI connector |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 100000b ; check 10Mbps AUI connector |
jz .coax_available |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0001b shl 20) ; set 10Mbps AUI connector |
out dx, eax |
xor al, al ; try 10Mbps AUI connector |
call e3c59x_try_loopback |
test al, al |
jz .coax_available |
ret |
.coax_available: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for coaxial 10BASE-2 port |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 10000b ; check 10BASE-2 |
jz .set_first_available_media |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0011b shl 20) ; set 10BASE-2 |
out dx, eax |
mov al, 1 |
call e3c59x_try_loopback |
test al, al |
jz .set_first_available_media |
ret |
.set_first_available_media: |
jmp e3c59x_set_available_media |
;*************************************************************************** |
; Function |
; e3c59x_wake_up |
; Description |
; set the power state to D0 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_wake_up: |
; wake up - we directly do it by programming PCI |
; check if the device is power management capable |
mov al, 2 |
mov ah, [pci_bus] |
mov bl, PCI_REG_STATUS |
mov bh, [pci_dev] |
push eax ebx |
call pci_read_reg |
test al, 10000b ; is there "new capabilities" linked list? |
pop ebx eax |
jz .device_awake |
; search for power management register |
mov al, 1 |
mov bl, PCI_REG_CAP_PTR |
push eax ebx |
call pci_read_reg |
mov cl, al |
cmp cl, 0x3f |
pop ebx eax |
jbe .device_awake |
; traverse the list |
mov al, 2 |
.pm_loop: |
mov bl, cl |
push eax ebx |
call pci_read_reg |
cmp al, 1 |
je .set_pm_state |
test ah, ah |
mov cl, ah |
pop ebx eax |
jnz .pm_loop |
jmp .device_awake |
; waku up the device if necessary |
.set_pm_state: |
pop ebx eax |
add bl, PCI_REG_PM_CTRL |
push eax ebx |
call pci_read_reg |
mov cx, ax |
test cl, 3 |
pop ebx eax |
jz .device_awake |
and cl, not 11b ; set state to D0 |
call pci_write_reg |
.device_awake: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_probe: |
movzx ebp, word [io_addr] |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
push ebp eax ebx |
call pci_read_reg |
mov cx, ax |
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
and cl, not (1 shl PCI_BIT_MMIO) |
pop ebx eax |
call pci_write_reg |
; wake up the card |
call e3c59x_wake_up |
pop ebp |
; get chip version |
mov ax, [pci_data+2] |
mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1 |
.chip_ver_loop: |
cmp ax, [e3c59x_hw_versions+ecx*4] |
jz .chip_ver_found |
dec ecx |
jns .chip_ver_loop |
xor ecx, ecx |
.chip_ver_found: |
mov [e3c59x_ver_id], cl |
test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM |
setnz [e3c59x_has_hwcksm] |
; set pci latency for vortex cards |
test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX |
jz .not_vortex |
mov cx, 11111000b ; 248 = max latency |
mov al, 1 |
mov ah, [pci_bus] |
mov bl, PCI_REG_LATENCY |
mov bh, [pci_dev] |
call pci_write_reg |
.not_vortex: |
; set RX/TX functions |
mov ax, E3C59X_EEPROM_REG_CAPABILITIES |
call e3c59x_read_eeprom |
test al, 100000b ; full bus master? |
setnz [e3c59x_full_bus_master] |
jnz .boomerang_func |
mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit |
mov dword [e3c59x_receive_function], e3c59x_vortex_poll |
jmp @f |
.boomerang_func: ; full bus master, so use boomerang functions |
mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit |
mov dword [e3c59x_receive_function], e3c59x_boomerang_poll |
@@: |
; read MAC from eeprom |
mov ecx, 2 |
.mac_loop: |
lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] |
call e3c59x_read_eeprom |
xchg ah, al ; htons |
mov [node_addr+ecx*2], ax |
dec ecx |
jns .mac_loop |
test byte [e3c59x_full_bus_master], 0xff |
jz .set_preamble |
; switch to register window 2 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 |
out dx, ax |
; activate xcvr by setting some magic bits |
lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] |
in ax, dx |
and ax, not 0x4010 |
movzx ebx, byte [e3c59x_ver_id] |
test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR |
jz @f |
or al, 0x10 |
@@: |
test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR |
jz @f |
or ah, 0x40 |
@@: |
out dx, ax |
.set_preamble: |
; use preamble as default |
mov byte [e3c59x_preamble], 1 ; enable preamble |
;*************************************************************************** |
; Function |
; e3c59x_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
e3c59x_reset: |
; issue global reset |
call e3c59x_global_reset |
; disable interrupts |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (1110b shl 11) |
out dx, ax |
; enable Statistics |
mov ax, (10101b shl 11) |
out dx, ax |
; set indication |
mov ax, (1111b shl 11) or 0x6c6 |
out dx, ax |
; acknowledge (clear) every interrupt indicator |
mov ax, (1101b shl 11) or 0x661 |
out dx, ax |
; switch to register window 2 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 |
out dx, ax |
; write MAC addres back into the station address registers |
lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] |
mov esi, node_addr |
cld |
outsw |
add edx, 2 |
outsw |
add edx, 2 |
outsw |
add edx, 2 |
; clear station mask |
xor eax, eax |
out dx, ax |
add edx, 2 |
out dx, ax |
add edx, 2 |
out dx, ax |
; switch to register window 6 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 |
out dx, ax |
; clear all statistics by reading |
lea edx, [ebp+E3C59X_REG_CARRIER_LOST] |
mov cl, 9 |
.stat_clearing_loop: |
in al, dx |
inc edx |
dec cl |
jns .stat_clearing_loop |
in ax, dx |
add dx, 2 |
in ax, dx |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; clear BadSSD |
lea edx, [ebp+E3C59X_REG_BAD_SSD] |
in al, dx |
; clear extra statistics bit in NetworkDiagnostic |
lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] |
in ax, dx |
or ax, 0x0040 |
out dx, ax |
; SetRxEarlyThreshold |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) |
out dx, ax |
test byte [e3c59x_full_bus_master], 0xff |
jz .skip_boomerang_setting |
; set upRxEarlyEnable |
lea edx, [ebp+E3C59X_REG_DMA_CTRL] |
in eax, dx |
or eax, 0x20 |
out dx, eax |
; TxFreeThreshold |
lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] |
mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) |
out dx, al |
; program DnListPtr |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
xor eax, eax |
out dx, eax |
.skip_boomerang_setting: |
; initialization |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
call e3c59x_set_active_port |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; program RxFilter for promiscuous operation |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1111b |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; switch to register window 4 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; wait for linkDetect |
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] |
mov cl, 20 ; wait for max 2s |
mov esi, 100 ; 100ms |
.link_detect_loop: |
call delay_ms |
in ax, dx |
test ah, 1000b ; linkDetect |
jnz @f |
dec cl |
jnz .link_detect_loop |
@@: |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
if defined E3C59X_DEBUG |
call e3c59x_debug |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_global_reset |
; Description |
; resets the device |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; ax, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_global_reset: |
; GlobalReset |
lea edx, [ebp+E3C59X_REG_COMMAND] |
xor eax, eax |
; or al, 0x14 |
out dx, ax |
; wait for GlobalReset to complete |
mov ecx, 64000 |
.global_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .finish |
dec ecx |
jnz .global_reset_loop |
.finish: |
; wait for 2 seconds for NIC to boot |
mov esi, 2000 ; 2000ms = 2s |
push ebp |
call delay_ms |
pop ebp |
ret |
;*************************************************************************** |
; Function |
; e3c59x_tx_reset |
; Description |
; resets and enables transmitter engine |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; ax, ecx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_tx_reset: |
; TxReset |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01011b shl 11) |
out dx, ax |
; Wait for TxReset to complete |
mov ecx, 200000 |
.tx_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .tx_set_prev |
dec ecx |
jns .tx_reset_loop |
.tx_set_prev: |
test byte [e3c59x_full_bus_master], 0xff |
jz .tx_enable |
; init last_dpd |
mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE |
mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE |
.tx_enable: |
mov ax, (01001b shl 11) ; TxEnable |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_rx_reset |
; Description |
; resets and enables receiver engine |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_rx_reset: |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (0101b shl 11) or 0x4 ; RxReset |
out dx, ax |
; wait for RxReset to complete |
mov ecx, 200000 |
.rx_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .setup_upd |
dec ecx |
jns .rx_reset_loop |
.setup_upd: |
; check if full bus mastering |
test byte [e3c59x_full_bus_master], 0xff |
jz .rx_enable |
; create upd ring |
mov eax, e3c59x_upd_buff |
zero_to_virt eax |
mov [e3c59x_curr_upd], eax |
mov esi, eax |
virt_to_dma esi |
mov edi, e3c59x_rx_buff |
zero_to_dma edi |
mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE |
zero_to_virt ebx |
mov cl, E3C59X_NUM_RX_DESC-1 |
.upd_loop: |
mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi |
mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31) |
add edi, E3C59X_MAX_ETH_FRAME_SIZE |
add esi, E3C59X_UPD_SIZE |
mov ebx, eax |
add eax, E3C59X_UPD_SIZE |
dec cl |
jns .upd_loop |
mov eax, e3c59x_upd_buff |
zero_to_dma eax |
lea edx, [ebp+E3C59X_REG_UP_LIST_PTR] |
out dx, eax ; write E3C59X_REG_UP_LIST_PTR |
lea edx, [ebp+E3C59X_REG_COMMAND] |
.rx_enable: |
mov ax, (00100b shl 11) ; RxEnable |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_write_eeprom |
; Description |
; reads eeprom |
; Note : the caller must switch to the register window 0 |
; before calling this function |
; Parameters: |
; ax - register to be read (only the first 63 words can be read) |
; cx - value to be read into the register |
; Return value: |
; ax - word read |
; Destroyed registers |
; ax, ebx, edx |
; |
;*************************************************************************** |
; align 4 |
;e3c59x_write_eeprom: |
; mov edx, [io_addr] |
; add edx, E3C59X_REG_EEPROM_COMMAND |
; cmp ah, 11b |
; ja .finish ; address may have a value of maximal 1023 |
; shl ax, 2 |
; shr al, 2 |
; push eax |
;; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .write_enable |
; dec ebx |
; jns @r |
;; write enable |
;.write_enable: |
; xor eax, eax |
; mov eax, (11b shl 4) |
; out dx, ax |
;; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .erase_loop |
; dec ebx |
; jns @r |
;.erase_loop: |
; pop eax |
; push eax |
; or ax, (11b shl 6) ; erase register |
; out dx, ax |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .write_reg |
; dec ebx |
; jns @r |
;.write_reg: |
; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND |
; mov eax, ecx |
; out dx, ax |
;; write enable |
; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA |
; xor eax, eax |
; mov eax, (11b shl 4) |
; out dx, ax |
; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .issue_write_reg |
; dec ebx |
; jns @r |
;.issue_write_reg: |
; pop eax |
; or ax, 01b shl 6 |
; out dx, ax |
;.finish: |
; ret |
;*************************************************************************** |
; Function |
; e3c59x_read_eeprom |
; Description |
; reads eeprom |
; Parameters: |
; ax - register to be read (only the first 63 words can be read) |
; ebp - io_addr |
; Return value: |
; ax - word read |
; Destroyed registers |
; ax, ebx, edx, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_read_eeprom: |
push eax |
; switch to register window 0 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+0 |
out dx, ax |
pop eax |
and ax, 111111b ; take only the first 6 bits into account |
movzx ebx, byte [e3c59x_ver_id] |
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT |
jz @f |
add ax, 0x230 ; hardware constant |
jmp .read |
@@: |
add ax, E3C59X_EEPROM_CMD_READ |
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET |
jz .read |
add ax, 0x30 |
.read: |
lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND] |
out dx, ax |
mov ebx, 0xffff ; duration of about 162 us ;-) |
.wait_for_reading: |
in ax, dx |
test ah, 0x80 ; check bit eepromBusy |
jz .read_data |
dec ebx |
jns .wait_for_reading |
.read_data: |
lea edx, [ebp+E3C59X_REG_EEPROM_DATA] |
in ax, dx |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_sync |
; Description |
; initial synchronization |
; Parameters |
; ebp - io_addr |
; Return value |
; Destroyed registers |
; ax, edx, cl |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_sync: |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
cmp byte [e3c59x_preamble], 0 |
je .no_preamble |
; send 32 logic ones |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
mov cl, 31 |
.loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR) |
out dx, ax |
in ax, dx ; delay |
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \ |
or (1 shl E3C59X_BIT_MGMT_DIR) \ |
or (1 shl E3C59X_BIT_MGMT_CLK) |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .loop |
.no_preamble: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_read |
; Description |
; read MII register |
; see page 16 in D83840A.pdf |
; Parameters |
; ah - PHY addr |
; al - register addr |
; ebp - io_addr |
; Return value |
; ax - register read |
; Destroyed registers |
; eax, ebx, cx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_read: |
push eax |
call e3c59x_mdio_sync ; returns with window #4 |
pop eax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
shl al, 3 |
shr ax, 3 |
and ax, not E3C59X_MII_CMD_MASK |
or ax, E3C59X_MII_CMD_READ |
mov ebx, eax |
xor ecx, ecx |
mov cl, 13 |
.cmd_loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii |
bt ebx, ecx |
jnc .zero_bit |
or al, (1 shl E3C59X_BIT_MGMT_DATA) |
.zero_bit: |
out dx, ax |
push eax |
in ax, dx ; delay |
pop eax |
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .cmd_loop |
; read data (18 bits with the two transition bits) |
mov cl, 17 |
xor ebx, ebx |
.read_loop: |
shl ebx, 1 |
xor eax, eax ; read comand |
out dx, ax |
in ax, dx ; delay |
in ax, dx |
test al, (1 shl E3C59X_BIT_MGMT_DATA) |
jz .dont_set |
inc ebx |
.dont_set: |
mov ax, (1 shl E3C59X_BIT_MGMT_CLK) |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .read_loop |
mov eax, ebx |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_write |
; Description |
; write MII register |
; see page 16 in D83840A.pdf |
; Parameters |
; ah - PHY addr |
; al - register addr |
; bx - word to be written |
; ebp - io_addr |
; Return value |
; ax - register read |
; Destroyed registers |
; eax, ebx, cx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_write: |
push eax |
call e3c59x_mdio_sync |
pop eax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
shl al, 3 |
shr ax, 3 |
and ax, not E3C59X_MII_CMD_MASK |
or ax, E3C59X_MII_CMD_WRITE |
shl eax, 2 |
or eax, 10b ; transition bits |
shl eax, 16 |
mov ax, bx |
mov ebx, eax |
mov ecx, 31 |
.cmd_loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii |
bt ebx, ecx |
jnc .zero_bit |
or al, (1 shl E3C59X_BIT_MGMT_DATA) |
.zero_bit: |
out dx, ax |
push eax |
in ax, dx ; delay |
pop eax |
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write |
out dx, ax |
in ax, dx ; delay |
dec ecx |
jns .cmd_loop |
ret |
;*************************************************************************** |
; Function |
; e3c59x_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, ecx, edx, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_transmit: |
jmp dword [e3c59x_transmit_function] |
;*************************************************************************** |
; Function |
; e3c59x_check_tx_status |
; Description |
; Checks TxStatus queue. |
; Return value |
; al - 0 no error was found |
; al - 1 error was found TxReset is needed |
; Destroyed registers |
; eax, ecx, edx, ebp |
; |
;*************************************************************************** |
e3c59x_check_tx_status: |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
; clear TxStatus queue |
lea edx, [ebp+E3C59X_REG_TX_STATUS] |
mov cl, 31 ; max number of queue entries |
.tx_status_loop: |
in al, dx |
test al, al |
jz .finish ; no error |
test al, 0x3f |
jnz .finish ; error |
.no_error_found: |
; clear current TxStatus entry which advances the next one |
xor al, al |
out dx, al |
dec cl |
jns .tx_status_loop |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_vortex_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_vortex_transmit: |
push ecx |
call e3c59x_check_tx_status |
pop ecx |
test al, al |
jz .no_error_found |
jmp e3c59x_tx_reset |
.no_error_found: |
; switch to register window 7 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 |
out dx, ax |
; check for master operation in progress |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jnz .finish ; no DMA for sending |
; dword boundary correction |
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE |
ja .finish ; packet is too long |
; write Frame Start Header |
mov eax, ecx |
; add header length and extend the complete length to dword boundary |
add eax, ETH_HLEN+3 |
and eax, not 3 |
lea edx, [ebp+E3C59X_REG_TX_DATA] |
out dx, eax |
; prepare the complete frame |
push esi |
mov esi, edi |
mov edi, e3c59x_tx_buff |
zero_to_virt edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy packet data |
pop esi |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
and ecx, 3 |
rep movsb |
mov ecx, eax |
; program frame address to be sent |
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] |
mov eax, e3c59x_tx_buff |
zero_to_dma eax |
out dx, eax |
; program frame length |
lea edx, [ebp+E3C59X_REG_MASTER_LEN] |
mov eax, ecx |
out dx, ax |
; start DMA Down |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10100b shl 11) + 1 ; StartDMADown |
out dx, ax |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_boomerang_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, ebx, ecx, edx, esi, edi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_boomerang_transmit: |
push ecx |
call e3c59x_check_tx_status |
pop ecx |
test al, al |
jz .no_error_found |
jmp e3c59x_tx_reset |
.no_error_found: |
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE |
ja .finish ; packet is too long |
; calculate descriptor address |
mov eax, [e3c59x_prev_dpd] |
cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE |
jb @f |
; wrap around |
mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE |
@@: |
add eax, E3C59X_DPD_SIZE |
zero_to_virt eax |
push eax |
; check DnListPtr |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
in eax, dx |
; mark if Dn_List_Ptr is cleared |
test eax, eax |
setz [e3c59x_dn_list_ptr_cleared] |
; finish if no more free descriptor is available - FIXME! |
cmp eax, [esp] |
pop eax |
jz .finish |
push eax esi |
mov esi, edi |
; calculate tx_buffer address |
mov edi, [e3c59x_prev_tx_frame] |
cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE |
jb @f |
; wrap around |
mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE |
@@: |
add edi, E3C59X_MAX_ETH_FRAME_SIZE |
zero_to_virt edi |
mov eax, edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy packet data |
pop esi |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
push ecx |
and ecx, 3 |
rep movsb |
; padding, do we really need it? |
pop ecx |
add ecx, ETH_HLEN |
cmp ecx, ETH_ZLEN |
jae @f |
mov ecx, ETH_ZLEN |
@@: |
; calculate |
mov ebx, ecx |
;test byte [e3c59x_has_hwcksm], 0xff |
;jz @f |
;or ebx, (1 shl 26) ; set AddTcpChecksum |
;@@: |
or ebx, 0x8000 ; transmission complete notification |
or ecx, 0x80000000 ; last fragment |
; program DPD |
mov edi, eax |
pop eax |
and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0 |
mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx |
virt_to_dma edi |
mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi |
mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx |
; calculate physical address |
virt_to_dma eax |
push eax |
cmp byte [e3c59x_dn_list_ptr_cleared], 0 |
jz .add_to_list |
; write Dn_List_Ptr |
out dx, eax |
jmp .finish |
.add_to_list: |
; DnStall |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+2) |
out dx, ax |
; wait for DnStall to complete |
mov ecx, 6000 |
.wait_for_stall: |
in ax, dx ; read E3C59X_REG_INT_STATUS |
test ah, 10000b |
jz .dnstall_ok |
dec ecx |
jnz .wait_for_stall |
.dnstall_ok: |
pop eax |
push eax |
mov ebx, [e3c59x_prev_dpd] |
zero_to_virt ebx |
mov [ebx], eax |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
in eax, dx |
test eax, eax |
jnz .dnunstall |
; if Dn_List_Ptr has been cleared fill it up |
pop eax |
push eax |
out dx, eax |
.dnunstall: |
; DnUnStall |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+3) |
out dx, ax |
.finish: |
pop eax |
dma_to_zero eax |
mov [e3c59x_prev_dpd], eax |
dma_to_zero edi |
mov [e3c59x_prev_tx_frame], edi |
ret |
;*************************************************************************** |
; Function |
; e3c59x_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed registers |
; eax, ebx, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_poll: |
jmp dword [e3c59x_receive_function] |
;*************************************************************************** |
; Function |
; e3c59x_vortex_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no packet received |
; al - 1 ; packet received |
; Destroyed registers |
; eax, ebx, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_vortex_poll: |
and word [eth_rx_data_len], 0 ; assume no packet received |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
.rx_status_loop: |
; examine RxStatus |
lea edx, [ebp+E3C59X_REG_RX_STATUS] |
in ax, dx |
test ax, ax |
jz .finish |
test ah, 0x80 ; rxIncomplete |
jz .check_error |
jmp .finish |
.check_error: |
test ah, 0x40 |
jz .check_length |
; discard the top frame received advancing the next one |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01000b shl 11) |
out dx, ax |
jmp .rx_status_loop |
.check_length: |
and eax, 0x1fff |
cmp eax, E3C59X_MAX_ETH_PKT_SIZE |
ja .discard_frame ; frame is too long discard it |
.check_dma: |
push eax |
; switch to register window 7 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 |
out dx, ax |
; check for master operation in progress |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jz .read_frame ; no DMA for receiving |
pop eax |
jmp .finish |
.read_frame: |
; program buffer address to read in |
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] |
if defined E3C59X_LINUX |
mov eax, e3c59x_rx_buff |
zero_to_dma eax |
else |
mov eax, Ether_buffer |
end if |
out dx, eax |
; program frame length |
lea edx, [ebp+E3C59X_REG_MASTER_LEN] |
mov ax, 1560 |
out dx, ax |
; start DMA Up |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10100b shl 11) ; StartDMAUp |
out dx, ax |
; check for master operation in progress |
.dma_loop: |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jnz .dma_loop |
; registrate the received packet length |
pop eax |
mov word [eth_rx_data_len], ax |
; discard the top frame received |
.discard_frame: |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01000b shl 11) |
out dx, ax |
.finish: |
; set return value |
cmp word [eth_rx_data_len], 0 |
setne al |
ret |
;*************************************************************************** |
; Function |
; e3c59x_boomerang_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no packet received |
; al - 1 ; packet received |
; Destroyed registers |
; eax, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_boomerang_poll: |
and word [eth_rx_data_len], 0 ; assume no packet received |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
; check if packet is uploaded |
mov eax, [e3c59x_curr_upd] |
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete |
jnz .check_error |
jmp .finish |
; packet is uploaded check for any error |
.check_error: |
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError |
jz .copy_packet_length |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
jmp .finish |
.copy_packet_length: |
mov ecx, [eax+E3C59X_UPD_PKT_STATUS] |
and ecx, 0x1fff |
cmp ecx, E3C59X_MAX_ETH_PKT_SIZE |
jbe .copy_packet |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
jmp .finish |
.copy_packet: |
push ecx |
mov word [eth_rx_data_len], cx |
mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR] |
dma_to_virt esi |
mov edi, Ether_buffer |
shr ecx, 2 ; first copy dword-wise |
cld |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
mov eax, [e3c59x_curr_upd] |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
virt_to_zero eax |
cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE |
jb .no_wrap |
; wrap around |
mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE |
.no_wrap: |
add eax, E3C59X_UPD_SIZE |
zero_to_virt eax |
mov [e3c59x_curr_upd], eax |
.finish: |
; check if the NIC is in the upStall state |
lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS] |
in eax, dx |
test ah, 0x20 ; UpStalled |
jz .noUpUnStall |
; issue upUnStall command |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+1) ; upUnStall |
out dx, ax |
.noUpUnStall: |
; set return value |
cmp word [eth_rx_data_len], 0 |
setnz al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/forcedeth.inc |
---|
0,0 → 1,2692 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; FORCEDETH.INC ;; |
;; ;; |
;; Ethernet driver for Kolibri OS ;; |
;; ;; |
;; Version 0.1 24 June 2008 - 23 Sep 2008 ;; |
;; ;; |
;; Driver for chips of NVIDIA nForce2 ;; |
;; References: ;; |
;; forcedeth.c - linux driver (etherboot project) ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2008 shurf, ;; |
;; cit.utc@gmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************** |
; Interface |
; forcedeth_reset |
; forcedeth_probe |
; forcedeth_poll |
; forcedeth_transmit |
; forcedeth_cable |
; |
;******************************************************************** |
;************************************************************************** |
; forcedeth Register Definitions |
;************************************************************************** |
PCI_REG_COMMAND equ 0x04 ; command register |
PCI_COMMAND_IO equ 0x01 ; Enable response in I/O space |
PCI_COMMAND_MASTER equ 0x04 ; Enable bus mastering |
PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
PCI_VENDOR_ID equ 0x00 ; 16 bit |
PCI_REVISION_ID equ 0x08 ; 8 bits |
PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits |
PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits |
PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits |
PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits |
PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits |
PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) |
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) |
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 |
PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address |
PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] |
PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address |
; NIC specific static variables go here |
PCI_DEVICE_ID_NVIDIA_NVENET_1 equ 0x01c3 |
PCI_DEVICE_ID_NVIDIA_NVENET_2 equ 0x0066 |
PCI_DEVICE_ID_NVIDIA_NVENET_4 equ 0x0086 |
PCI_DEVICE_ID_NVIDIA_NVENET_5 equ 0x008c |
PCI_DEVICE_ID_NVIDIA_NVENET_3 equ 0x00d6 |
PCI_DEVICE_ID_NVIDIA_NVENET_7 equ 0x00df |
PCI_DEVICE_ID_NVIDIA_NVENET_6 equ 0x00e6 |
PCI_DEVICE_ID_NVIDIA_NVENET_8 equ 0x0056 |
PCI_DEVICE_ID_NVIDIA_NVENET_9 equ 0x0057 |
PCI_DEVICE_ID_NVIDIA_NVENET_10 equ 0x0037 |
PCI_DEVICE_ID_NVIDIA_NVENET_11 equ 0x0038 |
PCI_DEVICE_ID_NVIDIA_NVENET_12 equ 0x0268 |
PCI_DEVICE_ID_NVIDIA_NVENET_13 equ 0x0269 |
PCI_DEVICE_ID_NVIDIA_NVENET_14 equ 0x0372 |
PCI_DEVICE_ID_NVIDIA_NVENET_15 equ 0x0373 |
ETH_DATA_LEN equ 1500 |
; rx/tx mac addr + type + vlan + align + slack |
RX_NIC_BUFSIZE equ (ETH_DATA_LEN + 64) |
; even more slack |
RX_ALLOC_BUFSIZE equ (ETH_DATA_LEN + 128) |
NvRegIrqStatus equ 0x00 |
NvRegIrqMask equ 0x04 |
NvRegUnknownSetupReg6 equ 0x08 |
NvRegPollingInterval equ 0x0c |
NvRegMacReset equ 0x3c |
NvRegMisc1 equ 0x80 |
NvRegTransmitterControl equ 0x84 |
NvRegTransmitterStatus equ 0x88 |
NvRegPacketFilterFlags equ 0x8c |
NvRegOffloadConfig equ 0x90 |
NvRegReceiverControl equ 0x94 |
NvRegReceiverStatus equ 0x98 |
NvRegRandomSeed equ 0x9c |
NvRegUnknownSetupReg1 equ 0xA0 |
NvRegUnknownSetupReg2 equ 0xA4 |
NvRegMacAddrA equ 0xA8 ; MAC address low |
NvRegMacAddrB equ 0xAC ; MAC address high |
NvRegMulticastAddrA equ 0xB0 |
NvRegMulticastAddrB equ 0xB4 |
NvRegMulticastMaskA equ 0xB8 |
NvRegMulticastMaskB equ 0xBC |
NvRegPhyInterface equ 0xC0 |
NvRegTxRingPhysAddr equ 0x100 |
NvRegRxRingPhysAddr equ 0x104 |
NvRegRingSizes equ 0x108 |
NvRegUnknownTransmitterReg equ 0x10c |
NvRegLinkSpeed equ 0x110 |
NvRegUnknownSetupReg5 equ 0x130 |
NvRegUnknownSetupReg3 equ 0x13c |
NvRegTxRxControl equ 0x144 |
NvRegMIIStatus equ 0x180 |
NvRegUnknownSetupReg4 equ 0x184 |
NvRegAdapterControl equ 0x188 |
NvRegMIISpeed equ 0x18c |
NvRegMIIControl equ 0x190 |
NvRegMIIData equ 0x194 |
NvRegWakeUpFlags equ 0x200 |
NvRegPowerState equ 0x26c |
NvRegPowerState2 equ 0x600 |
NVREG_UNKSETUP1_VAL equ 0x16070f |
NVREG_UNKSETUP2_VAL equ 0x16 |
NVREG_UNKSETUP3_VAL1 equ 0x200010 |
NVREG_UNKSETUP4_VAL equ 8 |
NVREG_UNKSETUP5_BIT31 equ (1 shl 31) |
NVREG_UNKSETUP6_VAL equ 3 |
NVREG_TXRXCTL_RXCHECK equ 0x0400 |
NVREG_MIISTAT_ERROR equ 0x0001 |
NVREG_MIISTAT_MASK equ 0x000f |
NVREG_MIISTAT_MASK2 equ 0x000f |
NVREG_MIICTL_INUSE equ 0x08000 |
NVREG_MIICTL_WRITE equ 0x00400 |
NVREG_MIICTL_ADDRSHIFT equ 5 |
NVREG_MIISPEED_BIT8 equ (1 shl 8) |
NVREG_MIIDELAY equ 5 |
NVREG_IRQ_RX_ERROR equ 0x0001 |
NVREG_IRQ_RX equ 0x0002 |
NVREG_IRQ_RX_NOBUF equ 0x0004 |
NVREG_IRQ_LINK equ 0x0040 |
NVREG_IRQ_TIMER equ 0x0020 |
NVREG_IRQMASK_WANTED_2 equ 0x0147 |
NVREG_IRQ_RX_ALL equ (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) |
NVREG_IRQ_TX_ALL equ 0 ; ??????????? |
NVREG_IRQ_OTHER_ALL equ (NVREG_IRQ_LINK or NVREG_IRQ_TIMER) |
NVREG_IRQSTAT_MASK equ 0x1ff |
NVREG_TXRXCTL_KICK equ 0x0001 |
NVREG_TXRXCTL_BIT1 equ 0x0002 |
NVREG_TXRXCTL_BIT2 equ 0x0004 |
NVREG_TXRXCTL_IDLE equ 0x0008 |
NVREG_TXRXCTL_RESET equ 0x0010 |
NVREG_TXRXCTL_RXCHECK equ 0x0400 |
NVREG_MCASTADDRA_FORCE equ 0x01 |
NVREG_MAC_RESET_ASSERT equ 0x0F3 |
NVREG_MISC1_HD equ 0x02 |
NVREG_MISC1_FORCE equ 0x3b0f3c |
NVREG_PFF_ALWAYS equ 0x7F0008 |
NVREG_PFF_PROMISC equ 0x80 |
NVREG_PFF_MYADDR equ 0x20 |
NVREG_OFFLOAD_HOMEPHY equ 0x601 |
NVREG_OFFLOAD_NORMAL equ RX_NIC_BUFSIZE |
NVREG_RNDSEED_MASK equ 0x00ff |
NVREG_RNDSEED_FORCE equ 0x7f00 |
NVREG_RNDSEED_FORCE2 equ 0x2d00 |
NVREG_RNDSEED_FORCE3 equ 0x7400 |
; NVREG_POLL_DEFAULT is the interval length of the timer source on the nic |
; NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms |
NVREG_POLL_DEFAULT equ 970 |
NVREG_ADAPTCTL_START equ 0x02 |
NVREG_ADAPTCTL_LINKUP equ 0x04 |
NVREG_ADAPTCTL_PHYVALID equ 0x40000 |
NVREG_ADAPTCTL_RUNNING equ 0x100000 |
NVREG_ADAPTCTL_PHYSHIFT equ 24 |
NVREG_WAKEUPFLAGS_VAL equ 0x7770 |
NVREG_POWERSTATE_POWEREDUP equ 0x8000 |
NVREG_POWERSTATE_VALID equ 0x0100 |
NVREG_POWERSTATE_MASK equ 0x0003 |
NVREG_POWERSTATE_D0 equ 0x0000 |
NVREG_POWERSTATE_D1 equ 0x0001 |
NVREG_POWERSTATE_D2 equ 0x0002 |
NVREG_POWERSTATE_D3 equ 0x0003 |
NVREG_POWERSTATE2_POWERUP_MASK equ 0x0F11 |
NVREG_POWERSTATE2_POWERUP_REV_A3 equ 0x0001 |
NVREG_RCVCTL_START equ 0x01 |
NVREG_RCVSTAT_BUSY equ 0x01 |
NVREG_XMITCTL_START equ 0x01 |
NVREG_LINKSPEED_FORCE equ 0x10000 |
NVREG_LINKSPEED_10 equ 1000 |
NVREG_LINKSPEED_100 equ 100 |
NVREG_LINKSPEED_1000 equ 50 |
NVREG_RINGSZ_TXSHIFT equ 0 |
NVREG_RINGSZ_RXSHIFT equ 16 |
LPA_1000FULL equ 0x0800 |
; Link partner ability register. |
LPA_SLCT equ 0x001f ; Same as advertise selector |
LPA_10HALF equ 0x0020 ; Can do 10mbps half-duplex |
LPA_10FULL equ 0x0040 ; Can do 10mbps full-duplex |
LPA_100HALF equ 0x0080 ; Can do 100mbps half-duplex |
LPA_100FULL equ 0x0100 ; Can do 100mbps full-duplex |
LPA_100BASE4 equ 0x0200 ; Can do 100mbps 4k packets |
LPA_RESV equ 0x1c00 ; Unused... |
LPA_RFAULT equ 0x2000 ; Link partner faulted |
LPA_LPACK equ 0x4000 ; Link partner acked us |
LPA_NPAGE equ 0x8000 ; Next page bit |
MII_READ equ (-1) |
MII_PHYSID1 equ 0x02 ; PHYS ID 1 |
MII_PHYSID2 equ 0x03 ; PHYS ID 2 |
MII_BMCR equ 0x00 ; Basic mode control register |
MII_BMSR equ 0x01 ; Basic mode status register |
MII_ADVERTISE equ 0x04 ; Advertisement control reg |
MII_LPA equ 0x05 ; Link partner ability reg |
MII_SREVISION equ 0x16 ; Silicon revision |
MII_RESV1 equ 0x17 ; Reserved... |
MII_NCONFIG equ 0x1c ; Network interface config |
; PHY defines |
PHY_OUI_MARVELL equ 0x5043 |
PHY_OUI_CICADA equ 0x03f1 |
PHYID1_OUI_MASK equ 0x03ff |
PHYID1_OUI_SHFT equ 6 |
PHYID2_OUI_MASK equ 0xfc00 |
PHYID2_OUI_SHFT equ 10 |
PHY_INIT1 equ 0x0f000 |
PHY_INIT2 equ 0x0e00 |
PHY_INIT3 equ 0x01000 |
PHY_INIT4 equ 0x0200 |
PHY_INIT5 equ 0x0004 |
PHY_INIT6 equ 0x02000 |
PHY_GIGABIT equ 0x0100 |
PHY_TIMEOUT equ 0x1 |
PHY_ERROR equ 0x2 |
PHY_100 equ 0x1 |
PHY_1000 equ 0x2 |
PHY_HALF equ 0x100 |
PHY_RGMII equ 0x10000000 |
; desc_ver values: |
; This field has two purposes: |
; - Newer nics uses a different ring layout. The layout is selected by |
; comparing np->desc_ver with DESC_VER_xy. |
; - It contains bits that are forced on when writing to NvRegTxRxControl. |
DESC_VER_1 equ 0x0 |
DESC_VER_2 equ (0x02100 or NVREG_TXRXCTL_RXCHECK) |
MAC_ADDR_LEN equ 6 |
NV_TX_LASTPACKET equ (1 shl 16) |
NV_TX_RETRYERROR equ (1 shl 19) |
NV_TX_LASTPACKET1 equ (1 shl 24) |
NV_TX_DEFERRED equ (1 shl 26) |
NV_TX_CARRIERLOST equ (1 shl 27) |
NV_TX_LATECOLLISION equ (1 shl 28) |
NV_TX_UNDERFLOW equ (1 shl 29) |
NV_TX_ERROR equ (1 shl 30) |
NV_TX_VALID equ (1 shl 31) |
NV_TX2_LASTPACKET equ (1 shl 29) |
NV_TX2_RETRYERROR equ (1 shl 18) |
NV_TX2_LASTPACKET1 equ (1 shl 23) |
NV_TX2_DEFERRED equ (1 shl 25) |
NV_TX2_CARRIERLOST equ (1 shl 26) |
NV_TX2_LATECOLLISION equ (1 shl 27) |
NV_TX2_UNDERFLOW equ (1 shl 28) |
; error and valid are the same for both |
NV_TX2_ERROR equ (1 shl 30) |
NV_TX2_VALID equ (1 shl 31) |
NV_RX_DESCRIPTORVALID equ (1 shl 16) |
NV_RX_AVAIL equ (1 shl 31) |
NV_RX2_DESCRIPTORVALID equ (1 shl 29) |
RX_RING equ 4 |
TX_RING equ 2 |
FLAG_MASK_V1 equ 0xffff0000 |
FLAG_MASK_V2 equ 0xffffc000 |
LEN_MASK_V1 equ (0xffffffff xor FLAG_MASK_V1) |
LEN_MASK_V2 equ (0xffffffff xor FLAG_MASK_V2) |
; Miscelaneous hardware related defines: |
NV_PCI_REGSZ_VER1 equ 0x270 |
NV_PCI_REGSZ_VER2 equ 0x604 |
; various timeout delays: all in usec |
NV_TXRX_RESET_DELAY equ 4 |
NV_TXSTOP_DELAY1 equ 10 |
NV_TXSTOP_DELAY1MAX equ 500000 |
NV_TXSTOP_DELAY2 equ 100 |
NV_RXSTOP_DELAY1 equ 10 |
NV_RXSTOP_DELAY1MAX equ 500000 |
NV_RXSTOP_DELAY2 equ 100 |
NV_SETUP5_DELAY equ 5 |
NV_SETUP5_DELAYMAX equ 50000 |
NV_POWERUP_DELAY equ 5 |
NV_POWERUP_DELAYMAX equ 5000 |
NV_MIIBUSY_DELAY equ 50 |
NV_MIIPHY_DELAY equ 10 |
NV_MIIPHY_DELAYMAX equ 10000 |
NV_MAC_RESET_DELAY equ 64 |
NV_WAKEUPPATTERNS equ 5 |
NV_WAKEUPMASKENTRIES equ 4 |
; Advertisement control register. |
ADVERTISE_SLCT equ 0x001f ; Selector bits |
ADVERTISE_CSMA equ 0x0001 ; Only selector supported |
ADVERTISE_10HALF equ 0x0020 ; Try for 10mbps half-duplex |
ADVERTISE_10FULL equ 0x0040 ; Try for 10mbps full-duplex |
ADVERTISE_100HALF equ 0x0080 ; Try for 100mbps half-duplex |
ADVERTISE_100FULL equ 0x0100 ; Try for 100mbps full-duplex |
ADVERTISE_100BASE4 equ 0x0200 ; Try for 100mbps 4k packets |
ADVERTISE_RESV equ 0x1c00 ; Unused... |
ADVERTISE_RFAULT equ 0x2000 ; Say we can detect faults |
ADVERTISE_LPACK equ 0x4000 ; Ack link partners response |
ADVERTISE_NPAGE equ 0x8000 ; Next page bit |
ADVERTISE_FULL equ (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA) |
ADVERTISE_ALL equ (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL) |
MII_1000BT_CR equ 0x09 |
MII_1000BT_SR equ 0x0a |
ADVERTISE_1000FULL equ 0x0200 |
ADVERTISE_1000HALF equ 0x0100 |
BMCR_ANRESTART equ 0x0200 ; Auto negotiation restart |
BMCR_ANENABLE equ 0x1000 ; Enable auto negotiation |
BMCR_SPEED100 equ 0x2000 ; Select 100Mbps |
BMCR_LOOPBACK equ 0x4000 ; TXD loopback bits |
BMCR_RESET equ 0x8000 ; Reset the DP83840 |
; Basic mode status register. |
BMSR_ERCAP equ 0x0001 ; Ext-reg capability |
BMSR_JCD equ 0x0002 ; Jabber detected |
BMSR_LSTATUS equ 0x0004 ; Link status |
BMSR_ANEGCAPABLE equ 0x0008 ; Able to do auto-negotiation |
BMSR_RFAULT equ 0x0010 ; Remote fault detected |
BMSR_ANEGCOMPLETE equ 0x0020 ; Auto-negotiation complete |
BMSR_RESV equ 0x07c0 ; Unused... |
BMSR_10HALF equ 0x0800 ; Can do 10mbps, half-duplex |
BMSR_10FULL equ 0x1000 ; Can do 10mbps, full-duplex |
BMSR_100HALF equ 0x2000 ; Can do 100mbps, half-duplex |
BMSR_100FULL equ 0x4000 ; Can do 100mbps, full-duplex |
BMSR_100BASE4 equ 0x8000 ; Can do 100mbps, 4k packets |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
uglobal |
forcedeth_mmio_addr dd 0 ; memory map physical address |
forcedeth_mmio_size dd 0 ; size of memory bar |
forcedeth_vendor_id dw 0 ; Vendor ID |
forcedeth_device_id dw 0 ; Device ID |
forcedeth_orig_mac0 dd 0 ; MAC |
forcedeth_orig_mac1 dd 0 ; MAC |
forcedeth_mapio_addr dd 0 ; mapped IO address |
forcedeth_txflags dd 0 ; |
forcedeth_desc_ver dd 0 ; |
forcedeth_irqmask dd 0 ; IRQ-mask |
forcedeth_wolenabled dd 0 ; WOL |
forcedeth_in_shutdown dd 0 ; |
forcedeth_cur_rx dd 0 ; |
forcedeth_refill_rx dd 0 ; |
forcedeth_phyaddr dd 0 ; |
forcedeth_phy_oui dd 0 ; |
forcedeth_gigabit dd 0 ; |
forcedeth_needs_mac_reset dd 0 ; |
forcedeth_linkspeed dd 0 ; |
forcedeth_duplex dd 0 ; |
forcedeth_next_tx dd 0 ; next TX descriptor number |
forcedeth_nic_tx dd 0 ; ??? d'nt used ??? |
forcedeth_packetlen dd 0 ; |
forcedeth_nocable dd 0 ; no cable present |
endg |
struc forcedeth_TxDesc { |
.PacketBuffer dd ? |
.FlagLen dd ? |
} |
virtual at 0 |
forcedeth_TxDesc forcedeth_TxDesc |
sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc |
end virtual |
struc forcedeth_RxDesc { |
.PacketBuffer dd ? |
.FlagLen dd ? |
} |
virtual at 0 |
forcedeth_RxDesc forcedeth_RxDesc |
sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc |
end virtual |
virtual at eth_data_start |
; Define the TX Descriptor |
align 256 |
forcedeth_tx_ring rb TX_RING * sizeof.forcedeth_TxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; TX Descriptor. All descriptors point to a |
; part of this buffer |
align 256 |
forcedeth_txb rb TX_RING * RX_NIC_BUFSIZE |
; Define the RX Descriptor |
align 256 |
forcedeth_rx_ring rb RX_RING * sizeof.forcedeth_RxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; RX Descriptor. All descriptors point to a |
; part of this buffer |
align 256 |
forcedeth_rxb rb RX_RING * RX_NIC_BUFSIZE |
end virtual |
;*************************************************************************** |
; Function |
; forcedeth_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
forcedeth_reset: |
; 1) erase previous misconfiguration |
; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill |
; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
; writel(0, base + NvRegMulticastAddrB) |
mov dword [edi+NvRegMulticastAddrB], 0 |
; writel(0, base + NvRegMulticastMaskA) |
mov dword [edi+NvRegMulticastMaskA], 0 |
; writel(0, base + NvRegMulticastMaskB) |
mov dword [edi+NvRegMulticastMaskB], 0 |
; writel(0, base + NvRegPacketFilterFlags) |
mov dword [edi+NvRegPacketFilterFlags], 0 |
; writel(0, base + NvRegTransmitterControl) |
mov dword [edi+NvRegTransmitterControl], 0 |
; writel(0, base + NvRegReceiverControl) |
mov dword [edi+NvRegReceiverControl], 0 |
; writel(0, base + NvRegAdapterControl) |
mov dword [edi+NvRegAdapterControl], 0 |
; 2) initialize descriptor rings |
; init_ring(nic) |
call forcedeth_init_ring |
; writel(0, base + NvRegLinkSpeed) |
mov dword [edi+NvRegLinkSpeed], 0 |
; writel(0, base + NvRegUnknownTransmitterReg) |
mov dword [edi+NvRegUnknownTransmitterReg], 0 |
; txrx_reset(nic) |
call forcedeth_txrx_reset |
; writel(0, base + NvRegUnknownSetupReg6) |
mov dword [edi+NvRegUnknownSetupReg6], 0 |
; np->in_shutdown = 0 |
mov dword [forcedeth_in_shutdown], 0 |
; 3) set mac address |
; writel(mac[0], base + NvRegMacAddrA) |
mov eax, dword [forcedeth_orig_mac0] |
mov dword [edi+NvRegMacAddrA], eax |
; writel(mac[1], base + NvRegMacAddrB) |
mov eax, dword [forcedeth_orig_mac1] |
mov dword [edi+NvRegMacAddrB], eax |
; 4) give hw rings |
; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr) |
mov eax, forcedeth_rx_ring |
;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax |
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov dword [edi+NvRegRxRingPhysAddr], eax |
; writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr) |
mov eax, forcedeth_tx_ring |
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov dword [edi+NvRegTxRingPhysAddr], eax |
; writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes) |
mov dword [edi+NvRegRingSizes], (((RX_RING - 1) shl NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) shl NVREG_RINGSZ_TXSHIFT)) |
; 5) continue setup |
; np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
mov dword [forcedeth_linkspeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; np->duplex = 0 |
mov dword [forcedeth_duplex], 0 |
; writel(np->linkspeed, base + NvRegLinkSpeed) |
mov dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3) |
mov dword [edi+NvRegUnknownSetupReg3], NVREG_UNKSETUP3_VAL1 |
; writel(np->desc_ver, base + NvRegTxRxControl) |
mov eax, dword [forcedeth_desc_ver] |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base) |
call forcedeth_pci_push |
; writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl) |
or eax, NVREG_TXRXCTL_BIT1 |
mov dword [edi+NvRegTxRxControl], eax |
; reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n") |
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
stdcall forcedeth_reg_delay,NvRegUnknownSetupReg5,NVREG_UNKSETUP5_BIT31,NVREG_UNKSETUP5_BIT31,NV_SETUP5_DELAY,NV_SETUP5_DELAYMAX,0 |
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
; writel(0, base + NvRegUnknownSetupReg4) |
mov dword [edi+NvRegUnknownSetupReg4], 0 |
; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half") |
;;;;;;;;;;; DEBUGF |
; 6) continue setup |
; writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1) |
mov dword [edi+NvRegMisc1], (NVREG_MISC1_FORCE or NVREG_MISC1_HD) |
; writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus) |
mov eax, dword [edi+NvRegTransmitterStatus] |
mov dword [edi+NvRegTransmitterStatus], eax |
; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags) |
mov dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS |
; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig) |
mov dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL |
; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus) |
mov eax, dword [edi+NvRegReceiverStatus] |
mov dword [edi+NvRegReceiverStatus], eax |
; Get a random number |
; i = random() |
push edi |
stdcall sys_clock ; eax = 0x00SSMMHH (current system time) |
pop edi |
; writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed) |
and eax, NVREG_RNDSEED_MASK |
or eax, NVREG_RNDSEED_FORCE |
mov dword [edi+NvRegRandomSeed], eax |
; writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1) |
mov dword [edi+NvRegUnknownSetupReg1], NVREG_UNKSETUP1_VAL |
; writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2) |
mov dword [edi+NvRegUnknownSetupReg2], NVREG_UNKSETUP2_VAL |
; writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval) |
mov dword [edi+NvRegPollingInterval], NVREG_POLL_DEFAULT |
; writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6) |
mov dword [edi+NvRegUnknownSetupReg6], NVREG_UNKSETUP6_VAL |
; writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING, |
; base + NvRegAdapterControl) |
mov eax, dword [forcedeth_phyaddr] |
shl eax, NVREG_ADAPTCTL_PHYSHIFT |
or eax, (NVREG_ADAPTCTL_PHYVALID or NVREG_ADAPTCTL_RUNNING) |
mov dword [edi+NvRegAdapterControl], eax |
; writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed) |
mov dword [edi+NvRegMIISpeed], (NVREG_MIISPEED_BIT8 or NVREG_MIIDELAY) |
; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4) |
mov dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL |
; writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags) |
mov dword [edi+NvRegWakeUpFlags], NVREG_WAKEUPFLAGS_VAL |
; i = readl(base + NvRegPowerState) |
mov eax, dword [edi+NvRegPowerState] |
; if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) |
test eax, NVREG_POWERSTATE_POWEREDUP |
jnz @f |
; writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState) |
or eax, NVREG_POWERSTATE_POWEREDUP |
mov dword [edi+NvRegPowerState], eax |
@@: |
; pci_push(base) |
call forcedeth_pci_push |
; nv_udelay(10) |
mov esi, 10 |
call forcedeth_nv_udelay |
; writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState) |
mov eax, dword [edi+NvRegPowerState] |
or eax, NVREG_POWERSTATE_VALID |
mov dword [edi+NvRegPowerState], eax |
; ??? disable all interrupts ??? |
; writel(0, base + NvRegIrqMask) |
mov dword [edi+NvRegIrqMask], 0 |
;;; ; ??? Mask RX interrupts |
;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_RX_ALL |
;;; ; ??? Mask TX interrupts |
;;; ;mov dword [edi+NvRegIrqMask], NVREG_IRQ_TX_ALL |
;;; ; ??? Mask OTHER interrupts |
;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_OTHER_ALL |
; pci_push(base) |
call forcedeth_pci_push |
; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus) |
mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
; pci_push(base) |
call forcedeth_pci_push |
; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
; writel(0, base + NvRegMulticastAddrB) |
mov dword [edi+NvRegMulticastAddrB], 0 |
; writel(0, base + NvRegMulticastMaskA) |
mov dword [edi+NvRegMulticastMaskA], 0 |
; writel(0, base + NvRegMulticastMaskB) |
mov dword [edi+NvRegMulticastMaskB], 0 |
; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags) |
mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR) |
; set_multicast(nic) |
call forcedeth_set_multicast |
; One manual link speed update: Interrupts are enabled, future link |
; speed changes cause interrupts and are handled by nv_link_irq(). |
; miistat = readl(base + NvRegMIIStatus) |
mov eax, dword [edi+NvRegMIIStatus] |
; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
; dprintf(("startup: got 0x%hX.\n", miistat)); |
;;; DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax |
; ret = update_linkspeed(nic) |
call forcedeth_update_linkspeed |
push eax |
; start_tx(nic) |
call forcedeth_start_tx |
pop eax |
; if (ret) { |
; //Start Connection netif_carrier_on(dev); |
; } else { |
; printf("no link during initialization.\n"); |
; } |
;*** added by shurf (21.09.2008) |
mov dword [forcedeth_nocable], 0 |
;*** |
test eax, eax |
jnz .return |
DEBUGF 1," K : FORCEDETH: no link during initialization.\n" |
;*** added by shurf (21.09.2008) |
mov dword [forcedeth_nocable], 1 |
;*** |
.return: |
; Indicate that we have successfully reset the card |
mov eax, dword [pci_data] |
mov dword [eth_status], eax |
ret |
;*************************************************************************** |
; Function |
; forcedeth_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
forcedeth_probe: |
; DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
mov dword [forcedeth_needs_mac_reset], 0 |
; BEGIN of adjust_pci_device() |
; read word from PCI-device |
mov al, 1 ;;;;;;;;;;;;;;2 |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_REG_COMMAND |
call pci_read_reg |
mov bx, ax ; new command |
or bx, PCI_COMMAND_MASTER |
or bx, PCI_COMMAND_IO |
cmp bx, ax |
je @f |
; Enabling PCI-device (make card as bus master) |
DEBUGF 1," K : FORCEDETH: Updating PCI command 0x%x->0x%x\n", ax, bx |
mov cx, bx |
mov al, 1 ;;;;;;;;;;;;2 |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_REG_COMMAND |
call pci_write_reg |
; Check latency settings |
@@: |
; Get current latency settings from Latency timer register (byte) |
mov al, 0 ;;;;;;;;;1 |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_LATENCY_TIMER |
call pci_read_reg |
; see if its at least 32 |
cmp al, 32 |
jge @f |
; set latency to 32 |
DEBUGF 1, "K : FORCEDETH: PCI latency timer (CFLT) is unreasonably low at %d.\n", al |
DEBUGF 1, "K : FORCEDETH: Setting to 32 clocks.\n" |
mov cl, 32 |
mov al, 0 ;;;;;;;1 |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_LATENCY_TIMER |
call pci_write_reg |
; END of adjust_pci_device() |
@@: |
; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0)) |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 |
call pci_read_reg |
test eax, PCI_BASE_ADDRESS_SPACE_IO |
jz @f |
and eax, PCI_BASE_ADDRESS_IO_MASK |
jmp .next |
@@: push eax |
and eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK |
cmp eax, PCI_BASE_ADDRESS_MEM_TYPE_64 |
jne .not64 |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 + 4 |
call pci_read_reg |
or eax, eax |
jz .not64 |
DEBUGF 1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n" |
or eax, -1 |
jmp .next |
.not64: |
pop eax |
and eax, PCI_BASE_ADDRESS_MEM_MASK |
.next: |
; END of pci_bar_start |
; addr = eax |
mov dword [forcedeth_mmio_addr], eax |
; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0)) |
; Save original bar |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 |
call pci_read_reg |
mov dword [forcedeth_tmp_start], eax |
; Compute which bits can be set |
; (ecx - value to write) |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 |
mov ecx, (not 0) |
call pci_write_reg |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 |
call pci_read_reg |
push eax |
; Restore the original size |
mov al, 2 ; dword |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_BASE_ADDRESS_0 |
mov ecx, dword [forcedeth_tmp_start] |
call pci_write_reg |
; Find the significant bits |
pop eax |
test dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO |
jz @f |
and eax, PCI_BASE_ADDRESS_IO_MASK |
jmp .next2 |
@@: and eax, PCI_BASE_ADDRESS_MEM_MASK |
.next2: |
; Find the lowest bit set |
mov ecx, eax |
sub eax, 1 |
not eax |
and ecx, eax |
; END of pci_bar_start |
mov dword [forcedeth_mmio_size], ecx |
DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8 |
; Get Vendor and Device ID |
mov al, 2 |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_VENDOR_ID |
call pci_read_reg |
mov word [forcedeth_vendor_id], ax |
shr eax, 16 |
mov word [forcedeth_device_id], ax |
DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
; handle different descriptor versions |
mov eax, dword [forcedeth_device_id] |
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_1 |
je .ver1 |
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_2 |
je .ver1 |
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_3 |
je .ver1 |
mov dword [forcedeth_desc_ver], DESC_VER_2 |
jmp @f |
.ver1: mov dword [forcedeth_desc_ver], DESC_VER_1 |
@@: |
; read the mac address |
; map memory |
stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE) |
test eax, eax |
jz .fail |
mov dword [forcedeth_mapio_addr], eax |
mov edi, eax |
mov eax, dword [edi+NvRegMacAddrA] |
mov dword [forcedeth_orig_mac0], eax |
mov edx, dword [edi+NvRegMacAddrB] |
mov dword [forcedeth_orig_mac1], edx |
; save MAC-address to global variable node_addr |
mov dword [node_addr], eax |
mov word [node_addr+4], dx |
; reverse if desired |
cmp word [forcedeth_device_id], 0x03E5 |
jae .no_reverse_mac |
mov al, byte [node_addr] |
xchg al, byte [node_addr+5] |
mov byte [node_addr], al |
mov al, byte [node_addr+1] |
xchg al, byte [node_addr+4] |
mov byte [node_addr+4], al |
mov al, byte [node_addr+2] |
xchg al, byte [node_addr+3] |
mov byte [node_addr+3], al |
.no_reverse_mac: |
; DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8 |
; DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8 |
DEBUGF 1," K : FORCEDETH: MAC = %x-%x-%x-%x-%x-%x\n", [node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2, |
; disable WOL |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegWakeUpFlags], 0 |
mov dword [forcedeth_wolenabled], 0 |
mov dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID) |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
mov dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID) |
@@: |
; BEGIN of switch (pci->dev_id) |
cmp word [forcedeth_device_id], 0x01C3 |
jne .next_0x0066 |
; nforce |
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
jmp .end_switch |
.next_0x0066: |
cmp word [forcedeth_device_id], 0x0066 |
je @f |
cmp word [forcedeth_device_id], 0x00D6 |
je @f |
jmp .next_0x0086 |
@@: |
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
jmp .end_switch |
@@: or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
jmp .end_switch |
.next_0x0086: |
cmp word [forcedeth_device_id], 0x0086 |
je @f |
cmp word [forcedeth_device_id], 0x008c |
je @f |
cmp word [forcedeth_device_id], 0x00e6 |
je @f |
cmp word [forcedeth_device_id], 0x00df |
je @f |
cmp word [forcedeth_device_id], 0x0056 |
je @f |
cmp word [forcedeth_device_id], 0x0057 |
je @f |
cmp word [forcedeth_device_id], 0x0037 |
je @f |
cmp word [forcedeth_device_id], 0x0038 |
je @f |
jmp .next_0x0268 |
@@: |
; np->irqmask = NVREG_IRQMASK_WANTED_2; |
; np->irqmask |= NVREG_IRQ_TIMER; |
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
; if (np->desc_ver == DESC_VER_1) |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
; np->tx_flags |= NV_TX_LASTPACKET1; |
or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
jmp .end_switch |
; else |
@@: |
; np->tx_flags |= NV_TX2_LASTPACKET1; |
or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
; break; |
jmp .end_switch |
.next_0x0268: |
; cmp word [forcedeth_device_id], 0x0268 |
; je @f |
; cmp word [forcedeth_device_id], 0x0269 |
; je @f |
; cmp word [forcedeth_device_id], 0x0372 |
; je @f |
; cmp word [forcedeth_device_id], 0x0373 |
; je @f |
; jmp .default_switch |
;@@: |
cmp word [forcedeth_device_id], 0x0268 |
jb .default_switch |
; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id); |
mov al, 0 ; byte |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, PCI_REVISION_ID |
call pci_read_reg |
mov ecx, eax ; cl = revision_id |
; take phy and nic out of low power mode |
; powerstate = readl(base + NvRegPowerState2); |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi+NvRegPowerState2] ; eax = powerstate |
; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; |
and eax, not NVREG_POWERSTATE2_POWERUP_MASK |
; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3) |
cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12 |
je @f |
cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13 |
je @f |
jmp .end_if |
@@: |
cmp cl, 0xA3 |
jl .end_if |
; powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; |
or eax, NVREG_POWERSTATE2_POWERUP_REV_A3 |
.end_if: |
; writel(powerstate, base + NvRegPowerState2); |
mov dword [edi+NvRegPowerState2], eax |
; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ |
; np->irqmask = NVREG_IRQMASK_WANTED_2; |
; np->irqmask |= NVREG_IRQ_TIMER; |
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
; needs_mac_reset = 1; |
mov dword [forcedeth_needs_mac_reset], 1 |
; if (np->desc_ver == DESC_VER_1) |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
; np->tx_flags |= NV_TX_LASTPACKET1; |
or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
jmp .end_if2 |
@@: |
; else |
; np->tx_flags |= NV_TX2_LASTPACKET1; |
or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
.end_if2: |
; break; |
jmp .end_switch |
.default_switch: |
DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n" |
DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n" |
.end_switch: |
; END of switch (pci->dev_id) |
; Find a suitable phy |
mov dword [forcedeth_tmp_i], 1 |
.for_loop: |
; for (i = 1; i <= 32; i++) |
; phyaddr = i & 0x1f |
mov ebx, dword [forcedeth_tmp_i] |
and ebx, 0x1f |
; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ) |
;EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_PHYSID1 |
mov ecx, MII_READ |
call forcedeth_mii_rw ; id1 = eax |
; if (id1 < 0 || id1 == 0xffff) |
cmp eax, 0xffffffff |
je .continue_for |
test eax, 0x80000000 |
jnz .continue_for |
mov dword [forcedeth_tmp_id1], eax |
; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ) |
mov eax, MII_PHYSID2 |
mov ecx, MII_READ |
call forcedeth_mii_rw ; id2 = eax |
; if (id2 < 0 || id2 == 0xffff) |
cmp eax, 0xffffffff |
je .continue_for |
test eax, 0x80000000 |
jnz .continue_for |
mov dword [forcedeth_tmp_id2], eax |
jmp .break_for |
.continue_for: |
inc dword [forcedeth_tmp_i] |
cmp dword [forcedeth_tmp_i], 32 |
jle .for_loop |
jmp .end_for |
.break_for: |
;;;; DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8 |
; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT |
mov eax, dword [forcedeth_tmp_id1] |
and eax, PHYID1_OUI_MASK |
shl eax, PHYID1_OUI_SHFT |
mov dword [forcedeth_tmp_id1], eax |
; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT |
mov eax, dword [forcedeth_tmp_id2] |
and eax, PHYID2_OUI_MASK |
shr eax, PHYID2_OUI_SHFT |
mov dword [forcedeth_tmp_id2], eax |
DEBUGF 1," K : FORCEDETH: Found PHY 0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx |
; np->phyaddr = phyaddr; |
mov dword [forcedeth_phyaddr], ebx |
; np->phy_oui = id1 | id2; |
mov eax, dword [forcedeth_tmp_id1] |
or eax, dword [forcedeth_tmp_id2] |
mov dword [forcedeth_phy_oui], eax |
.end_for: |
; if (i == 33) |
cmp dword [forcedeth_tmp_i], 33 |
jne @f |
; PHY in isolate mode? No phy attached and user wants to |
; test loopback? Very odd, but can be correct. |
DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n" |
jmp .next3 |
@@: |
; if (i != 33) |
; reset it |
call forcedeth_phy_init |
.next3: |
; dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n", |
; pci->name, pci->vendor, pci->dev_id, pci->name)); |
DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
; if(needs_mac_reset) mac_reset(nic); |
cmp dword [forcedeth_needs_mac_reset], 0 |
je @f |
call forcedeth_mac_reset |
@@: |
; if(!forcedeth_reset(nic)) return 0; // no valid link |
call forcedeth_reset |
test eax, eax |
jnz @f |
mov eax, 0 |
jmp .return |
@@: |
; point to NIC specific routines |
; dev->disable = forcedeth_disable; |
; nic->poll = forcedeth_poll; |
; nic->transmit = forcedeth_transmit; |
; nic->irq = forcedeth_irq; |
;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0 |
; return 1 |
mov eax, 1 |
jmp .return |
.fail: |
mov eax, 0 |
.return: |
ret |
uglobal |
forcedeth_tmp_start dd ? |
forcedeth_tmp_reg dd ? |
forcedeth_tmp_i dd ? |
forcedeth_tmp_id1 dd ? |
forcedeth_tmp_id2 dd ? |
forcedeth_tmp_phyinterface dd ? |
forcedeth_tmp_newls dd ? |
forcedeth_tmp_newdup dd ? |
forcedeth_tmp_retval dd ? |
forcedeth_tmp_control_1000 dd ? |
forcedeth_tmp_lpa dd ? |
forcedeth_tmp_adv dd ? |
forcedeth_tmp_len dd ? |
forcedeth_tmp_valid dd ? |
forcedeth_tmp_nr dd ? |
forcedeth_tmp_ptxb dd ? |
endg |
;*************************************************************************** |
; Function |
; forcedeth_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
forcedeth_poll: |
mov word [eth_rx_data_len], 0 |
; ???????????????????????????? |
; ??? Clear events? ??? |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
; ???????????????????????????? |
.top: |
; i = np->cur_rx % RX_RING |
mov eax, dword [forcedeth_cur_rx] |
and eax, (RX_RING-1) |
mov dword [forcedeth_tmp_i], eax |
; Flags = le32_to_cpu(rx_ring[i].FlagLen) |
; Flags = rx_ring[i].FlagLen |
mov cl, sizeof.forcedeth_RxDesc |
mul cl |
add eax, forcedeth_rx_ring |
mov ebx, eax |
mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
; if (Flags & NV_RX_AVAIL) |
test eax, NV_RX_AVAIL |
; return 0; /* still owned by hardware, */ |
; still owned by hardware |
jnz .return0 |
;;;;; DEBUGF 1,"poll: FlagLen = %x\n", eax |
; if (np->desc_ver == DESC_VER_1) { |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
; if (!(Flags & NV_RX_DESCRIPTORVALID)) |
test eax, NV_RX_DESCRIPTORVALID |
; return 0; |
jz .return0 |
jmp .next |
; } else { |
@@: |
; if (!(Flags & NV_RX2_DESCRIPTORVALID)) |
test eax, NV_RX2_DESCRIPTORVALID |
; return 0; |
jz .return0 |
; } |
.next: |
; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
; eax = FlagLen |
cmp dword [forcedeth_desc_ver], DESC_VER_1 |
jne @f |
and eax, LEN_MASK_V1 |
jmp .next2 |
@@: |
and eax, LEN_MASK_V2 |
.next2: |
; mov dword [forcedeth_tmp_len], eax |
; valid = 1 |
mov dword [forcedeth_tmp_valid], 1 |
; got a valid packet - forward it to the network core |
; nic->packetlen = len; |
mov dword [forcedeth_packetlen], eax |
; |
mov word [eth_rx_data_len], ax |
;;;;;;;;; DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen] |
; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen); |
; Copy packet to system buffer (Ether_buffer) |
;???? ecx = (len-4) |
mov ecx, eax |
push ecx |
shr ecx, 2 |
; rxb + (i * RX_NIC_BUFSIZE) |
mov eax, dword [forcedeth_tmp_i] |
mov bx, RX_NIC_BUFSIZE |
mul bx |
add eax, forcedeth_rxb |
mov esi, eax |
mov edi, Ether_buffer |
cld ; set to increment |
rep movsd ; mov dword from [esi++] to [edi++] |
pop ecx |
and ecx, 3 ; copy rest 1-3 bytes |
rep movsb |
; wmb(); |
; ??? |
; np->cur_rx++; |
inc dword [forcedeth_cur_rx] |
; if (!valid) |
cmp dword [forcedeth_tmp_valid], 0 |
jne @f |
; goto top; |
jmp .top |
@@: |
; alloc_rx(nic); |
call forcedeth_alloc_rx |
; return 1; |
jmp .return1 |
;;;;; DEBUGF 1,"K : FORCEDETH: poll: ...\n" |
.return0: |
mov eax, 0 |
jmp .return |
.return1: |
mov eax, 1 |
.return: |
;;push eax |
; ???????????????????????????????????????????????? |
; ????? clear interrupt mask/status |
; read IRQ status |
;;mov edi, dword [forcedeth_mapio_addr] |
;;mov eax, dword [edi+NvRegIrqStatus] |
; clear events |
;;and eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER) |
; write IRQ status |
;;mov dword [edi+NvRegIrqStatus], eax |
; ???????????????????????????????????????????????? |
;;pop eax |
ret |
;*************************************************************************** |
; Function |
; forcedeth_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
forcedeth_transmit: |
; send the packet to destination |
;pusha |
;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx |
;DEBUGF 1,"K : FORCEDETH: transmit: packet len = 0x%x\n", ecx |
;mov eax, dword [edi] |
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr = 0x%x\n", eax |
;mov eax, dword [edi+4] |
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2 = 0x%x\n", eax |
;mov eax, dword [node_addr] |
;DEBUGF 1,"K : FORCEDETH: transmit: src adr = 0x%x\n", eax |
;mov eax, dword [node_addr+4] |
;DEBUGF 1,"K : FORCEDETH: transmit: src adr2 = 0x%x\n", eax |
;popa |
; int nr = np->next_tx % TX_RING |
mov eax, dword [forcedeth_next_tx] |
and eax, (TX_RING-1) |
mov dword [forcedeth_tmp_nr], eax |
; point to the current txb incase multiple tx_rings are used |
; ptxb = txb + (nr * RX_NIC_BUFSIZE) |
push ecx |
mov cx, RX_NIC_BUFSIZE |
mul cx ; AX*CX, result to DX:AX |
add eax, forcedeth_txb |
mov dword [forcedeth_tmp_ptxb], eax |
push esi |
mov esi, edi ; dst MAC |
mov edi, eax ; packet buffer |
cld ; set to increment |
; copy the packet to ring buffer |
; memcpy(ptxb, d, ETH_ALEN); /* dst */ |
movsd |
movsw |
; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ |
mov esi, node_addr |
movsd |
movsw |
; nstype = htons((u16) t); /* type */ |
; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ |
mov word [edi], bx |
add edi, 2 |
; memcpy(ptxb + ETH_HLEN, p, s); |
pop esi |
pop ecx |
push ecx |
shr ecx, 2 ; count in dwords |
rep movsd ; copy dwords from [esi+=4] to [edi+=4] |
pop ecx |
push ecx |
and ecx, 3 ; copy rest 1-3 bytes |
rep movsb ; copy bytess from [esi++] to [edi++] |
; s += ETH_HLEN; |
; while (s < ETH_ZLEN) /* pad to min length */ |
; ptxb[s++] = '\0'; |
; pad to min length |
pop ecx |
add ecx, ETH_HLEN |
push ecx ; header length + data length |
cmp ecx, ETH_ZLEN |
jge @f |
mov eax, ETH_ZLEN |
sub eax, ecx |
xchg eax, ecx |
mov al, 0 |
rep stosb ; copy byte from al to [edi++] |
@@: |
; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb); |
mov eax, dword [forcedeth_tmp_nr] |
mov cl, sizeof.forcedeth_TxDesc |
mul cl |
add eax, forcedeth_tx_ring |
mov ebx, eax |
mov eax, dword [forcedeth_tmp_ptxb] |
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov [ebx + forcedeth_TxDesc.PacketBuffer], eax |
;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax |
;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8 |
; wmb(); |
; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags); |
pop eax ; header length + data length |
mov ecx, dword [forcedeth_txflags] |
or eax, ecx |
mov [ebx + forcedeth_TxDesc.FlagLen], eax |
; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl); |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [forcedeth_desc_ver] |
or eax, NVREG_TXRXCTL_KICK |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base); |
call forcedeth_pci_push |
; np->next_tx++ |
inc dword [forcedeth_next_tx] ; may be need to reset? Overflow? |
ret |
;*************************************************************************** |
; Function |
; forcedeth_cable |
; |
; Description |
; Return AL=0, if cable is not connected |
; Returm AL=1, if cable is connected |
; |
;*************************************************************************** |
forcedeth_cable: |
mov al, 1 |
cmp dword [forcedeth_nocable], 1 |
jne .return |
mov al, 0 |
.return: |
ret |
;*************************************************************************** |
; read/write a register on the PHY. |
; Caller must guarantee serialization |
; Input: EAX - miireg, EBX - addr, ECX - value |
; Output: EAX - retval |
forcedeth_mii_rw: |
push ebx |
push eax ; save miireg |
; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus) |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
; reg = readl(base + NvRegMIIControl) |
mov eax, dword [edi+NvRegMIIControl] |
test eax, NVREG_MIICTL_INUSE |
jz @f |
; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl) |
mov dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE |
; nv_udelay(NV_MIIBUSY_DELAY) |
mov esi, NV_MIIBUSY_DELAY |
call forcedeth_nv_udelay |
@@: |
; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg |
pop edx ; restore miireg |
mov eax, ebx |
shl eax, NVREG_MIICTL_ADDRSHIFT |
or eax, edx |
mov dword [forcedeth_tmp_reg], eax |
cmp ecx, MII_READ |
je @f |
; writel(value, base + NvRegMIIData) |
mov dword [edi+NvRegMIIData], ecx |
; reg |= NVREG_MIICTL_WRITE |
or dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE |
@@: |
; writel(reg, base + NvRegMIIControl) |
mov eax, dword [forcedeth_tmp_reg] |
mov dword [edi+NvRegMIIControl], eax |
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL) |
stdcall forcedeth_reg_delay,NvRegMIIControl,NVREG_MIICTL_INUSE,0,NV_MIIPHY_DELAY,NV_MIIPHY_DELAYMAX,0 |
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
test eax, eax |
jz @f |
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx |
mov eax, 0xffffffff |
jmp .return |
@@: |
cmp ecx, MII_READ |
je @f |
;it was a write operation - fewer failures are detectable |
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx |
mov eax, 0 |
jmp .return |
@@: |
; readl(base + NvRegMIIStatus) |
mov eax, dword [edi+NvRegMIIStatus] |
test eax, NVREG_MIISTAT_ERROR |
jz @f |
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx |
mov eax, 0xffffffff |
jmp .return |
@@: |
; retval = readl(base + NvRegMIIData) |
mov eax, dword [edi+NvRegMIIData] |
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax |
.return: |
pop ebx |
ret |
; Input: ESI - delay |
; Output: none |
forcedeth_nv_udelay: |
push ebx |
cmp dword [forcedeth_in_shutdown], 0 |
jne @f |
call forcedeth_udelay ; delay on ESI |
jmp .return |
@@: |
.loop: |
cmp esi, 0 |
je .return |
; Don't allow an rx_ring overflow to happen |
; while shutting down the NIC it will |
; kill the receive function. |
call forcedeth_drop_rx |
mov ebx, 3 ; sleep = 3 |
cmp ebx, esi ; if(sleep > delay) |
jle @f |
mov ebx, esi ; sleep = delay |
@@: |
push esi |
mov esi, ebx |
; udelay(sleep) |
call forcedeth_udelay ; delay on ESI |
pop esi |
sub esi, ebx ; delay -= sleep |
jmp .loop |
.return: |
pop ebx |
ret |
; Input: none |
; Output: none |
forcedeth_drop_rx: |
push eax ebx ecx edi |
; events = readl(base + NvRegIrqStatus) |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi+NvRegIrqStatus] |
test eax, eax |
jz @f |
; writel(events, base + NvRegIrqStatus) |
mov dword [edi+NvRegIrqStatus], eax |
@@: |
;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF))) |
test eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) |
jz .return |
.loop: |
; i = np->cur_rx % RX_RING |
mov eax, dword [forcedeth_cur_rx] |
and eax, (RX_RING-1) |
; //Flags = le32_to_cpu(rx_ring[i].FlagLen) |
; Flags = rx_ring[i].FlagLen |
mov cl, sizeof.forcedeth_RxDesc |
mul cl |
add eax, forcedeth_rx_ring |
mov ebx, eax |
mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2) |
; ??? len don't used later !!! ??? |
; ... |
test eax, NV_RX_AVAIL |
jnz .return ; still owned by hardware, |
; wmb() |
; ??? may be empty function ??? |
; np->cur_rx++ |
inc dword [forcedeth_cur_rx] |
; alloc_rx(NULL) |
call forcedeth_alloc_rx |
.return: |
pop edi ecx ebx eax |
ret |
; Fill rx ring entries. |
; Return 1 if the allocations for the skbs failed and the |
; rx engine is without Available descriptors |
; Input: none |
; Output: none |
forcedeth_alloc_rx: |
push eax ebx ecx edx |
; refill_rx = np->refill_rx |
mov ecx, dword [forcedeth_refill_rx] |
.loop: |
cmp dword [forcedeth_cur_rx], ecx |
je .loop_end |
; nr = refill_rx % RX_RING |
mov eax, ecx |
and eax, (RX_RING-1) ; nr |
; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE] |
push ecx |
push eax |
mov cl, sizeof.forcedeth_RxDesc |
mul cl |
add eax, forcedeth_rx_ring |
mov ebx, eax |
pop eax |
mov cx, RX_NIC_BUFSIZE |
mul cx |
pop ecx |
add eax, forcedeth_rxb |
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov [ebx + forcedeth_RxDesc.PacketBuffer], eax |
; wmb() |
; ... |
; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL |
mov [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL) |
inc ecx |
jmp .loop |
.loop_end: |
; np->refill_rx = refill_rx |
mov [forcedeth_refill_rx], ecx |
.return: |
pop edx ecx ebx eax |
ret |
; Delay in millisec |
; Input: ESI - delay in ms |
; Output: none |
forcedeth_udelay: |
call delay_ms |
ret |
; Input: offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword |
; Output: EAX - 0|1 |
;;;;proc forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword |
proc forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword |
push ebx esi edi |
; pci_push(base) |
call forcedeth_pci_push |
.loop: |
; nv_udelay(delay) |
mov esi, dword [delay] |
call forcedeth_nv_udelay ; delay in esi |
mov eax, dword [delaymax] |
sub eax, dword [delay] |
mov dword [delaymax], eax |
; if (delaymax < 0) |
test dword [delaymax], 0x80000000 |
jz @f |
; return 1 |
mov eax, 1 |
jmp .return |
@@: |
; while ((readl(base + offset) & mask) != target) |
mov edi, dword [forcedeth_mapio_addr] |
mov ebx, dword [offset] |
mov eax, dword [edi+ebx] |
and eax, dword [mask] |
cmp eax, dword [target] |
jne .loop |
xor eax, eax |
.return: |
pop edi esi ebx |
ret |
endp |
; Input: none |
; Output: none |
forcedeth_pci_push: |
push eax edi |
;force out pending posted writes |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi] |
pop edi eax |
ret |
; Input: none |
; Output: EAX - result (0 = OK, other = error) |
forcedeth_phy_init: |
push ebx ecx |
; set advertise register |
; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_ADVERTISE |
mov ecx, MII_READ |
call forcedeth_mii_rw ; reg = eax |
; reg |= |
; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | |
; ADVERTISE_100FULL | 0x800 | 0x400); |
or eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400) |
; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) |
; EBX - addr, EAX - miireg, ECX - value |
mov ecx, eax ; reg |
mov eax, MII_ADVERTISE |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz @f |
; printf("phy write to advertise failed.\n"); |
DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n" |
; return PHY_ERROR; |
mov eax, PHY_ERROR |
jmp .return |
@@: |
; get phy interface type |
; phyinterface = readl(base + NvRegPhyInterface); |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi+NvRegPhyInterface] ; phyinterface = eax |
mov dword [forcedeth_tmp_phyinterface], eax |
;;;;;;;;;;;;;;;;;;;;;;;;; |
DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8 |
;;;;;;;;;;;;;;;;;;;;;;;;; |
; see if gigabit phy |
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_BMSR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; mii_status = eax |
; if (mii_status & PHY_GIGABIT) |
test eax, PHY_GIGABIT |
jnz .gigabit |
; np->gigabit = 0; |
mov dword [forcedeth_gigabit], 0 |
jmp .next_if |
.gigabit: |
; np->gigabit = PHY_GIGABIT; |
mov dword [forcedeth_gigabit], PHY_GIGABIT |
; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_1000BT_CR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; mii_control_1000 = eax |
; mii_control_1000 &= ~ADVERTISE_1000HALF; |
and eax, (not ADVERTISE_1000HALF) |
; if (phyinterface & PHY_RGMII) |
test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
jz @f |
; mii_control_1000 |= ADVERTISE_1000FULL |
or eax, ADVERTISE_1000FULL |
jmp .next |
@@: |
; mii_control_1000 &= ~ADVERTISE_1000FULL |
and eax, (not ADVERTISE_1000FULL) |
.next: |
; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000)) |
; EBX - addr, EAX - miireg, ECX - value |
mov ecx, eax |
mov eax, MII_1000BT_CR |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz .next_if |
; printf("phy init failed.\n"); |
DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
; return PHY_ERROR; |
mov eax, PHY_ERROR |
jmp .return |
.next_if: |
; reset the phy |
; if (phy_reset(nic)) |
call forcedeth_phy_reset |
test eax, eax |
jz @f |
; printf("phy reset failed\n") |
DEBUGF 1," K : FORCEDETH: phy reset failed.\n" |
; return PHY_ERROR |
mov eax, PHY_ERROR |
jmp .return |
@@: |
; phy vendor specific configuration |
; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) |
cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
jne .next_if2 |
test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
jz .next_if2 |
; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ) |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_RESV1 |
mov ecx, MII_READ |
call forcedeth_mii_rw ; phy_reserved = eax |
; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2) |
and eax, (not (PHY_INIT1 or PHY_INIT2)) |
; phy_reserved |= (PHY_INIT3 | PHY_INIT4) |
or eax, (PHY_INIT3 or PHY_INIT4) |
; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) |
; EBX - addr, EAX - miireg, ECX - value |
mov ecx, eax |
mov eax, MII_RESV1 |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz @f |
; printf("phy init failed.\n") |
DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
; return PHY_ERROR |
mov eax, PHY_ERROR |
jmp .return |
@@: |
; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_NCONFIG |
mov ecx, MII_READ |
call forcedeth_mii_rw ; phy_reserved = eax |
; phy_reserved |= PHY_INIT5 |
or eax, PHY_INIT5 |
; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) |
; EBX - addr, EAX - miireg, ECX - value |
mov ecx, eax |
mov eax, MII_NCONFIG |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz .next_if2 |
; printf("phy init failed.\n") |
DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
; return PHY_ERROR |
mov eax, PHY_ERROR |
jmp .return |
.next_if2: |
; if (np->phy_oui == PHY_OUI_CICADA) |
cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
jne .restart |
; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ) |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_SREVISION |
mov ecx, MII_READ |
call forcedeth_mii_rw ; phy_reserved = eax |
; phy_reserved |= PHY_INIT6 |
or eax, PHY_INIT6 |
; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) |
mov ecx, eax |
mov eax, MII_SREVISION |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz .restart |
; printf("phy init failed.\n"); |
DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
; return PHY_ERROR; |
jmp .return |
.restart: |
; restart auto negotiation |
; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ) |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_BMCR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; mii_control = eax |
; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE) |
or eax, (BMCR_ANRESTART or BMCR_ANENABLE) |
; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) |
mov ecx, eax |
mov eax, MII_BMCR |
call forcedeth_mii_rw ; eax -> return |
test eax, eax |
jz .ok |
; return PHY_ERROR; |
mov eax, PHY_ERROR |
jmp .return |
.ok: |
mov eax, 0 |
.return: |
pop ecx ebx |
ret |
; Input: none |
; Output: EAX - result (0 = OK, other = error) |
forcedeth_phy_reset: |
push ebx ecx edx |
; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_BMCR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; miicontrol = eax |
; miicontrol |= BMCR_RESET; |
or eax, BMCR_RESET |
push eax |
; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) |
; EBX - addr, EAX - miireg, ECX - value |
mov ecx, eax |
mov eax, MII_BMCR |
call forcedeth_mii_rw ; miicontrol = eax |
test eax, eax |
jz @f |
pop eax |
mov eax, 0xffffffff |
jmp .return |
@@: |
pop eax |
; wait for 500ms |
; mdelay(500) |
mov esi, 500 |
call forcedeth_udelay |
; must wait till reset is deasserted |
; while (miicontrol & BMCR_RESET) { |
mov edx, 100 |
.while_loop: |
test eax, BMCR_RESET |
jz .while_loop_exit |
; mdelay(10); |
mov esi, 10 |
call forcedeth_udelay |
; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
; EBX - addr, EAX - miireg, ECX - value |
mov eax, MII_BMCR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; miicontrol = eax |
; FIXME: 100 tries seem excessive |
; if (tries++ > 100) |
dec edx |
jnz .while_loop |
; return -1; |
mov eax, 0xffffffff |
jmp .return |
.while_loop_exit: |
; return 0 |
mov eax, 0 |
.return: |
pop edx ecx ebx |
ret |
; Input: none |
; Output: none |
forcedeth_mac_reset: |
push esi edi |
; dprintf("mac_reset\n") |
DEBUGF 1," K : FORCEDETH: mac_reset.\n" |
; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [forcedeth_desc_ver] |
or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base) |
call forcedeth_pci_push |
; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset) |
mov dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT |
; pci_push(base) |
call forcedeth_pci_push |
; udelay(NV_MAC_RESET_DELAY) |
mov esi, NV_MAC_RESET_DELAY |
call forcedeth_nv_udelay |
; writel(0, base + NvRegMacReset) |
mov dword [edi+NvRegMacReset], 0 |
; pci_push(base) |
call forcedeth_pci_push |
; udelay(NV_MAC_RESET_DELAY) |
mov esi, NV_MAC_RESET_DELAY |
call forcedeth_nv_udelay |
; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
mov eax, dword [forcedeth_desc_ver] |
or eax, NVREG_TXRXCTL_BIT2 |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base) |
call forcedeth_pci_push |
pop edi esi |
ret |
; Input: none |
; Output: none |
forcedeth_init_ring: |
push eax ebx ecx |
; np->next_tx = np->nic_tx = 0 |
mov dword[forcedeth_next_tx], 0 |
mov dword[forcedeth_nic_tx], 0 |
; for (i = 0; i < TX_RING; i++) |
mov ecx, TX_RING |
.for_loop: |
; tx_ring[i].FlagLen = 0; |
mov eax, ecx |
dec eax |
mov bl, sizeof.forcedeth_TxDesc |
mul bl |
add eax, forcedeth_tx_ring |
mov ebx, eax |
mov dword [ebx + forcedeth_TxDesc.FlagLen], 0 |
loop .for_loop |
; np->cur_rx = RX_RING; |
mov dword [forcedeth_cur_rx], RX_RING |
; np->refill_rx = 0; |
mov dword [forcedeth_refill_rx], 0 |
;for (i = 0; i < RX_RING; i++) |
mov ecx, RX_RING |
.for_loop2: |
; rx_ring[i].FlagLen = 0; |
mov eax, ecx |
dec eax |
mov bl, sizeof.forcedeth_RxDesc |
mul bl |
add eax, forcedeth_rx_ring |
mov ebx, eax |
mov dword [ebx + forcedeth_RxDesc.FlagLen], 0 |
loop .for_loop2 |
; alloc_rx(nic); |
call forcedeth_alloc_rx |
.return: |
pop ecx ebx eax |
ret |
; Input: none |
; Output: none |
forcedeth_txrx_reset: |
push eax esi edi |
; dprintf(("txrx_reset\n")) |
DEBUGF 1," K : FORCEDETH: txrx_reset.\n" |
; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [forcedeth_desc_ver] |
or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base) |
call forcedeth_pci_push |
; nv_udelay(NV_TXRX_RESET_DELAY) |
mov esi, NV_TXRX_RESET_DELAY |
call forcedeth_nv_udelay |
; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
mov eax, dword [forcedeth_desc_ver] |
or eax, NVREG_TXRXCTL_BIT2 |
mov dword [edi+NvRegTxRxControl], eax |
; pci_push(base) |
call forcedeth_pci_push |
.return: |
pop edi esi eax |
ret |
; Input: none |
; Output: none |
forcedeth_set_multicast: |
push edi |
; u32 addr[2]; |
; u32 mask[2]; |
; u32 pff; |
; u32 alwaysOff[2]; |
; u32 alwaysOn[2]; |
; |
; memset(addr, 0, sizeof(addr)); |
; memset(mask, 0, sizeof(mask)); |
; |
; pff = NVREG_PFF_MYADDR; |
; |
; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0; |
; |
; addr[0] = alwaysOn[0]; |
; addr[1] = alwaysOn[1]; |
; mask[0] = alwaysOn[0] | alwaysOff[0]; |
; mask[1] = alwaysOn[1] | alwaysOff[1]; |
; |
; addr[0] |= NVREG_MCASTADDRA_FORCE; |
; pff |= NVREG_PFF_ALWAYS; |
; stop_rx(); |
call forcedeth_stop_rx |
; writel(addr[0], base + NvRegMulticastAddrA); |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
; writel(addr[1], base + NvRegMulticastAddrB); |
mov dword [edi+NvRegMulticastAddrB], 0 |
; writel(mask[0], base + NvRegMulticastMaskA); |
mov dword [edi+NvRegMulticastMaskA], 0 |
; writel(mask[1], base + NvRegMulticastMaskB); |
mov dword [edi+NvRegMulticastMaskB], 0 |
; writel(pff, base + NvRegPacketFilterFlags); |
mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS) |
; start_rx(nic); |
call forcedeth_start_rx |
.return: |
pop edi |
ret |
; Input: none |
; Output: none |
forcedeth_start_rx: |
push edi |
; dprintf(("start_rx\n")) |
DEBUGF 1," K : FORCEDETH: start_rx.\n" |
; Already running? Stop it. |
; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi+NvRegReceiverControl] |
test eax, NVREG_RCVCTL_START |
jz @f |
; writel(0, base + NvRegReceiverControl) |
mov dword [edi+NvRegReceiverControl], 0 |
; pci_push(base) |
call forcedeth_pci_push |
@@: |
; writel(np->linkspeed, base + NvRegLinkSpeed); |
mov eax, dword [forcedeth_linkspeed] |
mov dword [edi+NvRegLinkSpeed], eax |
; pci_push(base); |
call forcedeth_pci_push |
; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); |
mov dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START |
; pci_push(base); |
call forcedeth_pci_push |
.return: |
pop edi |
ret |
; Input: none |
; Output: none |
forcedeth_stop_rx: |
push esi edi |
; dprintf(("stop_rx\n")) |
DEBUGF 1," K : FORCEDETH: stop_rx.\n" |
; writel(0, base + NvRegReceiverControl) |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegReceiverControl], 0 |
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy"); |
stdcall forcedeth_reg_delay,NvRegReceiverStatus,NVREG_RCVSTAT_BUSY,0,NV_RXSTOP_DELAY1,NV_RXSTOP_DELAY1MAX,0 |
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
; nv_udelay(NV_RXSTOP_DELAY2) |
mov esi, NV_RXSTOP_DELAY2 |
call forcedeth_nv_udelay |
; writel(0, base + NvRegLinkSpeed) |
mov dword [edi+NvRegLinkSpeed], 0 |
.return: |
pop edi esi |
ret |
; Input: none |
; Output: EAX |
forcedeth_update_linkspeed: |
push ebx ecx esi edi |
; BMSR_LSTATUS is latched, read it twice: |
; we want the current value. |
; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
;EBX - addr, EAX - miireg, ECX - value |
mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_BMSR |
mov ecx, MII_READ |
call forcedeth_mii_rw |
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
;EBX - addr, EAX - miireg, ECX - value |
mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_BMSR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; mii_status = eax |
; yhlu |
; for(i=0;i<30;i++) { |
mov ecx, 30 |
.for_loop: |
push ecx |
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
;EBX - addr, EAX - miireg, ECX - value |
;mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_BMSR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; mii_status = eax |
; if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break; |
test eax, BMSR_LSTATUS |
jz @f |
test eax, BMSR_ANEGCOMPLETE |
jz @f |
; break |
pop ecx |
jmp .break |
@@: |
; mdelay(100); |
push eax ; ??? |
mov esi, 100 |
call forcedeth_udelay |
pop eax ; ??? |
pop ecx |
loop .for_loop |
.break: |
; if (!(mii_status & BMSR_LSTATUS)) { |
test eax, BMSR_LSTATUS |
jnz @f |
; printf("no link detected by phy - falling back to 10HD.\n") |
DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n" |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; newdup = 0; |
mov dword [forcedeth_tmp_newdup], 0 |
; retval = 0; |
mov dword [forcedeth_tmp_retval], 0 |
; goto set_speed; |
jmp .set_speed |
@@: |
; check auto negotiation is complete |
; if (!(mii_status & BMSR_ANEGCOMPLETE)) { |
test eax, BMSR_ANEGCOMPLETE |
jnz @f |
; still in autonegotiation - configure nic for 10 MBit HD and wait. |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; newdup = 0 |
mov dword [forcedeth_tmp_newdup], 0 |
; retval = 0 |
mov dword [forcedeth_tmp_retval], 0 |
; printf("autoneg not completed - falling back to 10HD.\n") |
DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n" |
; goto set_speed |
jmp .set_speed |
@@: |
; retval = 1 |
mov dword [forcedeth_tmp_retval], 1 |
; if (np->gigabit == PHY_GIGABIT) { |
cmp dword [forcedeth_gigabit], PHY_GIGABIT |
jne .end_if |
; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ) |
;EBX - addr, EAX - miireg, ECX - value |
;mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_1000BT_CR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; control_1000 = eax |
mov dword [forcedeth_tmp_control_1000], eax |
; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ) |
;EBX - addr, EAX - miireg, ECX - value |
;mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_1000BT_SR |
mov ecx, MII_READ |
call forcedeth_mii_rw ; status_1000 = eax |
;mov dword [forcedeth_tmp_status_1000], eax |
; if ((control_1000 & ADVERTISE_1000FULL) && |
; (status_1000 & LPA_1000FULL)) { |
test eax, LPA_1000FULL |
jz .end_if |
test dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL |
jz .end_if |
; printf ("update_linkspeed: GBit ethernet detected.\n") |
DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n" |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000) |
; newdup = 1 |
mov dword [forcedeth_tmp_newdup], 1 |
; goto set_speed |
jmp .set_speed |
.end_if: |
; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
;EBX - addr, EAX - miireg, ECX - value |
;mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_ADVERTISE |
mov ecx, MII_READ |
call forcedeth_mii_rw ; adv = eax |
mov dword [forcedeth_tmp_adv], eax |
; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ); |
;EBX - addr, EAX - miireg, ECX - value |
;mov ebx, dword [forcedeth_phyaddr] |
mov eax, MII_LPA |
mov ecx, MII_READ |
call forcedeth_mii_rw ; lpa = eax |
mov dword [forcedeth_tmp_lpa], eax |
; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa)); |
DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8 |
; FIXME: handle parallel detection properly, handle gigabit ethernet |
; lpa = lpa & adv |
mov eax, dword [forcedeth_tmp_adv] |
and dword [forcedeth_tmp_lpa], eax |
mov eax, dword [forcedeth_tmp_lpa] |
; if (lpa & LPA_100FULL) { |
test eax, LPA_100FULL |
jz @f |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
; newdup = 1 |
mov dword [forcedeth_tmp_newdup], 1 |
jmp .set_speed |
@@: |
; } else if (lpa & LPA_100HALF) { |
test eax, LPA_100HALF |
jz @f |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
; newdup = 0 |
mov dword [forcedeth_tmp_newdup], 0 |
jmp .set_speed |
@@: |
; } else if (lpa & LPA_10FULL) { |
test eax, LPA_10FULL |
jz @f |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; newdup = 1 |
mov dword [forcedeth_tmp_newdup], 1 |
jmp .set_speed |
@@: |
; } else if (lpa & LPA_10HALF) { |
test eax, LPA_10HALF |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; newdup = 0; |
mov dword [forcedeth_tmp_newdup], 0 |
jmp .set_speed |
@@: |
; } else { |
; printf("bad ability %hX - falling back to 10HD.\n", lpa) |
DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax |
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
; newdup = 0 |
mov dword [forcedeth_tmp_newdup], 0 |
; } |
.set_speed: |
; if (np->duplex == newdup && np->linkspeed == newls) |
mov eax, dword [forcedeth_tmp_newdup] |
cmp eax, dword [forcedeth_duplex] |
jne .end_if2 |
mov eax, dword [forcedeth_tmp_newls] |
cmp eax, dword [forcedeth_linkspeed] |
jne .end_if2 |
; return retval; |
jmp .return |
.end_if2: |
; dprintf(("changing link setting from %d/%s to %d/%s.\n", |
; np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex")) |
DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!! |
; np->duplex = newdup |
mov eax, dword [forcedeth_tmp_newdup] |
mov dword [forcedeth_duplex], eax |
; np->linkspeed = newls |
mov eax, [forcedeth_tmp_newls] |
mov dword [forcedeth_linkspeed], eax |
; if (np->gigabit == PHY_GIGABIT) { |
cmp dword [forcedeth_gigabit], PHY_GIGABIT |
jne .end_if3 |
; phyreg = readl(base + NvRegRandomSeed); |
mov edi, dword [forcedeth_mapio_addr] |
mov eax, dword [edi+NvRegRandomSeed] |
; phyreg &= ~(0x3FF00); |
and eax, not (0x3FF00) |
mov ecx, eax ; phyreg = ecx |
; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) |
mov eax, dword [forcedeth_linkspeed] |
and eax, 0xFFF |
cmp eax, NVREG_LINKSPEED_10 |
jne @f |
; phyreg |= NVREG_RNDSEED_FORCE3 |
or ecx, NVREG_RNDSEED_FORCE3 |
jmp .end_if4 |
@@: |
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
cmp eax, NVREG_LINKSPEED_100 |
jne @f |
; phyreg |= NVREG_RNDSEED_FORCE2 |
or ecx, NVREG_RNDSEED_FORCE2 |
jmp .end_if4 |
@@: |
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
cmp eax, NVREG_LINKSPEED_1000 |
jne .end_if4 |
; phyreg |= NVREG_RNDSEED_FORCE |
or ecx, NVREG_RNDSEED_FORCE |
.end_if4: |
; writel(phyreg, base + NvRegRandomSeed) |
mov dword [edi+NvRegRandomSeed], ecx |
.end_if3: |
; phyreg = readl(base + NvRegPhyInterface) |
mov ecx, dword [edi+NvRegPhyInterface] |
; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000) |
and ecx, not (PHY_HALF or PHY_100 or PHY_1000) |
; if (np->duplex == 0) |
cmp dword [forcedeth_duplex], 0 |
jne @f |
; phyreg |= PHY_HALF |
or ecx, PHY_HALF |
@@: |
; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
mov eax, dword [forcedeth_linkspeed] |
and eax, 0xFFF |
cmp eax, NVREG_LINKSPEED_100 |
jne @f |
; phyreg |= PHY_100 |
or ecx, PHY_100 |
jmp .end_if5 |
@@: |
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
cmp eax, NVREG_LINKSPEED_1000 |
jne .end_if5 |
; phyreg |= PHY_1000 |
or ecx, PHY_1000 |
.end_if5: |
; writel(phyreg, base + NvRegPhyInterface) |
mov dword [edi+NvRegPhyInterface], ecx |
; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); |
cmp dword [forcedeth_duplex], 0 |
je @f |
mov ecx, 0 |
jmp .next |
@@: |
mov ecx, NVREG_MISC1_HD |
.next: |
or ecx, NVREG_MISC1_FORCE |
mov dword [edi+NvRegMisc1], ecx |
; pci_push(base) |
call forcedeth_pci_push |
; writel(np->linkspeed, base + NvRegLinkSpeed) |
mov eax, dword [forcedeth_linkspeed] |
mov dword [edi+NvRegLinkSpeed], eax |
; pci_push(base) |
call forcedeth_pci_push |
.return: |
; return retval |
mov eax, dword [forcedeth_tmp_retval] |
pop edi esi ecx ebx |
ret |
; Input: none |
; Output: none |
forcedeth_start_tx: |
push edi |
; dprintf(("start_tx\n")) |
DEBUGF 1," K : FORCEDETH: start_tx.\n" |
; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl) |
mov edi, dword [forcedeth_mapio_addr] |
mov dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START |
; pci_push(base) |
call forcedeth_pci_push |
.return: |
pop edi |
ret |
; Interrupt handler |
forcedeth_int_handler: |
DEBUGF 1," K : FORCEDETH: interrupt handler.\n" |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8169.inc |
---|
0,0 → 1,1219 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8169.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.1 11 February 2007 ;; |
;; ;; |
;; Driver for chips of RealTek 8169 family ;; |
;; References: ;; |
;; r8169.c - linux driver (etherboot project) ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2007 mike.dld, ;; |
;; mike.dld@gmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address |
RTL8169_REG_MAR0 equ 0x8 ; Multicast filter |
RTL8169_REG_TxDescStartAddr equ 0x20 |
RTL8169_REG_TxHDescStartAddr equ 0x28 |
RTL8169_REG_FLASH equ 0x30 |
RTL8169_REG_ERSR equ 0x36 |
RTL8169_REG_ChipCmd equ 0x37 |
RTL8169_REG_TxPoll equ 0x38 |
RTL8169_REG_IntrMask equ 0x3C |
RTL8169_REG_IntrStatus equ 0x3E |
RTL8169_REG_TxConfig equ 0x40 |
RTL8169_REG_RxConfig equ 0x44 |
RTL8169_REG_RxMissed equ 0x4C |
RTL8169_REG_Cfg9346 equ 0x50 |
RTL8169_REG_Config0 equ 0x51 |
RTL8169_REG_Config1 equ 0x52 |
RTL8169_REG_Config2 equ 0x53 |
RTL8169_REG_Config3 equ 0x54 |
RTL8169_REG_Config4 equ 0x55 |
RTL8169_REG_Config5 equ 0x56 |
RTL8169_REG_MultiIntr equ 0x5C |
RTL8169_REG_PHYAR equ 0x60 |
RTL8169_REG_TBICSR equ 0x64 |
RTL8169_REG_TBI_ANAR equ 0x68 |
RTL8169_REG_TBI_LPAR equ 0x6A |
RTL8169_REG_PHYstatus equ 0x6C |
RTL8169_REG_RxMaxSize equ 0xDA |
RTL8169_REG_CPlusCmd equ 0xE0 |
RTL8169_REG_RxDescStartAddr equ 0xE4 |
RTL8169_REG_ETThReg equ 0xEC |
RTL8169_REG_FuncEvent equ 0xF0 |
RTL8169_REG_FuncEventMask equ 0xF4 |
RTL8169_REG_FuncPresetState equ 0xF8 |
RTL8169_REG_FuncForceEvent equ 0xFC |
; InterruptStatusBits |
RTL8169_ISB_SYSErr equ 0x8000 |
RTL8169_ISB_PCSTimeout equ 0x4000 |
RTL8169_ISB_SWInt equ 0x0100 |
RTL8169_ISB_TxDescUnavail equ 0x80 |
RTL8169_ISB_RxFIFOOver equ 0x40 |
RTL8169_ISB_LinkChg equ 0x20 |
RTL8169_ISB_RxOverflow equ 0x10 |
RTL8169_ISB_TxErr equ 0x08 |
RTL8169_ISB_TxOK equ 0x04 |
RTL8169_ISB_RxErr equ 0x02 |
RTL8169_ISB_RxOK equ 0x01 |
; RxStatusDesc |
RTL8169_SD_RxRES equ 0x00200000 |
RTL8169_SD_RxCRC equ 0x00080000 |
RTL8169_SD_RxRUNT equ 0x00100000 |
RTL8169_SD_RxRWT equ 0x00400000 |
; ChipCmdBits |
RTL8169_CMD_Reset equ 0x10 |
RTL8169_CMD_RxEnb equ 0x08 |
RTL8169_CMD_TxEnb equ 0x04 |
RTL8169_CMD_RxBufEmpty equ 0x01 |
; Cfg9346Bits |
RTL8169_CFG_9346_Lock equ 0x00 |
RTL8169_CFG_9346_Unlock equ 0xC0 |
; rx_mode_bits |
RTL8169_RXM_AcceptErr equ 0x20 |
RTL8169_RXM_AcceptRunt equ 0x10 |
RTL8169_RXM_AcceptBroadcast equ 0x08 |
RTL8169_RXM_AcceptMulticast equ 0x04 |
RTL8169_RXM_AcceptMyPhys equ 0x02 |
RTL8169_RXM_AcceptAllPhys equ 0x01 |
; RxConfigBits |
RTL8169_RXC_FIFOShift equ 13 |
RTL8169_RXC_DMAShift equ 8 |
; TxConfigBits |
RTL8169_TXC_InterFrameGapShift equ 24 |
RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits |
; rtl8169_PHYstatus |
RTL8169_PHYS_TBI_Enable equ 0x80 |
RTL8169_PHYS_TxFlowCtrl equ 0x40 |
RTL8169_PHYS_RxFlowCtrl equ 0x20 |
RTL8169_PHYS_1000bpsF equ 0x10 |
RTL8169_PHYS_100bps equ 0x08 |
RTL8169_PHYS_10bps equ 0x04 |
RTL8169_PHYS_LinkStatus equ 0x02 |
RTL8169_PHYS_FullDup equ 0x01 |
; GIGABIT_PHY_registers |
RTL8169_PHY_CTRL_REG equ 0 |
RTL8169_PHY_STAT_REG equ 1 |
RTL8169_PHY_AUTO_NEGO_REG equ 4 |
RTL8169_PHY_1000_CTRL_REG equ 9 |
; GIGABIT_PHY_REG_BIT |
RTL8169_PHY_Restart_Auto_Nego equ 0x0200 |
RTL8169_PHY_Enable_Auto_Nego equ 0x1000 |
; PHY_STAT_REG = 1; |
RTL8169_PHY_Auto_Neco_Comp equ 0x0020 |
; PHY_AUTO_NEGO_REG = 4; |
RTL8169_PHY_Cap_10_Half equ 0x0020 |
RTL8169_PHY_Cap_10_Full equ 0x0040 |
RTL8169_PHY_Cap_100_Half equ 0x0080 |
RTL8169_PHY_Cap_100_Full equ 0x0100 |
; PHY_1000_CTRL_REG = 9; |
RTL8169_PHY_Cap_1000_Full equ 0x0200 |
RTL8169_PHY_Cap_1000_Half equ 0x0100 |
RTL8169_PHY_Cap_PAUSE equ 0x0400 |
RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800 |
RTL8169_PHY_Cap_Null equ 0x0 |
; _MediaType |
RTL8169_MT_10_Half equ 0x01 |
RTL8169_MT_10_Full equ 0x02 |
RTL8169_MT_100_Half equ 0x04 |
RTL8169_MT_100_Full equ 0x08 |
RTL8169_MT_1000_Full equ 0x10 |
; _TBICSRBit |
RTL8169_TBI_LinkOK equ 0x02000000 |
; _DescStatusBit |
RTL8169_DSB_OWNbit equ 0x80000000 |
RTL8169_DSB_EORbit equ 0x40000000 |
RTL8169_DSB_FSbit equ 0x20000000 |
RTL8169_DSB_LSbit equ 0x10000000 |
; MAC address length |
MAC_ADDR_LEN equ 6 |
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) |
MAX_ETH_FRAME_SIZE equ 1536 |
TX_FIFO_THRESH equ 256 ; In bytes |
RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer |
RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 |
TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 |
ETTh equ 0x3F ; 0x3F means NO threshold |
EarlyTxThld equ 0x3F ; 0x3F means NO early transmit |
RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1 |
InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one |
NUM_TX_DESC equ 1 ; Number of Tx descriptor registers |
NUM_RX_DESC equ 4 ; Number of Rx descriptor registers |
RX_BUF_SIZE equ 1536 ; Rx Buffer size |
HZ equ 1000 |
RTL_MIN_IO_SIZE equ 0x80 |
TX_TIMEOUT equ (6*HZ) |
RTL8169_TIMER_EXPIRE_TIME equ 100 |
ETH_HDR_LEN equ 14 |
DEFAULT_MTU equ 1500 |
DEFAULT_RX_BUF_LEN equ 1536 |
;#ifdef RTL8169_JUMBO_FRAME_SUPPORT |
;#define MAX_JUMBO_FRAME_MTU ( 10000 ) |
;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) |
;#else |
MAX_RX_SKBDATA_SIZE equ 1600 |
;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT |
;#ifdef RTL8169_USE_IO |
;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) |
macro RTL_W8 reg,val8 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val8 eq al |
mov al,val8 |
end if |
out dx,al |
} |
;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) |
macro RTL_W16 reg,val16 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val16 eq ax |
mov ax,val16 |
end if |
out dx,ax |
} |
;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) |
macro RTL_W32 reg,val32 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val32 eq eax |
mov eax,val32 |
end if |
out dx,eax |
} |
;!!!#define RTL_R8(reg) inb (ioaddr + (reg)) |
macro RTL_R8 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in al,dx |
} |
;!!!#define RTL_R16(reg) inw (ioaddr + (reg)) |
macro RTL_R16 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in ax,dx |
} |
;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) |
macro RTL_R32 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in eax,dx |
} |
;#else |
; write/read MMIO register |
;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) |
;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) |
;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) |
;#define RTL_R8(reg) readb (ioaddr + (reg)) |
;#define RTL_R16(reg) readw (ioaddr + (reg)) |
;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) |
;#endif |
MCFG_METHOD_01 equ 0x01 |
MCFG_METHOD_02 equ 0x02 |
MCFG_METHOD_03 equ 0x03 |
MCFG_METHOD_04 equ 0x04 |
MCFG_METHOD_05 equ 0x05 |
MCFG_METHOD_11 equ 0x0b |
MCFG_METHOD_12 equ 0x0c |
MCFG_METHOD_13 equ 0x0d |
MCFG_METHOD_14 equ 0x0e |
MCFG_METHOD_15 equ 0x0f |
PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000 |
PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001 |
PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002 |
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space |
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space |
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering |
PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles |
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate |
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping |
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking |
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping |
PCI_COMMAND_SERR equ 0x100 ; Enable SERR |
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes |
struc rtl8169_TxDesc { |
.status dd ? |
.vlan_tag dd ? |
.buf_addr dd ? |
.buf_Haddr dd ? |
} |
virtual at 0 |
rtl8169_TxDesc rtl8169_TxDesc |
sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc |
end virtual |
struc rtl8169_RxDesc { |
.status dd ? |
.vlan_tag dd ? |
.buf_addr dd ? |
.buf_Haddr dd ? |
} |
virtual at 0 |
rtl8169_RxDesc rtl8169_RxDesc |
sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc |
end virtual |
virtual at eth_data_start |
; Define the TX Descriptor |
align 256 |
rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; TX Descriptor. All descriptors point to a |
; part of this buffer |
align 256 |
rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE |
; Define the RX Descriptor |
align 256 |
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_RxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; RX Descriptor All descriptors point to a |
; part of this buffer |
align 256 |
rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE |
rtl8169_tpc: |
.mmio_addr dd ? ; memory map physical address |
.chipset dd ? |
.pcfg dd ? |
.mcfg dd ? |
.cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt |
.cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt |
.TxDescArrays dd ? ; Index of Tx Descriptor buffer |
.RxDescArrays dd ? ; Index of Rx Descriptor buffer |
.TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer |
.RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer |
.RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array |
.Tx_skbuff rd NUM_TX_DESC |
end virtual |
rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK |
rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E |
iglobal |
;static struct { |
; const char *name; |
; u8 mcfg; /* depend on RTL8169 docs */ |
; u32 RxConfigMask; /* should clear the bits supported by this chip */ |
;} |
rtl_chip_info dd \ |
MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169 |
MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s |
MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s |
MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb |
MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc |
MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E |
MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E |
MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139 |
MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139 |
MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139 |
mac_info dd \ |
0x38800000, MCFG_METHOD_15, \ |
0x38000000, MCFG_METHOD_12, \ |
0x34000000, MCFG_METHOD_13, \ |
0x30800000, MCFG_METHOD_14, \ |
0x30000000, MCFG_METHOD_11, \ |
0x18000000, MCFG_METHOD_05, \ |
0x10000000, MCFG_METHOD_04, \ |
0x04000000, MCFG_METHOD_03, \ |
0x00800000, MCFG_METHOD_02, \ |
0x00000000, MCFG_METHOD_01 ; catch-all |
endg |
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space |
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space |
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering |
PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles |
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate |
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping |
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking |
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping |
PCI_COMMAND_SERR equ 0x100 ; Enable SERR |
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes |
PCI_VENDOR_ID equ 0x00 ; 16 bits |
PCI_DEVICE_ID equ 0x02 ; 16 bits |
PCI_COMMAND equ 0x04 ; 16 bits |
PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits |
PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits |
PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits |
PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits |
PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits |
PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits |
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 |
PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address |
PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] |
PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address |
PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) |
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_ROM_ADDRESS equ 0x30 ; 32 bits |
proc CONFIG_CMD,where:byte |
movzx eax,byte[pci_bus] |
shl eax,8 |
mov al,[pci_dev] |
shl eax,8 |
mov al,[where] |
and al,not 3 |
or eax,0x80000000 |
ret |
endp |
proc pci_read_config_byte,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,3 |
add edx,0xCFC |
in al,dx |
pop edx |
ret |
endp |
proc pci_read_config_word,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,2 |
add edx,0xCFC |
in ax,dx |
pop edx |
ret |
endp |
proc pci_read_config_dword,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov edx,0xCF8 |
out dx,eax |
mov edx,0xCFC |
in eax,dx |
pop edx |
ret |
endp |
proc pci_write_config_byte,where:dword,value:byte |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,3 |
add edx,0xCFC |
mov al,[value] |
out dx,al |
pop edx |
ret |
endp |
proc pci_write_config_word,where:dword,value:word |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,2 |
add edx,0xCFC |
mov ax,[value] |
out dx,ax |
pop edx |
ret |
endp |
proc pci_write_config_dword,where:dword,value:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov edx,0xCF8 |
out dx,eax |
mov edx,0xCFC |
mov eax,[value] |
out dx,eax |
pop edx |
ret |
endp |
; Set device to be a busmaster in case BIOS neglected to do so. |
; Also adjust PCI latency timer to a reasonable value, 32. |
proc adjust_pci_device |
; DEBUGF 1,"K : adjust_pci_device\n" |
stdcall pci_read_config_word,PCI_COMMAND |
mov bx,ax |
or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO |
cmp ax,bx |
je @f |
; DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2 |
stdcall pci_write_config_word,PCI_COMMAND,ebx |
@@: |
stdcall pci_read_config_byte,PCI_LATENCY_TIMER |
cmp al,32 |
jae @f |
; DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al |
stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32 |
@@: |
ret |
endp |
; Find the start of a pci resource |
proc pci_bar_start,index:dword |
stdcall pci_read_config_dword,[index] |
test eax,PCI_BASE_ADDRESS_SPACE_IO |
jz @f |
and eax,PCI_BASE_ADDRESS_IO_MASK |
jmp .exit |
@@: push eax |
and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK |
cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64 |
jne .not64 |
mov eax,[index] |
add eax,4 |
stdcall pci_read_config_dword,eax |
or eax,eax |
jz .not64 |
; DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n" |
add esp,4 |
or eax,-1 |
ret |
.not64: |
pop eax |
and eax,PCI_BASE_ADDRESS_MEM_MASK |
.exit: |
ret |
endp |
proc rtl8169_init_board |
; DEBUGF 1,"K : rtl8169_init_board\n" |
call adjust_pci_device |
stdcall pci_bar_start,PCI_BASE_ADDRESS_0 |
mov [rtl8169_tpc.mmio_addr],eax |
; Soft reset the chip |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset |
; Check that the chip has finished the reset |
mov ecx,1000 |
@@: RTL_R8 RTL8169_REG_ChipCmd |
test al,RTL8169_CMD_Reset |
jz @f |
stdcall udelay,10 |
loop @b |
@@: |
; identify config method |
RTL_R32 RTL8169_REG_TxConfig |
and eax,0x7c800000 |
; DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax |
mov esi,mac_info-8 |
@@: add esi,8 |
mov ecx,eax |
and ecx,[esi] |
cmp ecx,[esi] |
jne @b |
mov eax,[esi+4] |
mov [rtl8169_tpc.mcfg],eax |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_3 |
stdcall RTL8169_READ_GMII_REG,3 |
and al,0x0f |
or al,al |
jnz @f |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_1 |
jmp .pconf |
@@: dec al |
jnz .pconf |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_2 |
.pconf: |
; identify chip attached to board |
mov ecx,10 |
mov eax,[rtl8169_tpc.mcfg] |
@@: dec ecx |
js @f |
cmp eax,[rtl_chip_info+ecx*8] |
jne @b |
mov [rtl8169_tpc.chipset],ecx |
jmp .match |
@@: |
; if unknown chip, assume array element #0, original RTL-8169 in this case |
; DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n" |
RTL_R32 RTL8169_REG_TxConfig |
; DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax |
mov [rtl8169_tpc.chipset],0 |
xor eax,eax |
inc eax |
ret |
.match: |
xor eax,eax |
ret |
endp |
proc rtl8169_hw_PHY_config |
; DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg] |
; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg); |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04 |
jne .not_4 |
; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 |
; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e |
; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb |
; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0 |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 |
jmp .exit |
.not_4: |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
je @f |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jne .not_2_or_3 |
@@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 |
stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000 |
stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000 |
jmp .exit |
.not_2_or_3: |
; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg); |
; DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg] |
.exit: |
ret |
endp |
;proc pci_write_config_byte |
; ret |
;endp |
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword |
;;; DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value] |
movzx eax,[RegAddr] |
shl eax,16 |
or eax,[value] |
or eax,0x80000000 |
RTL_W32 RTL8169_REG_PHYAR,eax |
stdcall udelay,1 ;;;1000 |
mov ecx,2000 |
; Check if the RTL8169 has completed writing to the specified MII register |
@@: RTL_R32 RTL8169_REG_PHYAR |
test eax,0x80000000 |
jz .exit |
stdcall udelay,1 ;;;100 |
loop @b |
.exit: |
ret |
endp |
proc RTL8169_READ_GMII_REG,RegAddr:byte |
;;; DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2 |
push ecx |
movzx eax,[RegAddr] |
shl eax,16 |
; or eax,0x0 |
RTL_W32 RTL8169_REG_PHYAR,eax |
stdcall udelay,1 ;;;1000 |
mov ecx,2000 |
; Check if the RTL8169 has completed retrieving data from the specified MII register |
@@: RTL_R32 RTL8169_REG_PHYAR |
test eax,0x80000000 |
jnz .exit |
stdcall udelay,1 ;;;100 |
loop @b |
or eax,-1 |
pop ecx |
ret |
.exit: |
RTL_R32 RTL8169_REG_PHYAR |
and eax,0xFFFF |
pop ecx |
ret |
endp |
proc rtl8169_set_rx_mode |
; DEBUGF 1,"K : rtl8169_set_rx_mode\n" |
; IFF_ALLMULTI |
; Too many to filter perfectly -- accept all multicasts |
RTL_R32 RTL8169_REG_RxConfig |
mov ecx,[rtl8169_tpc.chipset] |
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask |
or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys) |
RTL_W32 RTL8169_REG_RxConfig,eax |
; Multicast hash filter |
RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff |
RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff |
ret |
endp |
proc rtl8169_init_ring |
; DEBUGF 1,"K : rtl8169_init_ring\n" |
xor eax,eax |
mov [rtl8169_tpc.cur_rx],eax |
mov [rtl8169_tpc.cur_tx],eax |
mov edi,[rtl8169_tpc.TxDescArray] |
mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4 |
cld |
rep stosd |
mov edi,[rtl8169_tpc.RxDescArray] |
mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4 |
rep stosd |
mov edi,rtl8169_tpc.Tx_skbuff |
mov eax,rtl8169_txb |
mov ecx,NUM_TX_DESC |
@@: stosd |
inc eax ; add eax,RX_BUF_SIZE ??? |
loop @b |
;!!! for (i = 0; i < NUM_RX_DESC; i++) { |
;!!! if (i == (NUM_RX_DESC - 1)) |
;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE; |
;!!! else |
;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE; |
;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; |
;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]); |
;!!! } |
mov esi,rtl8169_tpc.RxBufferRing |
mov edi,[rtl8169_tpc.RxDescArray] |
mov eax,rtl8169_rxb |
mov ecx,NUM_RX_DESC |
@@: mov [esi],eax |
mov [edi+rtl8169_RxDesc.buf_addr],eax |
sub [edi+rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 |
mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE |
add esi,4 |
add edi,sizeof.rtl8169_RxDesc |
add eax,RX_BUF_SIZE |
loop @b |
or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit |
ret |
endp |
proc rtl8169_hw_start |
; DEBUGF 1,"K : rtl8169_hw_start\n" |
; Soft reset the chip |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset |
; Check that the chip has finished the reset |
mov ecx,1000 |
@@: RTL_R8 RTL8169_REG_ChipCmd |
and al,RTL8169_CMD_Reset |
jz @f |
stdcall udelay,10 |
loop @b |
@@: |
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb |
RTL_W8 RTL8169_REG_ETThReg,ETTh |
; For gigabit rtl8169 |
RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize |
; Set Rx Config register |
RTL_R32 RTL8169_REG_RxConfig |
mov ecx,[rtl8169_tpc.chipset] |
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask |
or eax,rtl8169_rx_config |
RTL_W32 RTL8169_REG_RxConfig,eax |
; Set DMA burst size and Interframe Gap Time |
RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift) |
RTL_R16 RTL8169_REG_CPlusCmd |
RTL_W16 RTL8169_REG_CPlusCmd,ax |
RTL_R16 RTL8169_REG_CPlusCmd |
or ax,1 shl 3 |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
jne @f |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jne @f |
or ax,1 shl 14 |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n" |
jmp .set |
@@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n" |
.set: RTL_W16 RTL8169_REG_CPlusCmd,ax |
; RTL_W16 0xE2,0x1517 |
; RTL_W16 0xE2,0x152a |
; RTL_W16 0xE2,0x282a |
RTL_W16 0xE2,0x0000 |
MOV [rtl8169_tpc.cur_rx],0 |
push eax ; shurf 28.09.2008 |
mov eax, [rtl8169_tpc.TxDescArray] ; shurf 28.09.2008 |
sub eax, OS_BASE ; shurf 28.09.2008 |
RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray] ; shurf 28.09.2008 |
mov eax, [rtl8169_tpc.RxDescArray] ; shurf 28.09.2008 |
sub eax, OS_BASE ; shurf 28.09.2008 |
RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray] ; shurf 28.09.2008 |
pop eax ; shurf 28.09.2008 |
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock |
stdcall udelay,10 |
RTL_W32 RTL8169_REG_RxMissed,0 |
call rtl8169_set_rx_mode |
; no early-rx interrupts |
RTL_R16 RTL8169_REG_MultiIntr |
and ax,0xF000 |
RTL_W16 RTL8169_REG_MultiIntr,ax |
RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask |
ret |
endp |
proc udelay,msec:dword |
push esi |
mov esi,[msec] |
call delay_ms |
pop esi |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
proc rtl8169_probe |
; DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
call rtl8169_init_board |
mov ecx,MAC_ADDR_LEN |
mov edx,[rtl8169_tpc.mmio_addr] |
add edx,RTL8169_REG_MAC0 |
xor ebx,ebx |
; Get MAC address. FIXME: read EEPROM |
@@: RTL_R8 dx |
mov [node_addr+ebx],al |
inc edx |
inc ebx |
loop @b |
; DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2 |
; Config PHY |
stdcall rtl8169_hw_PHY_config |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" |
RTL_W8 0x82,0x01 |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jae @f |
; DEBUGF 1,"K : Set PCI Latency=0x40\n" |
; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40 |
@@: |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
jne @f |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" |
RTL_W8 0x82,0x01 |
; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n" |
stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0 |
@@: |
; if TBI is not enabled |
RTL_R8 RTL8169_REG_PHYstatus |
test al,RTL8169_PHYS_TBI_Enable |
jz .tbi_dis |
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG |
; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged |
and eax,0x0C1F |
or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax |
; enable 1000 Full Mode |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168 |
; Enable auto-negotiation and restart auto-nigotiation |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego |
stdcall udelay,100 |
mov ecx,10000 |
; wait for auto-negotiation process |
@@: dec ecx |
jz @f |
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG |
stdcall udelay,100 |
test eax,RTL8169_PHY_Auto_Neco_Comp |
jz @b |
RTL_R8 RTL8169_REG_PHYstatus |
jmp @f |
.tbi_dis: |
stdcall udelay,100 |
@@: |
call rtl8169_reset |
ret |
endp |
;*************************************************************************** |
; Function |
; rt8169_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
proc rtl8169_reset |
; DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring |
; Tx Desscriptor needs 256 bytes alignment |
mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring |
mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring |
; Rx Desscriptor needs 256 bytes alignment |
mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring |
call rtl8169_init_ring |
call rtl8169_hw_start |
; Construct a perfect filter frame with the mac address as first match |
; and broadcast for all others |
mov edi,rtl8169_txb |
or al,-1 |
mov ecx,192 |
cld |
rep stosb |
mov esi,node_addr |
mov edi,rtl8169_txb |
movsd |
movsw |
mov eax,[pci_data] |
mov [eth_status],eax |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; d - edi - Pointer to 48 bit destination address |
; t - bx - Type of packet |
; s - ecx - size of packet |
; p - esi - pointer to packet data |
; Destroyed registers |
; eax, edx, esi, edi |
; |
;*************************************************************************** |
proc rtl8169_transmit |
; DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi |
push ecx edx esi |
mov eax,MAX_ETH_FRAME_SIZE |
mul [rtl8169_tpc.cur_tx] |
mov esi,edi |
; point to the current txb incase multiple tx_rings are used |
mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4] |
mov eax,edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi,node_addr |
movsd |
movsw |
; copy packet type |
mov [edi],bx |
add edi,2 |
; copy the packet data |
pop esi edx ecx |
push ecx |
shr ecx,2 |
rep movsd |
pop ecx |
push ecx |
and ecx,3 |
rep movsb |
;!!! s += ETH_HLEN; |
;!!! s &= 0x0FFF; |
;!!! while (s < ETH_ZLEN) |
;!!! ptxb[s++] = '\0'; |
mov edi,eax |
pop ecx |
push eax |
add ecx,ETH_HLEN |
and ecx,0x0FFF |
xor al,al |
add edi,ecx |
@@: cmp ecx,ETH_ZLEN |
jae @f |
stosb |
inc ecx |
jmp @b |
@@: pop eax |
mov ebx,eax |
mov eax,sizeof.rtl8169_TxDesc |
mul [rtl8169_tpc.cur_tx] |
add eax,[rtl8169_tpc.TxDescArray] |
xchg eax,ebx |
mov [ebx + rtl8169_TxDesc.buf_addr],eax |
sub [ebx + rtl8169_TxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 |
mov eax,ecx |
cmp eax,ETH_ZLEN |
jae @f |
mov eax,ETH_ZLEN |
@@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit |
cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 |
jne @f |
or eax,RTL8169_DSB_EORbit |
@@: mov [ebx + rtl8169_TxDesc.status],eax |
RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit |
inc [rtl8169_tpc.cur_tx] |
and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 |
;!!! to = currticks() + TX_TIMEOUT; |
;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ |
mov ecx,TX_TIMEOUT / 10 |
@@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit |
jnz @f |
stdcall udelay,10 |
loop @b |
; DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n" |
@@: |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed register(s) |
; eax, edx, ecx |
; |
;*************************************************************************** |
proc rtl8169_poll |
; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8 |
mov word[eth_rx_data_len],0 |
mov eax,sizeof.rtl8169_RxDesc |
mul [rtl8169_tpc.cur_rx] |
add eax,[rtl8169_tpc.RxDescArray] |
mov ebx,eax |
; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status] |
test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600 |
jnz .exit |
; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx] |
; h/w no longer present (hotplug?) or major error, bail |
RTL_R16 RTL8169_REG_IntrStatus |
; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax |
cmp ax,0xFFFF |
je .exit |
push eax |
and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK) |
RTL_W16 RTL8169_REG_IntrStatus,ax |
mov eax,[ebx + rtl8169_RxDesc.status] |
; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax |
test eax,RTL8169_SD_RxRES |
jnz .else |
and eax,0x00001FFF |
; jz .exit.pop |
add eax,-4 |
mov [eth_rx_data_len],ax |
; DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax |
push eax |
mov ecx,eax |
shr ecx,2 |
mov eax,[rtl8169_tpc.cur_rx] |
mov edx,[rtl8169_tpc.RxBufferRing + eax * 4] |
mov esi,edx |
mov edi,Ether_buffer |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE |
cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 |
jne @f |
or eax,RTL8169_DSB_EORbit |
@@: mov [ebx + rtl8169_RxDesc.status],eax |
mov [ebx + rtl8169_RxDesc.buf_addr],edx |
sub [ebx + rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 |
jmp @f |
.else: |
; DEBUGF 1,"K : rtl8169_poll: Rx Error\n" |
; FIXME: shouldn't I reset the status on an error |
@@: |
inc [rtl8169_tpc.cur_rx] |
and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 |
.exit.pop: |
pop eax |
and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK |
RTL_W16 RTL8169_REG_IntrStatus,ax |
.exit: |
ret |
endp |
proc rtl8169_cable |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/i8255x.inc |
---|
0,0 → 1,760 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; I8255X.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.3 11 August 2003 ;; |
;; ;; |
;; This driver is based on the eepro100 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************** |
; Interface |
; I8255x_reset |
; I8255x_probe |
; I8255x_poll |
; I8255x_transmit |
; |
; These functions are referenced in ethernet.inc |
; |
;******************************************************************** |
rxfd_status equ eth_data_start |
rxfd_command equ eth_data_start + 2 |
rxfd_link equ eth_data_start + 4 |
rxfd_rx_buf_addr equ eth_data_start + 8 |
rxfd_count equ eth_data_start + 12 |
rxfd_size equ eth_data_start + 14 |
rxfd_packet equ eth_data_start + 16 |
uglobal |
eeprom_data: times 16 dd 0 |
align 4 |
lstats: |
tx_good_frames: dd 0 |
tx_coll16_errs: dd 0 |
tx_late_colls: dd 0 |
tx_underruns: dd 0 |
tx_lost_carrier: dd 0 |
tx_deferred: dd 0 |
tx_one_colls: dd 0 |
tx_multi_colls: dd 0 |
tx_total_colls: dd 0 |
rx_good_frames: dd 0 |
rx_crc_errs: dd 0 |
rx_align_errs: dd 0 |
rx_resource_errs: dd 0 |
rx_overrun_errs: dd 0 |
rx_colls_errs: dd 0 |
rx_runt_errs: dd 0 |
done_marker: dd 0 |
align 4 |
confcmd: |
confcmd_status: dw 0 |
confcmd_command: dw 0 |
confcmd_link: dd 0 |
endg |
iglobal |
confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 |
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 |
db 0x80, 0x3f, 0x05 |
endg |
uglobal |
align 4 |
txfd: |
txfd_status: dw 0 |
txfd_command: dw 0 |
txfd_link: dd 0 |
txfd_tx_desc_addr: dd 0 |
txfd_count: dd 0 |
txfd_tx_buf_addr0: dd 0 |
txfd_tx_buf_size0: dd 0 |
txfd_tx_buf_addr1: dd 0 |
txfd_tx_buf_size1: dd 0 |
align 4 |
hdr: |
hdr_dst_addr: times 6 db 0 |
hdr_src_addr: times 6 db 0 |
hdr_type: dw 0 |
endg |
;*************************************************************************** |
; Function |
; wait_for_cmd_done |
; |
; Description |
; waits for the hardware to complete a command |
; port address in edx |
; |
; al destroyed |
;*************************************************************************** |
wait_for_cmd_done: |
in al, dx |
cmp al, 0 |
jne wait_for_cmd_done |
ret |
;*************************************************************************** |
; Function |
; mdio_read |
; |
; Description |
; This probably reads a register in the "physical media interface chip" |
; Phy_id in ebx |
; location in ecx |
; |
; Data returned in eax |
; |
;*************************************************************************** |
mdio_read: |
mov edx, [io_addr] |
add edx, 16 ; SCBCtrlMDI |
mov eax, 0x08000000 |
shl ecx, 16 |
or eax, ecx |
shl ebx, 21 |
or eax, ebx |
out dx, eax |
mrlp: |
call delay_us |
in eax, dx |
mov ecx, eax |
and ecx, 0x10000000 |
jz mrlp |
and eax, 0xffff |
ret |
;*************************************************************************** |
; Function |
; mdio_write |
; |
; Description |
; This probably writes a register in the "physical media interface chip" |
; Phy_id in ebx |
; location in ecx |
; data in edx |
; Data returned in eax |
; |
;*************************************************************************** |
mdio_write: |
mov eax, 0x04000000 |
shl ecx, 16 |
or eax, ecx |
shl ebx, 21 |
or eax, ebx |
or eax, edx |
mov edx, [io_addr] |
add edx, 16 ; SCBCtrlMDI |
out dx, eax |
mwlp: |
call delay_us |
in eax, dx |
mov ecx, eax |
and ecx, 0x10000000 |
jz mwlp |
and eax, 0xffff |
ret |
;/***********************************************************************/ |
;/* I82557 related defines */ |
;/***********************************************************************/ |
; Serial EEPROM section. |
; A "bit" grungy, but we work our way through bit-by-bit :->. |
; EEPROM_Ctrl bits. |
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. |
EE_CS equ 0x02 ; EEPROM chip select. |
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. |
EE_DATA_READ equ 0x08 ; EEPROM chip data out. |
EE_WRITE_0 equ 0x4802 |
EE_WRITE_1 equ 0x4806 |
EE_ENB equ 0x4802 |
; The EEPROM commands include the alway-set leading bit. |
EE_READ_CMD equ 6 |
; The SCB accepts the following controls for the Tx and Rx units: |
CU_START equ 0x0010 |
CU_RESUME equ 0x0020 |
CU_STATSADDR equ 0x0040 |
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. |
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. |
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. |
RX_START equ 0x0001 |
RX_RESUME equ 0x0002 |
RX_ABORT equ 0x0004 |
RX_ADDR_LOAD equ 0x0006 |
RX_RESUMENR equ 0x0007 |
INT_MASK equ 0x0100 |
DRVR_INT equ 0x0200 ; Driver generated interrupt. |
;*************************************************************************** |
; Function |
; do_eeprom_cmd |
; |
; Description |
; writes a cmd to the ethernet cards eeprom, by bit bashing |
; cmd in ebx |
; cmd length in ecx |
; return in eax |
;*************************************************************************** |
do_eeprom_cmd: |
mov edx, [io_addr] ; We only require the value in dx |
add dx, 14 ; the value SCBeeprom |
mov ax, EE_ENB |
out dx, ax |
call delay_us |
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK |
out dx, ax |
call delay_us |
; dx holds ee_addr |
; ecx holds count |
; eax holds cmd |
xor edi, edi ; this will be the receive data |
dec_001: |
mov esi, 1 |
dec ecx |
shl esi, cl |
inc ecx |
and esi, ebx |
mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. |
cmp esi,0 |
jz dec_002 |
mov eax, EE_WRITE_1 |
dec_002: |
out dx, ax |
call delay_us |
or ax, EE_SHIFT_CLK |
out dx, ax |
call delay_us |
shl edi,1 |
in ax, dx |
and ax, EE_DATA_READ |
cmp ax,0 |
jz dec_003 |
inc edi |
dec_003: |
loop dec_001 |
mov ax, EE_ENB |
out dx, ax |
call delay_us |
mov ax, 0x4800 |
out dx, ax |
call delay_us |
mov eax, edi |
ret |
;*************************************************************************** |
; Function |
; I8255x_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
I8255x_probe: |
DEBUGF 1," K : Probing i8255x device \n" |
mov eax, [io_addr] |
mov ebx, [pci_bus] |
mov ecx, [pci_dev] |
mov edx, 0x04 ; PCI_COMMAND |
call pcibios_read_config_word |
or ax, 0x05 |
mov ebx, [pci_bus] |
mov ecx, [pci_dev] |
mov edx, 0x04 ; PCI_COMMAND |
call pcibios_write_config_word |
mov ebx, 0x6000000 |
mov ecx, 27 |
call do_eeprom_cmd |
and eax, 0xffe0000 |
cmp eax, 0xffe0000 |
je bige |
mov ebx, 0x1800000 |
mov ecx, 0x40 |
jmp doread |
bige: |
mov ebx, 0x6000000 |
mov ecx, 0x100 |
doread: |
; do-eeprom-cmd will destroy all registers |
; we have eesize in ecx |
; read_cmd in ebx |
; Ignore full eeprom - just load the mac address |
mov ecx, 0 |
drlp: |
push ecx ; save count |
push ebx |
mov eax, ecx |
shl eax, 16 |
or ebx, eax |
mov ecx, 27 |
call do_eeprom_cmd |
pop ebx |
pop ecx |
mov edx, ecx |
shl edx, 2 |
mov esi, eeprom_data |
add esi, edx |
mov [esi], eax |
inc ecx |
cmp ecx, 16 |
jne drlp |
; OK, we have the MAC address. |
; Now reset the card |
mov edx, [io_addr] |
add dx, 8 ; SCBPort |
xor eax, eax ; The reset cmd == 0 |
out dx, eax |
mov esi, 10 |
call delay_ms ; Give the card time to warm up. |
mov eax, lstats |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
mov eax, 0 |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
; build rxrd structure |
mov ax, 0x0001 |
mov [rxfd_status], ax |
mov ax, 0x0000 |
mov [rxfd_command], ax |
mov eax, rxfd_status |
sub eax, OS_BASE |
mov [rxfd_link], eax |
mov eax, Ether_buffer |
sub eax, OS_BASE |
mov [rxfd_rx_buf_addr], eax |
mov ax, 0 |
mov [rxfd_count], ax |
mov ax, 1528 |
mov [rxfd_size], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
sub eax, OS_BASE |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
call wait_for_cmd_done |
; start the reciver |
mov ax, 0 |
mov [rxfd_status], ax |
mov ax, 0xc000 |
mov [rxfd_command], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
sub eax, OS_BASE |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
; Init TX Stuff |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, 0 |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE |
out dx, ax |
call wait_for_cmd_done |
; Set TX Base address |
; First, set up confcmd values |
mov ax, 2 |
mov [confcmd_command], ax |
mov eax, txfd |
sub eax, OS_BASE |
mov [confcmd_link], eax |
mov ax, 1 |
mov [txfd_command], ax ; CmdIASetup |
mov ax, 0 |
mov [txfd_status], ax |
mov eax, confcmd |
sub eax, OS_BASE |
mov [txfd_link], eax |
; ETH_ALEN is 6 bytes |
mov esi, eeprom_data |
mov edi, node_addr |
mov ecx, 3 |
drp000: |
mov eax, [esi] |
mov [edi], al |
shr eax, 8 |
inc edi |
mov [edi], al |
inc edi |
add esi, 4 |
loop drp000 |
; Hard code your MAC address into node_addr at this point, |
; If you cannot read the MAC address from the eeprom in the previous step. |
; You also have to write the mac address into txfd_tx_desc_addr, rather |
; than taking data from eeprom_data |
mov esi, eeprom_data |
mov edi, txfd_tx_desc_addr |
mov ecx, 3 |
drp001: |
mov eax, [esi] |
mov [edi], al |
shr eax, 8 |
inc edi |
mov [edi], al |
inc edi |
add esi, 4 |
loop drp001 |
mov esi, eeprom_data + (6 * 4) |
mov eax, [esi] |
shr eax, 8 |
and eax, 0x3f |
cmp eax, 4 ; DP83840 |
je drp002 |
cmp eax, 10 ; DP83840A |
je drp002 |
jmp drp003 |
drp002: |
mov ebx, [esi] |
and ebx, 0x1f |
push ebx |
mov ecx, 23 |
call mdio_read |
pop ebx |
or eax, 0x0422 |
mov ecx, 23 |
mov edx, eax |
call mdio_write |
drp003: |
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure |
mov [confcmd_command], ax |
mov ax, 0 |
mov [confcmd_status], ax |
mov eax, txfd |
mov [confcmd_link], eax |
mov ebx, confcmd_data |
mov al, 0x88 ; fifo of 8 each |
mov [ebx + 1], al |
mov al, 0 |
mov [ebx + 4], al |
mov al, 0x80 |
mov [ebx + 5], al |
mov al, 0x48 |
mov [ebx + 15], al |
mov al, 0x80 |
mov [ebx + 19], al |
mov al, 0x05 |
mov [ebx + 21], al |
mov eax, txfd |
sub eax, OS_BASE |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0110 ; INT_MASK | CU_START |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
jmp skip |
; wait for thing to start |
drp004: |
mov ax, [txfd_status] |
cmp ax, 0 |
je drp004 |
skip: |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
I8255x_exit: |
ret |
;*************************************************************************** |
; Function |
; I8255x_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
I8255x_reset: |
ret |
;*************************************************************************** |
; Function |
; I8255x_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
I8255x_poll: |
mov ax, 0 ; assume no data |
mov [eth_rx_data_len], ax |
mov ax, [rxfd_status] |
cmp ax, 0 |
je i8p_exit |
mov ax, 0 |
mov [rxfd_status], ax |
mov ax, 0xc000 |
mov [rxfd_command], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
sub eax, OS_BASE |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
call wait_for_cmd_done |
mov esi, rxfd_packet |
mov edi, Ether_buffer |
mov ecx, 1518 |
cld |
rep movsb |
mov ax, [rxfd_count] |
and ax, 0x3fff |
mov [eth_rx_data_len], ax |
i8p_exit: |
ret |
;*************************************************************************** |
; Function |
; I8255x_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
I8255x_transmit: |
mov [hdr_type], bx |
mov eax, [edi] |
mov [hdr_dst_addr], eax |
mov ax, [edi+4] |
mov [hdr_dst_addr+4], ax |
mov eax, [node_addr] |
mov [hdr_src_addr], eax |
mov ax, [node_addr+4] |
mov [hdr_src_addr+4], ax |
mov edx, [io_addr] |
in ax, dx |
and ax, 0xfc00 |
out dx, ax |
xor ax, ax |
mov [txfd_status], ax |
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex |
mov [txfd_command], ax |
mov eax, txfd |
mov [txfd_link], eax |
mov eax, 0x02208000 |
mov [txfd_count], eax |
mov eax, txfd_tx_buf_addr0 |
sub eax, OS_BASE |
mov [txfd_tx_desc_addr], eax |
mov eax, hdr |
sub eax, OS_BASE |
mov [txfd_tx_buf_addr0], eax |
mov eax, 14 ; sizeof hdr |
mov [txfd_tx_buf_size0], eax |
; Copy the buffer address and size in |
mov eax, esi |
sub eax, OS_BASE |
mov [txfd_tx_buf_addr1], eax |
mov eax, ecx |
mov [txfd_tx_buf_size1], eax |
mov eax, txfd |
sub eax, OS_BASE |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov ax, 0x0110 ; INT_MASK | CU_START |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
mov edx, [io_addr] |
in ax, dx |
I8t_001: |
mov ax, [txfd_status] |
cmp ax, 0 |
je I8t_001 |
mov edx, [io_addr] |
in ax, dx |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/pcnet32.inc |
---|
0,0 → 1,848 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCNET32.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; - Version 1.0 31 July 2004: ;; |
;; Initial release ;; |
;; ;; |
;; - Version 1.01 29 March 2008: ;; |
;; Adapted to work with kolibrios flat kernel ;; |
;; Debug info is updated, and now uses DEBUGF macro ;; |
;; by hidnplayr@kolibrios.org ;; |
;; ;; |
;; This driver is based on the PCNet32 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2004 Jarek Pelczar, ;; |
;; jpelczar@interia.pl ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
PCNET32_PORT_AUI equ 0x00 |
PCNET32_PORT_10BT equ 0x01 |
PCNET32_PORT_GPSI equ 0x02 |
PCNET32_PORT_MII equ 0x03 |
PCNET32_PORT_PORTSEL equ 0x03 |
PCNET32_PORT_ASEL equ 0x04 |
PCNET32_PORT_100 equ 0x40 |
PCNET32_PORT_FD equ 0x80 |
PCNET32_DMA_MASK equ 0xffffffff |
PCNET32_LOG_TX_BUFFERS equ 1 |
PCNET32_LOG_RX_BUFFERS equ 2 |
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) |
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) |
PCNET32_TX_RING_LEN_BITS equ 0 |
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) |
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) |
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) |
PCNET32_PKT_BUF_SZ equ 1544 |
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 |
pcnet32_txb equ (eth_data_start) |
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_private: |
.mode dw ? |
.tlen_rlen dw ? |
.phys_addr db ?,?,?,?,?,? |
.reserved dw ? |
.filter dd ?,? |
.rx_ring dd ? |
.tx_ring dd ? |
.cur_rx dd ? |
.cur_tx dd ? |
.dirty_rx dd ? |
.dirty_tx dd ? |
.tx_full db ? |
.options dd ? |
.full_duplex db ? |
.chip_version dd ? |
.mii db ? |
.ltint db ? |
.dxsuflo db ? |
.fset db ? |
.fdx db ? |
end virtual |
virtual at 0 |
pcnet32_rx_head: |
.base dd ? |
.buf_length dw ? |
.status dw ? |
.msg_length dd ? |
.reserved dd ? |
end virtual |
virtual at 0 |
pcnet32_tx_head: |
.base dd ? |
.length dw ? |
.status dw ? |
.misc dd ? |
.reserved dd ? |
end virtual |
uglobal |
pcnet32_access: |
.read_csr dd ? |
.write_csr dd ? |
.read_bcr dd ? |
.write_bcr dd ? |
.read_rap dd ? |
.write_rap dd ? |
.reset dd ? |
endg |
iglobal |
pcnet32_options_mapping: |
dd PCNET32_PORT_ASEL ; 0 Auto-select |
dd PCNET32_PORT_AUI ; 1 BNC/AUI |
dd PCNET32_PORT_AUI ; 2 AUI/BNC |
dd PCNET32_PORT_ASEL ; 3 not supported |
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD |
dd PCNET32_PORT_ASEL ; 5 not supported |
dd PCNET32_PORT_ASEL ; 6 not supported |
dd PCNET32_PORT_ASEL ; 7 not supported |
dd PCNET32_PORT_ASEL ; 8 not supported |
dd PCNET32_PORT_MII ; 9 MII 10baseT |
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD |
dd PCNET32_PORT_MII ; 11 MII (autosel) |
dd PCNET32_PORT_10BT ; 12 10BaseT |
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx |
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD |
dd PCNET32_PORT_ASEL ; 15 not supported |
endg |
PCNET32_WIO_RDP equ 0x10 |
PCNET32_WIO_RAP equ 0x12 |
PCNET32_WIO_RESET equ 0x14 |
PCNET32_WIO_BDP equ 0x16 |
PCNET32_DWIO_RDP equ 0x10 |
PCNET32_DWIO_RAP equ 0x14 |
PCNET32_DWIO_RESET equ 0x18 |
PCNET32_DWIO_BDP equ 0x1C |
PCNET32_TOTAL_SIZE equ 0x20 |
; ebx - index |
; return: |
; eax - data |
pcnet32_wio_read_csr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
mov ax,bx |
out dx,ax |
lea edx,[ebp+PCNET32_WIO_RDP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - data |
; ebx - index |
pcnet32_wio_write_csr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
xchg eax,ebx |
out dx,ax |
xchg eax,ebx |
lea edx,[ebp+PCNET32_WIO_RDP] |
out dx,ax |
pop edx |
ret |
; ebx - index |
; return: |
; eax - data |
pcnet32_wio_read_bcr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
mov ax,bx |
out dx,ax |
lea edx,[ebp+PCNET32_WIO_BDP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - data |
; ebx - index |
pcnet32_wio_write_bcr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
xchg eax,ebx |
out dx,ax |
xchg eax,ebx |
lea edx,[ebp+PCNET32_WIO_BDP] |
out dx,ax |
pop edx |
ret |
pcnet32_wio_read_rap: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - val |
pcnet32_wio_write_rap: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
out dx,ax |
pop edx |
ret |
pcnet32_wio_reset: |
push edx |
push eax |
lea edx,[ebp+PCNET32_WIO_RESET] |
in ax,dx |
pop eax |
pop edx |
ret |
pcnet32_wio_check: |
push edx |
mov ax,88 |
lea edx,[ebp+PCNET32_WIO_RAP] |
out dx,ax |
nop |
nop |
in ax,dx |
cmp ax,88 |
sete al |
pop edx |
ret |
iglobal |
pcnet32_wio: |
dd pcnet32_wio_read_csr |
dd pcnet32_wio_write_csr |
dd pcnet32_wio_read_bcr |
dd pcnet32_wio_write_bcr |
dd pcnet32_wio_read_rap |
dd pcnet32_wio_write_rap |
dd pcnet32_wio_reset |
endg |
; ebx - index |
; return: |
; eax - data |
pcnet32_dwio_read_csr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
mov ebx,eax |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_RDP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; ebx - index |
; eax - data |
pcnet32_dwio_write_csr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
xchg eax,ebx |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_RDP] |
xchg eax,ebx |
out dx,eax |
pop edx |
ret |
; ebx - index |
; return: |
; eax - data |
pcnet32_dwio_read_bcr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
mov ebx,eax |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_BDP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; ebx - index |
; eax - data |
pcnet32_dwio_write_bcr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
xchg eax,ebx |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_BDP] |
xchg eax,ebx |
out dx,eax |
pop edx |
ret |
pcnet32_dwio_read_rap: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - val |
pcnet32_dwio_write_rap: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
out dx,eax |
pop edx |
ret |
pcnet32_dwio_reset: |
push edx |
push eax |
lea edx,[ebp+PCNET32_DWIO_RESET] |
in eax,dx |
pop eax |
pop edx |
ret |
pcnet32_dwio_check: |
push edx |
lea edx,[PCNET32_DWIO_RAP] |
mov eax,88 |
out dx,eax |
nop |
nop |
in eax,dx |
and eax,0xffff |
cmp eax,88 |
sete al |
pop edx |
ret |
iglobal |
pcnet32_dwio: |
dd pcnet32_dwio_read_csr |
dd pcnet32_dwio_write_csr |
dd pcnet32_dwio_read_bcr |
dd pcnet32_dwio_write_bcr |
dd pcnet32_dwio_read_rap |
dd pcnet32_dwio_write_rap |
dd pcnet32_dwio_reset |
endg |
pcnet32_init_ring: |
mov [pcnet32_private.tx_full],0 |
mov [pcnet32_private.cur_rx],0 |
mov [pcnet32_private.cur_tx],0 |
mov [pcnet32_private.dirty_rx],0 |
mov [pcnet32_private.dirty_tx],0 |
mov edi,pcnet32_rx_ring |
mov ecx,PCNET32_RX_RING_SIZE |
mov ebx,pcnet32_rxb |
sub ebx,OS_BASE |
.rx_init: |
mov [edi+pcnet32_rx_head.base],ebx |
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG |
mov [edi+pcnet32_rx_head.status],word 0x8000 |
add ebx,PCNET32_PKT_BUF_SZ |
; inc ebx |
add edi,16 |
loop .rx_init |
mov edi,pcnet32_tx_ring |
mov ecx,PCNET32_TX_RING_SIZE |
.tx_init: |
mov [edi+pcnet32_tx_head.base],dword 0 |
mov [edi+pcnet32_tx_head.status],word 0 |
add edi,16 |
loop .tx_init |
mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
mov esi,node_addr |
mov edi,pcnet32_private.phys_addr |
cld |
movsd |
movsw |
mov eax,pcnet32_rx_ring |
sub eax,OS_BASE |
mov dword [pcnet32_private.rx_ring],eax |
mov eax,pcnet32_tx_ring |
sub eax,OS_BASE |
mov dword [pcnet32_private.tx_ring],eax |
ret |
pcnet32_reset: |
; Reset PCNET32 |
mov ebp,[io_addr] |
call dword [pcnet32_access.reset] |
; set 32bit mode |
mov ebx,20 |
mov eax,2 |
call dword [pcnet32_access.write_bcr] |
; set/reset autoselect bit |
mov ebx,2 |
call dword [pcnet32_access.read_bcr] |
and eax,not 2 |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L1 |
or eax,2 |
.L1: |
call dword [pcnet32_access.write_bcr] |
; Handle full duplex setting |
cmp byte [pcnet32_private.full_duplex],0 |
je .L2 |
mov ebx,9 |
call dword [pcnet32_access.read_bcr] |
and eax,not 3 |
test [pcnet32_private.options],PCNET32_PORT_FD |
jz .L3 |
or eax,1 |
cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI |
jne .L4 |
or eax,2 |
jmp .L4 |
.L3: |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L4 |
cmp [pcnet32_private.chip_version],0x2627 |
jne .L4 |
or eax,3 |
.L4: |
mov ebx,9 |
call dword [pcnet32_access.write_bcr] |
.L2: |
; set/reset GPSI bit |
mov ebx,124 |
call dword [pcnet32_access.read_csr] |
mov ecx,[pcnet32_private.options] |
and ecx,PCNET32_PORT_PORTSEL |
cmp ecx,PCNET32_PORT_GPSI |
jne .L5 |
or eax,0x10 |
.L5: |
call dword [pcnet32_access.write_csr] |
cmp [pcnet32_private.mii],0 |
je .L6 |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jnz .L6 |
mov ebx,32 |
call dword [pcnet32_access.read_bcr] |
and eax,not 0x38 |
test [pcnet32_private.options],PCNET32_PORT_FD |
jz .L7 |
or eax,0x10 |
.L7: |
test [pcnet32_private.options],PCNET32_PORT_100 |
jz .L8 |
or eax,0x08 |
.L8: |
call dword [pcnet32_access.write_bcr] |
jmp .L9 |
.L6: |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L9 |
mov ebx,32 |
; DEBUGF 1," K : ASEL, enable auto-negotiation\n" |
call dword [pcnet32_access.read_bcr] |
and eax,not 0x98 |
or eax,0x20 |
call dword [pcnet32_access.write_bcr] |
.L9: |
cmp [pcnet32_private.ltint],0 |
je .L10 |
mov ebx,5 |
call dword [pcnet32_access.read_csr] |
or eax,(1 shl 14) |
call dword [pcnet32_access.write_csr] |
.L10: |
mov eax,[pcnet32_private.options] |
and eax,PCNET32_PORT_PORTSEL |
shl eax,7 |
mov [pcnet32_private.mode],ax |
mov [pcnet32_private.filter],dword 0xffffffff |
mov [pcnet32_private.filter+4],dword 0xffffffff |
call pcnet32_init_ring |
mov ebx,1 |
mov eax,pcnet32_private |
sub eax,OS_BASE |
and eax,0xffff |
call dword [pcnet32_access.write_csr] |
mov eax,pcnet32_private |
sub eax,OS_BASE |
mov ebx,2 |
shr eax,16 |
call dword [pcnet32_access.write_csr] |
mov ebx,4 |
mov eax,0x0915 |
call dword [pcnet32_access.write_csr] |
mov ebx,0 |
mov eax,1 |
call dword [pcnet32_access.write_csr] |
mov ecx,100 |
.L11: |
xor ebx,ebx |
call dword [pcnet32_access.read_csr] |
test ax,0x100 |
jnz .L12 |
loop .L11 |
.L12: |
; DEBUGF 1," K : hardware reset\n" |
xor ebx,ebx |
mov eax,0x0002 |
call dword [pcnet32_access.write_csr] |
xor ebx,ebx |
call dword [pcnet32_access.read_csr] |
; DEBUGF 1," K : PCNET reset complete\n" |
ret |
pcnet32_adjust_pci_device: |
;*******Get current setting************************ |
mov al, 2 ;read a word |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x04 ;from command Register |
call pci_read_reg |
;******see if its already set as bus master******** |
mov bx, ax |
and bx,5 |
cmp bx,5 |
je pcnet32_adjust_pci_device_Latency |
;******Make card a bus master******* |
mov cx, ax ;value to write |
mov bh, [pci_dev] |
mov al, 2 ;write a word |
or cx,5 |
mov ah, [pci_bus] |
mov bl, 0x04 ;to command register |
call pci_write_reg |
;******Check latency setting*********** |
pcnet32_adjust_pci_device_Latency: |
;*******Get current latency setting************************ |
; mov al, 1 ;read a byte |
; mov bh, [pci_dev] |
; mov ah, [pci_bus] |
; mov bl, 0x0D ;from Lantency Timer Register |
; call pci_read_reg |
;******see if its aat least 64 clocks******** |
; cmp ax,64 |
; jge pcnet32_adjust_pci_device_Done |
;******Set latency to 32 clocks******* |
; mov cx, 64 ;value to write |
; mov bh, [pci_dev] |
; mov al, 1 ;write a byte |
; mov ah, [pci_bus] |
; mov bl, 0x0D ;to Lantency Timer Register |
; call pci_write_reg |
;******Check latency setting*********** |
pcnet32_adjust_pci_device_Done: |
ret |
pcnet32_probe: |
mov ebp,[io_addr] |
call pcnet32_wio_reset |
xor ebx,ebx |
call pcnet32_wio_read_csr |
cmp eax,4 |
jne .try_dwio |
call pcnet32_wio_check |
and al,al |
jz .try_dwio |
; DEBUGF 1," K : Using WIO\n" |
mov esi,pcnet32_wio |
jmp .L1 |
.try_dwio: |
call pcnet32_dwio_reset |
xor ebx,ebx |
call pcnet32_dwio_read_csr |
cmp eax,4 |
jne .no_dev |
call pcnet32_dwio_check |
and al,al |
jz .no_dev |
; DEBUGF 1," K : Using DWIO\n" |
mov esi,pcnet32_dwio |
jmp .L1 |
.no_dev: |
DEBUGF 1," K : PCNET32 not found\n" |
ret |
.L1: |
mov edi,pcnet32_access |
mov ecx,7 |
cld |
rep movsd |
mov ebx,88 |
call dword [pcnet32_access.read_csr] |
mov ecx,eax |
mov ebx,89 |
call dword [pcnet32_access.read_csr] |
shl eax,16 |
or eax,ecx |
mov ecx,eax |
and ecx,0xfff |
cmp ecx,3 |
jne .no_dev |
shr eax,12 |
and eax,0xffff |
mov [pcnet32_private.chip_version],eax |
; DEBUGF 1," K : PCNET32 chip version OK\n" |
mov [pcnet32_private.fdx],0 |
mov [pcnet32_private.mii],0 |
mov [pcnet32_private.fset],0 |
mov [pcnet32_private.dxsuflo],0 |
mov [pcnet32_private.ltint],0 |
mov eax,[pcnet32_private.chip_version] |
cmp eax,0x2420 |
je .L2 |
cmp eax,0x2430 |
je .L3 |
cmp eax,0x2621 |
je .L4 |
cmp eax,0x2623 |
je .L5 |
cmp eax,0x2624 |
je .L6 |
cmp eax,0x2625 |
je .L7 |
cmp eax,0x2626 |
je .L8 |
cmp eax,0x2627 |
je .L9 |
DEBUGF 1," K : Invalid chip rev\n" |
jmp .no_dev |
.L2: |
; DEBUGF 1," K : PCnet/PCI 79C970\n" |
jmp .L10 |
.L3: |
; DEBUGF 1," K : PCnet/PCI 79C970\n" |
jmp .L10 |
.L4: |
; DEBUGF 1," K : PCnet/PCI II 79C970A\n" |
mov [pcnet32_private.fdx],1 |
jmp .L10 |
.L5: |
; DEBUGF 1," K : PCnet/FAST 79C971\n" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
mov [pcnet32_private.fset],1 |
mov [pcnet32_private.ltint],1 |
jmp .L10 |
.L6: |
; DEBUGF 1," K : PCnet/FAST+ 79C972\n" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
mov [pcnet32_private.fset],1 |
jmp .L10 |
.L7: |
; DEBUGF 1," K : PCnet/FAST III 79C973\n" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
jmp .L10 |
.L8: |
; DEBUGF 1," K : PCnet/Home 79C978\n" |
mov [pcnet32_private.fdx],1 |
mov ebx,49 |
call dword [pcnet32_access.read_bcr] |
call dword [pcnet32_access.write_bcr] |
jmp .L10 |
.L9: |
; DEBUGF 1," K : PCnet/FAST III 79C975\n" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
.L10: |
cmp [pcnet32_private.fset],1 |
jne .L11 |
mov ebx,18 |
call dword [pcnet32_access.read_bcr] |
or eax,0x800 |
call dword [pcnet32_access.write_bcr] |
mov ebx,80 |
call dword [pcnet32_access.read_csr] |
and eax,0xc00 |
or eax,0xc00 |
call dword [pcnet32_access.write_csr] |
mov [pcnet32_private.dxsuflo],1 |
mov [pcnet32_private.ltint],1 |
.L11: |
; read MAC |
mov edi,node_addr |
mov edx,ebp |
mov ecx,6 |
.Lmac: |
in al,dx |
stosb |
inc edx |
loop .Lmac |
; DEBUGF 1," K : MAC read\n" |
call pcnet32_adjust_pci_device |
; DEBUGF 1," K : PCI done\n" |
mov eax,PCNET32_PORT_ASEL |
mov [pcnet32_private.options],eax |
mov [pcnet32_private.mode],word 0x0003 |
mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
mov esi,node_addr |
mov edi,pcnet32_private.phys_addr |
cld |
movsd |
movsw |
mov [pcnet32_private.filter],dword 0 |
mov [pcnet32_private.filter+4],dword 0 |
mov eax,pcnet32_rx_ring |
sub eax,OS_BASE |
mov dword [pcnet32_private.rx_ring],eax |
mov eax,pcnet32_tx_ring |
sub eax,OS_BASE |
mov dword [pcnet32_private.tx_ring],eax |
; DEBUGF 1," K : Switching to 32\n" |
mov ebx,20 |
mov eax,2 |
call dword [pcnet32_access.write_bcr] |
mov ebx,1 |
mov eax,(pcnet32_private and 0xffff) |
call dword [pcnet32_access.write_csr] |
mov ebx,2 |
mov eax,(pcnet32_private shr 16) and 0xffff |
call dword [pcnet32_access.write_csr] |
mov ebx,0 |
mov eax,1 |
call dword [pcnet32_access.write_csr] |
mov esi,1 |
call delay_ms |
call pcnet32_reset |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
pcnet32_poll: |
xor ax,ax |
mov [eth_rx_data_len],ax |
mov eax,[pcnet32_private.cur_rx] |
and eax,PCNET32_RX_RING_MOD_MASK |
mov ebx,eax |
imul esi,eax,PCNET32_PKT_BUF_SZ |
add esi,pcnet32_rxb |
shl ebx,4 |
add ebx,pcnet32_rx_ring |
mov cx,[ebx+pcnet32_rx_head.status] |
test cx,0x8000 |
jnz .L1 |
cmp ch,3 |
jne .L1 |
mov ecx,[ebx+pcnet32_rx_head.msg_length] |
and ecx,0xfff |
sub ecx,4 |
mov [eth_rx_data_len],cx |
; DEBUGF 1," K : PCNETRX: %ub\n",cx |
push ecx |
shr ecx,2 |
mov edi,Ether_buffer |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG |
or [ebx+pcnet32_rx_head.status],word 0x8000 |
inc [pcnet32_private.cur_rx] |
.L1: |
ret |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
pcnet32_xmit: |
push edi |
push esi |
push ebx |
push ecx |
; DEBUGF 1," K : PCNETTX\n" |
mov esi,edi |
mov edi,[pcnet32_private.cur_tx] |
imul edi,PCNET32_PKT_BUF_SZ |
add edi,pcnet32_txb ; edi=ptxb |
mov eax,edi |
cld ; copy MAC |
movsd |
movsw |
mov esi,node_addr |
cld |
movsd |
movsw |
mov [edi],bx |
add edi,2 |
mov esi,[esp+8] |
mov ecx,[esp] |
push ecx |
shr ecx,2 |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
; mov ecx,[esp] |
; add ecx,14 ; ETH_HLEN |
; xor eax,eax |
; pad to min length (60=ETH_ZLEN) |
; cmp ecx,60 |
; jae .L1 |
; sub ecx,60 |
; cld |
; rep stosb |
;.L1: |
mov edi,pcnet32_tx_ring+0 ; entry=0 |
mov ecx,[esp] |
add ecx,14 |
cmp cx,60 |
jae .L1 |
mov cx,60 |
.L1: |
neg cx |
mov [edi+pcnet32_tx_head.length],cx |
mov [edi+pcnet32_tx_head.misc],dword 0 |
sub eax,OS_BASE |
mov [edi+pcnet32_tx_head.base],eax |
mov [edi+pcnet32_tx_head.status],word 0x8300 |
; trigger an immediate send poll |
mov ebx,0 |
mov eax,0x0008 ; 0x0048 |
mov ebp,[io_addr] |
call dword [pcnet32_access.write_csr] |
mov dword [pcnet32_private.cur_tx],0 |
; wait for TX to complete |
mov ecx,[timer_ticks];[0xfdf0] |
add ecx,100 |
.L2: |
mov ax,[edi+pcnet32_tx_head.status] |
test ax,0x8000 |
jz .L3 |
cmp ecx,[timer_ticks];[0xfdf0] |
jb .L4 |
mov esi,10 |
call delay_ms |
jnz .L2 |
.L4: |
DEBUGF 1," K : PCNET: Send timeout\n" |
.L3: |
mov dword [edi+pcnet32_tx_head.base],0 |
pop ecx |
pop ebx |
pop esi |
pop edi |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/sis900.inc |
---|
0,0 → 1,1158 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; SIS900.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.4 26 April 2004 ;; |
;; ;; |
;; This driver is based on the SIS900 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2004 Jason Delozier, ;; |
;; cordata51@hotmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; Updates: ;; |
;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************** |
; Interface |
; SIS900_reset |
; SIS900_probe |
; SIS900_poll |
; SIS900_transmit |
; |
;******************************************************************** |
;******************************************************************** |
; Comments: |
; Known to work with the following SIS900 ethernet cards: |
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 |
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 |
; |
; If your card is not listed, try it and let me know if it |
; functions properly and it will be aded to the list. If not |
; we may be able to add support for it. |
; |
; How To Use: |
; Add the following lines to Ethernet.inc in their appropriate locations |
; |
; include "Sis900.INC" |
; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, |
; SIS900_transmit |
; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, |
; SIS900_transmit ;untested |
; |
; ToDo: |
; - Enable MII interface for reading speed |
; and duplex settings. |
; |
; - Update Poll routine to support packet fragmentation. |
; |
; - Add additional support for other sis900 based cards |
; |
;******************************************************************** |
; comment the next line out if you don't want debug info printed |
; on the debug board. This option adds a lot of bytes to the driver |
; so it's worth to comment it out. |
; SIS900_DEBUG equ 1 |
;* buffers and descriptors |
cur_rx db 0 |
NUM_RX_DESC equ 4 ;* Number of RX descriptors * |
NUM_TX_DESC equ 1 ;* Number of TX descriptors * |
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * |
TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * |
uglobal |
align 4 |
txd: times (3 * NUM_TX_DESC) dd 0 |
rxd: times (3 * NUM_RX_DESC) dd 0 |
endg |
txb equ eth_data_start |
rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ) |
SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * |
SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * |
SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * |
SIS900_DSIZE equ 0x00000fff |
SIS900_CRC_SIZE equ 4 |
SIS900_RFADDR_shift equ 16 |
;SIS900 Symbolic offsets to registers. |
SIS900_cr equ 0x0 ; Command Register |
SIS900_cfg equ 0x4 ; Configuration Register |
SIS900_mear equ 0x8 ; EEPROM Access Register |
SIS900_ptscr equ 0xc ; PCI Test Control Register |
SIS900_isr equ 0x10 ; Interrupt Status Register |
SIS900_imr equ 0x14 ; Interrupt Mask Register |
SIS900_ier equ 0x18 ; Interrupt Enable Register |
SIS900_epar equ 0x18 ; Enhanced PHY Access Register |
SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register |
SIS900_txcfg equ 0x24 ; Transmit Configuration Register |
SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register |
SIS900_rxcfg equ 0x34 ; Receive Configuration Register |
SIS900_flctrl equ 0x38 ; Flow Control Register |
SIS900_rxlen equ 0x3c ; Receive Packet Length Register |
SIS900_rfcr equ 0x48 ; Receive Filter Control Register |
SIS900_rfdr equ 0x4C ; Receive Filter Data Register |
SIS900_pmctrl equ 0xB0 ; Power Management Control Register |
SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register |
;SIS900 Command Register Bits |
SIS900_RELOAD equ 0x00000400 |
SIS900_ACCESSMODE equ 0x00000200 |
SIS900_RESET equ 0x00000100 |
SIS900_SWI equ 0x00000080 |
SIS900_RxRESET equ 0x00000020 |
SIS900_TxRESET equ 0x00000010 |
SIS900_RxDIS equ 0x00000008 |
SIS900_RxENA equ 0x00000004 |
SIS900_TxDIS equ 0x00000002 |
SIS900_TxENA equ 0x00000001 |
;SIS900 Configuration Register Bits |
SIS900_DESCRFMT equ 0x00000100 ; 7016 specific |
SIS900_REQALG equ 0x00000080 |
SIS900_SB equ 0x00000040 |
SIS900_POW equ 0x00000020 |
SIS900_EXD equ 0x00000010 |
SIS900_PESEL equ 0x00000008 |
SIS900_LPM equ 0x00000004 |
SIS900_BEM equ 0x00000001 |
SIS900_RND_CNT equ 0x00000400 |
SIS900_FAIR_BACKOFF equ 0x00000200 |
SIS900_EDB_MASTER_EN equ 0x00002000 |
;SIS900 Eeprom Access Reigster Bits |
SIS900_MDC equ 0x00000040 |
SIS900_MDDIR equ 0x00000020 |
SIS900_MDIO equ 0x00000010 ; 7016 specific |
SIS900_EECS equ 0x00000008 |
SIS900_EECLK equ 0x00000004 |
SIS900_EEDO equ 0x00000002 |
SIS900_EEDI equ 0x00000001 |
;SIS900 TX Configuration Register Bits |
SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding |
SIS900_MLB equ 0x20000000 ;Mac Loopback Enable |
SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) |
SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du |
;SIS900 RX Configuration Register Bits |
SIS900_AJAB equ 0x08000000 ; |
SIS900_ATX equ 0x10000000 ;Accept Transmit Packets |
SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) |
SIS900_AEP equ 0x80000000 ;accept error packets |
;SIS900 Interrupt Reigster Bits |
SIS900_WKEVT equ 0x10000000 |
SIS900_TxPAUSEEND equ 0x08000000 |
SIS900_TxPAUSE equ 0x04000000 |
SIS900_TxRCMP equ 0x02000000 |
SIS900_RxRCMP equ 0x01000000 |
SIS900_DPERR equ 0x00800000 |
SIS900_SSERR equ 0x00400000 |
SIS900_RMABT equ 0x00200000 |
SIS900_RTABT equ 0x00100000 |
SIS900_RxSOVR equ 0x00010000 |
SIS900_HIBERR equ 0x00008000 |
SIS900_SWINT equ 0x00001000 |
SIS900_MIBINT equ 0x00000800 |
SIS900_TxURN equ 0x00000400 |
SIS900_TxIDLE equ 0x00000200 |
SIS900_TxERR equ 0x00000100 |
SIS900_TxDESC equ 0x00000080 |
SIS900_TxOK equ 0x00000040 |
SIS900_RxORN equ 0x00000020 |
SIS900_RxIDLE equ 0x00000010 |
SIS900_RxEARLY equ 0x00000008 |
SIS900_RxERR equ 0x00000004 |
SIS900_RxDESC equ 0x00000002 |
SIS900_RxOK equ 0x00000001 |
;SIS900 Interrupt Enable Reigster Bits |
SIS900_IE equ 0x00000001 |
;SIS900 Revision ID |
SIS900B_900_REV equ 0x03 |
SIS630A_900_REV equ 0x80 |
SIS630E_900_REV equ 0x81 |
SIS630S_900_REV equ 0x82 |
SIS630EA1_900_REV equ 0x83 |
SIS630ET_900_REV equ 0x84 |
SIS635A_900_REV equ 0x90 |
SIS900_960_REV equ 0x91 |
;SIS900 Receive Filter Control Register Bits |
SIS900_RFEN equ 0x80000000 |
SIS900_RFAAB equ 0x40000000 |
SIS900_RFAAM equ 0x20000000 |
SIS900_RFAAP equ 0x10000000 |
SIS900_RFPromiscuous equ 0x70000000 |
;SIS900 Reveive Filter Data Mask |
SIS900_RFDAT equ 0x0000FFFF |
;SIS900 Eeprom Address |
SIS900_EEPROMSignature equ 0x00 |
SIS900_EEPROMVendorID equ 0x02 |
SIS900_EEPROMDeviceID equ 0x03 |
SIS900_EEPROMMACAddr equ 0x08 |
SIS900_EEPROMChecksum equ 0x0b |
;The EEPROM commands include the alway-set leading bit. |
;SIS900 Eeprom Command |
SIS900_EEread equ 0x0180 |
SIS900_EEwrite equ 0x0140 |
SIS900_EEerase equ 0x01C0 |
SIS900_EEwriteEnable equ 0x0130 |
SIS900_EEwriteDisable equ 0x0100 |
SIS900_EEeraseAll equ 0x0120 |
SIS900_EEwriteAll equ 0x0110 |
SIS900_EEaddrMask equ 0x013F |
SIS900_EEcmdShift equ 16 |
;For SiS962 or SiS963, request the eeprom software access |
SIS900_EEREQ equ 0x00000400 |
SIS900_EEDONE equ 0x00000200 |
SIS900_EEGNT equ 0x00000100 |
;General Varibles |
SIS900_pci_revision: db 0 |
SIS900_Status dd 0x03000000 |
sis900_specific_table: |
; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 |
; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 |
dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN |
dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS900_960_REV,SIS960_get_mac_addr,0 |
dd SIS900B_900_REV,SIS900_get_mac_addr,0 |
dd 0,0,0,0 ; end of list |
sis900_get_mac_func: dd 0 |
sis900_special_func: dd 0 |
sis900_table_entries: db 8 |
;*************************************************************************** |
; Function |
; SIS900_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
;not done - still need to probe mii transcievers |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 |
end if |
SIS900_probe: |
;******Wake Up Chip******* |
mov al, 4 |
mov bh, [pci_dev] |
mov ecx, 0 |
mov ah, [pci_bus] |
mov bl, 0x40 |
call pci_write_reg |
;*******Set some PCI Settings********* |
call SIS900_adjust_pci_device |
;*****Get Card Revision****** |
mov al, 1 ;one byte to read |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x08 ;Revision Register |
call pci_read_reg |
mov [SIS900_pci_revision], al ;save the revision for later use |
;****** Look up through the sis900_specific_table |
mov esi,sis900_specific_table |
.probe_loop: |
cmp dword [esi],0 ; Check if we reached end of the list |
je .probe_loop_failed |
cmp al,[esi] ; Check if revision is OK |
je .probe_loop_ok |
add esi,12 ; Advance to next entry |
jmp .probe_loop |
.probe_loop_failed: |
jmp SIS900_Probe_Unsupported |
;*********Find Get Mac Function********* |
.probe_loop_ok: |
mov eax,[esi+4] ; Get pointer to "get MAC" function |
mov [sis900_get_mac_func],eax |
mov eax,[esi+8] ; Get pointer to special initialization fn |
mov [sis900_special_func],eax |
;******** Get MAC ******** |
call dword [sis900_get_mac_func] |
;******** Call special initialization fn if requested ******** |
cmp dword [sis900_special_func],0 |
je .no_special_init |
call dword [sis900_special_func] |
.no_special_init: |
;******** Set table entries ******** |
mov al,[SIS900_pci_revision] |
cmp al,SIS635A_900_REV |
jae .ent16 |
cmp al,SIS900B_900_REV |
je .ent16 |
jmp .ent8 |
.ent16: |
mov byte [sis900_table_entries],16 |
.ent8: |
;*******Probe for mii transceiver******* |
;TODO!!********************* |
;*******Initialize Device******* |
call sis900_init |
ret |
SIS900_Probe_Unsupported: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Str_Unsupported |
call sys_msg_board_str |
end if |
ret |
;*************************************************************************** |
; Function: sis900_init |
; |
; Description: resets the ethernet controller chip and various |
; data structures required for sending and receiving packets. |
; |
; Arguments: |
; |
; returns: none |
;not done |
;*************************************************************************** |
sis900_init: |
call SIS900_reset ;Done |
call SIS900_init_rxfilter ;Done |
call SIS900_init_txd ;Done |
call SIS900_init_rxd ;Done |
call SIS900_set_rx_mode ;done |
call SIS900_set_tx_mode |
;call SIS900_check_mode |
ret |
;*************************************************************************** |
; Function |
; SIS900_reset |
; Description |
; disables interrupts and soft resets the controller chip |
; |
;done+ |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Reset_Failed db 'Reset Failed ',0 |
end if |
SIS900_reset: |
;******Disable Interrupts and reset Receive Filter******* |
mov ebp, [io_addr] ; base address |
xor eax, eax ; 0 to initialize |
lea edx,[ebp+SIS900_ier] |
out dx, eax ; Write 0 to location |
lea edx,[ebp+SIS900_imr] |
out dx, eax ; Write 0 to location |
lea edx,[ebp+SIS900_rfcr] |
out dx, eax ; Write 0 to location |
;*******Reset Card*********************************************** |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_RESET ; set flags |
or eax, SIS900_RxRESET ; |
or eax, SIS900_TxRESET ; |
out dx, eax ; Write new Command Register |
;*******Wait Loop************************************************ |
lea edx,[ebp+SIS900_isr] |
mov ecx, [SIS900_Status] ; Status we would like to see from card |
mov ebx, 2001 ; only loop 1000 times |
SIS900_Wait: |
dec ebx ; 1 less loop |
jz SIS900_DoneWait_e ; 1000 times yet? |
in eax, dx ; move interrup status to eax |
and eax, ecx |
xor ecx, eax |
jz SIS900_DoneWait |
jmp SIS900_Wait |
SIS900_DoneWait_e: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Reset_Failed |
call sys_msg_board_str |
end if |
SIS900_DoneWait: |
;*******Set Configuration Register depending on Card Revision******** |
lea edx,[ebp+SIS900_cfg] |
mov eax, SIS900_PESEL ; Configuration Register Bit |
mov bl, [SIS900_pci_revision] ; card revision |
mov cl, SIS635A_900_REV ; Check card revision |
cmp bl, cl |
je SIS900_RevMatch |
mov cl, SIS900B_900_REV ; Check card revision |
cmp bl, cl |
je SIS900_RevMatch |
out dx, eax ; no revision match |
jmp SIS900_Reset_Complete |
SIS900_RevMatch: ; Revision match |
or eax, SIS900_RND_CNT ; Configuration Register Bit |
out dx, eax |
SIS900_Reset_Complete: |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
;*************************************************************************** |
; Function: sis_init_rxfilter |
; |
; Description: sets receive filter address to our MAC address |
; |
; Arguments: |
; |
; returns: |
;done+ |
;*************************************************************************** |
SIS900_init_rxfilter: |
;****Get Receive Filter Control Register ******** |
mov ebp, [io_addr] ; base address |
lea edx,[ebp+SIS900_rfcr] |
in eax, dx ; get register |
push eax |
;****disable packet filtering before setting filter******* |
mov eax, SIS900_RFEN ;move receive filter enable flag |
not eax ;1s complement |
pop ebx ;and with our saved register |
and eax, ebx ;disable receiver |
push ebx ;save filter for another use |
out dx, eax ;set receive disabled |
;********load MAC addr to filter data register********* |
xor ecx, ecx |
SIS900_RXINT_Mac_Write: |
;high word of eax tells card which mac byte to write |
mov eax, ecx |
lea edx,[ebp+SIS900_rfcr] |
shl eax, 16 ; |
out dx, eax ; |
lea edx,[ebp+SIS900_rfdr] |
mov ax, word [node_addr+ecx*2] ; Get Mac ID word |
out dx, ax ; Send Mac ID |
inc cl ; send next word |
cmp cl, 3 ; more to send? |
jne SIS900_RXINT_Mac_Write |
;********enable packet filitering ***** |
pop eax ;old register value |
lea edx,[ebp+SIS900_rfcr] |
or eax, SIS900_RFEN ;enable filtering |
out dx, eax ;set register |
ret |
;*************************************************************************** |
;* |
;* Function: sis_init_txd |
;* |
;* Description: initializes the Tx descriptor |
;* |
;* Arguments: |
;* |
;* returns: |
;*done |
;*************************************************************************** |
SIS900_init_txd: |
;********** initialize TX descriptor ************** |
mov [txd], dword 0 ;put link to next descriptor in link field |
mov [txd+4],dword 0 ;clear status field |
mov [txd+8], dword txb - OS_BASE ;save address to buffer ptr field |
;*************** load Transmit Descriptor Register *************** |
mov dx, [io_addr] ; base address |
add dx, SIS900_txdp ; TX Descriptor Pointer |
mov eax, txd - OS_BASE ; First Descriptor |
out dx, eax ; move the pointer |
ret |
;*************************************************************************** |
;* Function: sis_init_rxd |
;* |
;* Description: initializes the Rx descriptor ring |
;* |
;* Arguments: |
;* |
;* Returns: |
;*done |
;*************************************************************************** |
SIS900_init_rxd: |
xor ecx,ecx |
mov [cur_rx], cl ;Set cuurent rx discriptor to 0 |
;******** init RX descriptors ******** |
SIS900_init_rxd_Loop: |
mov eax, ecx ;current descriptor |
imul eax, 12 ; |
mov ebx, ecx ;determine next link descriptor |
inc ebx ; |
cmp ebx, NUM_RX_DESC ; |
jne SIS900_init_rxd_Loop_0 ; |
xor ebx, ebx ; |
SIS900_init_rxd_Loop_0: ; |
imul ebx, 12 ; |
add ebx, rxd - OS_BASE ; |
mov [rxd+eax], ebx ;save link to next descriptor |
mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size |
mov ebx, ecx ;find where the buf is located |
imul ebx,RX_BUFF_SZ ; |
add ebx, rxb - OS_BASE ; |
mov [rxd+eax+8], ebx ;save buffer pointer |
inc ecx ;next descriptor |
cmp ecx, NUM_RX_DESC ; |
jne SIS900_init_rxd_Loop ; |
;********* load Receive Descriptor Register with address of first |
; descriptor********* |
mov dx, [io_addr] |
add dx, SIS900_rxdp |
mov eax, rxd - OS_BASE |
out dx, eax |
ret |
;*************************************************************************** |
;* Function: sis900_set_tx_mode |
;* |
;* Description: |
;* sets the transmit mode to allow for full duplex |
;* |
;* |
;* Arguments: |
;* |
;* Returns: |
;* |
;* Comments: |
;* If you are having problems transmitting packet try changing the |
;* Max DMA Burst, Possible settings are as follows: |
;* 0x00000000 = 512 bytes |
;* 0x00100000 = 4 bytes |
;* 0x00200000 = 8 bytes |
;* 0x00300000 = 16 bytes |
;* 0x00400000 = 32 bytes |
;* 0x00500000 = 64 bytes |
;* 0x00600000 = 128 bytes |
;* 0x00700000 = 256 bytes |
;*************************************************************************** |
SIS900_set_tx_mode: |
mov ebp,[io_addr] |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxENA ;Enable Receive |
out dx, eax |
lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset |
mov eax, SIS900_ATP ;allow automatic padding |
or eax, SIS900_HBI ;allow heartbeat ignore |
or eax, SIS900_CSI ;allow carrier sense ignore |
or eax, 0x00600000 ;Max DMA Burst |
or eax, 0x00000100 ;TX Fill Threshold |
or eax, 0x00000020 ;TX Drain Threshold |
out dx, eax |
ret |
;*************************************************************************** |
;* Function: sis900_set_rx_mode |
;* |
;* Description: |
;* sets the receive mode to accept all broadcast packets and packets |
;* with our MAC address, and reject all multicast packets. Also allows |
;* full-duplex |
;* |
;* Arguments: |
;* |
;* Returns: |
;* |
;* Comments: |
;* If you are having problems receiving packet try changing the |
;* Max DMA Burst, Possible settings are as follows: |
;* 0x00000000 = 512 bytes |
;* 0x00100000 = 4 bytes |
;* 0x00200000 = 8 bytes |
;* 0x00300000 = 16 bytes |
;* 0x00400000 = 32 bytes |
;* 0x00500000 = 64 bytes |
;* 0x00600000 = 128 bytes |
;* 0x00700000 = 256 bytes |
;*************************************************************************** |
SIS900_mc_filter: times 16 dw 0 |
SIS900_set_rx_mode: |
mov ebp,[io_addr] |
;**************update Multicast Hash Table in Receive Filter |
mov ebx, 0xffff |
xor cl, cl |
SIS900_set_rx_mode_Loop: |
mov eax, ecx |
shl eax, 1 |
mov [SIS900_mc_filter+eax], bx |
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset |
mov eax, 4 ;determine table entry |
add al, cl |
shl eax, 16 |
out dx, eax ;tell card which entry to modify |
lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset |
mov eax, ebx ;entry value |
out dx, ax ;write value to table in card |
inc cl ;next entry |
cmp cl,[sis900_table_entries] ; |
jl SIS900_set_rx_mode_Loop |
;*******Set Receive Filter Control Register************* |
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset |
mov eax, SIS900_RFAAB ;accecpt all broadcast packets |
or eax, SIS900_RFAAM ;accept all multicast packets |
or eax, SIS900_RFAAP ;Accept all packets |
or eax, SIS900_RFEN ;enable receiver filter |
out dx, eax |
;******Enable Receiver************ |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_RxENA ;Enable Receive |
out dx, eax |
;*********Set |
lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset |
mov eax, SIS900_ATX ;Accept Transmit Packets |
; (Req for full-duplex and PMD Loopback) |
or eax, 0x00600000 ;Max DMA Burst |
or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes |
out dx, eax ; |
ret |
;*************************************************************************** |
; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model |
; * @pci_dev: the sis900 pci device |
; * @net_dev: the net device to get address for |
; * |
; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM |
; * is shared by |
; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first |
; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access |
; * by LAN, otherwise is not. After MAC address is read from EEPROM, send |
; * EEDONE signal to refuse EEPROM access by LAN. |
; * The EEPROM map of SiS962 or SiS963 is different to SiS900. |
; * The signature field in SiS962 or SiS963 spec is meaningless. |
; * MAC address is read into @net_dev->dev_addr. |
; *done |
;* |
;* Return 0 is EAX = failure |
;*Done+ |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 |
SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 |
SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 |
SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 |
end if |
SIS960_get_mac_addr: |
mov ebp,[io_addr] |
;**********Send Request for eeprom access********************* |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
mov eax, SIS900_EEREQ ; Request access to eeprom |
out dx, eax ; Send request |
xor ebx,ebx ; |
;******Loop 4000 times and if access not granted error out***** |
SIS96X_Get_Mac_Wait: |
in eax, dx ;get eeprom status |
and eax, SIS900_EEGNT ;see if eeprom access granted flag is set |
jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom |
inc ebx ;else keep waiting |
cmp ebx, 4000 ;have we tried 4000 times yet? |
jl SIS96X_Get_Mac_Wait ;if not ask again |
xor eax, eax ;return zero in eax indicating failure |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Failed |
call sys_msg_board_str |
end if |
jmp SIS960_get_mac_addr_done |
;**********EEprom access granted, read MAC from card************* |
SIS900_Got_EEP_Access: |
; zero based so 3-16 bit reads will take place |
mov ecx, 2 |
SIS96x_mac_read_loop: |
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address |
add eax, ecx ;Current Mac Byte Offset |
push ecx |
call sis900_read_eeprom ;try to read 16 bits |
pop ecx |
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible |
dec ecx ;one less word to read |
jns SIS96x_mac_read_loop ;if more read more |
mov eax, 1 ;return non-zero indicating success |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address2 |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
;**********Tell EEPROM We are Done Accessing It********************* |
SIS960_get_mac_addr_done: |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
mov eax, SIS900_EEDONE ;tell eeprom we are done |
out dx,eax |
ret |
;*************************************************************************** |
;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model |
;* @pci_dev: the sis900 pci device |
;* @net_dev: the net device to get address for |
;* |
;* Older SiS900 and friends, use EEPROM to store MAC address. |
;* MAC address is read from read_eeprom() into @net_dev->dev_addr. |
;* done/untested |
;*************************************************************************** |
SIS900_get_mac_addr: |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Start |
call sys_msg_board_str |
end if |
;******** check to see if we have sane EEPROM ******* |
mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature |
call sis900_read_eeprom ;try to read 16 bits |
cmp ax, 0xffff |
je SIS900_Bad_Eeprom |
cmp ax, 0 |
je SIS900_Bad_Eeprom |
;**************Read MacID************** |
; zero based so 3-16 bit reads will take place |
mov ecx, 2 |
SIS900_mac_read_loop: |
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address |
add eax, ecx ;Current Mac Byte Offset |
push ecx |
call sis900_read_eeprom ;try to read 16 bits |
pop ecx |
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage |
dec ecx ;one less word to read |
jns SIS900_mac_read_loop ;if more read more |
mov eax, 1 ;return non-zero indicating success |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
ret |
SIS900_Bad_Eeprom: |
xor eax, eax |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Failed |
call sys_msg_board_str |
end if |
ret |
;*************************************************************************** |
;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 |
;* |
;* |
;*************************************************************************** |
Get_Mac_SIS635_900_REV: |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Start |
call sys_msg_board_str |
end if |
mov ebp,[io_addr] |
lea edx,[ebp+SIS900_rfcr] |
in eax,dx |
mov edi,eax ; EDI=rfcrSave |
lea edx,[ebp+SIS900_cr] |
or eax,SIS900_RELOAD |
out dx,eax |
xor eax,eax |
out dx,eax |
; Disable packet filtering before setting filter |
lea edx,[ebp+SIS900_rfcr] |
mov eax,edi |
and edi,not SIS900_RFEN |
out dx,eax |
; Load MAC to filter data register |
xor ecx,ecx |
mov esi,node_addr |
.get_mac_loop: |
lea edx,[ebp+SIS900_rfcr] |
mov eax,ecx |
shl eax,SIS900_RFADDR_shift |
out dx,eax |
lea edx,[ebp+SIS900_rfdr] |
in eax,dx |
mov [esi],ax |
add esi,2 |
inc ecx |
cmp ecx,3 |
jne .get_mac_loop |
; Enable packet filtering |
;lea edx,[ebp+SIS900_rfcr] |
;mov eax,edi |
;or eax,SIS900_RFEN |
;out dx, eax |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
ret |
;*************************************************************************** |
;* Function: sis900_read_eeprom |
;* |
;* Description: reads and returns a given location from EEPROM |
;* |
;* Arguments: eax - location: requested EEPROM location |
;* |
;* Returns: eax : contents of requested EEPROM location |
;* |
; Read Serial EEPROM through EEPROM Access Register, Note that location is |
; in word (16 bits) unit */ |
;done+ |
;*************************************************************************** |
sis900_read_eeprom: |
push esi |
push edx |
push ecx |
push ebx |
mov ebp,[io_addr] |
mov ebx, eax ;location of Mac byte to read |
or ebx, SIS900_EEread ; |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
xor eax, eax ; start send |
out dx,eax |
call SIS900_Eeprom_Delay_1 |
mov eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
;************ Shift the read command (9) bits out. ********* |
mov cl, 8 ; |
sis900_read_eeprom_Send: |
mov eax, 1 |
shl eax, cl |
and eax, ebx |
jz SIS900_Read_Eeprom_8 |
mov eax, 9 |
jmp SIS900_Read_Eeprom_9 |
SIS900_Read_Eeprom_8: |
mov eax, 8 |
SIS900_Read_Eeprom_9: |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
or eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
cmp cl, 0 |
je sis900_read_eeprom_Send_Done |
dec cl |
jmp sis900_read_eeprom_Send |
;********************* |
sis900_read_eeprom_Send_Done: |
mov eax, SIS900_EECS ; |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
;********** Read 16-bits of data in *************** |
mov cx, 16 ;16 bits to read |
sis900_read_eeprom_Send2: |
mov eax, SIS900_EECS |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
or eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
in eax, dx |
shl ebx, 1 |
and eax, SIS900_EEDO |
jz SIS900_Read_Eeprom_0 |
or ebx, 1 |
SIS900_Read_Eeprom_0: |
dec cx |
jnz sis900_read_eeprom_Send2 |
;************** Terminate the EEPROM access. ************** |
xor eax, eax |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
mov eax, SIS900_EECLK |
out dx, eax |
mov eax, ebx |
and eax, 0x0000ffff ;return only 16 bits |
pop ebx |
pop ecx |
pop edx |
pop esi |
ret |
;*************************************************************************** |
; Function |
; SIS900_Eeprom_Delay_1 |
; Description |
; |
; |
; |
; |
;*************************************************************************** |
SIS900_Eeprom_Delay_1: |
push eax |
in eax, dx |
pop eax |
ret |
;*************************************************************************** |
; Function |
; SIS900_poll |
; Description |
; polls card to see if there is a packet waiting |
; |
; Currently only supports one descriptor per packet, if packet is fragmented |
; between multiple descriptors you will lose part of the packet |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 |
SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 |
SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 |
end if |
SIS900_poll: |
;**************Get Status ************** |
xor eax, eax ;get RX_Status |
mov [eth_rx_data_len], ax |
mov al, [cur_rx] ;find current discriptor |
imul eax, 12 ; |
mov ecx, [rxd+eax+4] ; get receive status |
;**************Check Status ************** |
mov ebx, ecx ;move status |
;Check RX_Status to see if packet is waiting |
and ebx, 0x80000000 |
jnz SIS900_poll_IS_packet |
ret |
;**********There is a packet waiting check it for errors************** |
SIS900_poll_IS_packet: |
mov ebx, ecx ;move status |
and ebx, 0x67C0000 ;see if there are any errors |
jnz SIS900_Poll_Error_Status |
;**************Check size of packet************* |
and ecx, SIS900_DSIZE ;get packet size minus CRC |
cmp cx, SIS900_CRC_SIZE |
;make sure packet contains data |
jle SIS900_Poll_Error_Size |
;*******Copy Good Packet to receive buffer****** |
sub cx, SIS900_CRC_SIZE ;dont want crc |
mov word [eth_rx_data_len], cx ;save size of packet |
;**********Continue copying packet**************** |
push ecx |
; first copy dword-wise, divide size by 4 |
shr ecx, 2 |
mov esi, [rxd+eax+8] ; set source |
add esi, OS_BASE ; get linear address |
mov edi, Ether_buffer ; set destination |
cld ; clear direction |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 ; |
rep movsb |
;********Debug, tell user we have a good packet************* |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Packet_good |
call sys_msg_board_str |
end if |
jmp SIS900_Poll_Cnt ; |
;*************Error occured let user know through debug window*********** |
SIS900_Poll_Error_Status: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Bad_Packet_Status |
call sys_msg_board_str |
end if |
jmp SIS900_Poll_Cnt |
SIS900_Poll_Error_Size: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Bad_Packet_Size |
call sys_msg_board_str |
end if |
;*************Increment to next available descriptor************** |
SIS900_Poll_Cnt: |
;Reset status, allow ethernet card access to descriptor |
mov ecx, RX_BUFF_SZ |
mov [rxd+eax+4], ecx ; |
inc [cur_rx] ;get next descriptor |
and [cur_rx],3 ;only 4 descriptors 0-3 |
;******Enable Receiver************ |
mov ebp, [io_addr] ; Base Address |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_RxENA ;Enable Receive |
out dx, eax |
ret |
;*************************************************************************** |
; Function |
; SIS900_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
; only one transmit descriptor is used |
; |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 |
SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 |
end if |
str1 db 'Transmitting packet:',13,10,0 |
str2 db ' ',0 |
SIS900_transmit: |
mov ebp, [io_addr] ; Base Address |
;******** Stop the transmitter ******** |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxDIS ; Disable Transmitter |
out dx, eax |
;*******load Transmit Descriptor Register ******* |
lea edx,[ebp+SIS900_txdp] |
mov eax, txd - OS_BASE |
out dx, eax |
;******* copy packet to descriptor******* |
push esi |
mov esi, edi ;copy destination addess |
mov edi, txb |
cld |
movsd |
movsw |
mov esi, node_addr ;copy my mac address |
movsd |
movsw |
mov [edi], bx ;copy packet type |
add edi, 2 |
pop esi ;restore pointer to source of packet |
push ecx ;save packet size |
shr ecx, 2 ;divide by 4, size in bytes send in dwords |
rep movsd ;copy data to decriptor |
pop ecx ;restore packet size |
push ecx ;save packet size |
and ecx, 3 ;last three bytes if not a multiple of 4 |
rep movsb |
;**************set length tag************** |
pop ecx ;restore packet size |
add ecx, SIS900_ETH_HLEN ;add header to length |
and ecx, SIS900_DSIZE ; |
;**************pad to minimum packet size **************not needed |
;cmp ecx, SIS900_ETH_ZLEN |
;jge SIS900_transmit_Size_Ok |
;push ecx |
;mov ebx, SIS900_ETH_ZLEN |
;sub ebx, ecx |
;mov ecx, ebx |
;rep movsb |
;pop ecx |
SIS900_transmit_Size_Ok: |
mov [txd+4], dword 0x80000000 ;card owns descriptor |
or [txd+4], ecx ;set size of packet |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Transmit_Packet |
call sys_msg_board_str |
end if |
;***************restart the transmitter ******** |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxENA ; Enable Transmitter |
out dx, eax |
;****make sure packet transmitted successfully**** |
; mov esi,10 |
; call delay_ms |
mov eax, [txd+4] |
and eax, 0x6200000 |
jz SIS900_transmit_OK |
;**************Tell user there was an error through debug window |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Transmit_Packet_Err |
call sys_msg_board_str |
end if |
SIS900_transmit_OK: |
;******** Disable interrupts by clearing the interrupt mask. ******** |
lea edx,[ebp+SIS900_imr] ; Interupt Mask Register |
xor eax, eax |
out dx,eax |
ret |
;*************************************************************************** |
;* Function: Create_Mac_String |
;* |
;* Description: Converts the 48 bit value to a string for display |
;* |
;* String Format: XX:XX:XX:XX:XX:XX |
;* |
;* Arguments: node_addr is location of 48 bit MAC ID |
;* |
;* Returns: Prints string to general debug window |
;* |
;* |
;done |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' |
db 'A','B','C','D','E','F' |
Mac_str_build: times 20 db 0 |
Create_Mac_String: |
pusha |
xor ecx, ecx |
Create_Mac_String_loop: |
mov al,byte [edx+ecx];[node_addr+ecx] |
push eax |
shr eax, 4 |
and eax, 0x0f |
mov bl, byte [SIS900_Char_String+eax] |
mov [Mac_str_build+ecx*3], bl |
pop eax |
and eax, 0x0f |
mov bl, byte [SIS900_Char_String+eax] |
mov [Mac_str_build+1+ecx*3], bl |
cmp ecx, 5 |
je Create_Mac_String_done |
mov bl, ':' |
mov [Mac_str_build+2+ecx*3], bl |
inc ecx |
jmp Create_Mac_String_loop |
Create_Mac_String_done: ;Insert CR and Zero Terminate |
mov [Mac_str_build+2+ecx*3],byte 13 |
mov [Mac_str_build+3+ecx*3],byte 10 |
mov [Mac_str_build+4+ecx*3],byte 0 |
mov esi, Mac_str_build |
call sys_msg_board_str ;Print String to message board |
popa |
ret |
end if |
;*************************************************************************** |
;* Set device to be a busmaster in case BIOS neglected to do so. |
;* Also adjust PCI latency timer to a reasonable value, 64. |
;*************************************************************************** |
SIS900_adjust_pci_device: |
;*******Get current setting************************ |
mov al, 2 ;read a word |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x04 ;from command Register |
call pci_read_reg |
;******see if its already set as bus master******** |
mov bx, ax |
and bx,5 |
cmp bx,5 |
je SIS900_adjust_pci_device_Latency |
;******Make card a bus master******* |
mov cx, ax ;value to write |
mov bh, [pci_dev] |
mov al, 2 ;write a word |
or cx,5 |
mov ah, [pci_bus] |
mov bl, 0x04 ;to command register |
call pci_write_reg |
;******Check latency setting*********** |
SIS900_adjust_pci_device_Latency: |
;*******Get current latency setting************************ |
mov al, 1 ;read a byte |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x0D ;from Lantency Timer Register |
call pci_read_reg |
;******see if its aat least 64 clocks******** |
cmp ax,64 |
jge SIS900_adjust_pci_device_Done |
;******Set latency to 32 clocks******* |
mov cx, 64 ;value to write |
mov bh, [pci_dev] |
mov al, 1 ;write a byte |
mov ah, [pci_bus] |
mov bl, 0x0D ;to Lantency Timer Register |
call pci_write_reg |
;******Check latency setting*********** |
SIS900_adjust_pci_device_Done: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8029.inc |
---|
0,0 → 1,959 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8029.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 31 July 2002 ;; |
;; ;; |
;; This driver is based on the ns8390 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; While this implementation handles only PCI bus RTL8029 ;; |
;; hardware, it can be easily adapted to other NE2000 clone ;; |
;; products. I just dont have any to try! ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************** |
; Interface |
; rtl8029_reset |
; rtl8029_probe |
; rtl8029_poll |
; rtl8029_transmit |
; |
;******************************************************************** |
;************************************************************************** |
; 8390 Register Definitions |
;************************************************************************** |
D8390_P0_COMMAND equ 0x00 |
D8390_P0_PSTART equ 0x01 |
D8390_P0_PSTOP equ 0x02 |
D8390_P0_BOUND equ 0x03 |
D8390_P0_TSR equ 0x04 |
D8390_P0_TPSR equ 0x04 |
D8390_P0_TBCR0 equ 0x05 |
D8390_P0_TBCR1 equ 0x06 |
D8390_P0_ISR equ 0x07 |
D8390_P0_RSAR0 equ 0x08 |
D8390_P0_RSAR1 equ 0x09 |
D8390_P0_RBCR0 equ 0x0A |
D8390_P0_RBCR1 equ 0x0B |
D8390_P0_RSR equ 0x0C |
D8390_P0_RCR equ 0x0C |
D8390_P0_TCR equ 0x0D |
D8390_P0_DCR equ 0x0E |
D8390_P0_IMR equ 0x0F |
D8390_P1_COMMAND equ 0x00 |
D8390_P1_PAR0 equ 0x01 |
D8390_P1_PAR1 equ 0x02 |
D8390_P1_PAR2 equ 0x03 |
D8390_P1_PAR3 equ 0x04 |
D8390_P1_PAR4 equ 0x05 |
D8390_P1_PAR5 equ 0x06 |
D8390_P1_CURR equ 0x07 |
D8390_P1_MAR0 equ 0x08 |
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select |
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select |
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select |
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control |
D8390_COMMAND_RD1 equ 0x10 |
D8390_COMMAND_RD0 equ 0x08 |
D8390_COMMAND_TXP equ 0x04 ; transmit packet |
D8390_COMMAND_STA equ 0x02 ; start |
D8390_COMMAND_STP equ 0x01 ; stop |
D8390_COMMAND_RD2_STA equ 0x22 |
D8390_COMMAND_RD2_STP equ 0x21 |
D8390_COMMAND_RD1_STA equ 0x12 |
D8390_COMMAND_RD0_STA equ 0x0A |
D8390_COMMAND_PS0_RD2_STP equ 0x21 |
D8390_COMMAND_PS1_RD2_STP equ 0x61 |
D8390_COMMAND_PS0_RD2_STA equ 0x22 |
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 |
D8390_RCR_MON equ 0x20 ; monitor mode |
D8390_DCR_FT1 equ 0x40 |
D8390_DCR_LS equ 0x08 ; Loopback select |
D8390_DCR_WTS equ 0x01 ; Word transfer select |
D8390_DCR_FT1_LS equ 0x48 |
D8390_DCR_WTS_FT1_LS equ 0x49 |
D8390_ISR_PRX equ 0x01 ; successful recv |
D8390_ISR_PTX equ 0x02 ; successful xmit |
D8390_ISR_RXE equ 0x04 ; receive error |
D8390_ISR_TXE equ 0x08 ; transmit error |
D8390_ISR_OVW equ 0x10 ; Overflow |
D8390_ISR_CNT equ 0x20 ; Counter overflow |
D8390_ISR_RDC equ 0x40 ; Remote DMA complete |
D8390_ISR_RST equ 0x80 ; reset |
D8390_RSTAT_PRX equ 0x01 ; successful recv |
D8390_RSTAT_CRC equ 0x02 ; CRC error |
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error |
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun |
D8390_TXBUF_SIZE equ 6 |
D8390_RXBUF_END equ 32 |
D8390_PAGE_SIZE equ 256 |
ETH_ALEN equ 6 |
ETH_HLEN equ 14 |
ETH_ZLEN equ 60 |
ETH_FRAME_LEN equ 1514 |
FLAG_PIO equ 0x01 |
FLAG_16BIT equ 0x02 |
ASIC_PIO equ 0 |
VENDOR_NONE equ 0 |
VENDOR_WD equ 1 |
VENDOR_NOVELL equ 2 |
VENDOR_3COM equ 3 |
NE_ASIC_OFFSET equ 0x10 |
NE_RESET equ 0x0F ; Used to reset card |
NE_DATA equ 0x00 ; Used to read/write NIC mem |
MEM_8192 equ 32 |
MEM_16384 equ 64 |
MEM_32768 equ 128 |
ISA_MAX_ADDR equ 0x400 |
uglobal |
eth_flags: db 0 |
eth_vendor: db 0 |
eth_nic_base: dw 0 |
eth_asic_base: dw 0 |
eth_memsize: db 0 |
eth_rx_start: db 0 |
eth_tx_start: db 0 |
eth_bmem: dd 0 |
eth_rmem: dd 0 |
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
endg |
iglobal |
test_data: db 'NE*000 memory',0 |
test_buffer: db ' ',0 |
endg |
uglobal |
eth_type: dw 0 |
pkthdr: db 0,0,0,0 ; status, next, (short) len |
pktoff: dw 0 |
eth_rx_data_ptr: dd 0 |
eth_tmp_len: dw 0 |
endg |
;*************************************************************************** |
; Function |
; eth_pio_read |
; |
; Description |
; Read a frame from the ethernet card via Programmed I/O |
; src in ebx |
; cnt in ecx |
; dst in edi |
;*************************************************************************** |
eth_pio_read: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epr_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD0_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_003 |
shr ecx, 1 |
epr_002: |
; 2 bytes at a time |
in ax, dx |
mov [edi], ax |
add edi, 2 |
loop epr_002 |
ret |
epr_003: |
; 1 byte at a time |
in al, dx |
mov [edi], al |
inc edi |
loop epr_003 |
ret |
;*************************************************************************** |
; Function |
; eth_pio_write |
; |
; Description |
; writes a frame to the ethernet card via Programmed I/O |
; dst in ebx |
; cnt in ecx |
; src in esi |
;*************************************************************************** |
eth_pio_write: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epw_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, D8390_ISR_RDC |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD1_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_003 |
shr ecx, 1 |
epw_002: |
; 2 bytes at a time |
mov ax, [esi] |
add esi, 2 |
out dx, ax |
loop epw_002 |
jmp epw_004 |
epw_003: |
; 1 byte at a time |
mov al, [esi] |
inc esi |
out dx, al |
loop epw_003 |
epw_004: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
epw_005: |
in al, dx |
and al, D8390_ISR_RDC |
cmp al, D8390_ISR_RDC |
jne epw_005 |
ret |
;*************************************************************************** |
; Function |
; rtl8029_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
rtl8029_reset: |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, FLAG_16BIT |
jne nsr_001 |
mov al, 0x49 |
jmp nsr_002 |
nsr_001: |
mov al, 0x48 |
nsr_002: |
out dx, al |
xor al, al |
mov dx, bx |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 0x20 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 2 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, [eth_memsize] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_BOUND |
mov al, [eth_memsize] |
dec al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_IMR |
xor al, al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P1_PAR0 |
mov esi, node_addr |
mov ecx, ETH_ALEN |
nsr_003: |
mov al, [esi] |
out dx, al |
inc esi |
inc dx |
loop nsr_003 |
mov dx, bx |
add dx, D8390_P1_MAR0 |
mov ecx, ETH_ALEN |
mov al, 0xff |
nsr_004: |
out dx, al |
inc dx |
loop nsr_004 |
mov dx, bx |
add dx, D8390_P1_CURR |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 4 |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; rtl8029_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
rtl8029_probe: |
mov eax, [io_addr] |
mov [eth_nic_base], ax ; The IO address space is 16 bit only |
mov al, VENDOR_NONE |
mov [eth_vendor], al |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
jne ep_check_have_vendor |
xor eax, eax |
mov [eth_bmem], eax |
mov al, FLAG_PIO |
mov [eth_flags], al |
mov ax, [eth_nic_base] |
add ax, NE_ASIC_OFFSET |
mov [eth_asic_base], ax |
mov al, MEM_16384 |
mov [eth_memsize], al |
mov al, 32 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov dx, [eth_asic_base] |
add dx, NE_RESET |
in al, dx |
out dx, al |
in al, 0x84 |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, D8390_RCR_MON |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_8192 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_16384 |
out dx, al |
mov esi, test_data |
mov ebx, 8192 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 8192 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
je ep_set_vendor |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
mov al, MEM_32768 |
mov [eth_memsize], al |
mov al, 64 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_WTS_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_16384 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_32768 |
out dx, al |
mov esi, test_data |
mov ebx, 16384 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 16384 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
ep_set_vendor: |
; this bit is odd - probably left over from my hacking |
mov ax, [eth_nic_base] |
cmp ax, 0 |
je rtl8029_exit |
cmp ax, ISA_MAX_ADDR |
jbe ep_001 |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
ep_001: |
mov al, VENDOR_NOVELL |
mov [eth_vendor], al |
mov ebx, 0 |
mov ecx, 16 |
mov edi, romdata |
call eth_pio_read |
mov ecx, ETH_ALEN |
mov esi, romdata |
mov edi, node_addr |
mov bl, [eth_flags] |
and bl, FLAG_16BIT |
ep_002: |
mov al, [esi] |
mov [edi], al |
inc edi |
inc esi |
cmp bl, FLAG_16BIT |
jne ep_003 |
inc esi |
ep_003: |
loop ep_002 |
ep_check_have_vendor: |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
je rtl8029_exit |
cmp al, VENDOR_3COM |
je ep_reset_card |
mov eax, [eth_bmem] |
mov [eth_rmem], eax |
ep_reset_card: |
; Reset the card |
call rtl8029_reset |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
rtl8029_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
rtl8029_poll: |
mov eax, Ether_buffer |
mov [eth_rx_data_ptr], eax |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_RSR |
in al, dx |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
mov dx, bx |
add dx, D8390_P0_BOUND |
in al, dx |
inc al |
cmp al, [eth_memsize] |
jb nsp_001 |
mov al, [eth_rx_start] |
nsp_001: |
mov ch, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1 |
out dx, al |
mov dx, bx |
add dx, D8390_P1_CURR |
in al, dx ; get current page |
mov cl, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0 |
out dx, al |
cmp cl, [eth_memsize] |
jb nsp_002 |
mov cl, [eth_rx_start] |
nsp_002: |
cmp cl, ch |
je nsp_exit |
xor ax, ax |
mov ah, ch |
mov [pktoff], ax |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_003 |
movzx ebx, word [pktoff] |
mov edi, pkthdr |
mov ecx, 4 |
call eth_pio_read |
jmp nsp_004 |
nsp_003: |
mov edi, [eth_rmem] |
movzx eax, word [pktoff] |
add edi, eax |
mov eax, [edi] |
mov [pkthdr], eax |
nsp_004: |
mov ax, [pktoff] |
add ax, 4 |
mov [pktoff], ax |
mov ax, [pkthdr + 2] |
sub ax, 4 |
mov [eth_tmp_len], ax |
cmp ax, ETH_ZLEN |
jb nsp_exit |
cmp ax, ETH_FRAME_LEN |
ja nsp_exit |
mov al, [pkthdr] |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
; Right, we can now get the data |
mov ax, [eth_tmp_len] |
mov [eth_rx_data_len], ax |
xor ebx, ebx |
mov bh, [eth_memsize] |
sub bx, [pktoff] |
cmp [eth_tmp_len], bx |
jbe nsp_005 |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_006 |
push ebx |
mov ecx, ebx |
xor ebx, ebx |
mov bx, [pktoff] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
pop ebx |
jmp nsp_007 |
nsp_006: |
; Not implemented, as we are using PIO mode on this card |
nsp_007: |
xor ax, ax |
mov ah, [eth_rx_start] |
mov [pktoff], ax |
mov eax, [eth_rx_data_ptr] |
add eax, ebx |
mov [eth_rx_data_ptr], eax |
mov ax, [eth_tmp_len] |
sub ax, bx |
mov [eth_tmp_len], ax |
nsp_005: |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_008 |
xor ebx, ebx |
mov bx, [pktoff] |
xor ecx, ecx |
mov cx, [eth_tmp_len] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
jmp nsp_009 |
nsp_008: |
; Not implemented, as we are using PIO mode on this card |
nsp_009: |
mov al, [pkthdr+1] |
cmp al, [eth_rx_start] |
jne nsp_010 |
mov al, [eth_memsize] |
nsp_010: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_BOUND |
dec al |
out dx, al |
nsp_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
rtl8029_transmit: |
mov [eth_type], bx |
pusha |
mov esi, edi |
xor bx, bx |
mov bh, [eth_tx_start] |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, node_addr |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, eth_type |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
add bx, ETH_ALEN |
mov ecx, 2 |
call eth_pio_write |
popa |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_HLEN |
push ecx |
call eth_pio_write |
pop ecx |
add ecx, ETH_HLEN |
cmp ecx, ETH_ZLEN |
jae nst_001 |
mov ecx, ETH_ZLEN |
nst_001: |
push ecx |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
pop ecx |
mov dx, bx |
add dx, D8390_P0_TBCR0 |
mov al, cl |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TBCR1 |
mov al, ch |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_TXP_RD2_STA |
out dx, al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8139.inc |
---|
0,0 → 1,621 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8139.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 11 August 2003 ;; |
;; ;; |
;; Driver for chips of RealTek 8139 family ;; |
;; References: ;; |
;; www.realtek.com.hw - data sheets ;; |
;; rtl8139.c - linux driver ;; |
;; 8139too.c - linux driver ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2003 Endre Kozma, ;; |
;; endre.kozma@axelero.hu ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
PCI_REG_COMMAND equ 0x04 ; command register |
PCI_BIT_PIO equ 0 ; bit0: io space control |
PCI_BIT_MMIO equ 1 ; bit1: memory space control |
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 |
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 |
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor |
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor |
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address |
RTL8139_REG_COMMAND equ 0x37 ; command register |
RTL8139_REG_CAPR equ 0x38 ; current address of packet read |
RTL8139_REG_IMR equ 0x3c ; interrupt mask register |
RTL8139_REG_ISR equ 0x3e ; interrupt status register |
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register |
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 |
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 |
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 |
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 |
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 |
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 |
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 |
RTL8139_REG_MPC equ 0x4c ; missed packet counter |
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register |
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 |
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 |
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register |
RTL8139_REG_BMCR equ 0x62 ; basic mode control register |
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register |
; 5.1 packet header |
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes |
RTL8139_BIT_LONG equ 3 ; total packet length > 4k |
RTL8139_BIT_CRC equ 2 ; crc error occured |
RTL8139_BIT_FAE equ 1 ; frame alignment error occured |
RTL8139_BIT_ROK equ 0 ; received packet is ok |
; 5.4 command register |
RTL8139_BIT_RST equ 4 ; reset bit |
RTL8139_BIT_RE equ 3 ; receiver enabled |
RTL8139_BIT_TE equ 2 ; transmitter enabled |
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored |
; 5.6 interrupt status register |
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok |
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt |
RTL8139_BIT_ISR_ROK equ 0 ; receive ok |
; 5.7 transmit configyration register |
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst |
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) |
; 5.8 receive configuration register |
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold |
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator |
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst |
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping |
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 |
RTL8139_BIT_AER equ 5 ; accept error packets |
RTL8139_BIT_AR equ 4 ; accept runt packets |
RTL8139_BIT_AB equ 3 ; accept broadcast packets |
RTL8139_BIT_AM equ 2 ; accept multicast packets |
RTL8139_BIT_APM equ 1 ; accept physical match packets |
RTL8139_BIT_AAP equ 0 ; accept all packets |
; 5.9 93C46/93C56 command register |
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 |
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 |
RTL8139_BIT_93C46_EECS equ 3 ; chip select |
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock |
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input |
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output |
; 5.11 configuration register 1 |
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 |
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips |
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips |
RTL8139_BIT_PMEn equ 0 ; power management enabled |
; 5.14 configuration register 4 |
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 |
; 6.2 transmit status register |
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold |
RTL8139_BIT_TOK equ 15 ; transmit ok |
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed |
; 6.18 basic mode control register |
RTL8139_BIT_ANE equ 12 ; auto negotiation enable |
; 6.20 auto negotiation advertisement register |
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex |
RTL8139_BIT_TX equ 7 ; 100base-T |
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex |
RTL8139_BIT_10 equ 5 ; 10base-T |
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 |
; RX/TX buffer size |
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k |
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) |
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC |
RTL8139_NUM_TX_DESC equ 4 |
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) |
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) |
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==2048 |
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 |
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==unlimited |
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==no threshold |
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ |
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ |
or (1 shl RTL8139_BIT_NOWRAP) \ |
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ |
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ |
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ |
or (1 shl RTL8139_BIT_AM)) |
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout |
EE_93C46_REG_ETH_ID equ 7 ; MAC offset |
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address |
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address |
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address |
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress |
VER_RTL8139 equ 1100000b |
VER_RTL8139A equ 1110000b |
; VER_RTL8139AG equ 1110100b |
VER_RTL8139B equ 1111000b |
VER_RTL8130 equ VER_RTL8139B |
VER_RTL8139C equ 1110100b |
VER_RTL8100 equ 1111010b |
VER_RTL8100B equ 1110101b |
VER_RTL8139D equ VER_RTL8100B |
VER_RTL8139CP equ 1110110b |
VER_RTL8101 equ 1110111b |
IDX_RTL8139 equ 0 |
IDX_RTL8139A equ 1 |
IDX_RTL8139B equ 2 |
IDX_RTL8139C equ 3 |
IDX_RTL8100 equ 4 |
IDX_RTL8139D equ 5 |
IDX_RTL8139D equ 6 |
IDX_RTL8101 equ 7 |
; These two must be 4 byte aligned ( which they are ) |
rtl8139_rx_buff equ eth_data_start |
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) |
uglobal |
align 4 |
rtl8139_rx_buff_offset: dd 0 |
curr_tx_desc dd 0 |
endg |
iglobal |
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C |
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 |
HW_VER_ARRAY_SIZE = $-hw_ver_array |
endg |
uglobal |
hw_ver_id: db 0 |
endg |
;*************************************************************************** |
; Function |
; rtl8139_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_probe: |
; enable the device |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_read_reg |
mov cx, ax |
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
and cl, not (1 shl PCI_BIT_MMIO) |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_write_reg |
; get chip version |
mov edx, [io_addr] |
add edx, RTL8139_REG_TXCONFIG_2 |
in ax, dx |
shr ah, 2 |
shr ax, 6 |
and al, 01111111b |
mov ecx, HW_VER_ARRAY_SIZE-1 |
.chip_ver_loop: |
cmp al, [hw_ver_array+ecx] |
je .chip_ver_found |
dec ecx |
jns .chip_ver_loop |
xor cl, cl ; default RTL8139 |
.chip_ver_found: |
mov [hw_ver_id], cl |
; wake up the chip |
mov edx, [io_addr] |
add edx, RTL8139_REG_HLTCLK |
mov al, 'R' ; run the clock |
out dx, al |
; unlock config and BMCR registers |
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; enable power management |
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR |
in al, dx |
cmp byte [hw_ver_id], IDX_RTL8139B |
jl .old_chip |
; set LWAKE pin to active high (default value). |
; it is for Wake-On-LAN functionality of some motherboards. |
; this signal is used to inform the motherboard to execute a wake-up process. |
; only at newer chips. |
or al, (1 shl RTL8139_BIT_PMEn) |
and al, not (1 shl RTL8139_BIT_LWACT) |
out dx, al |
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 |
in al, dx |
and al, not (1 shl RTL8139_BIT_LWPTN) |
out dx, al |
jmp .finish_wake_up |
.old_chip: |
; wake up older chips |
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) |
out dx, al |
.finish_wake_up: |
; lock config and BMCR registers |
xor al, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
out dx, al |
;*************************************************************************** |
; Function |
; rt8139_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_reset: |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
mov al, 1 shl RTL8139_BIT_RST |
out dx, al |
mov cx, 1000 ; wait no longer for the reset |
.wait_for_reset: |
in al, dx |
test al, 1 shl RTL8139_BIT_RST |
jz .reset_completed ; RST remains 1 during reset |
dec cx |
jns .wait_for_reset |
.reset_completed: |
; get MAC (hardware address) |
mov ecx, 2 |
.mac_read_loop: |
lea eax, [EE_93C46_REG_ETH_ID+ecx] |
push ecx |
call rtl8139_read_eeprom |
pop ecx |
mov [node_addr+ecx*2], ax |
dec ecx |
jns .mac_read_loop |
; unlock config and BMCR registers |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; initialize multicast registers (no filtering) |
mov eax, 0xffffffff |
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR |
out dx, eax |
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 |
out dx, eax |
; enable Rx/Tx |
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) |
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 |
out dx, al |
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold |
; accept broadcast packets, accept physical match packets |
mov ax, RTL8139_RX_CONFIG |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
out dx, ax |
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ |
or (RTL8139_TXRR shl RTL8139_BIT_TXRR) |
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG |
out dx, ax |
; enable auto negotiation |
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG |
in ax, dx |
or ax, (1 shl RTL8139_BIT_ANE) |
out dx, ax |
; set auto negotiation advertisement |
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR |
in ax, dx |
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ |
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ |
or (1 shl RTL8139_BIT_TXFD) |
out dx, ax |
; lock config and BMCR registers |
xor eax, eax |
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR |
out dx, al |
; init RX/TX pointers |
mov [rtl8139_rx_buff_offset], eax |
mov [curr_tx_desc], eax |
; clear missing packet counter |
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR |
out dx, eax |
; disable all interrupts |
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC |
out dx, ax |
; set RxBuffer address, init RX buffer offset, init TX ring |
mov eax, rtl8139_rx_buff ; simba |
sub eax,OS_BASE |
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR |
out dx, eax |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
;*************************************************************************** |
; Function |
; rtl8139_read_eeprom |
; Description |
; reads eeprom type 93c46 and 93c56 |
; Parameters |
; al - word to be read (6bit in case of 93c46 and 8bit otherwise) |
; Return value |
; ax - word read in |
; Destroyed register(s) |
; eax, cx, ebx, edx |
; |
;*************************************************************************** |
rtl8139_read_eeprom: |
movzx ebx, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_RXCONFIG |
in al, dx |
test al, (1 shl RTL8139_BIT_9356SEL) |
jz .type_93c46 |
; and bl, 01111111b ; don't care first bit |
or bx, EE_93C56_READ_CMD ; it contains start bit |
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter |
jmp .read_eeprom |
.type_93c46: |
and bl, 00111111b |
or bx, EE_93C46_READ_CMD ; it contains start bit |
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter |
.read_eeprom: |
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 |
; mov al, (1 shl RTL8139_BIT_93C46_EEM1) |
; out dx, al |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom |
out dx, al |
.cmd_loop: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
bt bx, cx |
jnc .zero_bit |
or al, (1 shl RTL8139_BIT_93C46_EEDI) |
.zero_bit: |
out dx, al |
; push eax |
; in eax, dx ; eeprom delay |
; pop eax |
or al, (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cx |
jns .cmd_loop |
; in eax, dx ; eeprom delay |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
mov cl, 0xf |
.read_loop: |
shl ebx, 1 |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) \ |
or (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
in al, dx |
and al, (1 shl RTL8139_BIT_93C46_EEDO) |
jz .dont_set |
inc ebx |
.dont_set: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cl |
jns .read_loop |
xor al, al |
out dx, al |
mov ax, bx |
ret |
;*************************************************************************** |
; Function |
; rtl8139_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; Size of packet in ecx |
; Pointer to packet data in esi |
; Destroyed registers |
; eax, edx, esi, edi |
; ToDo |
; for waiting of timeout the rtl8139 internal timer |
; should be used |
; |
;*************************************************************************** |
rtl8139_transmit: |
cmp ecx, MAX_ETH_FRAME_SIZE |
jg .finish ; packet is too long |
push ecx |
; check descriptor |
mov ecx, [curr_tx_desc] |
mov edx, [io_addr] |
lea edx, [edx+ecx*4+RTL8139_REG_TSD0] |
push edx ebx |
in ax, dx |
test ax, 0x1fff ; or no size given |
jz .send_packet |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
; wait for timeout |
mov ebx, RTL8139_TX_TIMEOUT |
mov eax, 0x5 ; delay x/100 secs |
int 0x40 |
in ax, dx |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
; chip hung, reset it |
call rtl8139_reset |
; reset the card |
.send_packet: |
; calculate tx_buffer address |
pop ebx |
push esi |
mov eax, MAX_ETH_FRAME_SIZE |
mul dword [curr_tx_desc] |
mov esi, edi |
lea edi, [rtl8139_tx_buff+eax] |
mov eax, edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy the packet data |
pop esi edx ecx |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
push ecx |
and ecx, 3 |
rep movsb |
; set address |
sub eax,OS_BASE |
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 |
out dx, eax |
; set size and early threshold |
pop eax ; pick up the size |
add eax, ETH_HLEN |
cmp eax, ETH_ZLEN |
jnc .no_pad |
mov eax, ETH_ZLEN |
.no_pad: |
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) |
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 |
out dx, eax |
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... |
inc dword [curr_tx_desc] |
and dword [curr_tx_desc], 3 |
.finish: |
ret |
;*************************************************************************** |
; Function |
; rtl8139_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed register(s) |
; eax, edx, ecx |
; |
;*************************************************************************** |
rtl8139_poll: |
mov word [eth_rx_data_len], 0 |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
in al, dx |
test al, (1 shl RTL8139_BIT_BUFE) |
jnz .finish |
; new packet received copy it from rx_buffer into Ether_buffer |
mov eax, rtl8139_rx_buff |
add eax, [rtl8139_rx_buff_offset] |
; check if packet is ok |
test byte [eax], (1 shl RTL8139_BIT_ROK) |
jz .reset_rx |
; packet is ok copy it into the Ether_buffer |
movzx ecx, word [eax+2] ; packet length |
sub ecx, 4 ; don't copy CRC |
mov word [eth_rx_data_len], cx |
push ecx |
shr ecx, 2 ; first copy dword-wise |
lea esi, [eax+4] ; don't copy the packet header |
mov edi, Ether_buffer |
cld |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
; update rtl8139_rx_buff_offset |
movzx eax, word [eax+2] ; packet length |
add eax, [rtl8139_rx_buff_offset] |
add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
and eax, not 3 ; dword alignment |
cmp eax, RTL8139_RX_BUFFER_SIZE |
jl .no_wrap |
sub eax, RTL8139_RX_BUFFER_SIZE |
.no_wrap: |
mov [rtl8139_rx_buff_offset], eax |
; update CAPR register |
sub eax, 0x10 ; value 0x10 is a constant for CAPR |
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND |
out dx, ax |
.finish: |
; clear active interrupt sources |
mov edx, [io_addr] |
add edx, RTL8139_REG_ISR |
in ax, dx |
out dx, ax |
ret |
.reset_rx: |
in al, dx ; read command register |
push eax |
and al, not (1 shl RTL8139_BIT_RE) |
out dx, al |
pop eax |
out dx, al |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
mov ax, RTL8139_RX_CONFIG |
out dx, ax |
ret |
rtl8139_cable: |
pusha |
mov edx, [io_addr] |
add edx, 0x58 |
in al,dx |
test al,1 SHL 2 |
jnz .notconnected |
popa |
xor al,al |
inc al |
ret |
.notconnected: |
popa |
xor al,al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/ethernet.inc |
---|
0,0 → 1,509 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ETHERNET.INC ;; |
;; ;; |
;; Ethernet network layer for Menuet OS ;; |
;; ;; |
;; This file contains the following: ;; |
;; PCI bus scanning for valid devices ;; |
;; Table of supported ethernet drivers ;; |
;; Code to identify and activate a supported driver ;; |
;; ARP handler ;; |
;; Driver interface to the IP layer ;; |
;; Gateway support ;; |
;; ;; |
;; Individual driver files are included here ;; |
;; ;; |
;; The PCI bus scanning code was ported from the etherboot ;; |
;; 5.0.6 project. The copyright statement for that code is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************** |
; Interface |
; ethernet_driver called by stack_handler in stack.inc |
; eth_probe called by app_stack_handler in stack.inc |
; |
;******************************************************************** |
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel |
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel |
ETHER_RARP equ 0x3580 |
struc ETH_FRAME |
{ .DstMAC dp ? ;destination MAC-address [6 bytes] |
.SrcMAC dp ? ;source MAC-address [6 bytes] |
.Type dw ? ;type of the upper-layer protocol [2 bytes] |
.Data db ? ;data [46-1500 bytes] |
} |
virtual at Ether_buffer |
ETH_FRAME ETH_FRAME |
end virtual |
; Some useful information on data structures |
; Ethernet Packet - ARP Request example |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Dest H/W Address | |
; | ( 14 byte header ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source H/W Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Protocol - ARP 08 06 | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | H/W Type 00 01 | Protocol Type 08 00 | |
; | ( ARP Request packet ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 | |
; | ( 0001 for request, 0002 for reply ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Hardware Address ( MAC Address ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Destination Hardware Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Destination IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; Include individual drivers source files at this point. |
; If you create a new driver, include it below. |
include "drivers/rtl8029.inc" |
include "drivers/i8255x.inc" |
include "drivers/rtl8139.inc" |
include "drivers/3c59x.inc" |
include "drivers/sis900.inc" |
include "drivers/pcnet32.inc" |
include "drivers/rtl8169.inc" |
include "drivers/forcedeth.inc" |
; PCICards |
; ======== |
; PCI vendor and hardware types for hardware supported by the above drivers |
; If you add a driver, ensure you update this datastructure, otherwise the |
; card will not be probed. |
; Each driver is defined by 4 double words. These are |
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction |
; The last entry must be kept at all zeros, to indicate the end of the list |
; As a PCI driver may support more than one hardware implementation, there may |
; be several lines which refer to the same functions. |
; The first driver found on the PCI bus will be the one used. |
PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry |
iglobal |
PCICards: |
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 |
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok |
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok |
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x816710ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 |
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
; following cards are untested |
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 |
;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller |
dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller |
dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested |
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove |
endg |
uglobal |
;Net-stack's interface's settings |
node_addr: db 0,0,0,0,0,0 |
gateway_ip: dd 0 |
dns_ip: dd 0 |
eth_rx_data_len: dw 0 |
eth_status: dd 0 |
io_addr: dd 0 |
hdrtype: db 0 |
vendor_device: dd 0 |
pci_data: dd 0 |
pci_dev: dd 0 |
pci_bus: dd 0 |
; These will hold pointers to the selected driver functions |
drvr_probe: dd 0 |
drvr_reset: dd 0 |
drvr_poll: dd 0 |
drvr_transmit: dd 0 |
drvr_cable: dd 0 |
endg |
iglobal |
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff |
subnet_mask: dd 0x00ffffff ; 255.255.255.0 |
endg |
include "arp.inc" ;arp-protocol functions |
include "pci.inc" ;PCI bus access functions |
;*************************************************************************** |
; Function |
; eth_tx |
; |
; Description |
; Looks at the NET1OUT_QUEUE for data to send. |
; Stores that destination IP in a location used by the tx routine |
; Looks up the MAC address in the ARP table; stores that where |
; the tx routine can get it |
; Get the length of the data. Store that where the tx routine wants it |
; Call tx |
; Places buffer on empty queue when the tx routine finished |
; |
;*************************************************************************** |
proc eth_tx stdcall uses ebx esi edi |
local MACAddress dp ? ;allocate 6 bytes in the stack |
; Look for a buffer to tx |
mov eax, NET1OUT_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit ; Exit if no buffer available |
push eax ;save buffer number |
; convert buffer pointer eax to the absolute address |
imul eax, IPBUFFSIZE |
add eax, IPbuffs |
; Extract the destination IP |
; find the destination IP in the ARP table, get MAC |
; store this MAC in 'MACAddress' |
mov ebx, eax ; Save buffer address |
mov edx, [ebx + 16] ; get destination address |
; If the destination address is 255.255.255.255, |
; set the MACAddress to all ones ( broadcast ) |
cld |
mov esi, broadcast_add |
lea edi, [MACAddress] |
movsd |
movsw |
cmp edx, 0xffffffff |
je .send ; If it is broadcast, just send |
lea eax, [MACAddress] ;cause this is local variable |
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address. |
cmp eax, ARP_VALID_MAPPING |
je .send |
; No valid entry. Has the request been sent, but timed out? |
cmp eax, ARP_RESPONSE_TIMEOUT |
je .freebuf |
.wait_response: ;we wait arp-response |
; Re-queue the packet, and exit |
pop ebx |
mov eax, NET1OUT_QUEUE |
call queue ; Get the buffer back |
jmp .exit |
.send: ;if ARP_VALID_MAPPING then send the packet |
lea edi, [MACAddress] ; Pointer to 48 bit destination address |
movzx ecx, word[ebx+2] ; Size of IP packet to send |
xchg ch, cl ; because mirror byte-order |
mov esi, ebx ; Pointer to packet data |
mov bx, ETHER_IP ; Type of packet |
push ebp |
call dword [drvr_transmit] ; Call the drivers transmit function |
pop ebp |
; OK, we have sent a packet, so increment the count |
inc dword [ip_tx_count] |
; And finally, return the buffer to the free queue |
.freebuf: |
pop eax |
call freeBuff |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; ether_IP_handler |
; |
; Description |
; Called when an IP ethernet packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; We just need to get a buffer from the 'free' queue, and |
; store the packet in it, then insert the packet number into the |
; IPRX queue. |
; If no queue entry is available, the packet is silently discarded |
; All registers may be destroyed |
; |
;*************************************************************************** |
;uglobal |
; ether_IP_handler_cnt dd ? |
;endg |
ether_IP_handler: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je eiph00x |
; convert buffer pointer eax to the absolute address |
push eax |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edi, eax |
; get a pointer to the start of the DATA |
mov esi, ETH_FRAME.Data |
; Now store it all away |
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available |
; data across - worse case |
cld |
rep movsd |
; inc [ether_IP_handler_cnt] |
; DEBUGF 1, "K : ether_IP_handler (%u)\n", [ether_IP_handler_cnt] |
; And finally, place the buffer in the IPRX queue |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
eiph00x: |
ret |
;*************************************************************************** |
; Function |
; eth_probe |
; Description |
; Searches for an ethernet card. If found, the card is enabled and |
; the ethernet -> IP link established |
; |
; This function scans the PCI bus looking for a supported device. |
; ISA bus is currently not supported. |
; |
; eax is 0 if no hardware found |
;*************************************************************************** |
eth_probe: |
; Find a card on the PCI bus, and get it's address |
call scan_bus ; Find the ethernet cards PIC address |
xor eax, eax |
cmp [io_addr], eax |
je ep_00x ; Return 0 in eax if no cards found |
call dword [drvr_probe] ; Call the drivers probe function |
mov eax, [io_addr] ; return a non zero value |
ep_00x: |
ret |
;*************************************************************************** |
; Function |
; ethernet_driver |
; |
; Description |
; The ethernet RX and TX handler |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
ethernet_driver: |
; Do nothing if the driver is inactive |
cmp [ethernet_active], byte 0 |
je eth_exit |
call eth_rx |
call eth_tx |
eth_exit: |
ret |
;*************************************************************************** |
; Function |
; eth_rx |
; |
; Description |
; Polls the ethernet card for received data. Extracts if present |
; Depending on the Protocol within the packet: |
; ARP : Pass to ARP_handler. This may result in an ARP reply |
; being tx'ed |
; IP : Store in an IP buffer |
; |
;*************************************************************************** |
eth_rx: |
xor ax, ax |
mov [eth_rx_data_len], ax |
call dword [drvr_poll] ; Call the drivers poll function |
mov ax, [eth_rx_data_len] |
cmp ax, 0 |
je .exit |
; Check the protocol. Call appropriate handler |
mov ax, [ETH_FRAME.Type] ; The address of the protocol word |
cmp ax, ETHER_IP |
je .is_ip ; It's IP |
cmp ax, ETHER_ARP |
je .is_arp ; It is ARP |
DEBUGF 1,"K : eth_rx - dumped (%u)\n", ax |
inc [dumped_rx_count] |
jmp .exit ; If not IP or ARP, ignore |
.is_ip: |
; DEBUGF 1,"K : eth_rx - IP packet\n" |
inc dword [ip_rx_count] |
call ether_IP_handler |
jmp .exit |
.is_arp: |
; DEBUGF 1,"K : eth_rx - ARP packet\n" |
; At this point, the packet is still in the Ether_buffer |
call arp_handler |
.exit: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/arp.inc |
---|
0,0 → 1,556 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ARP.INC ;; |
;; ;; |
;; Address Resolution Protocol ;; |
;; ;; |
;; This file contains the following: ;; |
;; arp_table_manager - Manages an ARPTable ;; |
;; arp_request - Sends an ARP request on the ethernet ;; |
;; arp_handler - Called when an ARP packet is received ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
ARP_NO_ENTRY equ 0 |
ARP_VALID_MAPPING equ 1 |
ARP_AWAITING_RESPONSE equ 2 |
ARP_RESPONSE_TIMEOUT equ 3 |
struc ARP_ENTRY ;=14 bytes |
{ .IP dd ? ;+00 |
.MAC dp ? ;+04 |
.Status dw ? ;+10 |
.TTL dw ? ;+12 : ( in seconds ) |
} |
virtual at 0 |
ARP_ENTRY ARP_ENTRY |
end virtual |
; The TTL field is decremented every second, and is deleted when it |
; reaches 0. It is refreshed every time a packet is received |
; If the TTL field is 0xFFFF it is a static entry and is never deleted |
; The status field can be the following values: |
; 0x0000 entry not used |
; 0x0001 entry holds a valid mapping |
; 0x0002 entry contains an IP address, awaiting ARP response |
; 0x0003 No response received to ARP request. |
; The last status value is provided to allow the network layer to delete |
; a packet that is queued awaiting an ARP response |
; The follow is the ARP Table. |
; This table must be manually updated and the kernel recompilied if |
; changes are made to it. |
; Empty entries are filled with zeros |
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry |
ARP_TABLE_SIZE equ 20 ; Size of table |
ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table |
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!! |
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!! |
uglobal |
ARPTable: |
;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF |
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 |
endg |
iglobal |
NumARP: dd ARP_TABLE_ENTRIES |
ARPTable_ptr dd ARPTable ;pointer to ARPTable |
endg |
ARP_REQ_OPCODE equ 0x0100 ;request |
ARP_REP_OPCODE equ 0x0200 ;reply |
struc ARP_PACKET |
{ .HardwareType dw ? ;+00 |
.ProtocolType dw ? ;+02 |
.HardwareSize db ? ;+04 |
.ProtocolSize db ? ;+05 |
.Opcode dw ? ;+06 |
.SenderMAC dp ? ;+08 |
.SenderIP dd ? ;+14 |
.TargetMAC dp ? ;+18 |
.TargetIP dd ? ;+24 |
} |
virtual at 0 |
ARP_PACKET ARP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; arp_table_manager [by Johnny_B] |
; |
; Description |
; Does a most required operations with ARP-table |
; IN: |
; Operation: see Opcode's constants below |
; Index: Index of entry in the ARP-table |
; Extra: Extra parameter for some Opcodes |
; OUT: |
; EAX = Returned value depends on opcodes, more detailed see below |
; |
;*************************************************************************** |
;Opcode's constants |
ARP_TABLE_ADD equ 1 |
ARP_TABLE_DEL equ 2 |
ARP_TABLE_GET equ 3 |
ARP_TABLE_GET_ENTRIES_NUMBER equ 4 |
ARP_TABLE_IP_TO_MAC equ 5 |
ARP_TABLE_TIMER equ 6 |
;Index's constants |
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET |
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY |
align 4 |
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\ |
Opcode:DWORD,Index:DWORD,Extra:DWORD |
mov ebx, dword[ARPTable_ptr] ;ARPTable base |
mov ecx, dword[NumARP] ;ARP-entries counter |
mov eax, dword[Opcode] |
cmp eax, ARP_TABLE_TIMER |
je .timer |
cmp eax, ARP_TABLE_ADD |
je .add |
cmp eax, ARP_TABLE_DEL |
je .del |
cmp eax, ARP_TABLE_GET |
je .get |
cmp eax, ARP_TABLE_IP_TO_MAC |
je .ip_to_mac |
cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER |
je .get_entries_number |
jmp .exit ;if unknown opcode |
;;BEGIN TIMER |
;;Description: it must be callback every second. It is responsible for removing expired routes. |
;;IN: Operation: ARP_TABLE_TIMER |
;; Index: must be zero |
;; Extra: must be zero |
;;OUT: |
;; EAX=not defined |
;; |
.timer: |
test ecx, ecx |
jz .exit ;if NumARP=0 nothing to do |
sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number |
jz .exit ;if NumARP=number of static entries then exit |
add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base |
.timer_loop: |
movsx esi, word [ebx + ARP_ENTRY.TTL] |
cmp esi, 0xFFFFFFFF |
je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
test esi, esi |
jnz .timer_loop_end_with_dec ;if TTL!=0 |
; Ok, TTL is 0 |
;if Status==AWAITING_RESPONSE and TTL==0 |
;then we have to change it to ARP_RESPONSE_TIMEOUT |
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
jne @f |
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
jmp .timer_loop_end |
@@: |
;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
mov esi, dword[NumARP] |
sub esi, ecx ;esi=index of entry, will be deleted |
stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra |
jmp .timer_loop_end |
.timer_loop_end_with_dec: |
dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
.timer_loop_end: |
add ebx, ARP_ENTRY_SIZE |
loop .timer_loop |
jmp .exit |
;;END TIMER |
;;BEGIN ADD |
;;Description: it adds an entry in the table. If ARP-table already |
;; contains same IP, it will be updated. |
;;IN: Operation: ARP_TABLE_ADD |
;; Index: specifies what contains Extra-parameter |
;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR, |
;; then Extra contains pointer to ARP_PACKET, |
;; otherwise Extra contains pointer to ARP_ENTRY |
;;OUT: |
;; EAX=index of entry, that has been added |
;; |
.add: |
sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack |
mov esi, [Extra] ;pointer |
mov edi, [Index] ;opcode |
cmp edi, EXTRA_IS_ARP_PACKET_PTR |
je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry |
;else it contain ptr to arp-entry |
cld |
; esi already has been loaded |
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! |
rep movsw ;copy |
jmp .search |
.arp_packet_to_entry: |
mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET |
mov [esp + ARP_ENTRY.IP], edx |
cld |
lea esi, [esi + ARP_PACKET.SenderMAC] |
lea edi, [esp + ARP_ENTRY.MAC] |
movsd |
movsw |
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry |
mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour |
.search: |
mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search |
mov ecx, dword[NumARP] ;ecx=ARP-entries counter |
jecxz .add_to_end ;if ARP-entries number == 0 |
imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes) |
@@: |
sub eax, ARP_ENTRY_SIZE |
cmp dword[ebx + eax + ARP_ENTRY.IP], edx |
loopnz @b |
jz .replace ; found, replace existing entry, ptr to it is in eax |
.add_to_end: |
;else add to end |
or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible |
mov ecx, dword[NumARP] |
cmp ecx, ARP_TABLE_SIZE |
je .add_exit ;if arp-entries number is equal to arp-table maxsize |
imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable |
inc dword [NumARP] ;increase ARP-entries counter |
.replace: |
cld |
mov esi, esp ;esp=base of ARP-entry, that will be added |
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! |
rep movsw |
mov ecx, ARP_ENTRY_SIZE |
xor edx, edx ;"div" takes operand from EDX:EAX |
div ecx ;eax=index of entry, which has been added |
.add_exit: |
add esp, ARP_ENTRY_SIZE ;free stack |
jmp .exit |
;;END ADD |
;;BEGIN DEL |
;;Description: it deletes an entry in the table. |
;;IN: Operation: ARP_TABLE_DEL |
;; Index: index of entry, that should be deleted |
;; Extra: must be zero |
;;OUT: |
;; EAX=not defined |
;; |
.del: |
mov esi, [Index] |
imul esi, ARP_ENTRY_SIZE |
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE |
sub ecx, esi |
lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted |
lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry |
shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
cld |
rep movsw |
dec dword[NumARP] ;decrease arp-entries counter |
jmp .exit |
;;END DEL |
;;BEGIN GET |
;;Description: it reads an entry of table into buffer. |
;;IN: Operation: ARP_TABLE_GET |
;; Index: index of entry, that should be read |
;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) |
;;OUT: |
;; EAX=not defined |
;; |
.get: |
mov esi, [Index] |
imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY |
mov edi, [Extra] ;edi=buffer for reading |
mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!! |
cld |
rep movsw |
jmp .exit |
;;END GET |
;;BEGIN IP_TO_MAC |
;;Description: it gets an IP from Index, scans each entry in the table and writes |
;; MAC, that relates to specified IP, into buffer specified in Extra. |
;; And if it cannot find an IP-address in the table, it does an ARP-request of that. |
;;IN: Operation: ARP_TABLE_IP_TO_MAC |
;; Index: IP that should be transformed into MAC |
;; Extra: pointer to buffer where will be written the MAC-address. |
;;OUT: |
;; EAX=ARP table entry status code. |
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. |
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. |
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. |
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. |
;; |
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet |
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this |
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. |
;; |
.ip_to_mac: |
xor eax, eax |
mov edi, dword[Extra] |
cld |
stosd |
stosw |
; first, check destination IP to see if it is on 'this' network. |
; The test is: |
; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
; destination is local |
; else |
; destination is remote, so pass to gateway |
mov eax, [Index] ;eax=required IP |
mov esi, eax |
and esi, [subnet_mask] |
mov ecx, [stack_ip] |
and ecx, [subnet_mask] |
cmp esi, ecx |
je @f ;if we and target IP are located in the same network |
mov eax, [gateway_ip] |
mov [Index], eax |
@@: |
cmp dword[NumARP], 0 |
je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. |
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY |
mov ecx, dword[NumARP] |
imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size |
@@: |
sub esi, ARP_ENTRY_SIZE |
cmp [ebx + esi], eax ; ebx=ARPTable base |
loopnz @b ; Return back if non match |
jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table |
; Return the entry status in eax |
movzx eax, word[ebx + esi + ARP_ENTRY.Status] |
; esi holds index |
cld |
lea esi, [ebx + esi + ARP_ENTRY.MAC] |
mov edi, [Extra] ;edi=ptr to buffer for write MAC |
movsd |
movsw |
jmp .exit |
.ip_to_mac_send_request: |
stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr |
mov eax, ARP_NO_ENTRY |
jmp .exit |
;;END IP_TO_MAC |
;;BEGIN GET_ENTRIES_NUMBER |
;;Description: returns an ARP-entries number in the ARPTable |
;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER |
;; Index: must be zero |
;; Extra: must be zero |
;;OUT: |
;; EAX=ARP-entries number in the ARPTable |
.get_entries_number: |
mov eax, dword[NumARP] |
jmp .exit |
;;END GET_ENTRIES_NUMBER |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; arp_handler |
; |
; Description |
; Called when an ARP packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; It looks to see if the packet is a request to resolve this Hosts |
; IP address. If it is, send the ARP reply packet. |
; This Hosts IP address is in dword [stack_ip] ( in network format ) |
; This Hosts MAC address is in node_addr[6] |
; All registers may be destroyed |
; |
;*************************************************************************** |
arp_handler: |
; Is this a REQUEST? |
; Is this a request for My Host IP |
; Yes - So construct a response message. |
; Send this message to the ethernet card for transmission |
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET |
inc dword[arp_rx_count] ;increase ARP-packets counter |
cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet? |
jne .exit ; No - so exit |
mov eax, [stack_ip] |
cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address? |
jne .exit ; No - so quit now |
; OK, it is a request for my MAC address. Build the frame and send it |
; We can reuse the packet. |
mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE |
cld |
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC |
movsd |
movsw |
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP |
movsd |
mov esi, node_addr |
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC |
movsd |
movsw |
mov esi, stack_ip |
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP |
movsd |
; Now, send it! |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address |
mov bx, ETHER_ARP ;type of protocol |
mov ecx, 28 ;data size |
mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data |
push ebp |
call dword [drvr_transmit] ;transmit packet |
pop ebp |
.exit: |
ret |
;*************************************************************************** |
; Function |
; arp_request [by Johnny_B] |
; |
; Description |
; Sends an ARP request on the ethernet |
; IN: |
; TargetIP : requested IP address |
; SenderIP_ptr : POINTER to sender's IP address(our system's address) |
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) |
; OUT: |
; EAX=0 (if all is ok), otherwise EAX is not defined |
; |
; EBX,ESI,EDI will be saved |
; |
;*************************************************************************** |
proc arp_request stdcall uses ebx esi edi,\ |
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD |
inc dword[arp_tx_count] ; increase counter |
sub esp, 28 ; allocate memory for ARP_PACKET |
mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet |
mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP |
mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length |
mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length |
mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request |
cld |
mov esi,[SenderMAC_ptr] |
lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr |
movsd |
movsw |
mov esi,[SenderIP_ptr] |
lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr |
movsd |
xor eax, eax |
lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed) |
stosd |
stosw |
mov esi, dword[TargetIP] |
mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter) |
; Now, send it! |
mov edi, broadcast_add ; Pointer to 48 bit destination address |
mov bx, ETHER_ARP ; Type of packet |
mov ecx, 28 ; size of packet |
lea esi, [esp + ARP_PACKET]; pointer to packet data |
push ebp |
call dword [drvr_transmit] ; Call the drivers transmit function |
pop ebp |
add esp, 28 ; free memory, allocated before for ARP_PACKET |
; Add an entry in the ARP table, awaiting response |
sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry |
mov esi, dword[TargetIP] |
mov dword[esp + ARP_ENTRY.IP],esi |
lea edi, [esp + ARP_ENTRY.MAC] |
xor eax, eax |
stosd |
stosw |
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds |
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp |
add esp, ARP_ENTRY_SIZE ; free memory |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv/pci.inc |
---|
0,0 → 1,351 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;*************************************************************************** |
; |
; PCI CODE FOLLOWS |
; |
; the following functions provide access to the PCI interface. |
; These functions are used by scan_bus, and also some ethernet drivers |
; |
;*************************************************************************** |
; PCI Bus defines |
PCI_HEADER_TYPE equ 0x0e ;8 bit |
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit |
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_VENDOR_ID equ 0x00 ;16 bit |
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC |
;*************************************************************************** |
; Function |
; config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ebx |
; devfn in ecx |
; where in edx |
; |
; command dword returned in eax |
; Only eax destroyed |
;*************************************************************************** |
config_cmd: |
push ecx |
mov eax, ebx |
shl eax, 16 |
or eax, 0x80000000 |
shl ecx, 8 |
or eax, ecx |
pop ecx |
or eax, edx |
and eax, 0xFFFFFFFC |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_byte |
; |
; Description |
; reads a byte from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; byte returned in al ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_byte: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x03 |
add dx, 0xCFC |
; and dx, 0xFFC |
in al, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_word |
; |
; Description |
; reads a word from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; word returned in ax ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_word: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x02 |
add dx, 0xCFC |
; and dx, 0xFFC |
in ax, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_dword |
; |
; Description |
; reads a dword from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; dword returned in eax |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_dword: |
push edx |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
mov dx, 0xCFC |
in eax, dx |
pop edx |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_byte |
; |
; Description |
; write a byte in al to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_byte: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x03 |
add dx, 0xCFC |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_word |
; |
; Description |
; write a word in ax to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_word: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x02 |
add dx, 0xCFC |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; delay_us |
; |
; Description |
; delays for 30 to 60 us |
; |
; I would prefer this routine to be able to delay for |
; a selectable number of microseconds, but this works for now. |
; |
; If you know a better way to do 2us delay, pleae tell me! |
;*************************************************************************** |
delay_us: |
push eax |
push ecx |
mov ecx,2 |
in al,0x61 |
and al,0x10 |
mov ah,al |
cld |
dcnt1: |
in al,0x61 |
and al,0x10 |
cmp al,ah |
jz dcnt1 |
mov ah,al |
loop dcnt1 |
pop ecx |
pop eax |
ret |
;*************************************************************************** |
; Function |
; scan_bus |
; |
; Description |
; Scans the PCI bus for a supported device |
; If a supported device is found, the drvr_ variables are initialised |
; to that drivers functions ( as defined in the PCICards table) |
; |
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid |
; pci_data holds the PCI vendor + device code |
; pci_dev holds PCI bus dev # |
; pci_bus holds PCI bus # |
; |
; io_addr will be zero if no card found |
; |
;*************************************************************************** |
scan_bus: |
xor eax, eax |
mov [hdrtype], al |
mov [pci_data], eax |
xor ebx, ebx ; ebx = bus# 0 .. 255 |
sb_bus_loop: |
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) |
sb_devf_loop: |
mov eax, ecx |
and eax, 0x07 |
cmp eax, 0 |
jne sb_001 |
mov edx, PCI_HEADER_TYPE |
call pcibios_read_config_byte |
mov [hdrtype], al |
jmp sb_002 |
sb_001: |
mov al, [hdrtype] |
and al, 0x80 |
cmp al, 0x80 |
jne sb_inc_devf |
sb_002: |
mov edx, PCI_VENDOR_ID |
call pcibios_read_config_dword |
mov [vendor_device], eax |
cmp eax, 0xffffffff |
je sb_empty |
cmp eax, 0 |
jne sb_check_vendor |
sb_empty: |
mov [hdrtype], byte 0 |
jmp sb_inc_devf |
sb_check_vendor: |
; iterate though PCICards until end or match found |
mov esi, PCICards |
sb_check: |
cmp [esi], dword 0 |
je sb_inc_devf ; Quit if at last entry |
cmp eax, [esi] |
je sb_got_card |
add esi, PCICARDS_ENTRY_SIZE |
jmp sb_check |
sb_got_card: |
; indicate that we have found the card |
mov [pci_data], eax |
mov [pci_dev], ecx |
mov [pci_bus], ebx |
; Define the driver functions |
push eax |
mov eax, [esi+4] |
mov [drvr_probe], eax |
mov eax, [esi+8] |
mov [drvr_reset], eax |
mov eax, [esi+12] |
mov [drvr_poll], eax |
mov eax, [esi+16] |
mov [drvr_transmit], eax |
mov eax, [esi+20] |
mov [drvr_cable], eax |
pop eax |
mov edx, PCI_BASE_ADDRESS_0 |
sb_reg_check: |
call pcibios_read_config_dword |
mov [io_addr], eax |
and eax, PCI_BASE_ADDRESS_IO_MASK |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_SPACE_IO |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_IO_MASK |
mov [io_addr], eax |
sb_exit1: |
ret |
sb_inc_reg: |
add edx, 4 |
cmp edx, PCI_BASE_ADDRESS_5 |
jbe sb_reg_check |
sb_inc_devf: |
inc ecx |
cmp ecx, 255 |
jb sb_devf_loop |
inc ebx |
cmp ebx, 256 |
jb sb_bus_loop |
; We get here if we didn't find our card |
; set io_addr to 0 as an indication |
xor eax, eax |
mov [io_addr], eax |
sb_exit2: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/eth_drv |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/network/socket.inc |
---|
0,0 → 1,1107 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; SOCKET.INC ;; |
;; ;; |
;; Sockets constants, structures and functions ;; |
;; ;; |
;; This file contains the following: ;; |
;; is_localport_unused ;; |
;; get_free_socket ;; |
;; socket_open ;; |
;; socket_open_tcp ;; |
;; socket_close ;; |
;; socket_close_tcp ;; |
;; socket_poll ;; |
;; socket_status ;; |
;; socket_read ;; |
;; socket_write ;; |
;; socket_write_tcp ;; |
;; ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; socket data structure |
struct SOCKET |
.PrevPtr dd ? ; pointer to previous socket in list |
.NextPtr dd ? ; pointer to next socket in list |
.Number dd ? ; socket number (unique within single process) |
.PID dd ? ; application process id |
.LocalIP dd ? ; local IP address |
.LocalPort dw ? ; local port |
.RemoteIP dd ? ; remote IP address |
.RemotePort dw ? ; remote port |
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) |
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) |
.rxDataCount dd ? ; rx data count |
.TCBState dd ? ; TCB state |
.TCBTimer dd ? ; TCB timer (seconds) |
.ISS dd ? ; initial send sequence |
.IRS dd ? ; initial receive sequence |
.SND_UNA dd ? ; sequence number of unack'ed sent packets |
.SND_NXT dd ? ; bext send sequence number to use |
.SND_WND dd ? ; send window |
.RCV_NXT dd ? ; next receive sequence number to use |
.RCV_WND dd ? ; receive window |
.SEG_LEN dd ? ; segment length |
.SEG_WND dd ? ; segment window |
.wndsizeTimer dd ? ; window size timer |
.lock dd ? ; lock mutex |
.rxData dd ? ; receive data buffer here |
ends |
; TCP opening modes |
SOCKET_PASSIVE = 0 |
SOCKET_ACTIVE = 1 |
; socket types |
SOCK_STREAM = 1 |
SOCK_DGRAM = 2 |
; pointer to bitmap of free ports (1=free, 0=used) |
uglobal |
align 4 |
network_free_ports dd ? |
endg |
iglobal |
align 4 |
network_free_hint dd 1024/8 |
endg |
;; Allocate memory for socket data and put new socket into the list |
; Newly created socket is initialized with calling PID and number and |
; put into beginning of list (which is a fastest way). |
; |
; @return socket structure address in EAX |
;; |
proc net_socket_alloc stdcall uses ebx ecx edx edi |
stdcall kernel_alloc, SOCKETBUFFSIZE |
DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax |
; check if we can allocate needed amount of memory |
or eax, eax |
jz .exit |
; zero-initialize allocated memory |
push eax |
mov edi, eax |
mov ecx, SOCKETBUFFSIZE / 4 |
cld |
xor eax, eax |
rep stosd |
pop eax |
; add socket to the list by changing pointers |
mov ebx, net_sockets |
push [ebx + SOCKET.NextPtr] |
mov [ebx + SOCKET.NextPtr], eax |
mov [eax + SOCKET.PrevPtr], ebx |
pop ebx |
mov [eax + SOCKET.NextPtr], ebx |
or ebx, ebx |
jz @f |
mov [ebx + SOCKET.PrevPtr], eax |
@@: ; set socket owner PID to the one of calling process |
mov ebx, [TASK_BASE] |
mov ebx, [ebx + TASKDATA.pid] |
mov [eax + SOCKET.PID], ebx |
; find first free socket number and use it |
;mov edx, ebx |
mov ebx, net_sockets |
xor ecx, ecx |
.next_socket_number: |
inc ecx |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .last_socket_number |
cmp [ebx + SOCKET.Number], ecx |
jne .next_socket |
;cmp [ebx + SOCKET.PID], edx |
;jne .next_socket |
mov ebx, net_sockets |
jmp .next_socket_number |
.last_socket_number: |
mov [eax + SOCKET.Number], ecx |
.exit: |
ret |
endp |
;; Free socket data memory and pop socket off the list |
; |
; @param sockAddr is a socket structure address |
;; |
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD |
mov eax, [sockAddr] |
DEBUGF 1, "K : net_socket_free (0x%x)\n", eax |
; check if we got something similar to socket structure address |
or eax, eax |
jz .error |
; make sure sockAddr is one of the socket addresses in the list |
mov ebx, net_sockets |
;mov ecx, [TASK_BASE] |
;mov ecx, [ecx + TASKDATA.pid] |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .error |
cmp ebx, eax |
jne .next_socket |
;cmp [ebx + SOCKET.PID], ecx |
;jne .next_socket |
; okay, we found the correct one |
; mark local port as unused |
movzx ebx, [eax + SOCKET.LocalPort] |
push eax |
mov eax, [network_free_ports] |
xchg bl, bh |
lock bts [eax], ebx |
pop eax |
; remove it from the list first, changing pointers |
mov ebx, [eax + SOCKET.NextPtr] |
mov eax, [eax + SOCKET.PrevPtr] |
mov [eax + SOCKET.NextPtr], ebx |
or ebx, ebx |
jz @f |
mov [ebx + SOCKET.PrevPtr], eax |
@@: ; and finally free the memory structure used |
stdcall kernel_free, [sockAddr] |
ret |
.error: |
DEBUGF 1, "K : failed\n" |
ret |
endp |
;; Get socket structure address by its number |
; Scan through sockets list to find the socket with specified number. |
; This proc uses SOCKET.PID indirectly to check if socket is owned by |
; calling process. |
; |
; @param sockNum is a socket number |
; @return socket structure address or 0 (not found) in EAX |
;; |
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD |
mov eax, [sockNum] |
; check if we got something similar to socket number |
or eax, eax |
jz .error |
; scan through sockets list |
mov ebx, net_sockets |
;mov ecx, [TASK_BASE] |
;mov ecx, [ecx + TASKDATA.pid] |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .error |
cmp [ebx + SOCKET.Number], eax |
jne .next_socket |
;cmp [ebx + SOCKET.PID], ecx |
;jne .next_socket |
; okay, we found the correct one |
mov eax, ebx |
ret |
.error: |
xor eax, eax |
ret |
endp |
;; Get socket number by its structure address |
; Scan through sockets list to find the socket with specified address. |
; This proc uses SOCKET.PID indirectly to check if socket is owned by |
; calling process. |
; |
; @param sockAddr is a socket structure address |
; @return socket number (SOCKET.Number) or 0 (not found) in EAX |
;; |
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD |
mov eax, [sockAddr] |
; check if we got something similar to socket structure address |
or eax, eax |
jz .error |
; scan through sockets list |
mov ebx, net_sockets |
;mov ecx, [TASK_BASE] |
;mov ecx, [ecx + TASKDATA.pid] |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .error |
cmp ebx, eax |
jne .next_socket |
;cmp [ebx + SOCKET.PID], ecx |
;jne .next_socket |
; okay, we found the correct one |
mov eax, [ebx + SOCKET.Number] |
ret |
.error: |
xor eax, eax |
ret |
endp |
;; [53.9] Check if local port is used by any socket in the system. |
; Scan through sockets list, checking SOCKET.LocalPort. |
; Useful when you want a to generate a unique local port number. |
; This proc doesn't guarantee that after calling it and trying to use |
; the port reported being free in calls to socket_open/socket_open_tcp it'll |
; still be free or otherwise it'll still be used if reported being in use. |
; |
; @param BX is a port number |
; @return 1 (port is free) or 0 (port is in use) in EAX |
;; |
proc is_localport_unused stdcall |
movzx ebx, bx |
mov eax, [network_free_ports] |
bt [eax], ebx |
setc al |
movzx eax, al |
ret |
endp |
;====================================== |
set_local_port: |
;-------------------------------------- |
;? Set local port in socket structure. |
;-------------------------------------- |
;> eax -> struct SOCKET |
;> bx = local port, or 0 if the kernel must select it itself |
;-------------------------------------- |
;< CF set on error / cleared on success |
;< [eax+SOCKET.LocalPort] filled on success |
;====================================== |
; 0. Prepare: save registers, make eax point to ports table, expand port to ebx. |
push eax ecx |
mov eax, [network_free_ports] |
movzx ebx, bx |
; 1. Test, whether the kernel should choose port itself. If no, proceed to 5. |
test ebx, ebx |
jnz .given |
; 2. Yes, it should. Set ecx = limit of table, eax = start value |
lea ecx, [eax+0x10000/8] |
add eax, [network_free_hint] |
; 3. First scan loop: from free hint to end of table. |
.scan1: |
; 3a. For each dword, find bit set to 1 |
bsf ebx, [eax] |
jz .next1 |
; 3b. If such bit has been found, atomically test again and clear it. |
lock btr [eax], ebx |
; 3c. If the bit was still set (usual case), we have found and reserved one port. |
; Proceed to 6. |
jc .found |
; 3d. Otherwise, someone has reserved it between bsf and btr, so retry search. |
jmp .scan1 |
.next1: |
; 3e. All bits are cleared, so advance to next dword. |
add eax, 4 |
; 3f. Check limit and continue loop. |
cmp eax, ecx |
jb .scan1 |
; 4. Second scan loop: from port 1024 (start of non-system ports) to free hint. |
mov eax, [network_free_ports] |
mov ecx, eax |
add ecx, [network_free_hint] |
add eax, 1024/8 |
; 4a. Test whether there is something to scan. |
cmp eax, ecx |
jae .fail |
; 4b. Enter the loop, the process is same as for 3. |
.scan2: |
bsf ebx, [eax] |
jz .next2 |
lock btr [eax], ebx |
jc .found |
jmp .scan2 |
.next2: |
add eax, 4 |
cmp eax, ecx |
jb .scan2 |
; 4c. None found. Fail. |
.fail: |
pop ecx eax |
stc |
ret |
; 5. No, the kernel should reserve selected port. |
.given: |
; 5a. Atomically test old value and clear bit. |
lock btr [eax], ebx |
; 5b. If the bit was set, reservation is successful. Proceed to 8. |
jc .set |
; 5c. Otherwise, fail. |
jmp .fail |
.found: |
; 6. We have found the bit set to 1, convert the position to port number. |
sub eax, [network_free_ports] |
lea ebx, [ebx+eax*8] |
; 7. Update free hint. |
add eax, 4 |
cmp eax, 65536/8 |
jb @f |
mov eax, 1024/8 |
@@: |
mov [network_free_hint], eax |
.set: |
; 8. Restore eax, set SOCKET.LocalPort and return. |
pop ecx eax |
xchg bl, bh ; Intel -> network byte order |
mov [eax + SOCKET.LocalPort], bx |
clc |
ret |
;; [53.0] Open DGRAM socket (connectionless, unreliable) |
; |
; @param BX is local port number |
; @param CX is remote port number |
; @param EDX is remote IP address |
; @return socket number or -1 (error) in EAX |
;; |
proc socket_open stdcall |
call net_socket_alloc |
or eax, eax |
jz .error |
DEBUGF 1, "K : socket_open (0x%x)\n", eax |
push eax |
call set_local_port |
jc .error.free |
xchg ch, cl |
mov [eax + SOCKET.RemotePort], cx |
mov ebx, [stack_ip] |
mov [eax + SOCKET.LocalIP], ebx |
mov [eax + SOCKET.RemoteIP], edx |
;pop eax ; Get the socket number back, so we can return it |
stdcall net_socket_addr_to_num |
ret |
.error.free: |
stdcall net_socket_free;, eax |
.error: |
DEBUGF 1, "K : socket_open (fail)\n" |
or eax, -1 |
ret |
endp |
;; [53.5] Open STREAM socket (connection-based, sequenced, reliable, two-way) |
; |
; @param BX is local port number |
; @param CX is remote port number |
; @param EDX is remote IP address |
; @param ESI is open mode (SOCKET_ACTIVE, SOCKET_PASSIVE) |
; @return socket number or -1 (error) in EAX |
;; |
proc socket_open_tcp stdcall |
local sockAddr dd ? |
cmp esi, SOCKET_PASSIVE |
jne .skip_port_check |
push ebx |
mov eax, ebx |
xchg al, ah |
mov ebx, net_sockets |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .last_socket |
cmp [ebx + SOCKET.TCBState], TCB_LISTEN |
jne .next_socket |
cmp [ebx + SOCKET.LocalPort], ax |
jne .next_socket |
xchg al, ah |
DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx |
pop ebx |
jmp .error |
.last_socket: |
pop ebx |
.skip_port_check: |
call net_socket_alloc |
or eax, eax |
jz .error |
DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax |
mov [sockAddr], eax |
; TODO - check this works! |
;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer. |
call set_local_port |
jc .error.free |
xchg ch, cl |
mov [eax + SOCKET.RemotePort], cx |
mov [eax + SOCKET.OrigRemotePort], cx |
mov ebx, [stack_ip] |
mov [eax + SOCKET.LocalIP], ebx |
mov [eax + SOCKET.RemoteIP], edx |
mov [eax + SOCKET.OrigRemoteIP], edx |
mov ebx, TCB_LISTEN |
cmp esi, SOCKET_PASSIVE |
je @f |
mov ebx, TCB_SYN_SENT |
@@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB |
cmp ebx, TCB_LISTEN |
je .exit |
; Now, if we are in active mode, then we have to send a SYN to the specified remote port |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit |
push eax |
mov bl, TH_SYN |
xor ecx, ecx |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
mov esi, [sockAddr] |
; increment SND.NXT in socket |
add esi, SOCKET.SND_NXT |
call inc_inet_esi |
.exit: |
; Get the socket number back, so we can return it |
stdcall net_socket_addr_to_num, [sockAddr] |
ret |
.error.free: |
stdcall net_socket_free, eax |
.error: |
DEBUGF 1, "K : socket_open_tcp (fail)\n" |
or eax, -1 |
ret |
endp |
;; [53.1] Close DGRAM socket |
; |
; @param EBX is socket number |
; @return 0 (closed successfully) or -1 (error) in EAX |
;; |
proc socket_close stdcall |
DEBUGF 1, "K : socket_close (0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
stdcall net_socket_free, eax |
xor eax, eax |
ret |
.error: |
DEBUGF 1, "K : socket_close (fail)\n" |
or eax, -1 |
ret |
endp |
;; [53.8] Close STREAM socket |
; Closing TCP sockets takes time, so when you get successful return code |
; from this function doesn't always mean that socket is actually closed. |
; |
; @param EBX is socket number |
; @return 0 (closed successfully) or -1 (error) in EAX |
;; |
proc socket_close_tcp stdcall |
local sockAddr dd ? |
DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx |
; first, remove any resend entries |
pusha |
mov esi, resendQ |
mov ecx, 0 |
.next_resendq: |
cmp ecx, NUMRESENDENTRIES |
je .last_resendq ; None left |
cmp [esi + 4], ebx |
je @f ; found one |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: mov dword[esi + 4], 0 |
inc ecx |
add esi, 8 |
jmp .next_resendq |
.last_resendq: |
popa |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
mov ebx, eax |
mov [sockAddr], eax |
cmp [ebx + SOCKET.TCBState], TCB_LISTEN |
je .destroy_tcb |
cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT |
je .destroy_tcb |
cmp [ebx + SOCKET.TCBState], TCB_CLOSED |
je .destroy_tcb |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .error |
push eax |
mov bl, TH_FIN+TH_ACK |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov ebx, [sockAddr] |
; increament SND.NXT in socket |
lea esi, [ebx + SOCKET.SND_NXT] |
call inc_inet_esi |
; Get the socket state |
mov eax, [ebx + SOCKET.TCBState] |
cmp eax, TCB_SYN_RECEIVED |
je .fin_wait_1 |
cmp eax, TCB_ESTABLISHED |
je .fin_wait_1 |
; assume CLOSE WAIT |
; Send a fin, then enter last-ack state |
mov [ebx + SOCKET.TCBState], TCB_LAST_ACK |
jmp .send |
.fin_wait_1: |
; Send a fin, then enter finwait2 state |
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1 |
.send: |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
jmp .exit |
.destroy_tcb: |
; Clear the socket variables |
stdcall net_socket_free, ebx |
.exit: |
xor eax, eax |
ret |
.error: |
DEBUGF 1, "K : socket_close_tcp (fail)\n" |
or eax, -1 |
ret |
endp |
;; [53.2] Poll socket |
; |
; @param EBX is socket number |
; @return count or bytes in rx buffer or 0 (error) in EAX |
;; |
proc socket_poll stdcall |
; DEBUGF 1, "socket_poll(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
mov eax, [eax + SOCKET.rxDataCount] |
ret |
.error: |
xor eax, eax |
ret |
endp |
;; [53.6] Get socket TCB state |
; |
; @param EBX is socket number |
; @return socket TCB state or 0 (error) in EAX |
;; |
proc socket_status stdcall |
;; DEBUGF 1, "socket_status(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
mov eax, [eax + SOCKET.TCBState] |
ret |
.error: |
xor eax, eax |
ret |
endp |
;; [53.3] Get one byte from rx buffer |
; This function can return 0 in two cases: if there's one byte read and |
; non left, and if an error occured. Behavior should be changed and function |
; shouldn't be used for now. Consider using [53.11] instead. |
; |
; @param EBX is socket number |
; @return number of bytes left in rx buffer or 0 (error) in EAX |
; @return byte read in BL |
;; |
proc socket_read stdcall |
; DEBUGF 1, "socket_read(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
lea ebx, [eax + SOCKET.lock] |
call wait_mutex |
mov ebx, eax |
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
test eax, eax |
jz .error_release |
dec eax |
mov esi, ebx ; esi is address of socket |
mov [ebx + SOCKET.rxDataCount], eax ; store new count |
movzx eax, byte[ebx + SOCKET.rxData] ; get the byte |
mov ecx, SOCKETBUFFSIZE - SOCKET.rxData - 1 |
lea edi, [esi + SOCKET.rxData] |
lea esi, [edi + 1] |
cld |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
and ecx, 3 |
rep movsb |
mov [ebx + SOCKET.lock], 0 |
mov ebx, eax |
ret |
.error_release: |
mov [ebx + SOCKET.lock], 0 |
.error: |
xor ebx, ebx |
ret |
endp |
;; [53.11] Get specified number of bytes from rx buffer |
; Number of bytes in rx buffer can be less than requested size. In this case, |
; only available number of bytes is read. |
; This function can return 0 in two cases: if there's no data to read, and if |
; an error occured. Behavior should be changed. |
; |
; @param EBX is socket number |
; @param ECX is pointer to application buffer |
; @param EDX is application buffer size (number of bytes to read) |
; @return number of bytes read or 0 (error) in EAX |
;; |
proc socket_read_packet stdcall |
; DEBUGF 1, "socket_read_packet(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx ; get real socket address |
or eax, eax |
jz .error |
lea ebx, [eax + SOCKET.lock] |
call wait_mutex |
mov ebx, eax |
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
test eax, eax ; if count of bytes is zero.. |
jz .exit ; exit function (eax will be zero) |
test edx, edx ; if buffer size is zero, copy all data |
jz .copy_all_bytes |
cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data |
jge .copy_all_bytes |
sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy) |
mov [ebx + SOCKET.rxDataCount], eax ; |
push eax |
mov eax, edx ; number of bytes we want to copy must be in eax |
call .start_copy ; copy to the application |
mov esi, ebx ; now we're going to copy the remaining bytes to the beginning |
add esi, SOCKET.rxData ; we dont need to copy the header |
mov edi, esi ; edi is where we're going to copy to |
add esi, edx ; esi is from where we copy |
pop ecx ; count of bytes we have left |
push ecx ; push it again so we can re-use it later |
shr ecx, 2 ; divide eax by 4 |
cld |
rep movsd ; copy all full dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy remaining bytes |
.exit: |
mov [ebx + SOCKET.lock], 0 |
ret ; at last, exit |
.error: |
xor eax, eax |
ret |
.copy_all_bytes: |
xor esi, esi |
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) |
call .start_copy |
mov [ebx + SOCKET.lock], 0 |
ret |
.start_copy: |
mov edi, ecx |
mov esi, ebx |
add esi, SOCKET.rxData ; we dont need to copy the header |
mov ecx, eax ; eax is count of bytes |
push ecx |
shr ecx, 2 ; divide eax by 4 |
cld ; copy all full dwords |
rep movsd |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
retn ; exit, or go back to shift remaining bytes if any |
endp |
;; [53.4] Send data through DGRAM socket |
; |
; @param EBX is socket number |
; @param ECX is application data size (number of bytes to send) |
; @param EDX is pointer to application data buffer |
; @return 0 (sent successfully) or -1 (error) in EAX |
;; |
proc socket_write stdcall |
; DEBUGF 1, "socket_write(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx ; get real socket address |
or eax, eax |
jz .error |
mov ebx, eax |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .error |
; Save the queue entry number |
push eax |
; save the pointers to the data buffer & size |
push edx |
push ecx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
; Fill in the IP header (some data is in the socket descriptor) |
mov eax, [ebx + SOCKET.LocalIP] |
mov [edx + IP_PACKET.SourceAddress], eax |
mov eax, [ebx + SOCKET.RemoteIP] |
mov [edx + IP_PACKET.DestinationAddress], eax |
mov [edx + IP_PACKET.VersionAndIHL], 0x45 |
mov [edx + IP_PACKET.TypeOfService], 0 |
pop eax ; Get the UDP data length |
push eax |
add eax, 20 + 8 ; add IP header and UDP header lengths |
xchg al, ah |
mov [edx + IP_PACKET.TotalLength], ax |
xor eax, eax |
mov [edx + IP_PACKET.Identification], ax |
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040 |
mov [edx + IP_PACKET.TimeToLive], 0x20 |
mov [edx + IP_PACKET.Protocol], PROTOCOL_UDP |
; Checksum left unfilled |
mov [edx + IP_PACKET.HeaderChecksum], ax |
; Fill in the UDP header (some data is in the socket descriptor) |
mov ax, [ebx + SOCKET.LocalPort] |
mov [edx + 20 + UDP_PACKET.SourcePort], ax |
mov ax, [ebx + SOCKET.RemotePort] |
mov [edx + 20 + UDP_PACKET.DestinationPort], ax |
pop eax |
push eax |
add eax, 8 |
xchg al, ah |
mov [edx + 20 + UDP_PACKET.Length], ax |
; Checksum left unfilled |
xor eax, eax |
mov [edx + 20 + UDP_PACKET.Checksum], ax |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
pop eax ; get callers ptr to data to send |
; Get the address of the callers data |
mov edi, [TASK_BASE] |
add edi, TASKDATA.mem_start |
add eax, [edi] |
mov esi, eax |
mov edi, edx |
add edi, 28 |
cld |
rep movsb ; copy the data across |
; we have edx as IPbuffer ptr. |
; Fill in the UDP checksum |
; First, fill in pseudoheader |
mov eax, [edx + IP_PACKET.SourceAddress] |
mov [pseudoHeader], eax |
mov eax, [edx + IP_PACKET.DestinationAddress] |
mov [pseudoHeader + 4], eax |
mov word[pseudoHeader + 8], PROTOCOL_UDP shl 8 + 0 ; 0 + protocol |
add ebx, 8 |
mov eax, ebx |
xchg al, ah |
mov [pseudoHeader + 10], ax |
mov eax, pseudoHeader |
mov [checkAdd1], eax |
mov [checkSize1], word 12 |
mov eax, edx |
add eax, 20 |
mov [checkAdd2], eax |
mov eax, ebx |
mov [checkSize2], ax ; was eax!! mjh 8/7/02 |
call checksum |
; store it in the UDP checksum ( in the correct order! ) |
mov ax, [checkResult] |
; If the UDP checksum computes to 0, we must make it 0xffff |
; (0 is reserved for 'not used') |
test ax, ax |
jnz @f |
mov ax, 0xffff |
@@: xchg al, ah |
mov [edx + 20 + UDP_PACKET.Checksum], ax |
; Fill in the IP header checksum |
GET_IHL ecx,edx ; get IP-Header length |
stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size |
xchg al, ah |
mov [edx + IP_PACKET.HeaderChecksum], ax |
; Check destination IP address. |
; If it is the local host IP, route it back to IP_RX |
pop ebx |
mov eax, NET1OUT_QUEUE |
mov ecx, [edx + SOCKET.RemoteIP] |
mov edx, [stack_ip] |
cmp edx, ecx |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
call queue |
xor eax, eax |
ret |
.error: |
or eax, -1 |
ret |
endp |
;; [53.7] Send data through STREAM socket |
; |
; @param EBX is socket number |
; @param ECX is application data size (number of bytes to send) |
; @param EDX is pointer to application data buffer |
; @return 0 (sent successfully) or -1 (error) in EAX |
;; |
proc socket_write_tcp stdcall |
local sockAddr dd ? |
; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx |
stdcall net_socket_num_to_addr, ebx |
or eax, eax |
jz .error |
mov ebx, eax |
mov [sockAddr], ebx |
; If the sockets window timer is nonzero, do not queue packet |
cmp [ebx + SOCKET.wndsizeTimer], 0 |
jne .error |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .error |
push eax |
; Get the address of the callers data |
mov edi, [TASK_BASE] |
add edi, TASKDATA.mem_start |
add edx, [edi] |
mov esi, edx |
pop eax |
push eax |
push ecx |
mov bl, TH_ACK |
stdcall build_tcp_packet, [sockAddr] |
pop ecx |
; Check destination IP address. |
; If it is the local host IP, route it back to IP_RX |
pop ebx |
push ecx |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
pop ecx |
push ebx ; save ipbuffer number |
call queue |
mov esi, [sockAddr] |
; increament SND.NXT in socket |
; Amount to increment by is in ecx |
add esi, SOCKET.SND_NXT |
call add_inet_esi |
pop ebx |
; Copy the IP buffer to a resend queue |
; If there isn't one, dont worry about it for now |
mov esi, resendQ |
mov ecx, 0 |
.next_resendq: |
cmp ecx, NUMRESENDENTRIES |
je .exit ; None found |
cmp dword[esi + 4], 0 |
je @f ; found one |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: push ebx |
; OK, we have a buffer descriptor ptr in esi. |
; resend entry # in ecx |
; Populate it |
; socket # |
; retries count |
; retry time |
; fill IP buffer associated with this descriptor |
stdcall net_socket_addr_to_num, [sockAddr] |
mov [esi + 4], eax |
mov byte[esi + 1], TCP_RETRIES |
mov word[esi + 2], TCP_TIMEOUT |
inc ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
mov edi, resendBuffer - IPBUFFSIZE |
@@: add edi, IPBUFFSIZE |
loop @b |
; we have dest buffer location in edi |
pop eax |
; convert source buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov esi, eax |
; do copy |
mov ecx, IPBUFFSIZE |
cld |
rep movsb |
.exit: |
xor eax, eax |
ret |
.error: |
or eax, -1 |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/tcp.inc |
---|
0,0 → 1,1169 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; TCP.INC ;; |
;; ;; |
;; TCP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; v0.6 : Added reset handling in the established state ;; |
;; Added a timer per socket to allow delays when ;; |
;; rx window gets below 1KB ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; TCP TCB states |
TCB_LISTEN equ 1 |
TCB_SYN_SENT equ 2 |
TCB_SYN_RECEIVED equ 3 |
TCB_ESTABLISHED equ 4 |
TCB_FIN_WAIT_1 equ 5 |
TCB_FIN_WAIT_2 equ 6 |
TCB_CLOSE_WAIT equ 7 |
TCB_CLOSING equ 8 |
TCB_LAST_ACK equ 9 |
TCB_TIMED_WAIT equ 10 |
TCB_CLOSED equ 11 |
TH_FIN = 0x01 |
TH_SYN = 0x02 |
TH_RST = 0x04 |
TH_PUSH = 0x08 |
TH_ACK = 0x10 |
TH_URG = 0x20 |
TWOMSL equ 10 ; # of secs to wait before closing socket |
TCP_RETRIES equ 5 ; Number of times to resend a packet |
TCP_TIMEOUT equ 20 ; resend if not replied to in x hs |
;******************************************************************* |
; Interface |
; |
; tcp_tx_handler Handles the TCP transmit queue |
; tcp_rx The protocol handler for received data |
; buildTCPPacket fills in the packet headers and data |
; tcpStateMachine Main state machine for received TCP packets |
; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state |
; |
;******************************************************************* |
; TCP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;20 | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;24 | Sequence Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;28 | Acknowledgment Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;32 | Data | |U|A|P|R|S|F| | |
; | Offset| Reserved |R|C|S|S|Y|I| Window | |
; | | |G|K|H|T|N|N| | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;36 | Checksum | Urgent Pointer | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;40 | Options | Padding | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | data |
struc TCP_PACKET |
{ .SourcePort dw ? ;+00 |
.DestinationPort dw ? ;+02 |
.SequenceNumber dd ? ;+04 |
.AckNumber dd ? ;+08 |
.DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7] |
.Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
.Window dw ? ;+14 |
.Checksum dw ? ;+16 |
.UrgentPointer dw ? ;+18 |
.Options rb 3 ;+20 |
.Padding db ? ;+23 |
.Data db ? ;+24 |
} |
virtual at 0 |
TCP_PACKET TCP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; tcp_tcb_handler |
; |
; Description |
; Handles sockets in the timewait state, closing them |
; when the TCB timer expires |
; |
;*************************************************************************** |
proc tcp_tcb_handler stdcall uses ebx |
; scan through all the sockets, decrementing active timers |
mov ebx, net_sockets |
cmp [ebx + SOCKET.NextPtr], 0 |
je .exit |
;DEBUGF 1, "K : sockets:\n" |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .exit |
;DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState] |
cmp [ebx + SOCKET.TCBTimer], 0 |
jne .decrement_tcb |
cmp [ebx + SOCKET.wndsizeTimer], 0 |
jne .decrement_wnd |
jmp .next_socket |
.decrement_tcb: |
; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
dec [ebx + SOCKET.TCBTimer] |
jnz .next_socket |
cmp [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
jne .next_socket |
push [ebx + SOCKET.PrevPtr] |
stdcall net_socket_free, ebx |
pop ebx |
jmp .next_socket |
.decrement_wnd: |
; TODO - prove it works! |
dec [ebx + SOCKET.wndsizeTimer] |
jmp .next_socket |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; tcp_tx_handler |
; |
; Description |
; Handles queued TCP data |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
proc tcp_tx_handler stdcall |
; decrement all resend buffers timers. If they |
; expire, queue them for sending, and restart the timer. |
; If the retries counter reach 0, delete the entry |
mov esi, resendQ |
mov ecx, 0 |
.next_resendq: |
cmp ecx, NUMRESENDENTRIES |
je .exit ; None left |
cmp dword[esi + 4], 0 |
jne @f ; found one |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: ; we have one. decrement it's timer by 1 |
dec word[esi + 2] |
jz @f |
inc ecx |
add esi, 8 |
jmp .next_resendq ; Timer not zero, so move on |
@@: |
xor ebx, ebx |
; restart timer, and decrement retries |
; After the first resend, back of on next, by a factor of 5 |
mov [esi + 2], word TCP_TIMEOUT * 5 |
dec byte[esi + 1] |
jnz @f |
; retries now 0, so delete from queue |
xchg [esi + 4], ebx |
@@: ; resend packet |
pushad |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
jne .tth004z |
; TODO - try again in 10ms. |
test ebx, ebx |
jnz @f |
mov [esi + 4], ebx |
@@: ; Mark it to expire in 10ms - 1 tick |
mov byte[esi + 1], 1 |
mov word[esi + 2], 1 |
jmp .tth005 |
.tth004z: |
; we have a buffer # in ax |
push eax ecx |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
; we have the buffer address in eax |
mov edi, eax |
pop ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
imul esi, ecx, IPBUFFSIZE |
add esi, resendBuffer |
; we have resend buffer location in esi |
mov ecx, IPBUFFSIZE |
; copy data across |
push edi |
cld |
rep movsb |
pop edi |
; queue packet |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
cmp edx, [edi + IP_PACKET.DestinationAddress] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
pop ebx |
call queue |
.tth005: |
popad |
inc ecx |
add esi, 8 |
jmp .next_resendq |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; tcp_rx |
; |
; Description |
; TCP protocol handler |
; This is a kernel function, called by ip_rx |
; IP buffer address given in edx |
; IP buffer number in eax |
; Free up (or re-use) IP buffer when finished |
; |
;*************************************************************************** |
proc tcp_rx stdcall uses ebx |
; The process is as follows. |
; Look for a socket with matching remote IP, remote port, local port |
; if not found, then |
; look for remote IP + local port match ( where sockets remote port = 0) |
; if not found, then |
; look for a socket where local socket port == IP packets remote port |
; where sockets remote port, remote IP = 0 |
; discard if not found |
; Call sockets tcbStateMachine, with pointer to packet. |
; the state machine will not delete the packet, so do that here. |
push eax |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; IP Packet SA = Remote IP |
; IP Packet TCP Source Port = remote Port |
mov ebx, net_sockets |
.next_socket.1: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .next_socket.1.exit |
; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr |
cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr |
jne .next_socket.1 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP] |
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr |
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP |
jne .next_socket.1 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4 |
mov ax, [edx + 20 + TCP_PACKET.SourcePort] ; get the source port from the TCP hdr |
cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port |
jne .next_socket.1 ; different - try next socket |
; We have a complete match - use this socket |
jmp .change_state |
.next_socket.1.exit: |
; If we got here, there was no match |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; IP Packet SA = Remote IP |
; socket remote Port = 0 |
mov ebx, net_sockets |
.next_socket.2: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .next_socket.2.exit |
; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr |
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port |
jne .next_socket.2 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP] |
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr |
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP |
jne .next_socket.2 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 |
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 |
jne .next_socket.2 ; different - try next socket |
; We have a complete match - use this socket |
jmp .change_state |
.next_socket.2.exit: |
; If we got here, there was no match |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; socket Remote IP = 0 |
; socket remote Port = 0 |
mov ebx, net_sockets |
.next_socket.3: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .next_socket.3.exit |
; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get destination port from the TCP hdr |
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port |
jne .next_socket.3 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP] |
cmp [ebx + SOCKET.RemoteIP], 0 ; only match a socket remote IP of 0 |
jne .next_socket.3 ; different - try next socket |
; DEBUGF 1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 |
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 |
jne .next_socket.3 ; different - try next socket |
; We have a complete match - use this socket |
jmp .change_state |
.next_socket.3.exit: |
; If we got here, we need to reject the packet |
DEBUGF 1, "K : tcp_rx - dumped\n" |
DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2 |
inc [dumped_rx_count] |
jmp .exit |
.change_state: |
; We have a valid socket/TCB, so call the TCB State Machine for that skt. |
; socket is pointed to by ebx |
; IP packet is pointed to by edx |
; IP buffer number is on stack ( it will be popped at the end) |
stdcall tcpStateMachine, ebx |
.exit: |
pop eax |
call freeBuff |
ret |
endp |
;*************************************************************************** |
; Function |
; buildTCPPacket |
; |
; Description |
; builds an IP Packet with TCP data fully populated for transmission |
; You may destroy any and all registers |
; TCP control flags specified in bl |
; This TCB is in [sktAddr] |
; User data pointed to by esi |
; Data length in ecx |
; Transmit buffer number in eax |
; |
;*************************************************************************** |
proc build_tcp_packet stdcall, sockAddr:DWORD |
push ecx ; Save data length |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
mov [edx + 20 + TCP_PACKET.Flags], bl ; TCP flags |
mov ebx, [sockAddr] |
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
; Fill in the IP header ( some data is in the socket descriptor) |
mov eax, [ebx + SOCKET.LocalIP] |
mov [edx + IP_PACKET.SourceAddress], eax |
mov eax, [ebx + SOCKET.RemoteIP] |
mov [edx + IP_PACKET.DestinationAddress], eax |
mov [edx + IP_PACKET.VersionAndIHL], 0x45 |
mov [edx + IP_PACKET.TypeOfService], 0 |
pop eax ; Get the TCP data length |
push eax |
add eax, 20 + 20 ; add IP header and TCP header lengths |
rol ax, 8 |
mov [edx + IP_PACKET.TotalLength], ax |
mov [edx + IP_PACKET.Identification], 0 |
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040 |
mov [edx + IP_PACKET.TimeToLive], 0x20 |
mov [edx + IP_PACKET.Protocol], PROTOCOL_TCP |
; Checksum left unfilled |
mov [edx + IP_PACKET.HeaderChecksum], 0 |
; Fill in the TCP header (some data is in the socket descriptor) |
mov ax, [ebx + SOCKET.LocalPort] |
mov [edx + 20 + TCP_PACKET.SourcePort], ax ; Local Port |
mov ax, [ebx + SOCKET.RemotePort] |
mov [edx + 20 + TCP_PACKET.DestinationPort], ax ; desitination Port |
; Checksum left unfilled |
mov [edx + 20 + TCP_PACKET.Checksum], 0 |
; sequence number |
mov eax, [ebx + SOCKET.SND_NXT] |
mov [edx + 20 + TCP_PACKET.SequenceNumber], eax |
; ack number |
mov eax, [ebx + SOCKET.RCV_NXT] |
mov [edx + 20 + TCP_PACKET.AckNumber], eax |
; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) |
; 768 bytes seems better |
mov [edx + 20 + TCP_PACKET.Window], 0x0003 |
; Urgent pointer (0) |
mov [edx + 20 + TCP_PACKET.UrgentPointer], 0 |
; data offset ( 0x50 ) |
mov [edx + 20 + TCP_PACKET.DataOffset], 0x50 |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
cmp ebx, 0 |
jz @f |
mov edi, edx |
add edi, 40 |
cld |
rep movsb ; copy the data across |
@@: ; we have edx as IPbuffer ptr. |
; Fill in the TCP checksum |
; First, fill in pseudoheader |
mov eax, [edx + IP_PACKET.SourceAddress] |
mov [pseudoHeader], eax |
mov eax, [edx + IP_PACKET.DestinationAddress] |
mov [pseudoHeader + 4], eax |
mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0 |
add ebx, 20 |
mov [pseudoHeader + 10], bh |
mov [pseudoHeader + 11], bl |
mov eax, pseudoHeader |
mov [checkAdd1], eax |
mov word[checkSize1], 12 |
mov eax, edx |
add eax, 20 |
mov [checkAdd2], eax |
mov eax, ebx |
mov [checkSize2], ax |
call checksum |
; store it in the TCP checksum ( in the correct order! ) |
mov ax, [checkResult] |
rol ax, 8 |
mov [edx + 20 + TCP_PACKET.Checksum], ax |
; Fill in the IP header checksum |
GET_IHL eax, edx ; get IP-Header length |
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size |
rol ax, 8 |
mov [edx + IP_PACKET.HeaderChecksum], ax |
ret |
endp |
; Increments the 32 bit value pointed to by esi in internet order |
proc inc_inet_esi stdcall |
push eax |
mov eax, [esi] |
bswap eax |
inc eax |
bswap eax |
mov [esi], eax |
pop eax |
ret |
endp |
; Increments the 32 bit value pointed to by esi in internet order |
; by the value in ecx |
proc add_inet_esi stdcall |
push eax |
mov eax, [esi] |
bswap eax |
add eax, ecx |
bswap eax |
mov [esi], eax |
pop eax |
ret |
endp |
iglobal |
TCBStateHandler dd \ |
stateTCB_LISTEN, \ |
stateTCB_SYN_SENT, \ |
stateTCB_SYN_RECEIVED, \ |
stateTCB_ESTABLISHED, \ |
stateTCB_FIN_WAIT_1, \ |
stateTCB_FIN_WAIT_2, \ |
stateTCB_CLOSE_WAIT, \ |
stateTCB_CLOSING, \ |
stateTCB_LAST_ACK, \ |
stateTCB_TIME_WAIT, \ |
stateTCB_CLOSED |
endg |
;*************************************************************************** |
; Function |
; tcpStateMachine |
; |
; Description |
; TCP state machine |
; This is a kernel function, called by tcp_rx |
; |
; IP buffer address given in edx |
; Socket/TCB address in ebx |
; |
; The IP buffer will be released by the caller |
;*************************************************************************** |
proc tcpStateMachine stdcall, sockAddr:DWORD |
; as a packet has been received, update the TCB timer |
mov [ebx + SOCKET.TCBTimer], TWOMSL |
; If the received packet has an ACK bit set, |
; remove any packets in the resend queue that this |
; received packet acknowledges |
pushad |
test [edx + 20 + TCP_PACKET.Flags], TH_ACK |
jz .call_handler ; No ACK, so no data yet |
; get skt number in eax |
stdcall net_socket_addr_to_num, ebx |
; The ack number is in [edx + 28], inet format |
; skt in eax |
mov esi, resendQ |
xor ecx, ecx |
.next_resendq: |
cmp ecx, NUMRESENDENTRIES |
je .call_handler ; None left |
cmp [esi + 4], eax |
je @f ; found one |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: ; Can we delete this buffer? |
; If yes, goto @@. No, goto .next_resendq |
; Get packet data address |
push ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
imul edi, ecx, IPBUFFSIZE |
add edi, resendBuffer |
; we have dest buffer location in edi. incoming packet in edx. |
; Get this packets sequence number |
; preserve al, ecx, esi, edx |
mov ecx, [edi + 20 + TCP_PACKET.SequenceNumber] |
bswap ecx |
movzx ebx, word[edi + 2] |
xchg bl, bh |
sub ebx, 40 |
add ecx, ebx ; ecx is now seq# of last byte +1, intel format |
; get recievd ack #, in intel format |
mov ebx, [edx + 20 + TCP_PACKET.AckNumber] |
bswap ebx |
cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que |
; DANGER! need to handle case that we have just |
; passed the 2**32, and wrapped round! |
pop ecx |
jae @f ; if rx > old, delete old |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: mov dword[esi + 4], 0 |
inc ecx |
add esi, 8 |
jmp .next_resendq |
.call_handler: |
popad |
; Call handler for given TCB state |
mov eax, [ebx + SOCKET.TCBState] |
cmp eax, TCB_LISTEN |
jb .exit |
cmp eax, TCB_CLOSED |
ja .exit |
stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr] |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; signal_network_event |
; |
; Description |
; Signals about network event to socket owner |
; This is a kernel function, called from TCP handler |
; |
; Socket/TCB address in ebx |
;*************************************************************************** |
proc signal_network_event |
push ecx esi eax |
mov eax, [ebx + SOCKET.PID] |
mov ecx, 1 |
mov esi, TASK_DATA + TASKDATA.pid |
.next_pid: |
cmp [esi], eax |
je .found_pid |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next_pid |
.found_pid: |
shl ecx, 8 |
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
pop eax esi ecx |
ret |
endp |
proc stateTCB_LISTEN stdcall, sockAddr:DWORD |
; In this case, we are expecting a SYN packet |
; For now, if the packet is a SYN, process it, and send a response |
; If not, ignore it |
; Look at control flags |
test [edx + 20 + TCP_PACKET.Flags], TH_SYN |
jz .exit |
; We have a SYN. update the socket with this IP packets details, |
; And send a response |
mov eax, [edx + IP_PACKET.SourceAddress] |
mov [ebx + SOCKET.RemoteIP], eax |
mov ax, [edx + 20 + TCP_PACKET.SourcePort] |
mov [ebx + SOCKET.RemotePort], ax |
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber] |
mov [ebx + SOCKET.IRS], eax |
mov [ebx + SOCKET.RCV_NXT], eax |
lea esi, [ebx + SOCKET.RCV_NXT] |
call inc_inet_esi ; RCV.NXT |
mov eax, [ebx + SOCKET.ISS] |
mov [ebx + SOCKET.SND_NXT], eax |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit |
push ebx |
push eax |
mov bl, TH_SYN + TH_ACK |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
pop ebx |
mov esi, [sockAddr] |
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED |
call signal_network_event |
; increment SND.NXT in socket |
add esi, SOCKET.SND_NXT |
call inc_inet_esi |
.exit: |
ret |
endp |
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD |
; We are awaiting an ACK to our SYN, with a SYM |
; Look at control flags - expecting an ACK |
mov al, [edx + 20 + TCP_PACKET.Flags] |
and al, TH_SYN + TH_ACK |
cmp al, TH_SYN + TH_ACK |
je .syn_ack |
test al, TH_SYN |
jz .exit |
mov [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED |
push TH_SYN + TH_ACK |
jmp .send |
.syn_ack: |
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED |
push TH_ACK |
.send: |
call signal_network_event |
; Store the recv.nxt field |
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber] |
; Update our recv.nxt field |
mov [ebx + SOCKET.RCV_NXT], eax |
lea esi, [ebx + SOCKET.RCV_NXT] |
call inc_inet_esi |
; Send an ACK |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
pop ebx |
je .exit |
push eax |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
.exit: |
ret |
endp |
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD |
; In this case, we are expecting an ACK packet |
; For now, if the packet is an ACK, process it, |
; If not, ignore it |
test [edx + 20 + TCP_PACKET.Flags], TH_RST |
jz .check_ack |
push [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP] |
pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort] |
mov [ebx + SOCKET.TCBState], TCB_LISTEN |
jmp .signal |
.check_ack: |
; Look at control flags - expecting an ACK |
test [edx + 20 + TCP_PACKET.Flags], TH_ACK |
jz .exit |
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED |
.signal: |
call signal_network_event |
.exit: |
ret |
endp |
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD |
; Here we are expecting data, or a request to close |
; OR both... |
; Ignore all packets with sequnce number other than next expected |
; recv.nxt is in dword [edx+24], in inet format |
; recv seq is in [sktAddr]+56, in inet format |
; just do a comparision |
mov eax, [ebx + SOCKET.RCV_NXT] |
cmp eax, [edx + 20 + TCP_PACKET.SequenceNumber] |
jne .exit |
; Did we receive a FIN or RST? |
test [edx + 20 + TCP_PACKET.Flags], TH_FIN+TH_RST |
jz .check_ack |
; It was a fin or reset. |
; Remove resend entries from the queue - I dont want to send any more data |
pushad |
; get skt # |
stdcall net_socket_addr_to_num, ebx |
mov esi, resendQ |
mov ecx, 0 |
.next_resendq: |
cmp ecx, NUMRESENDENTRIES |
je .last_resendq ; None left |
cmp [esi + 4], eax |
je @f ; found one |
inc ecx |
add esi, 8 |
jmp .next_resendq |
@@: mov dword[esi + 4], 0 |
inc ecx |
add esi, 8 |
jmp .next_resendq |
.last_resendq: |
popad |
@@: ; Send an ACK to that fin, and enter closewait state |
mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT |
test [edx + 20 + TCP_PACKET.Flags], TH_RST |
je @f |
mov [ebx + SOCKET.TCBState], TCB_CLOSED |
@@: |
call signal_network_event |
lea esi, [ebx + SOCKET.RCV_NXT] |
mov eax, [esi] ; save original |
call inc_inet_esi |
;; jmp ste_ack - NO, there may be data |
.check_ack: |
; Check that we received an ACK |
test [edx + 20 + TCP_PACKET.Flags], TH_ACK |
jz .exit |
; TODO - done, I think! |
; First, look at the incoming window. If this is less than or equal to 1024, |
; Set the socket window timer to 1. This will stop an additional packets being queued. |
; ** I may need to tweak this value, since I do not know how many packets are already queued |
mov cx, [edx + 20 + TCP_PACKET.Window] |
xchg cl, ch |
cmp cx, 1024 |
ja @f |
mov [ebx + SOCKET.wndsizeTimer], 1 |
@@: ; OK, here is the deal |
; Read the data bytes, store in socket buffer |
movzx ecx, [edx + IP_PACKET.TotalLength] |
xchg cl, ch |
sub ecx, 40 ; Discard 40 bytes of header |
ja .data ; Read data, if any |
; If we had received a fin, we need to ACK it. |
cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT |
je .ack |
jmp .exit |
.data: |
push ebx |
add ebx, SOCKET.lock |
call wait_mutex |
pop ebx |
push ecx |
push ebx |
mov eax, [ebx + SOCKET.rxDataCount] |
add eax, ecx |
cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE |
ja .overflow |
mov [ebx + SOCKET.rxDataCount], eax ; increment the count of bytes in buffer |
; point to the location to store the data |
lea edi, [ebx + eax + SOCKETHEADERSIZE] |
sub edi, ecx |
add edx, 40 ; edx now points to the data |
mov esi, edx |
cld |
rep movsb ; copy the data across |
mov [ebx + SOCKET.lock], 0 ; release mutex |
; flag an event to the application |
pop ebx |
call signal_network_event |
pop ecx |
; Update our recv.nxt field |
lea esi, [ebx + SOCKET.RCV_NXT] |
call add_inet_esi |
.ack: |
; Send an ACK |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit |
push eax |
mov bl, TH_ACK |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
.exit: |
ret |
.overflow: |
; no place in buffer |
; so simply restore stack and exit |
pop eax ecx |
mov [ebx + SOCKET.lock], 0 |
ret |
endp |
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD |
; We can either receive an ACK of a fin, or a fin |
mov al, [edx + 20 + TCP_PACKET.Flags] |
and al, TH_FIN + TH_ACK |
cmp al, TH_ACK |
jne @f |
; It was an ACK |
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2 |
jmp .exit |
@@: mov [ebx + SOCKET.TCBState], TCB_CLOSING |
cmp al, TH_FIN |
je @f |
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
@@: lea esi, [ebx + SOCKET.RCV_NXT] |
call inc_inet_esi |
; Send an ACK |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit |
push eax |
mov bl, TH_ACK |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
.exit: |
ret |
endp |
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD |
test [edx + 20 + TCP_PACKET.Flags], TH_FIN |
jz .exit |
; Change state, as we have a fin |
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
lea esi, [ebx + SOCKET.RCV_NXT] |
call inc_inet_esi |
; Send an ACK |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit |
push eax |
mov bl, TH_ACK |
xor ecx, ecx |
xor esi, esi |
stdcall build_tcp_packet, [sockAddr] |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [sockAddr] |
cmp edx, [ecx + SOCKET.RemoteIP] |
jne .not_local |
mov eax, IPIN_QUEUE |
.not_local: |
; Send it. |
pop ebx |
call queue |
.exit: |
ret |
endp |
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD |
; Intentionally left empty |
; socket_close_tcp handles this |
ret |
endp |
proc stateTCB_CLOSING stdcall, sockAddr:DWORD |
; We can either receive an ACK of a fin, or a fin |
test [edx + 20 + TCP_PACKET.Flags], TH_ACK |
jz .exit |
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
.exit: |
ret |
endp |
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD |
; Look at control flags - expecting an ACK |
test [edx + 20 + TCP_PACKET.Flags], TH_ACK |
jz .exit |
; delete the socket |
stdcall net_socket_free, ebx |
.exit: |
ret |
endp |
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD |
ret |
endp |
proc stateTCB_CLOSED stdcall, sockAddr:DWORD |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/stack.inc |
---|
0,0 → 1,1024 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; STACK.INC ;; |
;; ;; |
;; TCP/IP stack for Menuet OS ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; Version 0.7 ;; |
;; Added a timer per socket to allow delays when rx window ;; |
;; gets below 1KB ;; |
;; ;; |
;;10.01.2007 Bugfix for checksum function from Paolo Franchetti ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************* |
; Interface |
; The interfaces defined in ETHERNET.INC plus: |
; stack_init |
; stack_handler |
; app_stack_handler |
; app_socket_handler |
; checksum |
; |
;******************************************************************* |
uglobal |
StackCounters: |
dumped_rx_count dd 0 |
arp_tx_count: dd 0 |
arp_rx_count: dd 0 |
ip_rx_count: dd 0 |
ip_tx_count: dd 0 |
endg |
; socket buffers |
SOCKETBUFFSIZE equ 4096 ; state + config + buffer. |
SOCKETHEADERSIZE equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data |
;NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 |
; IPBUFF status values |
BUFF_EMPTY equ 0 |
BUFF_RX_FULL equ 1 |
BUFF_ALLOCATED equ 2 |
BUFF_TX_FULL equ 3 |
NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX |
NUMQUEUES equ 4 |
EMPTY_QUEUE equ 0 |
IPIN_QUEUE equ 1 |
IPOUT_QUEUE equ 2 |
NET1OUT_QUEUE equ 3 |
NO_BUFFER equ 0xFFFF |
IPBUFFSIZE equ 1500 ; MTU of an ethernet packet |
NUMQUEUEENTRIES equ NUM_IPBUFFERS |
NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets |
; These are the 0x40 function codes for application access to the stack |
STACK_DRIVER_STATUS equ 52 |
SOCKET_INTERFACE equ 53 |
; 128KB allocated for the stack and network driver buffers and other |
; data requirements |
;stack_data_start equ 0x700000 |
;eth_data_start equ 0x700000 |
;stack_data equ 0x704000 |
;stack_data_end equ 0x71ffff |
; 32 bit word |
stack_config equ stack_data |
; 32 bit word - IP Address in network format |
stack_ip equ stack_data + 4 |
; 1 byte. 0 == inactive, 1 = active |
ethernet_active equ stack_data + 9 |
; TODO :: empty memory area |
; Address of selected socket |
;sktAddr equ stack_data + 32 |
; Parameter to checksum routine - data ptr |
checkAdd1 equ stack_data + 36 |
; Parameter to checksum routine - 2nd data ptr |
checkAdd2 equ stack_data + 40 |
; Parameter to checksum routine - data size |
checkSize1 equ stack_data + 44 |
; Parameter to checksum routine - 2nd data size |
checkSize2 equ stack_data + 46 |
; result of checksum routine |
checkResult equ stack_data + 48 |
; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| |
pseudoHeader equ stack_data + 50 |
; receive and transmit IP buffer allocation |
;sockets equ stack_data + 62 |
Next_free2 equ stack_data + 62;Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) |
; 1560 byte buffer for rx / tx ethernet packets |
Ether_buffer equ Next_free2 |
Next_free3 equ Ether_buffer + 1518 |
last_1sTick equ Next_free3 |
IPbuffs equ Next_free3 + 1 |
queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) |
queueList equ queues + (2 * NUMQUEUES) |
last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) |
;resendQ equ 0x770000 |
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP ; XTODO: validate size |
resendBuffer equ resendQ + ( 8 * NUMRESENDENTRIES ) ; for TCP |
uglobal |
net_sockets rd 2 |
endg |
; simple macro for memory set operation |
macro _memset_dw adr,value,amount |
{ |
mov edi, adr |
mov ecx, amount |
if value = 0 |
xor eax, eax |
else |
mov eax, value |
end if |
cld |
rep stosd |
} |
; Below, the main network layer source code is included |
; |
include "queue.inc" |
include "eth_drv/ethernet.inc" |
include "ip.inc" |
include "socket.inc" |
;*************************************************************************** |
; Function |
; stack_init |
; |
; Description |
; Clear all allocated memory to zero. This ensures that |
; on startup, the stack is inactive, and consumes no resources |
; This is a kernel function, called prior to the OS main loop |
; in set_variables |
; |
;*************************************************************************** |
stack_init: |
; Init two address spaces with default values |
_memset_dw stack_data_start, 0, 0x20000/4 |
_memset_dw resendQ, 0, NUMRESENDENTRIES * 2 |
mov [net_sockets], 0 |
mov [net_sockets + 4], 0 |
; Queries initialization |
call queueInit |
; The following block sets up the 1s timer |
mov al, 0x0 |
out 0x70, al |
in al, 0x71 |
mov [last_1sTick], al |
ret |
;*************************************************************************** |
; Function |
; stack_handler |
; |
; Description |
; The kernel loop routine for the stack |
; This is a kernel function, called in the main loop |
; |
;*************************************************************************** |
align 4 |
stack_handler: |
call ethernet_driver |
call ip_rx |
; Test for 10ms tick, call tcp timer |
mov eax, [timer_ticks] ;[0xfdf0] |
cmp eax, [last_1hsTick] |
je sh_001 |
mov [last_1hsTick], eax |
call tcp_tx_handler |
sh_001: |
; Test for 1 second event, call 1s timer functions |
mov al, 0x0 ;second |
out 0x70, al |
in al, 0x71 |
cmp al, [last_1sTick] |
je sh_exit |
mov [last_1sTick], al |
stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0 |
call tcp_tcb_handler |
sh_exit: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Checksum [by Johnny_B] |
;; IN: |
;; buf_ptr=POINTER to buffer |
;; buf_size=SIZE of buffer |
;; OUT: |
;; AX=16-bit checksum |
;; Saves all used registers |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc checksum_jb stdcall uses ebx esi ecx,\ |
buf_ptr:DWORD, buf_size:DWORD |
xor eax, eax |
xor ebx, ebx ;accumulator |
mov esi, dword[buf_ptr] |
mov ecx, dword[buf_size] |
shr ecx, 1 ; ecx=ecx/2 |
jnc @f ; if CF==0 then size is even number |
mov bh, byte[esi + ecx*2] |
@@: |
cld |
.loop: |
lodsw ;eax=word[esi],esi=esi+2 |
xchg ah,al ;cause must be a net byte-order |
add ebx, eax |
loop .loop |
mov eax, ebx |
shr eax, 16 |
add ax, bx |
not ax |
ret |
endp |
;*************************************************************************** |
; Function |
; checksum |
; |
; Description |
; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult |
; Dont break anything; Most registers are used by the caller |
; This code is derived from the 'C' source, cksum.c, in the book |
; Internetworking with TCP/IP Volume II by D.E. Comer |
; |
;*************************************************************************** |
checksum: |
pusha |
mov eax, [checkAdd1] |
xor edx, edx ; edx is the accumulative checksum |
xor ebx, ebx |
mov cx, [checkSize1] |
shr cx, 1 |
jz cs1_1 |
cs1: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs1 |
cs1_1: |
and word [checkSize1], 0x01 |
jz cs_test2 |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_test2: |
mov cx, [checkSize2] |
cmp cx, 0 |
jz cs_exit ; Finished if no 2nd buffer |
mov eax, [checkAdd2] |
shr cx, 1 |
jz cs2_1 |
cs2: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs2 |
cs2_1: |
and word [checkSize2], 0x01 |
jz cs_exit |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_exit: |
mov ebx, edx |
shr ebx, 16 |
and edx, 0xffff |
add edx, ebx |
mov eax, edx |
shr eax, 16 |
add edx, eax |
not dx |
mov [checkResult], dx |
popa |
ret |
;*************************************************************************** |
; Function |
; app_stack_handler |
; |
; Description |
; This is an application service, called by int 0x40, function 52 |
; It provides application access to the network interface layer |
; |
;*************************************************************************** |
app_stack_handler: |
cmp eax, 0 |
jnz not0 |
; Read the configuration word |
mov eax, [stack_config] |
ret |
not0: |
cmp eax, 1 |
jnz not1 |
; read the IP address |
mov eax, [stack_ip] |
ret |
not1: |
cmp eax, 2 |
jnz not2 |
; write the configuration word |
mov [stack_config], ebx |
; <Slip shouldn't be active anyway - thats an operational issue.> |
; If ethernet now enabled, probe for the card, reset it and empty |
; the packet buffer |
; If all successfull, enable the card. |
; If ethernet now disabled, set it as disabled. Should really |
; empty the tcpip data area too. |
; ethernet interface is '3' in ls 7 bits |
and bl, 0x7f |
cmp bl, 3 |
je ash_eth_enable |
; Ethernet isn't enabled, so make sure that the card is disabled |
mov [ethernet_active], byte 0 |
ret |
ash_eth_enable: |
; Probe for the card. This will reset it and enable the interface |
; if found |
call eth_probe |
cmp eax, 0 |
je ash_eth_done ; Abort if no hardware found |
mov [ethernet_active], byte 1 |
ash_eth_done: |
ret |
not2: |
cmp eax, 3 |
jnz not3 |
; write the IP Address |
mov [stack_ip], ebx |
ret |
;old functions was deleted |
not3: |
cmp eax, 6 |
jnz not6 |
; Insert an IP packet into the stacks received packet queue |
call stack_insert_packet |
ret |
not6: |
cmp eax, 7 |
jnz not7 |
; Test for any packets queued for transmission over the network |
not7: |
cmp eax, 8 |
jnz not8 |
call stack_get_packet |
; Extract a packet queued for transmission by the network |
ret |
not8: |
cmp eax, 9 |
jnz not9 |
; read the gateway IP address |
mov eax, [gateway_ip] |
ret |
not9: |
cmp eax, 10 |
jnz not10 |
; read the subnet mask |
mov eax, [subnet_mask] |
ret |
not10: |
cmp eax, 11 |
jnz not11 |
; write the gateway IP Address |
mov [gateway_ip], ebx |
ret |
not11: |
cmp eax, 12 |
jnz not12 |
; write the subnet mask |
mov [subnet_mask], ebx |
not12: |
cmp eax, 13 |
jnz not13 |
; read the dns |
mov eax, [dns_ip] |
ret |
not13: |
cmp eax, 14 |
jnz not14 |
; write the dns IP Address |
mov [dns_ip], ebx |
ret |
;<added by Frank Sommer> |
not14: |
cmp eax, 15 |
jnz not15 |
; in ebx we need 4 to read the last 2 bytes |
cmp ebx, dword 4 |
je read |
; or we need 0 to read the first 4 bytes |
cmp ebx, dword 0 |
jnz param_error |
; read MAC, returned (in mirrored byte order) in eax |
read: |
mov eax, [node_addr + ebx] |
jmp @f |
param_error: |
mov eax, -1 ; params not accepted |
@@: |
ret |
; 0 -> arp_probe |
; 1 -> arp_announce |
; 2 -> arp_responce (not supported yet) |
not15: ; ARP stuff |
cmp eax, 16 |
jnz not16 |
cmp ebx, 0 |
je a_probe |
cmp ebx, 1 |
je a_ann ; arp announce |
; cmp ebx,2 |
; jne a_resp ; arp response |
jmp param15_error |
; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed |
; ecx: pointer to target MAC, MAC should set to 0 by application |
; edx: target IP |
a_probe: |
push dword [stack_ip] |
mov edx, [stack_ip] |
mov [stack_ip], dword 0 |
mov esi, ecx ; pointer to target MAC address |
call arp_request |
pop dword [stack_ip] |
jmp @f |
; arp announce, sender IP must be set to target IP |
; ecx: pointer to target MAC |
a_ann: |
mov edx, [stack_ip] |
mov esi, ecx ; pointer to target MAC address |
call arp_request |
jmp @f |
param15_error: |
mov eax, -1 |
@@: |
ret |
;</added by Frank Sommer> |
; modified by [smb] |
;<added by Johnny_B> |
; ARPTable manager interface |
not16: |
cmp eax, 17 |
jnz stack_driver_end |
;see "proc arp_table_manager" for more details |
stdcall arp_table_manager,ebx,ecx,edx ;Opcode,Index,Extra |
ret |
;</added by Johnny_B> |
stack_driver_end: |
ret |
;*************************************************************************** |
; Function |
; app_socket_handler |
; |
; Description |
; This is an application service, called by int 0x40, function 53 |
; It provides application access to stack socket services |
; such as opening sockets |
; |
;*************************************************************************** |
app_socket_handler: |
cmp eax, 0 |
jnz nots0 |
call socket_open |
ret |
nots0: |
cmp eax, 1 |
jnz nots1 |
call socket_close |
ret |
nots1: |
cmp eax, 2 |
jnz nots2 |
call socket_poll |
ret |
nots2: |
cmp eax, 3 |
jnz nots3 |
call socket_read |
ret |
nots3: |
cmp eax, 4 |
jnz nots4 |
call socket_write |
ret |
nots4: |
cmp eax, 5 |
jnz nots5 |
call socket_open_tcp |
ret |
nots5: |
cmp eax, 6 |
jnz nots6 |
call socket_status |
ret |
nots6: |
cmp eax, 7 |
jnz nots7 |
call socket_write_tcp |
ret |
nots7: |
cmp eax, 8 |
jnz nots8 |
call socket_close_tcp |
ret |
nots8: |
cmp eax, 9 |
jnz nots9 |
call is_localport_unused |
ret |
nots9: |
cmp eax, 10 |
jnz nots10 |
mov eax,dword[drvr_cable] |
test eax,eax |
jnz @f ; if function is not implented, return -1 |
mov al,-1 |
ret |
@@: |
call dword[drvr_cable] |
ret |
nots10: |
cmp eax, 11 |
jnz nots11 |
call socket_read_packet |
ret |
nots11: |
cmp eax, 254 |
jnz notdump |
ret |
notdump: |
cmp eax, 255 |
jnz notsdebug |
; This sub function allows access to debugging information on the stack |
; ebx holds the request: |
; 100 : return length of empty queue |
; 101 : return length of IPOUT QUEUE |
; 102 : return length of IPIN QUEUE |
; 103 : return length of NET1OUT QUEUE |
; 200 : return # of ARP entries |
; 201 : return size of ARP table ( max # entries ) |
; 202 : select ARP table entry # |
; 203 : return IP of selected table entry |
; 204 : return High 4 bytes of MAC address of selected table entry |
; 205 : return low 2 bytes of MAC address of selected table entry |
; 206 : return status word of selected table entry |
; 207 : return Time to live of selected table entry |
; 2 : return number of IP packets received |
; 3 : return number of packets transmitted |
; 4 : return number of received packets dumped |
; 5 : return number of arp packets received |
; 6 : return status of packet driver |
; ( 0 == not active, FFFFFFFF = successful ) |
call stack_internal_status |
ret |
notsdebug: |
; Invalid Option |
ret |
uglobal |
ARPTmp: |
times 14 db 0 |
endg |
;*************************************************************************** |
; Function |
; stack_internal_status |
; |
; Description |
; Returns information about the internal status of the stack |
; This is only useful for debugging |
; It works with the ethernet driver |
; sub function in ebx |
; return requested data in eax |
; |
;*************************************************************************** |
stack_internal_status: |
cmp ebx, 100 |
jnz notsis100 |
; 100 : return length of EMPTY QUEUE |
mov ebx, EMPTY_QUEUE |
call queueSize |
ret |
notsis100: |
cmp ebx, 101 |
jnz notsis101 |
; 101 : return length of IPOUT QUEUE |
mov ebx, IPOUT_QUEUE |
call queueSize |
ret |
notsis101: |
cmp ebx, 102 |
jnz notsis102 |
; 102 : return length of IPIN QUEUE |
mov ebx, IPIN_QUEUE |
call queueSize |
ret |
notsis102: |
cmp ebx, 103 |
jnz notsis103 |
; 103 : return length of NET1OUT QUEUE |
mov ebx, NET1OUT_QUEUE |
call queueSize |
ret |
notsis103: |
cmp ebx, 200 |
jnz notsis200 |
; 200 : return num entries in arp table |
movzx eax, byte [NumARP] |
ret |
notsis200: |
cmp ebx, 201 |
jnz notsis201 |
; 201 : return arp table size |
mov eax, 20 ; ARP_TABLE_SIZE |
ret |
notsis201: |
cmp ebx, 202 |
jnz notsis202 |
; 202 - read the requested table entry |
; into a temporary buffer |
; ecx holds the entry number |
mov eax, ecx |
mov ecx, 14 ; ARP_ENTRY_SIZE |
mul ecx |
mov ecx, [eax + ARPTable] |
mov [ARPTmp], ecx |
mov ecx, [eax + ARPTable+4] |
mov [ARPTmp+4], ecx |
mov ecx, [eax + ARPTable+8] |
mov [ARPTmp+8], ecx |
mov cx, [eax + ARPTable+12] |
mov [ARPTmp+12], cx |
ret |
notsis202: |
cmp ebx, 203 |
jnz notsis203 |
; 203 - return IP address |
mov eax, [ARPTmp] |
ret |
notsis203: |
cmp ebx, 204 |
jnz notsis204 |
; 204 - return MAC high dword |
mov eax, [ARPTmp+4] |
ret |
notsis204: |
cmp ebx, 205 |
jnz notsis205 |
; 205 - return MAC ls word |
movzx eax, word [ARPTmp+8] |
ret |
notsis205: |
cmp ebx, 206 |
jnz notsis206 |
; 206 - return status word |
movzx eax, word [ARPTmp+10] |
ret |
notsis206: |
cmp ebx, 207 |
jnz notsis207 |
; 207 - return ttl word |
movzx eax, word [ARPTmp+12] |
ret |
notsis207: |
cmp ebx, 2 |
jnz notsis2 |
; 2 : return number of IP packets received |
mov eax, [ip_rx_count] |
ret |
notsis2: |
cmp ebx, 3 |
jnz notsis3 |
; 3 : return number of packets transmitted |
mov eax, [ip_tx_count] |
ret |
notsis3: |
cmp ebx, 4 |
jnz notsis4 |
; 4 : return number of received packets dumped |
mov eax, [dumped_rx_count] |
ret |
notsis4: |
cmp ebx, 5 |
jnz notsis5 |
; 5 : return number of arp packets received |
mov eax, [arp_rx_count] |
ret |
notsis5: |
cmp ebx, 6 |
jnz notsis6 |
; 6 : return status of packet driver |
; ( 0 == not active, FFFFFFFF = successful ) |
mov eax, [eth_status] |
ret |
notsis6: |
xor eax, eax |
ret |
;*************************************************************************** |
; Function |
; stack_get_packet |
; |
; Description |
; extracts an IP packet from the NET1 output queue |
; and sends the data to the calling process |
; pointer to data in edx |
; returns number of bytes read in eax |
; |
;*************************************************************************** |
stack_get_packet: |
; Look for a buffer to tx |
mov eax, NET1OUT_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sgp_non_exit ; Exit if no buffer available |
push eax ; Save buffer number for freeing at end |
push edx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
pop edx |
push eax ; save address of IP data |
; Get the address of the callers data |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add edx,[edi] |
mov edi, edx |
pop eax |
mov ecx, 1500 ; should get the actual number of bytes to write |
mov esi, eax |
cld |
rep movsb ; copy the data across |
; And finally, return the buffer to the free queue |
pop eax |
call freeBuff |
mov eax, 1500 |
ret |
sgp_non_exit: |
xor eax, eax |
ret |
;*************************************************************************** |
; Function |
; stack_insert_packet |
; |
; Description |
; writes an IP packet into the stacks receive queue |
; # of bytes to write in ecx |
; pointer to data in edx |
; returns 0 in eax ok, -1 == failed |
; |
;*************************************************************************** |
stack_insert_packet: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sip_err_exit |
push eax |
; save the pointers to the data buffer & size |
push edx |
push ecx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
; So, edx holds the IPbuffer ptr |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
pop eax ; get callers ptr to data to send |
; Get the address of the callers data |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
mov esi, eax |
mov edi, edx |
cld |
rep movsb ; copy the data across |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
inc dword [ip_rx_count] |
mov eax, 0 |
ret |
sip_err_exit: |
mov eax, 0xFFFFFFFF |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/queue.inc |
---|
0,0 → 1,229 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; QUEUE.INC ;; |
;; ;; |
;; Buffer queue management for Menuet OS TCP/IP Stack ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************* |
; Interface |
; |
; queueInit Configures the queues to empty |
; dequeue Removes a buffer pointer from a queue |
; queue Inserts a buffer pointer into a queue |
; freeBuff Adds the buffer pointer to the list of free buffers |
; queueSize Returns the number of entries in a queue |
; |
; The various defines for queue names can be found in stack.inc |
; |
;******************************************************************* |
;*************************************************************************** |
; Function |
; freeBuff |
; |
; Description |
; Adds a buffer number to the beginning of the free list. |
; buffer number in eax ( ms word zeroed ) |
; all other registers preserved |
; This always works, so no error returned |
;*************************************************************************** |
;uglobal |
; freeBuff_cnt dd ? |
;endg |
freeBuff: |
; inc [freeBuff_cnt] |
; DEBUGF 1, "K : freeBuff (%u)\n", [freeBuff_cnt] |
push ebx |
push ecx |
mov ebx, queues + EMPTY_QUEUE * 2 |
cli ; Ensure that another process does not interfer |
mov cx, [ebx] |
mov [ebx], ax |
mov [queueList + eax * 2], cx |
sti |
pop ecx |
pop ebx |
ret |
;*************************************************************************** |
; Function |
; queueSize |
; |
; Description |
; Counts the number of entries in a queue |
; queue number in ebx ( ms word zeroed ) |
; Queue size returned in eax |
; This always works, so no error returned |
;*************************************************************************** |
queueSize: |
xor eax, eax |
shl ebx, 1 |
add ebx, queues |
movzx ecx, word [ebx] |
cmp cx, NO_BUFFER |
je qs_exit |
qs_001: |
inc eax |
shl ecx, 1 |
add ecx, queueList |
movzx ecx, word [ecx] |
cmp cx, NO_BUFFER |
je qs_exit |
jmp qs_001 |
qs_exit: |
ret |
;*************************************************************************** |
; Function |
; queue |
; |
; Description |
; Adds a buffer number to the *end* of a queue |
; This is quite quick because these queues will be short |
; queue number in eax ( ms word zeroed ) |
; buffer number in ebx ( ms word zeroed ) |
; all other registers preserved |
; This always works, so no error returned |
;*************************************************************************** |
;uglobal |
; queue_cnt dd ? |
;endg |
queue: |
; inc [queue_cnt] |
; DEBUGF 1, "K : queue (%u)\n", [queue_cnt] |
push ebx |
shl ebx, 1 |
add ebx, queueList ; eax now holds address of queue entry |
mov [ebx], word NO_BUFFER ; This buffer will be the last |
cli |
shl eax, 1 |
add eax, queues ; eax now holds address of queue |
movzx ebx, word [eax] |
cmp bx, NO_BUFFER |
jne qu_001 |
pop ebx |
; The list is empty, so add this to the head |
mov [eax], bx |
jmp qu_exit |
qu_001: |
; Find the last entry |
shl ebx, 1 |
add ebx, queueList |
mov eax, ebx |
movzx ebx, word [ebx] |
cmp bx, NO_BUFFER |
jne qu_001 |
mov ebx, eax |
pop eax |
mov [ebx], ax |
qu_exit: |
sti |
ret |
;*************************************************************************** |
; Function |
; dequeue |
; |
; Description |
; removes a buffer number from the head of a queue |
; This is fast, as it unlinks the first entry in the list |
; queue number in eax ( ms word zeroed ) |
; buffer number returned in eax ( ms word zeroed ) |
; all other registers preserved |
; |
;*************************************************************************** |
;uglobal |
; dequeue_cnt dd ? |
;endg |
dequeue: |
push ebx |
shl eax, 1 |
add eax, queues ; eax now holds address of queue |
mov ebx, eax |
cli |
movzx eax, word [eax] |
cmp ax, NO_BUFFER |
je dq_exit |
; inc [dequeue_cnt] |
; DEBUGF 1, "K : dequeue (%u)\n", [dequeue_cnt] |
push eax |
shl eax, 1 |
add eax, queueList ; eax now holds address of queue entry |
mov ax, [eax] |
mov [ebx], ax |
pop eax |
dq_exit: |
sti |
pop ebx |
ret |
;*************************************************************************** |
; Function |
; queueInit |
; |
; Description |
; Initialises the queues to empty, and creates the free queue |
; list. |
; |
;*************************************************************************** |
queueInit: |
mov esi, queues |
mov ecx, NUMQUEUES |
mov ax, NO_BUFFER |
qi001: |
mov [esi], ax |
inc esi |
inc esi |
loop qi001 |
mov esi, queues + ( 2 * EMPTY_QUEUE ) |
; Initialise empty queue list |
xor ax, ax |
mov [esi], ax |
mov ecx, NUMQUEUEENTRIES - 1 |
mov esi, queueList |
qi002: |
inc ax |
mov [esi], ax |
inc esi |
inc esi |
loop qi002 |
mov ax, NO_BUFFER |
mov [esi], ax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/udp.inc |
---|
0,0 → 1,155 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; UDP.INC ;; |
;; ;; |
;; UDP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;******************************************************************* |
; Interface |
; |
; udp_rx Handles received IP packets with the UDP protocol |
; |
;******************************************************************* |
; |
; UDP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Length ( UDP Header + Data ) | Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | UDP Data | |
; +-+-+-.......... -+ |
; |
struc UDP_PACKET |
{ .SourcePort dw ? ;+00 |
.DestinationPort dw ? ;+02 |
.Length dw ? ;+04 - Length of (UDP Header + Data) |
.Checksum dw ? ;+06 |
.Data db ? ;+08 |
} |
virtual at 0 |
UDP_PACKET UDP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; udp_rx [by Johnny_B] |
; |
; Description |
; UDP protocol handler |
; This is a kernel function, called by ip_rx |
; IP buffer address given in edx |
; IP buffer number in eax |
; Free up (or re-use) IP buffer when finished |
; |
;*************************************************************************** |
proc udp_rx stdcall |
push eax |
; First validate the header & checksum. Discard buffer if error |
; Look for a socket where |
; IP Packet UDP Destination Port = local Port |
; IP Packet SA = Remote IP |
mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from |
; the IP packet's UDP header |
mov ebx, net_sockets |
.next_socket: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .exit ; No match, so exit |
cmp [ebx + SOCKET.LocalPort], ax ; ax will hold the 'wrong' value, |
; but the comparision is correct |
jne .next_socket ; Return back if no match |
; For dhcp, we must allow any remote server to respond. |
; I will accept the first incoming response to be the one |
; I bind to, if the socket is opened with a destination IP address of |
; 255.255.255.255 |
cmp [ebx + SOCKET.RemoteIP], 0xffffffff |
je @f |
mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet |
cmp [ebx + SOCKET.RemoteIP], eax |
jne .exit ; Quit if the source IP is not valid |
@@: ; OK - we have a valid UDP packet for this socket. |
; First, update the sockets remote port number with the incoming msg |
; - it will have changed |
; from the original ( 69 normally ) to allow further connects |
mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port |
; ( was 69, now new ) |
mov [ebx + SOCKET.RemotePort], ax |
; Now, copy data to socket. We have socket address as [eax + sockets]. |
; We have IP packet in edx |
; get # of bytes in ecx |
movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract |
xchg cl, ch ; 20 + 8 gives data length |
sub ecx, 28 |
mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer |
add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer |
; ecx has count, edx points to data |
add edx, 28 ; edx now points to the data |
lea edi, [ebx + eax + SOCKETHEADERSIZE] |
mov esi, edx |
cld |
rep movsb ; copy the data across |
; flag an event to the application |
mov eax, [ebx + SOCKET.PID] ; get socket owner PID |
mov ecx, 1 |
mov esi, TASK_DATA + TASKDATA.pid |
.next_pid: |
cmp [esi], eax |
je .found_pid |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next_pid |
jmp .exit |
.found_pid: |
shl ecx, 8 |
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
mov [check_idle_semaphore], 200 |
.exit: |
pop eax |
call freeBuff ; Discard the packet |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/ip.inc |
---|
0,0 → 1,244 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; IP.INC ;; |
;; ;; |
;; IP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Version 0.3 29 August 2002 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; IP underlying protocols numbers |
PROTOCOL_ICMP equ 1 |
PROTOCOL_TCP equ 6 |
PROTOCOL_UDP equ 17 |
struc IP_PACKET |
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits] |
.TypeOfService db ? ;+01 |
.TotalLength dw ? ;+02 |
.Identification dw ? ;+04 |
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15] |
.TimeToLive db ? ;+08 |
.Protocol db ? ;+09 |
.HeaderChecksum dw ? ;+10 |
.SourceAddress dd ? ;+12 |
.DestinationAddress dd ? ;+16 |
.DataOrOptional dd ? ;+20 |
} |
virtual at 0 |
IP_PACKET IP_PACKET |
end virtual |
;******************************************************************* |
; Interface |
; |
; ip_rx processes all packets received by the network layer |
; It calls the appropriate protocol handler |
; |
; |
; |
;******************************************************************* |
; |
; IP Packet after reception - Normal IP packet format |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;0 |Version| IHL |Type of Service| Total Length | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;4 | Identification |Flags| Fragment Offset | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;8 | Time to Live | Protocol | Header Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;12 | Source Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;16 | Destination Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;20 | Data | |
; +-+-+-.......... -+ |
; |
; |
; [smb] attention! according to RFC 791 IP packet may have 'options' sections, |
; so we can't simply think, that data have offset 20. We must calculate offset from |
; IHL field |
; |
macro GET_IHL reg, header_addr |
{ |
movzx reg, byte [header_addr] |
; we need 4-7 bits, so.... |
and reg, 0x0000000F |
; IHL keeps number of octets, so we need to << 2 'reg' |
shl reg, 2 |
} |
include "tcp.inc" |
include "udp.inc" |
include "icmp.inc" |
;*************************************************************************** |
; Function |
; ip_rx |
; |
; Description |
; This is a kernel function, called by stack_handler |
; Processes all IP-packets received by the network layer |
; It calls the appropriate protocol handler |
; |
;*************************************************************************** |
proc ip_rx stdcall |
local buffer_number dd ? |
; Look for a buffer to tx |
mov eax, IPIN_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit ; Exit if no buffer available |
mov [buffer_number], eax ;save buffer number |
; convert buffer pointer eax to the absolute address |
imul eax, IPBUFFSIZE |
add eax, IPbuffs |
mov ebx, eax ; ebx=pointer to IP_PACKET |
; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1 |
; Validate the IP checksum |
mov dx, word[ebx + IP_PACKET.HeaderChecksum] |
xchg dh,dl ; Get the checksum in intel format |
mov [ebx + IP_PACKET.HeaderChecksum], 0 ; clear checksum field - need to when |
; recalculating checksum |
; this needs two data pointers and two size #. |
; 2nd pointer can be of length 0 |
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx |
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size |
cmp dx, ax |
; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax |
jnz .dump.1 ;if CHECKSUM isn't valid then dump packet |
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!! |
; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip] |
; Validate the IP address, if it isn't broadcast |
mov eax, [stack_ip] |
cmp dword[ebx + IP_PACKET.DestinationAddress], eax |
je @f |
; If the IP address is 255.255.255.255, accept it |
; - it is a broadcast packet, which we need for dhcp |
mov eax, [ebx + IP_PACKET.DestinationAddress] |
cmp eax, 0xffffffff |
je @f |
mov ecx, [stack_ip] |
and eax, [subnet_mask] |
and ecx, [subnet_mask] |
cmp eax, ecx |
jne .dump.2 |
mov eax, [ebx + IP_PACKET.DestinationAddress] |
or eax, [subnet_mask] |
cmp eax, 0xffffffff |
jne .dump.2 |
@@: |
mov al, [ebx + IP_PACKET.VersionAndIHL] |
and al, 0x0f ;get IHL(header length) |
cmp al, 0x05 ;if IHL!= 5*4(20 bytes) |
; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al |
jnz .dump.3 ;then dump it |
; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2 |
cmp [ebx + IP_PACKET.TimeToLive], 0 |
je .dump.4 ;if TTL==0 then dump it |
mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset] |
and ax, 0xFFBF ;get flags |
; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax |
cmp ax, 0 ;if some flags was set then we dump this packet |
jnz .dump.5 ;the flags should be used for fragmented packets |
; Check the protocol, and call the appropriate handler |
; Each handler will re-use or free the queue buffer as appropriate |
mov al, [ebx + IP_PACKET.Protocol] |
cmp al , PROTOCOL_TCP |
jne .not_tcp |
; DEBUGF 1,"K : ip_rx - TCP packet\n" |
mov eax, dword[buffer_number] |
call tcp_rx |
jmp .exit |
.not_tcp: |
cmp al, PROTOCOL_UDP |
jne .not_udp |
; DEBUGF 1,"K : ip_rx - UDP packet\n" |
mov eax, dword[buffer_number] |
call udp_rx |
jmp .exit |
.not_udp: |
cmp al, PROTOCOL_ICMP |
jne .dump.6 ;protocol ain't supported |
; DEBUGF 1,"K : ip_rx - ICMP packet\n" |
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx |
mov eax, dword[buffer_number] |
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength |
jmp .exit |
.dump.1: |
DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax |
jmp .dump.x |
.dump.2: |
DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1 |
jmp .dump.x |
.dump.3: |
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al |
jmp .dump.x |
.dump.4: |
DEBUGF 1, "K : ip_rx - dumped (ttl: %u)\n", [ebx + IP_PACKET.TimeToLive] |
jmp .dump.x |
.dump.5: |
DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax |
jmp .dump.x |
.dump.6: |
DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1 |
.dump.x: |
inc dword[dumped_rx_count] |
mov eax, [buffer_number] |
call freeBuff |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network/icmp.inc |
---|
0,0 → 1,193 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ICMP.INC ;; |
;; ;; |
;; Internet Control Message Protocol ( RFC 792 ) ;; |
;; ;; |
;; Last revision: 11.11.2006 ;; |
;; ;; |
;; This file contains the following: ;; |
;; icmp_rx - processes ICMP-packets received by the IP layer ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;; Current status: ;; |
;; This implemetation of ICMP proto supports message of ECHO type. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
struc ICMP_PACKET |
{ .Type db ? ;+00 |
.Code db ? ;+01 |
.Checksum dw ? ;+02 |
.Identifier dw ? ;+04 |
.SequenceNumber dw ? ;+06 |
.Data db ? ;+08 |
} |
virtual at 0 |
ICMP_PACKET ICMP_PACKET |
end virtual |
; Example: |
; ECHO message format |
; |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Type | Code | Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Identifier | Sequence Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Data ... |
; +-+-+-+-+- |
; |
; |
; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources |
; |
ICMP_ECHOREPLY equ 0 ; echo reply message |
ICMP_UNREACH equ 3 |
ICMP_UNREACH_NET equ 0 ; bad net |
ICMP_UNREACH_HOST equ 1 ; bad host |
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol |
ICMP_UNREACH_PORT equ 3 ; bad port |
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop |
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed |
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net |
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host |
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated |
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access |
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto |
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net |
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host |
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib |
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. |
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff |
ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down |
ICMP_REDIRECT equ 5 ; shorter route, codes: |
ICMP_REDIRECT_NET equ 0 ; for network |
ICMP_REDIRECT_HOST equ 1 ; for host |
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net |
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host |
ICMP_ALTHOSTADDR equ 6 ; alternate host address |
ICMP_ECHO equ 8 ; echo service |
ICMP_ROUTERADVERT equ 9 ; router advertisement |
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement |
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing |
ICMP_ROUTERSOLICIT equ 10 ; router solicitation |
ICMP_TIMXCEED equ 11 ; time exceeded, code: |
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit |
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass |
ICMP_PARAMPROB equ 12 ; ip header bad |
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr |
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent |
ICMP_PARAMPROB_LENGTH equ 2 ; bad length |
ICMP_TSTAMP equ 13 ; timestamp request |
ICMP_TSTAMPREPLY equ 14 ; timestamp reply |
ICMP_IREQ equ 15 ; information request |
ICMP_IREQREPLY equ 16 ; information reply |
ICMP_MASKREQ equ 17 ; address mask request |
ICMP_MASKREPLY equ 18 ; address mask reply |
ICMP_TRACEROUTE equ 30 ; traceroute |
ICMP_DATACONVERR equ 31 ; data conversion error |
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect |
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you |
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here |
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req |
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply |
ICMP_SKIP equ 39 ; SKIP |
ICMP_PHOTURIS equ 40 ; Photuris |
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index |
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed |
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed |
;*************************************************************************** |
; Function |
; icmp_rx [by Johnny_B] |
; |
; Description |
; ICMP protocol handler |
; This is a kernel function, called by ip_rx |
; |
; IN: |
; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards |
; IPPacketBase - IP_PACKET base address |
; IPHeaderLength - Header length of IP_PACKET |
; |
; OUT: |
; EAX=not defined |
; |
; All used registers will be saved |
; |
;*************************************************************************** |
proc icmp_rx stdcall uses ebx esi edi,\ |
buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD |
mov esi,[IPPacketBase] ;esi=IP_PACKET base address |
mov edi, esi |
add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address |
cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not |
jz .icmp_echo |
mov eax, [buffer_number] |
call freeBuff |
jmp .exit |
.icmp_echo: |
; swap the source and destination addresses |
mov ecx, [esi + IP_PACKET.DestinationAddress] |
mov ebx, [esi + IP_PACKET.SourceAddress] |
mov [esi + IP_PACKET.DestinationAddress], ebx |
mov [esi + IP_PACKET.SourceAddress], ecx |
; recalculate the IP header checksum |
mov eax,[IPHeaderLength] |
stdcall checksum_jb,esi,eax ;buf_ptr,buf_size |
mov byte[esi + IP_PACKET.HeaderChecksum], ah |
mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order? |
mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response |
mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc |
; Calculate the length of the ICMP data ( IP payload) |
xor eax, eax |
mov ah, byte[esi + IP_PACKET.TotalLength] |
mov al, byte[esi + IP_PACKET.TotalLength + 1] |
sub ax, word[IPHeaderLength] ;ax=ICMP-packet length |
stdcall checksum_jb,edi,eax ;buf_ptr,buf_size |
mov byte[edi + ICMP_PACKET.Checksum], ah |
mov byte[edi + ICMP_PACKET.Checksum + 1], al |
; Queue packet for transmission |
mov ebx, [buffer_number] |
mov eax, NET1OUT_QUEUE |
call queue |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/network |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/blkdev/cd_drv.inc |
---|
0,0 → 1,929 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI) |
;********************************************************** |
; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷ |
; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz> |
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ |
MaxRetr equ 10 |
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû |
; (â òèêàõ) |
BSYWaitTime equ 1000 ;2 |
NoTickWaitTime equ 0xfffff |
CDBlockSize equ 2048 |
;******************************************** |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ * |
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ * |
;******************************************** |
ReadCDWRetr: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
pushad |
mov eax,[CDSectorAddress] |
mov ebx,[CDDataBuf_pointer] |
call cd_calculate_cache |
xor edi,edi |
add esi,8 |
inc edi |
.hdreadcache: |
; cmp dword [esi+4],0 ; empty |
; je .nohdcache |
cmp [esi],eax ; correct sector |
je .yeshdcache |
.nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz .hdreadcache |
call find_empty_slot_CD_cache ; ret in edi |
push edi |
push eax |
call cd_calculate_cache_2 |
shl edi,11 |
add edi,eax |
mov [CDDataBuf_pointer],edi |
pop eax |
pop edi |
call ReadCDWRetr_1 |
cmp [DevErrorCode],0 |
jne .exit |
mov [CDDataBuf_pointer],ebx |
call cd_calculate_cache_1 |
lea esi,[edi*8+esi] |
mov [esi],eax ; sector number |
; mov dword [esi+4],1 ; hd read - mark as same as in hd |
.yeshdcache: |
mov esi,edi |
shl esi,11 ;9 |
push eax |
call cd_calculate_cache_2 |
add esi,eax |
pop eax |
mov edi,ebx ;[CDDataBuf_pointer] |
mov ecx,512 ;/4 |
cld |
rep movsd ; move data |
.exit: |
popad |
ret |
ReadCDWRetr_1: |
pushad |
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå |
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê |
mov ECX,MaxRetr |
@@NextRetr: |
; Ïîäàòü êîìàíäó |
;************************************************* |
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ * |
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ * |
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. * |
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. * |
;************************************************* |
;ReadCD: |
push ecx |
; pusha |
; Çàäàòü ðàçìåð ñåêòîðà |
; mov [CDBlockSize],2048 ;2352 |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
; Çàäàòü êîä êîìàíäû Read CD |
mov [PacketCommand],byte 0x28 ;0xBE |
; Çàäàòü àäðåñ ñåêòîðà |
mov AX,word [CDSectorAddress+2] |
xchg AL,AH |
mov word [PacketCommand+2],AX |
mov AX,word [CDSectorAddress] |
xchg AL,AH |
mov word [PacketCommand+4],AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ |
mov [PacketCommand+8],byte 1 |
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå |
; mov [PacketCommand+9],byte 0xF8 |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
pop ecx |
; ret |
; cmp [DevErrorCode],0 |
test eax,eax |
jz @@End_4 |
or ecx,ecx ;{SPraid.simba} (for cd load) |
jz @@End_4 |
dec ecx |
cmp [timer_ticks_enable],0 |
jne @f |
mov eax,NoTickWaitTime |
.wait: |
dec eax |
; test eax,eax |
jz @@NextRetr |
jmp .wait |
@@: |
; Çàäåðæêà íà 2,5 ñåêóíäû |
; mov EAX,[timer_ticks] |
; add EAX,50 ;250 |
;@@Wait: |
; call change_task |
; cmp EAX,[timer_ticks] |
; ja @@Wait |
loop @@NextRetr |
@@End_4: |
mov dword [DevErrorCode],eax |
popad |
ret |
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå |
; ïàêåòíûõ êîìàíä â ðåæèìå PIO |
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè |
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ) |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
uglobal |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: rb 12 ;DB 12 DUP (?) |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
;CDBlockSize DW ? |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: DD ? |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
WURStartTime DD 0 |
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ |
CDDataBuf_pointer dd 0 |
endg |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; * |
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. * |
; return eax DevErrorCode |
;**************************************************** |
SendPacketDatCommand: |
xor eax,eax |
; mov byte [DevErrorCode],al |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode],al |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures],al |
mov byte [ATASectorCount],al |
mov byte [ATASectorNumber],al |
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà |
mov [ATAHead],al |
; mov AX,[CDBlockSize] |
mov [ATACylinder],CDBlockSize |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
test eax,eax |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,NoTickWaitTime |
@@WaitDevice0: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
jmp .test |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test: |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
cli |
mov DX,[ATABasePortAddr] |
mov AX,[PacketCommand] |
out DX,AX |
mov AX,[PacketCommand+2] |
out DX,AX |
mov AX,[PacketCommand+4] |
out DX,AX |
mov AX,[PacketCommand+6] |
out DX,AX |
mov AX,[PacketCommand+8] |
out DX,AX |
mov AX,[PacketCommand+10] |
out DX,AX |
sti |
; Îæèäàíèå ãîòîâíîñòè äàííûõ |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,NoTickWaitTime |
@@WaitDevice1: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
jmp .test_1 |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test_1: |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_temp |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf |
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ |
xor ecx,ecx |
mov CX,CDBlockSize |
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ |
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2 |
; Ïðèíÿòü áëîê äàííûõ |
cli |
cld |
rep insw |
sti |
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ |
@@End_8: |
xor eax,eax |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_1: |
xor eax,eax |
inc eax |
ret |
; mov [DevErrorCode],1 |
; ret |
@@Err6_temp: |
mov eax,7 |
ret |
; mov [DevErrorCode],7 |
; ret |
@@Err6: |
mov eax,6 |
ret |
; mov [DevErrorCode],6 |
;@@End_8: |
; ret |
;*********************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç * |
;* ãëîáàëüíûå ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. * |
;*********************************************** |
SendPacketNoDatCommand: |
pushad |
xor eax,eax |
; mov byte [DevErrorCode],al |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode],al |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures],al |
mov byte [ATASectorCount],al |
mov byte [ATASectorNumber],al |
mov word [ATACylinder],ax |
mov byte [ATAHead],al |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
test eax,eax |
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0_1 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
; cli |
mov DX,[ATABasePortAddr] |
mov AX,word [PacketCommand] |
out DX,AX |
mov AX,word [PacketCommand+2] |
out DX,AX |
mov AX,word [PacketCommand+4] |
out DX,AX |
mov AX,word [PacketCommand+6] |
out DX,AX |
mov AX,word [PacketCommand+8] |
out DX,AX |
mov AX,word [PacketCommand+10] |
out DX,AX |
; sti |
cmp [ignore_CD_eject_wait],1 |
je @@clear_DEC |
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY |
jz @@WaitDevice1_1 |
@@clear_DEC: |
and [DevErrorCode],0 |
popad |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_3: |
xor eax,eax |
inc eax |
jmp @@End_9 |
@@Err6_1: |
mov eax,6 |
@@End_9: |
mov [DevErrorCode],eax |
popad |
ret |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè â eax * |
;**************************************************** |
SendCommandToHDD_1: |
; pushad |
; mov [DevErrorCode],0 not need |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2_4 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_4 |
cmp BX,2 |
ja @@Err3_4 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov eax,[timer_ticks] |
mov [TickCounter_1],eax |
mov ecx,NoTickWaitTime |
@@WaitHDReady_2: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_4 |
jmp .test |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov eax,[timer_ticks] |
sub eax,[TickCounter_1] |
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê. |
ja @@Err1_4 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
.test: |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_2 |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady_2 |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5_4 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
; mov [DevErrorCode],0 |
@@End_10: |
xor eax,eax |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_4: |
xor eax,eax |
inc eax |
; mov [DevErrorCode],1 |
ret |
@@Err2_4: |
mov eax,2 |
; mov [DevErrorCode],2 |
ret |
@@Err3_4: |
mov eax,3 |
; mov [DevErrorCode],3 |
ret |
@@Err4_4: |
mov eax,4 |
; mov [DevErrorCode],4 |
ret |
@@Err5_4: |
mov eax,5 |
; mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
; sti |
; popad |
;************************************************* |
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
WaitUnitReady: |
pusha |
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè |
mov EAX,[timer_ticks] |
mov [WURStartTime],EAX |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY |
mov [PacketCommand],word 00h |
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ |
mov ecx,NoTickWaitTime |
@@SendCommand: |
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè |
call SendPacketNoDatCommand |
cmp [timer_ticks_enable],0 |
jne @f |
cmp [DevErrorCode],0 |
je @@End_11 |
dec ecx |
; cmp ecx,0 |
jz .Error |
jmp @@SendCommand |
@@: |
call change_task |
; Ïðîâåðèòü êîä îøèáêè |
cmp [DevErrorCode],0 |
je @@End_11 |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè |
mov EAX,[timer_ticks] |
sub EAX,[WURStartTime] |
cmp EAX,MaxCDWaitTime |
jb @@SendCommand |
.Error: |
; Îøèáêà òàéì-àóòà |
mov [DevErrorCode],1 |
@@End_11: |
popa |
ret |
;************************************************* |
;* ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
prevent_medium_removal: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 0x1E |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4],byte 11b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax,ATAPI_IDE0_lock |
add eax,[cdpos] |
dec eax |
mov [eax],byte 1 |
popa |
ret |
;************************************************* |
;* ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
allow_medium_removal: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 0x1E |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4],byte 00b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax,ATAPI_IDE0_lock |
add eax,[cdpos] |
dec eax |
mov [eax],byte 0 |
popa |
ret |
;************************************************* |
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
LoadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ |
mov [PacketCommand+4],word 00000011b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
EjectMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ |
mov [PacketCommand+4],word 00000010b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ * |
;* äèñêà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
align 4 |
check_ATAPI_device_event: |
pusha |
mov eax,[timer_ticks] |
sub eax,[timer_ATAPI_check] |
cmp eax,100 |
jb .end_1 |
mov al,[DRIVE_DATA+1] |
and al,11b |
cmp al,10b |
jz .ide3 |
.ide2_1: |
mov al,[DRIVE_DATA+1] |
and al,1100b |
cmp al,1000b |
jz .ide2 |
.ide1_1: |
mov al,[DRIVE_DATA+1] |
and al,110000b |
cmp al,100000b |
jz .ide1 |
.ide0_1: |
mov al,[DRIVE_DATA+1] |
and al,11000000b |
cmp al,10000000b |
jz .ide0 |
.end: |
sti |
mov eax,[timer_ticks] |
mov [timer_ATAPI_check],eax |
.end_1: |
popa |
ret |
.ide3: |
cli |
cmp [ATAPI_IDE3_lock],1 |
jne .ide2_1 |
cmp [IDE_Channel_2],0 |
jne .ide1_1 |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_2],1 |
call reserve_ok2 |
mov [ChannelNumber],2 |
mov [DiskNumber],1 |
mov [cdpos],4 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide3 |
call syscall_cdaudio.free |
jmp .ide2_1 |
.eject_ide3: |
call .eject |
call syscall_cdaudio.free |
jmp .ide2_1 |
.ide2: |
cli |
cmp [ATAPI_IDE2_lock],1 |
jne .ide1_1 |
cmp [IDE_Channel_2],0 |
jne .ide1_1 |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_2],1 |
call reserve_ok2 |
mov [ChannelNumber],2 |
mov [DiskNumber],0 |
mov [cdpos],3 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide2 |
call syscall_cdaudio.free |
jmp .ide1_1 |
.eject_ide2: |
call .eject |
call syscall_cdaudio.free |
jmp .ide1_1 |
.ide1: |
cli |
cmp [ATAPI_IDE1_lock],1 |
jne .ide0_1 |
cmp [IDE_Channel_1],0 |
jne .end |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_1],1 |
call reserve_ok2 |
mov [ChannelNumber],1 |
mov [DiskNumber],1 |
mov [cdpos],2 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide1 |
call syscall_cdaudio.free |
jmp .ide0_1 |
.eject_ide1: |
call .eject |
call syscall_cdaudio.free |
jmp .ide0_1 |
.ide0: |
cli |
cmp [ATAPI_IDE0_lock],1 |
jne .end |
cmp [IDE_Channel_1],0 |
jne .end |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_1],1 |
call reserve_ok2 |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
mov [cdpos],1 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide0 |
call syscall_cdaudio.free |
jmp .end |
.eject_ide0: |
call .eject |
call syscall_cdaudio.free |
jmp .end |
.eject: |
call clear_CD_cache |
call allow_medium_removal |
mov [ignore_CD_eject_wait],1 |
call EjectMedium |
mov [ignore_CD_eject_wait],0 |
ret |
iglobal |
timer_ATAPI_check dd 0 |
ATAPI_IDE0_lock db 0 |
ATAPI_IDE1_lock db 0 |
ATAPI_IDE2_lock db 0 |
ATAPI_IDE3_lock db 0 |
ignore_CD_eject_wait db 0 |
endg |
;************************************************* |
;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè * |
;* óñòðîéñòâà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
GetEvent_StatusNotification: |
pusha |
mov [CDDataBuf_pointer],CDDataBuf |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 4Ah |
mov [PacketCommand+1],byte 00000001b |
; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé |
mov [PacketCommand+4],byte 00010000b |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7],byte 8h |
mov [PacketCommand+8],byte 0h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
; ïðî÷èòàòü èíôîðìàöèþ èç TOC |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
Read_TOC: |
pusha |
mov [CDDataBuf_pointer],CDDataBuf |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
mov [PacketCommand],byte 0x43 |
; Çàäàòü ôîðìàò |
mov [PacketCommand+2],byte 1 |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7],byte 0xFF |
mov [PacketCommand+8],byte 0h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
;ReadCapacity: |
; pusha |
;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
; call clear_packet_buffer |
;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ |
; mov [CDBlockSize],8 |
;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY |
; mov [PacketCommand],word 25h |
;; Ïîäàòü êîìàíäó |
; call SendPacketDatCommand |
; popa |
; ret |
clear_packet_buffer: |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
and [PacketCommand],dword 0 |
and [PacketCommand+4],dword 0 |
and [PacketCommand+8],dword 0 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc |
---|
0,0 → 1,626 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
; mov edi,[TASK_BASE] |
; mov edi,[edi+TASKDATA.mem_start] |
; add edi,ecx |
give_back_application_data_1: |
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
; mov esi,[TASK_BASE] |
; mov esi,[esi+TASKDATA.mem_start] |
; add esi,ecx |
take_data_from_application_1: |
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
FDC_C DB ? |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,0xD000 |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
popad |
ret |
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH,AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL,AH |
out DX,AL |
@@End_5: |
; popa |
pop edx ecx eax |
ret |
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
pop ECX |
ret |
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],1 |
ret |
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func],FDCInterrupt |
ret |
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status],FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag],0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
ret |
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
; cmp [fdd_motor_status],1 |
; je fdd_motor_on |
mov al,[flp_number] |
cmp [fdd_motor_status],al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0 |
out DX,AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number],1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
mov AL,1Ch ; Floppy A |
jmp FDDMotorON_1 |
FDDMotorON_B: |
; call FDDMotorOFF_A |
mov AL,2Dh ; Floppy B |
FDDMotorON_1: |
out DX,AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;10 |
jb @@dT |
cmp [flp_number],1 |
jne fdd_motor_on_B |
mov [fdd_motor_status],1 |
jmp fdd_motor_on |
fdd_motor_on_B: |
mov [fdd_motor_status],2 |
fdd_motor_on: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax,[timer_ticks] |
mov [timer_fdd_motor],eax |
ret |
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
align 4 |
check_fdd_motor_status: |
cmp [fdd_motor_status],0 |
je end_check_fdd_motor_status_1 |
mov eax,[timer_ticks] |
sub eax,[timer_fdd_motor] |
cmp eax,500 |
jb end_check_fdd_motor_status |
call FDDMotorOFF |
mov [fdd_motor_status],0 |
end_check_fdd_motor_status_1: |
mov [flp_status],0 |
end_check_fdd_motor_status: |
ret |
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
push DX |
cmp [flp_number],1 |
jne FDDMotorOFF_1 |
call FDDMotorOFF_A |
jmp FDDMotorOFF_2 |
FDDMotorOFF_1: |
call FDDMotorOFF_B |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read],0 |
mov [flp_fat],0 |
ret |
FDDMotorOFF_A: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0Ch ; Floppy A |
out DX,AL |
ret |
FDDMotorOFF_B: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,5h ; Floppy B |
out DX,AL |
ret |
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL,07h |
call FDCDataOutput |
mov AL,00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
; mov [flp_status],0 |
;no_fdc_status_error: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL,0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL,[FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL,08h |
call FDCDataOutput |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_C],AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0],100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
mov AL,[FDC_C] |
cmp AL,[FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL,[FDC_ST0] |
and AL,100b |
shr AL,2 |
cmp AL,[FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status],FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status],FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
call save_timer_fdd_motor |
popa |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11011000b |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@ReadSector_1: |
call ReadSector |
cmp [FDC_Status],0 |
je @@Exit_2 |
cmp [FDC_Status],1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain |
; mov [flp_status],0 |
@@Exit_2: |
popa |
ret |
@@Err_3: |
mov [flp_status],0 |
popa |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11000000b ;11011000b |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@WriteSector_1: |
call WriteSector |
cmp [FDC_Status],0 |
je @@Exit_4 |
cmp [FDC_Status],1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain_1 |
@@Exit_4: |
popa |
ret |
@@Err_4: |
mov [flp_status],0 |
popa |
ret |
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_ST1],AL |
call FDCDataInput |
mov [FDC_ST2],AL |
call FDCDataInput |
mov [FDC_C],AL |
call FDCDataInput |
mov [FDC_H],AL |
call FDCDataInput |
mov [FDC_R],AL |
call FDCDataInput |
mov [FDC_N],AL |
pop AX |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/rd.inc |
---|
0,0 → 1,2266 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; calculate fat chain |
calculatefatchain: |
pushad |
mov esi,RAMDISK+512 |
mov edi,RAMDISK_FAT |
fcnew: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
mov dword [edi+4],ebx |
mov dword [edi+8],ecx |
mov dword [edi+12],edx |
add edi,16 |
add esi,12 |
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters |
jnz fcnew |
popad |
ret |
restorefatchain: ; restore fat chain |
pushad |
mov esi,RAMDISK_FAT |
mov edi,RAMDISK+512 |
fcnew2: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
mov word [edi+4],bx |
add edi,6 |
add esi,8 |
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT |
jb fcnew2 |
mov esi,RAMDISK+512 ; duplicate fat chain |
mov edi,RAMDISK+512+0x1200 |
mov ecx,1069 ;4274/4 |
cld |
rep movsd |
popad |
ret |
ramdisk_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; rewr.by Mihasik |
;--------------------------------------------- |
push eax ebx ecx |
mov edi,RAMDISK_FAT ;start of FAT |
xor ax,ax ;Free cluster=0x0000 in FAT |
xor ebx,ebx ;counter |
mov ecx,2849 ;2849 clusters |
cld |
rdfs1: |
repne scasw |
jnz rdfs2 ;if last cluster not 0 |
inc ebx |
test ecx, ecx |
jnz rdfs1 |
rdfs2: |
shl ebx,9 ;free clusters*512 |
mov edi,ebx |
pop ecx ebx eax |
ret |
expand_filename: |
;--------------------------------------------- |
; |
; exapand filename with '.' to 11 character |
; eax - pointer to filename |
;--------------------------------------------- |
push esi edi ebx |
mov edi,esp ; check for '.' in the name |
add edi,12+8 |
mov esi,eax |
mov eax,edi |
mov [eax+0],dword ' ' |
mov [eax+4],dword ' ' |
mov [eax+8],dword ' ' |
flr1: |
cmp [esi],byte '.' |
jne flr2 |
mov edi,eax |
add edi,7 |
jmp flr3 |
flr2: |
mov bl,[esi] |
mov [edi],bl |
flr3: |
inc esi |
inc edi |
mov ebx,eax |
add ebx,11 |
cmp edi,ebx |
jbe flr1 |
pop ebx edi esi |
ret |
fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X 0=root |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
test ebx,ebx ;if ebx=0 - set to 1 |
jnz frfl5 |
inc ebx |
frfl5: |
test ecx,ecx ;if ecx=0 - set to 1 |
jnz frfl6 |
inc ecx |
frfl6: |
test esi,esi ; return ramdisk root |
jnz fr_noroot ;if not root |
cmp ebx,14 ;14 clusters=root dir |
ja oorr |
cmp ecx,14 |
ja oorr |
jmp fr_do |
oorr: |
mov eax,5 ;out of root range (fnf) |
xor ebx,ebx |
dec ebx ;0xffffffff |
ret |
fr_do: ;reading rootdir |
mov edi,edx |
dec ebx |
push edx |
mov edx,ecx |
add edx,ebx |
cmp edx,15 ;ebx+ecx=14+1 |
pushf |
jbe fr_do1 |
sub edx,14 |
sub ecx,edx |
fr_do1: |
shl ebx,9 |
mov esi,RAMDISK+512*19 |
add esi,ebx |
shl ecx,7 |
cld |
rep movsd |
popf |
pop edx |
jae fr_do2 |
xor eax,eax ; ok read |
xor ebx,ebx |
ret |
fr_do2: ;if last cluster |
mov eax,6 ;end of file |
xor ebx,ebx |
ret |
fr_noroot: |
sub esp,32 |
call expand_filename |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifound |
add esp,32+28 ;if file not found |
ret |
fifound: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi=cluster |
frnew: |
add eax,31 ;bootsector+2*fat+filenames |
shl eax,9 ;*512 |
add eax,RAMDISK ;image base |
mov ebx,[esp+8] |
mov ecx,512 ;[esp+4] |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7 |
call memmove |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
je frnoread |
jmp frfl8 |
frfl7: |
dec dword [esp+16] |
frfl8: |
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
mov edi,eax |
cmp edi,4095 ;eof - cluster |
jz frnoread2 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread |
sub [esp+24],dword 512 |
jmp frnew |
frnoread2: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
ret |
frnoread: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax ;read ok |
ret |
rd_findfile: |
;by Mihasik |
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx |
mov edi,RAMDISK+512*18+512 ;Point at directory |
cld |
rd_newsearch: |
mov esi,eax |
mov ecx,11 |
rep cmpsb |
je rd_ff |
add cl,21 |
add edi,ecx |
cmp edi,RAMDISK+512*33 |
jb rd_newsearch |
mov eax,5 ;if file not found - eax=5 |
xor ebx,ebx |
dec ebx ;ebx=0xffffffff and zf=0 |
rd_ff: |
ret |
; \begin{diamond} |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
test ax, ax |
jz .done |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
stosb |
jmp uni2ansi_str |
.done: |
mov byte [edi], 0 |
ret |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .ret |
; 0x80-0xAF -> 0x410-0x43F |
cmp al, 0xB0 |
jae @f |
add ax, 0x410-0x80 |
.ret: |
ret |
@@: |
; 0xE0-0xEF -> 0x440-0x44F |
cmp al, 0xE0 |
jb .unk |
cmp al, 0xF0 |
jae @f |
add ax, 0x440-0xE0 |
ret |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
ret |
.yo1: |
mov ax, 0x401 |
ret |
.yo2: |
mov ax, 0x451 |
ret |
char_toupper: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, ' ' |
jb .ret |
cmp al, 'à' |
jb .rus1 |
cmp al, 'ï' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0xA0-0xAF -> 0x80-0x8F |
.az: |
and al, not 0x20 |
ret |
fat_get_name: |
; in: edi->FAT entry |
; out: CF=1 - no valid entry |
; else CF=0 and ebp->ASCIIZ-name |
; (maximum length of filename is 255 (wide) symbols without trailing 0, |
; but implementation requires buffer 261 words) |
; destroys eax |
cmp byte [edi], 0 |
jz .no |
cmp byte [edi], 0xE5 |
jnz @f |
.no: |
stc |
ret |
@@: |
cmp byte [edi+11], 0xF |
jz .longname |
test byte [edi+11], 8 |
jnz .no |
push ecx |
push edi ebp |
test byte [ebp-4], 1 |
jnz .unicode_short |
mov eax, [edi] |
mov ecx, [edi+4] |
mov [ebp], eax |
mov [ebp+4], ecx |
mov ecx, 8 |
@@: |
cmp byte [ebp+ecx-1], ' ' |
loope @b |
mov eax, [edi+8] |
cmp al, ' ' |
je .done |
shl eax, 8 |
mov al, '.' |
lea ebp, [ebp+ecx+1] |
mov [ebp], eax |
mov ecx, 3 |
@@: |
rol eax, 8 |
cmp al, ' ' |
jne .done |
loop @b |
dec ebp |
.done: |
and byte [ebp+ecx+1], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
mov ecx, 8 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
dec ebp |
dec ebp |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
cmp al, 20 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
pop edi esi |
.ret: |
clc |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
jnz .done |
pop eax |
test al, al |
jnz .loop |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
ret |
.done: |
cmp al, '/' |
jnz @f |
cmp byte [esp], 0 |
jnz @f |
mov [esp+4], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_time_to_bdfe: |
; in: eax=FAT time |
; out: eax=BDFE time |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 11 |
shl eax, 16 ; hours |
and edx, 0x1F |
add edx, edx |
mov al, dl ; seconds |
shr ecx, 5 |
and ecx, 0x3F |
mov ah, cl ; minutes |
pop edx ecx |
ret |
fat_date_to_bdfe: |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 9 |
add ax, 1980 |
shl eax, 16 ; year |
and edx, 0x1F |
mov al, dl ; day |
shr ecx, 5 |
and ecx, 0xF |
mov ah, cl ; month |
pop edx ecx |
ret |
bdfe_to_fat_time: |
push edx |
mov edx, eax |
shr eax, 16 |
and dh, 0x3F |
shl eax, 6 |
or al, dh |
shr dl, 1 |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
bdfe_to_fat_date: |
push edx |
mov edx, eax |
shr eax, 16 |
sub ax, 1980 |
and dh, 0xF |
shl eax, 4 |
or al, dh |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
movzx eax, word [edi+14] |
call fat_time_to_bdfe |
mov [esi+8], eax ; creation time |
movzx eax, word [edi+16] |
call fat_date_to_bdfe |
mov [esi+12], eax ; creation date |
and dword [esi+16], 0 ; last access time is not supported on FAT |
movzx eax, word [edi+18] |
call fat_date_to_bdfe |
mov [esi+20], eax ; last access date |
movzx eax, word [edi+22] |
call fat_time_to_bdfe |
mov [esi+24], eax ; last write time |
movzx eax, word [edi+24] |
call fat_date_to_bdfe |
mov [esi+28], eax ; last write date |
mov eax, [edi+28] |
mov [esi+32], eax ; file size (low dword) |
xor eax, eax |
mov [esi+36], eax ; file size (high dword) |
test ebp, ebp |
jz .ret |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
rep movsd |
mov [edi-2], ax |
@@: |
mov esi, edi |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
jmp @b |
bdfe_to_fat_entry: |
; convert BDFE at edx to FAT entry at edi |
; destroys eax |
; attributes byte |
test byte [edi+11], 8 ; volume label? |
jnz @f |
mov al, [edx] |
and al, 0x27 |
and byte [edi+11], 0x10 |
or byte [edi+11], al |
@@: |
mov eax, [edx+8] |
call bdfe_to_fat_time |
mov [edi+14], ax ; creation time |
mov eax, [edx+12] |
call bdfe_to_fat_date |
mov [edi+16], ax ; creation date |
mov eax, [edx+20] |
call bdfe_to_fat_date |
mov [edi+18], ax ; last access date |
mov eax, [edx+24] |
call bdfe_to_fat_time |
mov [edi+22], ax ; last write time |
mov eax, [edx+28] |
call bdfe_to_fat_date |
mov [edi+24], ax ; last write date |
ret |
ramdisk_root_first: |
mov edi, RAMDISK+512*19 |
clc |
ret |
ramdisk_root_next: |
add edi, 0x20 |
cmp edi, RAMDISK+512*33 |
cmc |
ret |
ramdisk_root_extend_dir: |
stc |
ret |
uglobal |
; this is for delete support |
rd_prev_sector dd ? |
rd_prev_prev_sector dd ? |
endg |
ramdisk_notroot_next: |
add edi, 0x20 |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ret ; CF=0 |
ramdisk_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
push [rd_prev_sector] |
pop [rd_prev_prev_sector] |
mov [rd_prev_sector], ecx |
mov ecx, [ecx*2+RAMDISK_FAT] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae ramdisk_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
ramdisk_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
shl eax, 9 |
lea edi, [eax+(31 shl 9)+RAMDISK] |
clc |
ret |
.err2: |
pop ecx |
.err: |
stc |
ret |
ramdisk_notroot_next_write: |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ramdisk_root_next_write: |
ret |
ramdisk_notroot_extend_dir: |
pusha |
xor eax, eax |
mov edi, RAMDISK_FAT |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [RAMDISK_FAT+ecx*2], di |
mov [eax], edi |
shl edi, 9 |
add edi, (31 shl 9)+RAMDISK |
mov [esp], edi |
xor eax, eax |
mov ecx, 128 |
rep stosd |
popa |
clc |
ret |
.notfound: |
popa |
stc |
ret |
rd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push ramdisk_root_first |
push ramdisk_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] |
mov [esp+8], eax |
mov dword [esp+4], ramdisk_notroot_first |
mov dword [esp], ramdisk_notroot_next |
test eax, eax |
jnz .loop |
mov dword [esp+4], ramdisk_root_first |
mov dword [esp], ramdisk_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRead - LFN variant for reading sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] ; cluster |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
lea eax, [edi+31] ; bootsector+2*fat+filenames |
shl eax, 9 ; *512 |
add eax, RAMDISK ; image base |
; now eax points to data of cluster |
sub ebx, 512 |
jae .skip |
lea eax, [eax+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
jmp .new |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder |
; |
; esi points to filename; only root is folder on ramdisk |
; ebx pointer to structure 32-bit number = first wanted block |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskReadFolder: |
push edi |
cmp byte [esi], 0 |
jz .root |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push esi ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
pop ecx eax |
mov esi, edi ; esi points to block of data of folder entry (BDFE) |
.main_loop: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
test edi, 0x1FF |
jnz .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
test edi, 0x1FF |
jnz .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
jmp .main_loop |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi edi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
clc |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
add dword [esp], 8 |
jmp .zerorest |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
.succ: |
pop edi |
popad |
clc |
ret |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
.zerorest: |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp ebx, ecx |
jb @f |
pop ebx |
push ecx |
@@: |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, [edi] |
dec ebx |
mov [ebx], al |
mov byte [edi], ' ' |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing ramdisk |
; fs_RamdiskCreateFolder - create folder on ramdisk |
; |
; esi points to file/folder name |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ (ignored for folders) |
; edx mem location to data (ignored for folders) |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskCreateFolder: |
mov al, 1 ; create folder |
jmp fs_RamdiskRewrite.common |
fs_RamdiskRewrite: |
xor eax, eax ; create file |
.common: |
cmp byte [esi], 0 |
jz @b |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
push ramdisk_root_extend_dir |
push ramdisk_root_next_write |
push edi |
push ramdisk_root_first |
push ramdisk_root_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call rd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call rd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push ramdisk_notroot_extend_dir |
push ramdisk_notroot_next_write |
push ebp |
push ramdisk_notroot_first |
push ramdisk_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 20 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+20+28], 0 |
jz @f |
add esp, 20 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 20 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+8] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to last entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call .read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call .read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call .read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+20+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
push edx |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
jecxz .done |
mov ecx, 2849 |
mov edi, RAMDISK_FAT |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
jnz .disk_full2 |
dec edi |
dec edi |
; lea eax, [edi-(RAMDISK_FAT)] |
mov eax, edi |
sub eax, RAMDISK_FAT |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp] |
stosw |
pop edi |
push edi |
inc ecx |
; write data |
cmp byte [esp+16+20+28], 0 |
jnz .writedir |
shl eax, 9 |
add eax, RAMDISK+31*512 |
.writefile: |
mov ebx, edx |
xchg eax, ebx |
push ecx |
mov ecx, 512 |
cmp dword [esp+12], ecx |
jae @f |
mov ecx, [esp+12] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
xor eax, eax |
ret |
.disk_full2: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
push ERROR_DISK_FULL |
pop eax |
ret |
.writedir: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK+31*512 |
mov esi, edx |
mov ecx, 32/4 |
push ecx |
rep movsd |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov word [edi-32+26], ax |
mov esi, edx |
pop ecx |
rep movsd |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov eax, [esp+16+8] |
mov word [edi-32+26], ax |
xor eax, eax |
mov ecx, (512-32*2)/4 |
rep stosd |
pop edi edi ecx edx |
add esp, 20 |
popad |
xor eax, eax |
xor ebx, ebx |
ret |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskWrite - LFN variant for writing to sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_RamdiskWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_RamdiskWrite: |
cmp byte [esi], 0 |
jz @b |
pushad |
call rd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
popad |
push ERROR_ACCESS_DENIED |
jmp .ret0 |
@@: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
call fat_update_datetime |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push 0 ; return value=0 |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call ramdisk_extend_file |
jnc .length_ok |
; ramdisk_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
mov [esp], eax |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
mov [esp+28], eax ; eax=return value |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
movzx edi, word [edi+26] ; starting cluster |
.write_loop: |
sub ebx, 0x200 |
jae .next_cluster |
push ecx |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov eax, edi |
shl eax, 9 |
add eax, RAMDISK+31*512+0x200 |
sub eax, ebx |
mov ebx, eax |
mov eax, edx |
call memmove |
xor ebx, ebx |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .ret |
.next_cluster: |
movzx edi, word [edi*2+RAMDISK_FAT] |
jmp .write_loop |
ramdisk_extend_file.zero_size: |
xor eax, eax |
jmp ramdisk_extend_file.start_extend |
; extends file on ramdisk to given size, new data area is filled by 0 |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
ramdisk_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
jz .fat_err |
cmp eax, 0xFF8 |
jb @b |
.fat_err: |
pop ecx |
push ERROR_FAT_TABLE |
pop eax |
stc |
ret |
@@: |
push eax |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
pop eax |
jb .fat_err |
; set length to full number of sectors and make sure that last sector is zero-padded |
sub [edi+28], ecx |
push eax edi |
mov edi, eax |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+0x200+ecx] |
neg ecx |
xor eax, eax |
rep stosb |
pop edi eax |
.start_extend: |
pop ecx |
; now do extend |
push edx esi |
mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2 |
mov edx, 2847 ; number of clusters to scan |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
mov ecx, edx |
push edi |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi ; now edi=new cluster |
test eax, eax |
jz .first_cluster |
mov [RAMDISK_FAT+eax*2], di |
jmp @f |
.first_cluster: |
pop eax ; eax->direntry |
push eax |
mov [eax+26], di |
@@: |
push edi |
shl edi, 9 |
add edi, RAMDISK+31*512 |
xor eax, eax |
mov ecx, 512/4 |
rep stosd |
pop eax ; eax=new cluster |
pop edi ; edi->direntry |
pop ecx ; ecx=required size |
add dword [edi+28], 0x200 |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop esi edx |
xor eax, eax ; CF=0 |
ret |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
fat_update_datetime: |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskSetFileEnd - set end of file on ramdisk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskSetFileEnd: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop edi |
xor eax, eax |
ret |
.expand: |
push ecx |
mov ecx, eax |
call ramdisk_extend_file |
pop ecx |
pop edi |
ret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [RAMDISK_FAT+ecx*2] |
jmp @b |
@@: |
; zero data at the end of last sector |
push ecx |
mov edi, ecx |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+eax+0x200] |
mov ecx, eax |
neg ecx |
xor eax, eax |
rep stosb |
pop ecx |
; terminate FAT chain |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
mov word [ecx], 0xFFF |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.zero_size: |
and word [edi+26], 0 |
.delete: |
; delete FAT chain starting with ecx |
; mark all clusters as free |
cmp ecx, 0xFF8 |
jae .deleted |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
and word [ecx], 0 |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.deleted: |
pop ecx |
pop edi |
xor eax, eax |
ret |
fs_RamdiskGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
fs_GetFileInfo_finish: |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push esi ebp |
xor ebp, ebp |
mov esi, edx |
and dword [esi+4], 0 |
call fat_entry_to_bdfe2 |
pop ebp esi |
pop edi |
xor eax, eax |
ret |
fs_RamdiskSetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
call bdfe_to_fat_entry |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskDelete - delete file or empty folder from ramdisk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskDelete: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [rd_prev_sector], 0 |
and [rd_prev_prev_sector], 0 |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
movzx eax, word [edi+26] |
push ebx |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
test ebx, 0x1FF |
jnz .checkempty |
movzx eax, word [RAMDISK_FAT + eax*2] |
test eax, eax |
jz .empty |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 |
jmp .checkempty |
.notempty: |
pop ebx |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
.dodel: |
movzx eax, word [edi+26] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
test edi, 0x1FF |
jnz @f |
cmp [rd_prev_sector], 0 |
jz @f |
cmp [rd_prev_sector], -1 |
jz .lfndone |
mov edi, [rd_prev_sector] |
push [rd_prev_prev_sector] |
pop [rd_prev_sector] |
or [rd_prev_prev_sector], -1 |
shl edi, 9 |
add edi, RAMDISK + 31*0x200 + 0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
; delete FAT chain |
test eax, eax |
jz .done |
lea eax, [RAMDISK_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jmp .lfndone |
.done: |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc |
---|
0,0 → 1,928 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Low-level driver for HDD access |
; DMA support by Mario79 |
; Access through BIOS by diamond |
align 4 |
hd_read: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
and [hd_error], 0 |
push ecx esi edi ; scan cache |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
call calculate_cache |
add esi,8 |
mov edi,1 |
hdreadcache: |
cmp dword [esi+4],0 ; empty |
je nohdcache |
cmp [esi],eax ; correct sector |
je yeshdcache |
nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz hdreadcache |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne return_01 |
; Read through BIOS? |
cmp [hdpos], 0x80 |
jae .bios |
; DMA read is permitted if [allow_dma_access]=1 or 2 |
cmp [allow_dma_access], 2 |
ja .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
call hd_read_dma |
jmp @f |
.nodma: |
call hd_read_pio |
jmp @f |
.bios: |
call bd_read |
@@: |
cmp [hd_error], 0 |
jne return_01 |
; lea esi,[edi*8+HD_CACHE] |
; push eax |
call calculate_cache_1 |
lea esi,[edi*8+esi] |
; pop eax |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
yeshdcache: |
mov esi,edi |
shl esi,9 |
; add esi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add esi,eax |
pop eax |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
align 4 |
hd_read_pio: |
push eax edx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_read_error |
cli |
push edi |
shl edi,9 |
; add edi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx eax |
ret |
disable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,2 |
; out dx,al |
cli |
ret |
enable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,0 |
; out dx,al |
sti |
ret |
align 4 |
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
; check if the cache already has the sector and overwrite it |
; mov ecx,cache_max |
; mov esi,HD_CACHE+8 |
call calculate_cache |
add esi,8 |
mov edi,1 |
hdwritecache: |
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
not_in_cache_write: |
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
; sector not found in cache |
; write the block to a new location |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
; lea esi,[edi*8+HD_CACHE] |
; push eax |
call calculate_cache_1 |
lea esi,[edi*8+esi] |
; pop eax |
mov [esi],eax ; sector number |
yes_in_cache_write: |
mov dword [esi+4],2 ; write - differs from hd |
shl edi,9 |
; add edi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov esi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
hd_write_access_denied: |
pop edi esi ecx |
ret |
align 4 |
cache_write_pio: |
; call disable_ide_int |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_write_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esi] ; eax = sector to write |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,30h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_write_error |
push ecx esi |
cli |
mov esi,edi |
shl esi,9 |
; add esi,HD_CACHE+65536 ; esi = from memory position |
push eax |
call calculate_cache_2 |
add esi,eax |
pop eax |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
sti |
; call enable_ide_int |
pop esi ecx |
ret |
save_hd_wait_timeout: |
push eax |
mov eax,[timer_ticks] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
align 4 |
check_hd_wait_timeout: |
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
;iglobal |
; hd_timeout_str db 'K : FS - HD timeout',0 |
; hd_read_str db 'K : FS - HD read error',0 |
; hd_write_str db 'K : FS - HD write error',0 |
; hd_lba_str db 'K : FS - HD LBA error',0 |
;endg |
hd_timeout_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_timeout_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD timeout\n" |
mov [hd_error],1 |
pop eax |
ret |
hd_read_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_read_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop edx eax |
ret |
hd_write_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD write error\n" |
ret |
hd_write_error_dma: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi, hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop esi |
ret |
hd_lba_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_lba_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD LBA error\n" |
jmp LBA_read_ret |
align 4 |
wait_for_hd_idle: |
push eax edx |
call save_hd_wait_timeout |
mov edx,[hdbase] |
add edx,0x7 |
wfhil1: |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,128 |
jnz wfhil1 |
@@: |
pop edx eax |
ret |
align 4 |
wait_for_sector_buffer: |
push eax edx |
mov edx,[hdbase] |
add edx,0x7 |
call save_hd_wait_timeout |
hdwait_sbuf: ; wait for sector buffer to be ready |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,8 |
jz hdwait_sbuf |
mov [hd_error],0 |
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
buf_wait_ok: |
pop edx eax |
ret |
; \begin{Mario79} |
align 4 |
wait_for_sector_dma_ide0: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq14_func], hdd_irq14 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
align 4 |
wait_for_sector_dma_ide1: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq15_func], hdd_irq15 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
iglobal |
align 4 |
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
IDE_descriptor_table: |
dd IDE_DMA |
dw 0x2000 |
dw 0x8000 |
dma_cur_sector dd not 40h |
dma_hdpos dd 0 |
irq14_func dd hdd_irq_null |
irq15_func dd hdd_irq_null |
endg |
uglobal |
; all uglobals are zeroed at boot |
dma_process dd 0 |
dma_slot_ptr dd 0 |
cache_chain_pos dd 0 |
cache_chain_ptr dd 0 |
cache_chain_size db 0 |
cache_chain_started db 0 |
dma_task_switched db 0 |
dma_hdd db 0 |
allow_dma_access db 0 |
endg |
align 4 |
hdd_irq14: |
pushfd |
cli |
pushad |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
align 4 |
hdd_irq_null: |
ret |
align 4 |
hdd_irq15: |
pushfd |
cli |
pushad |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
ret |
align 4 |
hd_read_dma: |
push eax |
push edx |
mov edx,[dma_hdpos] |
cmp edx,[hdpos] |
jne .notread |
mov edx, [dma_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, 15 |
cmp [esp+4], edx |
ja .notread |
mov eax, [esp+4] |
sub eax, [dma_cur_sector] |
shl eax, 9 |
add eax, (OS_BASE+IDE_DMA) |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
; add edi, HD_CACHE+0x10000 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx, 512/4 |
cld |
rep movsd |
pop edi esi ecx |
pop edx |
pop eax |
ret |
.notread: |
mov eax, IDE_descriptor_table |
mov dword [eax], IDE_DMA |
mov word [eax+4], 0x2000 |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_read_error |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov eax, 10h |
out dx, al |
inc edx |
mov eax, [esp+4] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xC8 |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 9 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_read_error |
mov eax,[hdpos] |
mov [dma_hdpos],eax |
pop edx |
pop eax |
mov [dma_cur_sector], eax |
jmp hd_read_dma |
align 4 |
write_cache_sector: |
mov [cache_chain_size],1 |
mov [cache_chain_pos],edi |
write_cache_chain: |
cmp [hdpos], 0x80 |
jae bd_write_cache_chain |
push esi |
mov eax, IDE_descriptor_table |
mov edx,eax |
pusha |
mov esi,[cache_chain_pos] |
shl esi, 9 |
call calculate_cache_2 |
add esi,eax |
mov edi, (OS_BASE+IDE_DMA) |
mov dword [edx], IDE_DMA |
movzx ecx, [cache_chain_size] |
shl ecx, 9 |
mov word [edx+4], cx |
shr ecx,2 |
cld |
rep movsd |
popa |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov al, [cache_chain_size] |
out dx, al |
inc edx |
mov esi, [cache_chain_ptr] |
mov eax, [esi] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xCA |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 1 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
mov [dma_cur_sector], not 0x40 |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
pop esi |
ret |
uglobal |
IDEContrRegsBaseAddr dw ? |
endg |
; \end{Mario79} |
; \begin{diamond} |
uglobal |
bios_hdpos dd 0 ; 0 is invalid value for [hdpos] |
bios_cur_sector dd ? |
bios_read_len dd ? |
endg |
bd_read: |
push eax |
push edx |
mov edx, [bios_hdpos] |
cmp edx, [hdpos] |
jne .notread |
mov edx, [bios_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, [bios_read_len] |
dec edx |
cmp eax, edx |
ja .notread |
sub eax, [bios_cur_sector] |
shl eax, 9 |
add eax, (OS_BASE+0x9A000) |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
; add edi, HD_CACHE+0x10000 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx, 512/4 |
cld |
rep movsd |
pop edi esi ecx |
pop edx |
pop eax |
ret |
.notread: |
push ecx |
mov dl, 42h |
mov ecx, 16 |
call int13_call |
pop ecx |
test eax, eax |
jnz .v86err |
test edx, edx |
jz .readerr |
mov [bios_read_len], edx |
mov edx, [hdpos] |
mov [bios_hdpos], edx |
pop edx |
pop eax |
mov [bios_cur_sector], eax |
jmp bd_read |
.readerr: |
.v86err: |
mov [hd_error], 1 |
jmp hd_read_error |
bd_write_cache_chain: |
pusha |
mov esi, [cache_chain_pos] |
shl esi, 9 |
call calculate_cache_2 |
add esi, eax |
mov edi, OS_BASE + 0x9A000 |
movzx ecx, [cache_chain_size] |
push ecx |
shl ecx, 9-2 |
rep movsd |
pop ecx |
mov dl, 43h |
mov eax, [cache_chain_ptr] |
mov eax, [eax] |
call int13_call |
test eax, eax |
jnz .v86err |
cmp edx, ecx |
jnz .writeerr |
popa |
ret |
.v86err: |
.writeerr: |
popa |
mov [hd_error], 1 |
jmp hd_write_error |
uglobal |
int13_regs_in rb v86_regs.size |
int13_regs_out rb v86_regs.size |
endg |
int13_call: |
; Because this code uses fixed addresses, |
; it can not be run simultaniously by many threads. |
; In current implementation it is protected by common mutex 'hd1_status' |
mov word [BOOT_VAR + 510h], 10h ; packet length |
mov word [BOOT_VAR + 512h], cx ; number of sectors |
mov dword [BOOT_VAR + 514h], 9A000000h ; buffer 9A00:0000 |
mov dword [BOOT_VAR + 518h], eax |
and dword [BOOT_VAR + 51Ch], 0 |
push ebx ecx esi edi |
mov ebx, int13_regs_in |
mov edi, ebx |
mov ecx, v86_regs.size/4 |
xor eax, eax |
rep stosd |
mov byte [ebx+v86_regs.eax+1], dl |
mov eax, [hdpos] |
lea eax, [BiosDisksData+(eax-80h)*4] |
mov dl, [eax] |
mov byte [ebx+v86_regs.edx], dl |
movzx edx, byte [eax+1] |
; mov dl, 5 |
test edx, edx |
jnz .hasirq |
dec edx |
jmp @f |
.hasirq: |
pushad |
stdcall enable_irq, edx |
popad |
@@: |
mov word [ebx+v86_regs.esi], 510h |
mov word [ebx+v86_regs.ss], 9000h |
mov word [ebx+v86_regs.esp], 0A000h |
mov word [ebx+v86_regs.eip], 500h |
mov [ebx+v86_regs.eflags], 20200h |
mov esi, [sys_v86_machine] |
mov ecx, 0x502 |
call v86_start |
and [bios_hdpos], 0 |
pop edi esi ecx ebx |
movzx edx, byte [BOOT_VAR + 512h] |
test byte [int13_regs_out+v86_regs.eflags], 1 |
jnz @f |
mov edx, ecx |
@@: |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc |
---|
0,0 → 1,71 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
uglobal |
dmasize db 0x0 |
dmamode db 0x0 |
endg |
fdc_init: ;start with clean tracks. |
mov edi,OS_BASE+0xD201 |
mov al,0 |
mov ecx,160 |
rep stosb |
ret |
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |
save_image: |
call reserve_flp |
call restorefatchain |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
mov esi,RAMDISK |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
popa |
mov [flp_status],0 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/ide_cache.inc |
---|
0,0 → 1,922 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;************************************************************************** |
; |
; [cache_ide[X]_pointer] |
; or [cache_ide[X]_data_pointer] first entry in cache list |
; |
; +0 - lba sector |
; +4 - state of cache sector |
; 0 = empty |
; 1 = used for read ( same as in hd ) |
; 2 = used for write ( differs from hd ) |
; |
; [cache_ide[X]_system_data] |
; or [cache_ide[x]_appl_data] - cache entries |
; |
;************************************************************************** |
$Revision$ |
align 4 |
write_cache: |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
push eax ecx edx esi edi |
; write difference ( 2 ) from cache to hd |
call calculate_cache |
add esi,8 |
mov edi,1 |
write_cache_more: |
cmp dword [esi+4],2 ; if cache slot is not different |
jne .write_chain |
mov dword [esi+4],1 ; same as in hd |
mov eax,[esi] ; eax = sector to write |
cmp eax,[PARTITION_START] |
jb danger |
cmp eax,[PARTITION_END] |
ja danger |
cmp [hdpos], 0x80 |
jae @f |
; DMA write is permitted only if [allow_dma_access]=1 |
cmp [allow_dma_access], 2 |
jae .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
@@: |
; ¡ê¥¤¨ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+8+4], 2 |
jnz .nonext |
push eax |
inc eax |
cmp eax, [esi+8] |
pop eax |
jnz .nonext |
cmp [cache_chain_started], 1 |
jz @f |
mov [cache_chain_started], 1 |
mov [cache_chain_size], 0 |
mov [cache_chain_pos], edi |
mov [cache_chain_ptr], esi |
@@: |
inc [cache_chain_size] |
cmp [cache_chain_size], 16 |
jnz .continue |
jmp .write_chain |
.nonext: |
call flush_cache_chain |
mov [cache_chain_size], 1 |
mov [cache_chain_ptr], esi |
call write_cache_sector |
jmp .continue |
.nodma: |
call cache_write_pio |
.write_chain: |
call flush_cache_chain |
.continue: |
danger: |
add esi,8 |
inc edi |
dec ecx |
jnz write_cache_more |
call flush_cache_chain |
return_02: |
pop edi esi edx ecx eax |
ret |
flush_cache_chain: |
cmp [cache_chain_started], 0 |
jz @f |
call write_cache_chain |
mov [cache_chain_started], 0 |
@@: |
ret |
;-------------------------------------------------------------------- |
align 4 |
find_empty_slot: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
; push ecx esi |
search_again: |
call calculate_cache_3 |
shr ecx,3 |
search_for_empty: |
inc edi |
call calculate_cache_4 |
jbe inside_cache |
mov edi,1 |
inside_cache: |
push esi |
call calculate_cache_1 |
cmp dword [edi*8+esi+4],2 |
pop esi |
jb found_slot ; it's empty or read |
dec ecx |
jnz search_for_empty |
call write_cache ; no empty slots found, write all |
cmp [hd_error],0 |
jne found_slot_access_denied |
jmp search_again ; and start again |
found_slot: |
call calculate_cache_5 |
found_slot_access_denied: |
ret |
;-------------------------------------------------------------------- |
align 4 |
clear_hd_cache: |
mov [fat_in_cache],-1 |
mov [fat_change],0 |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache: |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov esi,[cache_ide3_data_pointer] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] |
mov esi,[cache_ide0_pointer-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] |
mov esi,[cache_ide0_data_pointer-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_1: |
; lea esi,[edi*8+HD_CACHE] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov esi,[cache_ide3_data_pointer] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov esi,[cache_ide0_pointer-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov esi,[cache_ide0_data_pointer-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_2: |
; add esi,HD_CACHE+65536 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov eax,[cache_ide0_system_data] |
ret |
.ide0_appl_data: |
mov eax,[cache_ide0_appl_data] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov eax,[cache_ide1_system_data] |
ret |
.ide1_appl_data: |
mov eax,[cache_ide1_appl_data] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov eax,[cache_ide2_system_data] |
ret |
.ide2_appl_data: |
mov eax,[cache_ide2_appl_data] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov eax,[cache_ide3_system_data] |
ret |
.ide3_appl_data: |
mov eax,[cache_ide3_appl_data] |
ret |
.noide: |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov eax,[cache_ide0_system_data-cache_ide0+eax] |
ret |
.bd_appl_data: |
mov eax,[cache_ide0_appl_data-cache_ide0+eax] |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_3: |
; mov ecx,cache_max*10/100 |
; mov edi,[cache_search_start] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov edi,[cache_ide0_search_start] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov edi,[cache_ide0_appl_search_start] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov edi,[cache_ide1_search_start] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov edi,[cache_ide1_appl_search_start] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov edi,[cache_ide2_search_start] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov edi,[cache_ide2_appl_search_start] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov edi,[cache_ide3_search_start] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov edi,[cache_ide3_appl_search_start] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] |
mov edi,[cache_ide0_search_start-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] |
mov edi,[cache_ide0_appl_search_start-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_4: |
; cmp edi,cache_max |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
cmp edi,[cache_ide0_system_sad_size] |
ret |
.ide0_appl_data: |
cmp edi,[cache_ide0_appl_sad_size] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
cmp edi,[cache_ide1_system_sad_size] |
ret |
.ide1_appl_data: |
cmp edi,[cache_ide1_appl_sad_size] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
cmp edi,[cache_ide2_system_sad_size] |
ret |
.ide2_appl_data: |
cmp edi,[cache_ide2_appl_sad_size] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
cmp edi,[cache_ide3_system_sad_size] |
ret |
.ide3_appl_data: |
cmp edi,[cache_ide3_appl_sad_size] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_5: |
; mov [cache_search_start],edi |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov [cache_ide0_search_start],edi |
ret |
.ide0_appl_data: |
mov [cache_ide0_appl_search_start],edi |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov [cache_ide1_search_start],edi |
ret |
.ide1_appl_data: |
mov [cache_ide1_appl_search_start],edi |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov [cache_ide2_search_start],edi |
ret |
.ide2_appl_data: |
mov [cache_ide2_appl_search_start],edi |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov [cache_ide3_search_start],edi |
ret |
.ide3_appl_data: |
mov [cache_ide3_appl_search_start],edi |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov [cache_ide0_search_start-cache_ide0+eax],edi |
pop eax |
ret |
.bd_appl_data: |
mov [cache_ide0_appl_search_start-cache_ide0+eax],edi |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
find_empty_slot_CD_cache: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
.search_again: |
call cd_calculate_cache_3 |
.search_for_empty: |
inc edi |
call cd_calculate_cache_4 |
jbe .inside_cache |
mov edi,1 |
.inside_cache: |
call cd_calculate_cache_5 |
ret |
;-------------------------------------------------------------------- |
clear_CD_cache: |
pusha |
.ide0: |
xor eax,eax |
cmp [cdpos],1 |
jne .ide1 |
mov [cache_ide0_search_start],eax |
mov ecx,[cache_ide0_system_sad_size] |
mov edi,[cache_ide0_pointer] |
call .clear |
mov [cache_ide0_appl_search_start],eax |
mov ecx,[cache_ide0_appl_sad_size] |
mov edi,[cache_ide0_data_pointer] |
jmp .continue |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
mov [cache_ide1_search_start],eax |
mov ecx,[cache_ide1_system_sad_size] |
mov edi,[cache_ide1_pointer] |
call .clear |
mov [cache_ide1_appl_search_start],eax |
mov ecx,[cache_ide1_appl_sad_size] |
mov edi,[cache_ide1_data_pointer] |
jmp .continue |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
mov [cache_ide2_search_start],eax |
mov ecx,[cache_ide2_system_sad_size] |
mov edi,[cache_ide2_pointer] |
call .clear |
mov [cache_ide2_appl_search_start],eax |
mov ecx,[cache_ide2_appl_sad_size] |
mov edi,[cache_ide2_data_pointer] |
jmp .continue |
.ide3: |
mov [cache_ide3_search_start],eax |
mov ecx,[cache_ide3_system_sad_size] |
mov edi,[cache_ide3_pointer] |
call .clear |
mov [cache_ide3_appl_search_start],eax |
mov ecx,[cache_ide3_appl_sad_size] |
mov edi,[cache_ide3_data_pointer] |
.continue: |
call .clear |
popa |
ret |
.clear: |
shl ecx,1 |
cld |
rep stosd |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache: |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov esi,[cache_ide3_data_pointer] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_1: |
; lea esi,[edi*8+HD_CACHE] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov esi,[cache_ide3_data_pointer] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_2: |
; add esi,HD_CACHE+65536 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov eax,[cache_ide0_system_data] |
ret |
.ide0_appl_data: |
mov eax,[cache_ide0_appl_data] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov eax,[cache_ide1_system_data] |
ret |
.ide1_appl_data: |
mov eax,[cache_ide1_appl_data] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov eax,[cache_ide2_system_data] |
ret |
.ide2_appl_data: |
mov eax,[cache_ide2_appl_data] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov eax,[cache_ide3_system_data] |
ret |
.ide3_appl_data: |
mov eax,[cache_ide3_appl_data] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_3: |
; mov ecx,cache_max*10/100 |
; mov edi,[cache_search_start] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov edi,[cache_ide0_search_start] |
ret |
.ide0_appl_data: |
mov edi,[cache_ide0_appl_search_start] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov edi,[cache_ide1_search_start] |
ret |
.ide1_appl_data: |
mov edi,[cache_ide1_appl_search_start] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov edi,[cache_ide2_search_start] |
ret |
.ide2_appl_data: |
mov edi,[cache_ide2_appl_search_start] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov edi,[cache_ide3_search_start] |
ret |
.ide3_appl_data: |
mov edi,[cache_ide3_appl_search_start] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_4: |
; cmp edi,cache_max |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
cmp edi,[cache_ide0_system_sad_size] |
ret |
.ide0_appl_data: |
cmp edi,[cache_ide0_appl_sad_size] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
cmp edi,[cache_ide1_system_sad_size] |
ret |
.ide1_appl_data: |
cmp edi,[cache_ide1_appl_sad_size] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
cmp edi,[cache_ide2_system_sad_size] |
ret |
.ide2_appl_data: |
cmp edi,[cache_ide2_appl_sad_size] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
cmp edi,[cache_ide3_system_sad_size] |
ret |
.ide3_appl_data: |
cmp edi,[cache_ide3_appl_sad_size] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_5: |
; mov [cache_search_start],edi |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov [cache_ide0_search_start],edi |
ret |
.ide0_appl_data: |
mov [cache_ide0_appl_search_start],edi |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov [cache_ide1_search_start],edi |
ret |
.ide1_appl_data: |
mov [cache_ide1_appl_search_start],edi |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov [cache_ide2_search_start],edi |
ret |
.ide2_appl_data: |
mov [cache_ide2_appl_search_start],edi |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov [cache_ide3_search_start],edi |
ret |
.ide3_appl_data: |
mov [cache_ide3_appl_search_start],edi |
ret |
;-------------------------------------------------------------------- |
;align 4 |
;calculate_linear_to_real: |
; shr eax, 12 |
; mov eax, [page_tabs+eax*4] |
; and eax, 0xFFFFF000 |
; ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc |
---|
0,0 → 1,32 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
saverd_fileinfo: |
dd 2 ; subfunction: write |
dd 0 ; (reserved) |
dd 0 ; (reserved) |
dd 1440*1024 ; size 1440 Kb |
dd RAMDISK |
db 0 |
.name: |
dd ? |
endg |
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) |
call restorefatchain |
mov eax, saverd_fileinfo |
mov [saverd_fileinfo.name], ecx |
pushad |
push eax |
call file_system_lfn |
pop eax |
popad |
mov [esp+32], eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc |
---|
0,0 → 1,271 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
sys_cd_audio: |
cmp word [cdbase],word 0 |
jnz @f |
mov eax,1 |
ret |
@@: |
; eax=1 cdplay at ebx 0x00FFSSMM |
; eax=2 get tracklist size of ecx to [ebx] |
; eax=3 stop/pause playing |
cmp eax,1 |
jnz nocdp |
call sys_cdplay |
ret |
nocdp: |
cmp eax,2 |
jnz nocdtl |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call sys_cdtracklist |
ret |
nocdtl: |
cmp eax,3 |
jnz nocdpause |
call sys_cdpause |
ret |
nocdpause: |
mov eax,0xffffff01 |
ret |
sys_cd_atapi_command: |
pushad |
mov dx,word [cdbase] |
add dx,6 |
mov ax,word [cdid] |
out dx,al |
mov esi,10 |
call delay_ms |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x80 |
cmp al,0 |
jnz res |
jmp cdl6 |
res: |
mov dx,word [cdbase] |
add dx,7 |
mov al,0x8 |
out dx,al |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0xe |
out dx,al |
mov esi,1 |
call delay_ms |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0x8 |
out dx,al |
mov esi,30 |
call delay_ms |
xor cx,cx |
cdl5: |
inc cx |
cmp cx,10 |
jz cdl6 |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x88 |
cmp al,0x00 |
jz cdl5 |
mov esi,100 |
call delay_ms |
jmp cdl5 |
cdl6: |
mov dx,word [cdbase] |
add dx,4 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,5 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,7 |
mov al,0xec |
out dx,al |
mov esi,5 |
call delay_ms |
mov dx,word [cdbase] |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,128 |
out dx,al |
add dx,2 |
mov al,0xa0 |
out dx,al |
xor cx,cx |
mov dx,word [cdbase] |
add dx,7 |
cdl1: |
inc cx |
cmp cx,100 |
jz cdl2 |
in al,dx |
and ax,0x88 |
cmp al,0x8 |
jz cdl2 |
mov esi,2 |
call delay_ms |
jmp cdl1 |
cdl2: |
popad |
ret |
sys_cdplay: |
mov ax,5 |
push ax |
push ebx |
cdplay: |
call sys_cd_atapi_command |
cli |
mov dx,word [cdbase] |
mov ax,0x0047 |
out dx,ax |
mov al,1 |
mov ah,[esp+0] ; min xx |
out dx,ax |
mov ax,[esp+1] ; fr sec |
out dx,ax |
mov ax,256+99 |
out dx,ax |
mov ax,0x0001 |
out dx,ax |
mov ax,0x0000 |
out dx,ax |
mov esi,10 |
call delay_ms |
sti |
add dx,7 |
in al,dx |
test al,1 |
jz cdplayok |
mov ax,[esp+4] |
dec ax |
mov [esp+4],ax |
cmp ax,0 |
jz cdplayfail |
jmp cdplay |
cdplayfail: |
cdplayok: |
pop ebx |
pop ax |
xor eax, eax |
ret |
sys_cdtracklist: |
push ebx |
tcdplay: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x43+2*256 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,200 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
in al,dx |
mov cx,1000 |
mov dx,word [cdbase] |
add dx,7 |
cld |
cdtrnwewait: |
mov esi,10 |
call delay_ms |
in al,dx |
and al,128 |
cmp al,0 |
jz cdtrl1 |
loop cdtrnwewait |
cdtrl1: |
; read the result |
mov ecx,[esp+0] |
mov dx,word [cdbase] |
cdtrread: |
add dx,7 |
in al,dx |
and al,8 |
cmp al,8 |
jnz cdtrdone |
sub dx,7 |
in ax,dx |
mov [ecx],ax |
add ecx,2 |
jmp cdtrread |
cdtrdone: |
pop ecx |
xor eax, eax |
ret |
sys_cdpause: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x004B |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov esi,10 |
call delay_ms |
add dx,7 |
in al,dx |
xor eax, eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/blkdev |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/detect/dev_hdcd.inc |
---|
0,0 → 1,385 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;****************************************************** |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
;****************************************************** |
;**************************************************** |
;* ÏÎÈÑÊ HDD è CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov ax,[Sector512+176] |
; mov [DRIVE_DATA+6],ax |
; mov ax,[Sector512+126] |
; mov [DRIVE_DATA+8],ax |
; mov ax,[Sector512+128] |
; mov [DRIVE_DATA+8],ax |
mov [DiskNumber],1 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+7],al |
inc [ChannelNumber] |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+8],al |
mov [DiskNumber],1 |
call FindHDD_1 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+9],al |
jmp EndFindHDD |
FindHDD_1: |
call ReadHDD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2 |
cmp [Sector512+6],word 16 |
ja FindHDD_2 |
cmp [Sector512+12],word 255 |
ja FindHDD_2 |
inc byte [DRIVE_DATA+1] |
jmp FindHDD_2_2 |
FindHDD_2: |
call DeviceReset |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
call ReadCD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
inc byte [DRIVE_DATA+1] |
inc byte [DRIVE_DATA+1] |
FindHDD_2_2: |
ret |
FindHDD_3: |
call FindHDD_1 |
shl byte [DRIVE_DATA+1],2 |
ret |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
uglobal |
SectorAddress DD ? |
endg |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATAHead],0 |
mov [ATACommand],0ECh |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
mov DX,[ATABasePortAddr] |
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíè |
mov ecx,0xffff |
@@WaitCompleet: |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
dec ecx |
; cmp ecx,0 |
jz @@Error1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw ;ïðèíÿòü áëîê äàííûõ |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Error1: |
mov [DevErrorCode],1 |
ret |
@@Error6: |
mov [DevErrorCode],6 |
@@End: ret |
iglobal |
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2 |
StandardATABases DW 1F0h, 170h |
endg |
uglobal |
; Íîìåð êàíàëà |
ChannelNumber DW ? |
; Íîìåð äèñêà |
DiskNumber DB ? |
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA |
ATABasePortAddr DW ? |
; Ïàðàìåòðû ATA-êîìàíäû |
ATAFeatures DB ? ;îñîáåííîñòè |
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ |
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà |
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà |
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè |
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA) |
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ |
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé |
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè, |
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà, |
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè |
; êîìàíäû) |
DevErrorCode dd ? |
endg |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD: |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3 |
cmp BX,2 |
ja @@Err3 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov ecx,0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
; cmp ecx,0 |
jz @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;îæèäàòü 300 òèêîâ |
; ja @@Err1 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1: mov [DevErrorCode],1 |
ret |
@@Err2: mov [DevErrorCode],2 |
ret |
@@Err3: mov [DevErrorCode],3 |
ret |
@@Err4: mov [DevErrorCode],4 |
ret |
@@Err5: mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadCD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
mov [ATACylinder],0 |
mov [ATAHead],0 |
mov [ATACommand],0A1h |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,0xffff |
@@WaitCompleet_1: |
; Ïðîâåðèòü âðåì |
dec ecx |
; cmp ecx,0 |
jz @@Error1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet_1 |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Error1_1: |
mov [DevErrorCode],1 |
ret |
@@Error6_1: |
mov [DevErrorCode],6 |
@@End_1: |
ret |
;************************************************* |
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1). * |
;************************************************* |
DeviceReset: |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_2 |
cmp BX,2 |
ja @@Err3_2 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov DX,[ebx+StandardATABases] |
mov [ATABasePortAddr],DX |
; Âûáðàòü íóæíûé äèñê |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_2 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Ïîñëàòü êîìàíäó "Ñáðîñ" |
mov AL,08h |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
mov ecx,0x80000 |
@@WaitHDReady_1: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
; cmp ecx,0 |
je @@Err1_2 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_1 |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
ret |
; Îáðàáîòêà îøèáîê |
@@Err1_2: mov [DevErrorCode],1 |
ret |
@@Err3_2: mov [DevErrorCode],3 |
ret |
@@Err4_2: mov [DevErrorCode],4 |
; Çàïèñàòü êîä îøèáêè |
ret |
EndFindHDD: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect/biosdisk.inc |
---|
0,0 → 1,81 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Detect all BIOS hard drives. |
; diamond, 2008 |
xor cx, cx |
mov es, cx |
mov di, 0x9080 |
mov byte [es:di-1], cl |
cmp [preboot_biosdisk], 1 |
jnz bdde |
mov dl, 80h |
bdds: |
mov ah, 15h |
push cx dx di |
int 13h |
pop di dx cx |
jc bddc |
test ah, ah |
jz bddc |
inc cx |
mov ah, 48h |
push ds |
push es |
pop ds |
mov si, 0xA000 |
mov word [si], 1Eh |
mov ah, 48h |
int 13h |
pop ds |
jc bddc2 |
inc byte [es:0x907F] |
cmp word [es:si], 1Eh |
jb bddl |
cmp word [es:si+1Ah], 0xFFFF |
jz bddl |
mov al, dl |
stosb |
push ds |
lds si, [es:si+1Ah] |
mov al, [si+6] |
and al, 0xF |
stosb |
mov al, byte [si+4] |
shr al, 4 |
and ax, 1 |
cmp word [si], 1F0h |
jz @f |
inc ax |
inc ax |
cmp word [si], 170h |
jz @f |
or ax,-1 |
; mov ax, -1 |
@@: |
stosw |
pop ds |
jmp bddc2 |
bddl: |
mov al, dl |
stosb |
xor ax,ax |
stosb |
dec ax |
stosw |
; mov al, 0 |
; stosb |
; mov ax, -1 |
; stosw |
bddc2: |
cmp cl, [es:0x475] |
jae bdde |
bddc: |
inc dl |
jnz bdds |
bdde: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc |
---|
0,0 → 1,30 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;*************************************************** |
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû |
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD |
; àâòîð Mario79 |
;*************************************************** |
xor eax,eax |
mov edi,DRIVE_DATA |
mov ecx,16384 |
cld |
rep stosd |
mov al,0x10 |
out 0x70,al |
mov cx,0xff |
wait_cmos: |
dec cx |
test cx,cx |
jnz wait_cmos |
in al,0x71 |
mov [DRIVE_DATA],al |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect/getcache.inc |
---|
0,0 → 1,212 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
pusha |
mov eax,[pg_data.pages_free] |
; 1/32 |
shr eax,5 |
; round off up to 8 pages |
shr eax,3 |
shl eax,3 |
; translate pages in butes *4096 |
shl eax,12 |
; check a upper size of the cache, no more than 1 Mb on the physical device |
cmp eax,1024*1024 |
jbe @f |
mov eax,1024*1024 |
jmp .continue |
@@: |
; check a lower size of the cache, not less than 128 Kb on the physical device |
cmp eax,128*1024 |
jae @f |
mov eax,128*1024 |
@@: |
.continue: |
mov [cache_ide0_size],eax |
mov [cache_ide1_size],eax |
mov [cache_ide2_size],eax |
mov [cache_ide3_size],eax |
xor eax,eax |
mov [hdd_appl_data],1 ;al |
mov [cd_appl_data],1 |
mov ch,[DRIVE_DATA+1] |
mov cl,ch |
and cl,11b |
je .ide2 |
mov esi,cache_ide3 |
call get_cache_ide |
.ide2: |
mov cl,ch |
shr cl,2 |
and cl,11b |
je .ide1 |
mov esi,cache_ide2 |
call get_cache_ide |
.ide1: |
mov cl,ch |
shr cl,4 |
and cl,11b |
je .ide0 |
mov esi,cache_ide1 |
call get_cache_ide |
.ide0: |
mov cl,ch |
shr cl,6 |
and cl,11b |
je @f |
mov esi,cache_ide0 |
call get_cache_ide |
@@: |
xor ecx,ecx |
cmp [NumBiosDisks],ecx |
jz .endbd |
mov esi,BiosDiskCaches |
.loopbd: |
push ecx |
movsx ecx,byte [BiosDisksData+ecx*4+2] |
inc ecx |
jz .getbd |
add ecx,ecx |
movzx eax,byte [DRIVE_DATA+1] |
shl eax,cl |
and ah,3 |
cmp ah,1 |
jz .contbd |
pop ecx |
mov byte [BiosDisksData+ecx*4+2], -1 |
push ecx |
.getbd: |
mov eax,[cache_ide0_size] |
mov [esi+cache_ide0_size-cache_ide0],eax |
mov cl,1 |
call get_cache_ide |
.contbd: |
pop ecx |
add esi,cache_ide1-cache_ide0 |
inc ecx |
cmp ecx,[NumBiosDisks] |
jb .loopbd |
.endbd: |
jmp end_get_cache |
get_cache_ide: |
and [esi+cache_ide0_search_start-cache_ide0],0 |
and [esi+cache_ide0_appl_search_start-cache_ide0],0 |
push ecx |
stdcall kernel_alloc,[esi+cache_ide0_size-cache_ide0] |
mov [esi+cache_ide0_pointer-cache_ide0],eax |
pop ecx |
mov edx,eax |
mov eax,[esi+cache_ide0_size-cache_ide0] |
shr eax,3 |
mov [esi+cache_ide0_system_data_size-cache_ide0],eax |
mov ebx,eax |
imul eax,7 |
mov [esi+cache_ide0_appl_data_size-cache_ide0],eax |
add ebx,edx |
mov [esi+cache_ide0_data_pointer-cache_ide0],ebx |
cmp cl,10b |
je .cd |
push ecx |
mov eax,[esi+cache_ide0_system_data_size-cache_ide0] |
call calculate_for_hd |
add eax,[esi+cache_ide0_pointer-cache_ide0] |
mov [esi+cache_ide0_system_data-cache_ide0],eax |
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx |
push edi |
mov edi,[esi+cache_ide0_pointer-cache_ide0] |
call clear_ide_cache |
pop edi |
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0] |
call calculate_for_hd |
add eax,[esi+cache_ide0_data_pointer-cache_ide0] |
mov [esi+cache_ide0_appl_data-cache_ide0],eax |
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx |
push edi |
mov edi,[esi+cache_ide0_data_pointer-cache_ide0] |
call clear_ide_cache |
pop edi |
pop ecx |
ret |
.cd: |
push ecx |
mov eax,[esi+cache_ide0_system_data_size-cache_ide0] |
call calculate_for_cd |
add eax,[esi+cache_ide0_pointer-cache_ide0] |
mov [esi+cache_ide0_system_data-cache_ide0],eax |
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx |
push edi |
mov edi,[esi+cache_ide0_pointer-cache_ide0] |
call clear_ide_cache |
pop edi |
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0] |
call calculate_for_cd |
add eax,[esi+cache_ide0_data_pointer-cache_ide0] |
mov [esi+cache_ide0_appl_data-cache_ide0],eax |
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx |
push edi |
mov edi,[esi+cache_ide0_data_pointer-cache_ide0] |
call clear_ide_cache |
pop edi |
pop ecx |
ret |
calculate_for_hd: |
push eax |
mov ebx,eax |
shr eax,9 |
shl eax,3 |
sub ebx,eax |
shr ebx,9 |
mov ecx,ebx |
shl ebx,9 |
pop eax |
sub eax,ebx |
dec ecx |
ret |
calculate_for_cd: |
push eax |
mov ebx,eax |
shr eax,11 |
shl eax,3 |
sub ebx,eax |
shr ebx,11 |
mov ecx,ebx |
shl ebx,11 |
pop eax |
sub eax,ebx |
dec ecx |
ret |
clear_ide_cache: |
push eax |
shl ecx,1 |
xor eax,eax |
cld |
rep stosd |
pop eax |
ret |
end_get_cache: |
; mov [cache_ide0_pointer],HD_CACHE |
; mov [cache_ide0_system_data],HD_CACHE+65536 |
; mov [cache_ide0_system_sad_size],1919 |
popa |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect/biosmem.inc |
---|
0,0 → 1,43 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2009. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Query physical memory map from BIOS. |
; diamond, 2009 |
push ds |
; first call to fn E820 |
mov eax, 0xE820 |
xor ebx, ebx |
mov es, bx |
mov ds, bx |
mov di, 0x9104 |
mov [di-4], ebx ; no blocks yet |
mov ecx, 20 |
mov edx, 0x534D4150 |
int 15h |
jc no_E820 |
cmp eax, 0x534D4150 |
jnz no_E820 |
e820_mem_loop: |
cmp byte [di+16], 1 ; ignore non-free areas |
jnz e820_mem_next |
inc byte [0x9100] |
add di, 20 |
e820_mem_next: |
; consequent calls to fn E820 |
test ebx, ebx |
jz e820_test_done |
cmp byte [0x9100], 32 |
jae e820_test_done |
mov eax, 0xE820 |
int 15h |
jc e820_test_done |
jmp e820_mem_loop |
no_E820: |
; let's hope for mem_test from init.inc |
e820_test_done: |
pop ds |
/kernel/tags/kolibri0.7.7.0/detect/disks.inc |
---|
0,0 → 1,15 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
include 'dev_fd.inc' |
include 'dev_hdcd.inc' |
include 'getcache.inc' |
include 'sear_par.inc' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect/sear_par.inc |
---|
0,0 → 1,153 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;**************************************************** |
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD |
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû |
; àâòîð Mario79 |
;**************************************************** |
mov [transfer_adress],DRIVE_DATA+0xa |
search_partitions_ide0: |
test [DRIVE_DATA+1],byte 0x40 |
jz search_partitions_ide1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],1 |
search_partitions_ide0_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide1 |
inc byte [DRIVE_DATA+2] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide0_1 |
search_partitions_ide1: |
test [DRIVE_DATA+1],byte 0x10 |
jz search_partitions_ide2 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],1 |
search_partitions_ide1_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide2 |
inc byte [DRIVE_DATA+3] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide1_1 |
search_partitions_ide2: |
test [DRIVE_DATA+1],byte 0x4 |
jz search_partitions_ide3 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],1 |
search_partitions_ide2_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide3 |
inc byte [DRIVE_DATA+4] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide2_1 |
search_partitions_ide3: |
test [DRIVE_DATA+1],byte 0x1 |
jz end_search_partitions_ide |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],1 |
search_partitions_ide3_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne end_search_partitions_ide |
inc byte [DRIVE_DATA+5] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide3_1 |
end_search_partitions_ide: |
mov [hdpos], 80h |
mov ecx, [NumBiosDisks] |
test ecx, ecx |
jz end_search_partitions |
start_search_partitions_bd: |
push ecx |
mov eax, [hdpos] |
and [BiosDiskPartitions+(eax-80h)*4], 0 |
mov [fat32part], 1 |
search_partitions_bd: |
call set_FAT32_variables |
cmp [problem_partition], 0 |
jne end_search_partitions_bd |
mov eax, [hdpos] |
inc [BiosDiskPartitions+(eax-80h)*4] |
call partition_data_transfer |
add [transfer_adress], 100 |
inc [fat32part] |
jmp search_partitions_bd |
end_search_partitions_bd: |
pop ecx |
inc [hdpos] |
loop start_search_partitions_bd |
jmp end_search_partitions |
partition_data_transfer: |
mov edi,[transfer_adress] |
mov esi,PARTITION_START |
mov ecx,(file_system_data_size+3)/4 |
rep movsd |
ret |
uglobal |
transfer_adress dd 0 |
endg |
partition_data_transfer_1: |
; cli |
push edi |
mov edi,PARTITION_START |
mov esi,[transfer_adress] |
mov ecx,(file_system_data_size+3)/4 |
rep movsd |
pop edi |
; sti |
ret |
end_search_partitions: |
;PARTITION_START dd 0x3f |
;PARTITION_END dd 0 |
;SECTORS_PER_FAT dd 0x1f3a |
;NUMBER_OF_FATS dd 0x2 |
;SECTORS_PER_CLUSTER dd 0x8 |
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
;ROOT_CLUSTER dd 2 ; first rootdir cluster |
;FAT_START dd 0 ; start of fat table |
;ROOT_START dd 0 ; start of rootdir (only fat16) |
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
;DATA_START dd 0 ; start of data area (=first cluster 2) |
;LAST_CLUSTER dd 0 ; last availabe cluster |
;ADR_FSINFO dd 0 ; used only by fat32 |
; |
;fatRESERVED dd 0x0FFFFFF6 |
;fatBAD dd 0x0FFFFFF7 |
;fatEND dd 0x0FFFFFF8 |
;fatMASK dd 0x0FFFFFFF |
; |
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/detect |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/vmodeint.inc |
---|
0,0 → 1,58 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; |
; Call of videomode driver's functions |
; |
; (Add in System function 21 (and/or 26) as a subfunction 13) |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
uglobal |
old_screen_width dd ? |
old_screen_height dd ? |
endg |
; cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS |
dec ebx |
jnz .no_vmode_drv_access |
pushd [Screen_Max_X] [Screen_Max_Y] |
popd [old_screen_height] [old_screen_width] |
or eax,-1 ; If driver is absent then eax does not change |
call (VMODE_BASE+0x100) ; Entry point of video driver |
mov [esp+36-4],eax |
mov [esp+24-4],ebx |
mov [esp+32-4],ecx |
; mov [esp+28],edx |
mov eax,[old_screen_width] |
mov ebx,[old_screen_height] |
sub eax,[Screen_Max_X] |
jnz @f |
sub ebx,[Screen_Max_Y] |
jz .resolution_wasnt_changed |
jmp .lp1 |
@@: sub ebx,[Screen_Max_Y] |
.lp1: sub [screen_workarea.right],eax |
sub [screen_workarea.bottom],ebx |
call repos_windows |
xor eax,eax |
xor ebx,ebx |
mov ecx, [Screen_Max_X] |
mov edx, [Screen_Max_Y] |
call calculatescreen |
.resolution_wasnt_changed: |
ret |
.no_vmode_drv_access: |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootcode.inc |
---|
0,0 → 1,1191 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;; ;; |
;; BOOTCODE.INC ;; |
;; ;; |
;; KolibriOS 16-bit loader, ;; |
;; based on bootcode for MenuetOS ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;========================================================================== |
; |
; 16 BIT FUNCTIONS |
; |
;========================================================================== |
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 |
test al,al |
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 |
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 |
} |
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 |
jb @b |
mov si, badsect |
sayerr_plain: |
call printplain |
jmp $ |
@@: |
pop si |
ret |
; 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 |
;========================================================================= |
; |
; 16 BIT CODE |
; |
;========================================================================= |
include 'bootvesa.inc' ;Include source for boot vesa |
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 |
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? |
; 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 |
; default value for VRR is OFF |
cmp byte [di+preboot_vrrm-preboot_device], 0 |
jnz @f |
mov byte [di+preboot_vrrm-preboot_device], 2 |
@@: |
; 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' |
jz .change_c |
cmp al, 'd' |
jnz .show_remarks |
_setcursor 15,0 |
mov si, bdev |
call print |
mov bx, '14' |
call getkey |
mov [preboot_device], al |
_setcursor 13,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 |
.change_c: |
_setcursor 15,0 |
mov si, vrrmprint |
call print |
mov bx, '12' |
call getkey |
mov [preboot_vrrm], al |
_setcursor 12,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 ;call back |
.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 |
; GET MEMORY MAP |
include 'detect/biosmem.inc' |
; READ DISKETTE TO MEMORY |
cmp [boot_dev],0 |
jne no_sys_on_floppy |
mov si,diskload |
call print |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
; do we boot from CD-ROM? |
mov ah, 41h |
mov bx, 55AAh |
xor dx, dx |
int 0x13 |
jc .nocd |
cmp bx, 0AA55h |
jnz .nocd |
mov ah, 48h |
push ds |
push es |
pop ds |
mov si, 0xa000 |
mov word [si], 30 |
int 0x13 |
pop ds |
jc .nocd |
push ds |
lds si, [es:si+26] |
test byte [ds:si+10], 40h |
pop ds |
jz .nocd |
; yes - read all floppy by 18 sectors |
; TODO: !!!! read only first sector and set variables !!!!! |
; ... |
; TODO: !!! then read flippy image track by track |
mov cx, 0x0001 ; startcyl,startsector |
.a1: |
push cx dx |
mov al, 18 |
mov bx, 0xa000 |
call boot_read_floppy |
mov si, movedesc |
push es |
push ds |
pop es |
mov cx, 256*18 |
mov ah, 0x87 |
int 0x15 |
pop es |
pop dx cx |
test ah, ah |
jnz sayerr_floppy |
add dword [si+8*3+2], 512*18 |
inc dh |
cmp dh, 2 |
jnz .a1 |
mov dh, 0 |
inc ch |
cmp ch, 80 |
jae ok_sys_on_floppy |
pusha |
mov al, ch |
shr ch, 2 |
add al, ch |
aam |
xchg al, ah |
add ax, '00' |
mov si, pros |
mov [si], ax |
call printplain |
popa |
jmp .a1 |
.nocd: |
; no - read only used sectors from floppy |
; now load floppy image to memory |
; at first load boot sector and first FAT table |
; read only first sector and fill variables |
mov cx, 0x0001 ; first logical sector |
xor dx, dx ; head = 0, drive = 0 (a:) |
mov al, 1 ; read one sector |
mov bx, 0xB000 ; es:bx -> data area |
call boot_read_floppy |
; fill the necessary parameters to work with a floppy |
mov ax, word [es:bx+24] |
mov word [BPB_SecPerTrk], ax |
mov ax, word [es:bx+26] |
mov word [BPB_NumHeads], ax |
mov ax, word [es:bx+17] |
mov word [BPB_RootEntCnt], ax |
mov ax, word [es:bx+14] |
mov word [BPB_RsvdSecCnt], ax |
mov ax, word [es:bx+19] |
mov word [BPB_TotSec16], ax |
mov al, byte [es:bx+13] |
mov byte [BPB_SecPerClus], al |
mov al, byte [es:bx+16] |
mov byte [BPB_NumFATs], al |
;<Lrz> 18.11.2008 |
mov ax, word [es:bx+22] |
mov word [BPB_FATSz16], ax |
mov cx, word [es:bx+11] |
mov word [BPB_BytsPerSec], cx |
; count of clusters in FAT12 ((size_of_FAT*2)/3) |
; mov ax, word [BPB_FATSz16] |
; mov cx, word [BPB_BytsPerSec] |
;end <Lrz> 18.11.2008 |
xor dx, dx |
mul cx |
shl ax, 1 |
mov cx, 3 |
div cx ; now ax - number of clusters in FAT12 |
mov word [end_of_FAT], ax |
; load first FAT table |
mov cx, 0x0002 ; startcyl,startsector ; TODO!!!!! |
xor dx, dx ; starthead,drive |
mov al, byte [BPB_FATSz16] ; no of sectors to read |
add bx, word [BPB_BytsPerSec] ; es:bx -> data area |
call boot_read_floppy |
mov bx, 0xB000 |
; and copy them to extended memory |
mov si, movedesc |
mov [si+8*2+3], bh ; from |
mov ax, word [BPB_BytsPerSec] |
shr ax, 1 ; words per sector |
mov cx, word [BPB_RsvdSecCnt] |
add cx, word [BPB_FATSz16] |
mul cx |
push ax ; save to stack count of words in boot+FAT |
xchg ax, cx |
push es |
push ds |
pop es |
mov ah, 0x87 |
int 0x15 |
pop es |
test ah, ah |
jz @f |
sayerr_floppy: |
mov dx, 0x3f2 |
mov al, 0 |
out dx, al |
mov si, memmovefailed |
jmp sayerr_plain |
@@: |
pop ax ; restore from stack count of words in boot+FAT |
shl ax, 1 ; make bytes count from count of words |
and eax, 0ffffh |
add dword [si+8*3+2], eax |
; copy first FAT to second copy |
; TODO: BPB_NumFATs !!!!! |
add bx, word [BPB_BytsPerSec] ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!! |
mov byte [si+8*2+3], bh ; bx - begin of FAT |
mov ax, word [BPB_BytsPerSec] |
shr ax, 1 ; words per sector |
mov cx, word [BPB_FATSz16] |
mul cx |
mov cx, ax ; cx - count of words in FAT |
push es |
push ds |
pop es |
mov ah, 0x87 |
int 0x15 |
pop es |
test ah, ah |
jnz sayerr_floppy |
mov ax, cx |
shl ax, 1 |
and eax, 0ffffh ; ax - count of bytes in FAT |
add dword [si+8*3+2], eax |
; reading RootDir |
; TODO: BPB_NumFATs |
add bx, ax |
add bx, 100h |
and bx, 0ff00h ; bx - place in buffer to write RootDir |
push bx |
mov bx, word [BPB_BytsPerSec] |
shr bx, 5 ; divide bx by 32 |
mov ax, word [BPB_RootEntCnt] |
xor dx, dx |
div bx |
push ax ; ax - count of RootDir sectors |
mov ax, word [BPB_FATSz16] |
xor cx, cx |
mov cl, byte [BPB_NumFATs] |
mul cx |
add ax, word [BPB_RsvdSecCnt] ; ax - first sector of RootDir |
mov word [FirstDataSector], ax |
pop bx |
push bx |
add word [FirstDataSector], bx ; Begin of data region of floppy |
; read RootDir |
call conv_abs_to_THS |
pop ax |
pop bx ; place in buffer to write |
push ax |
call boot_read_floppy ; read RootDir into buffer |
; copy RootDir |
mov byte [si+8*2+3], bh ; from buffer |
pop ax ; ax = count of RootDir sectors |
mov cx, word [BPB_BytsPerSec] |
mul cx |
shr ax, 1 |
mov cx, ax ; count of words to copy |
push es |
push ds |
pop es |
mov ah, 0x87 |
int 0x15 |
pop es |
mov ax, cx |
shl ax, 1 |
and eax, 0ffffh ; ax - count of bytes in RootDir |
add dword [si+8*3+2], eax ; add count of bytes copied |
; Reading data clusters from floppy |
mov byte [si+8*2+3], bh |
push bx |
mov di, 2 ; First data cluster |
.read_loop: |
mov bx, di |
shr bx, 1 ; bx+di = di*1.5 |
jnc .even |
test word [es:bx+di+0xB200], 0xFFF0 ; TODO: may not be 0xB200 !!! |
jmp @f |
.even: |
test word [es:bx+di+0xB200], 0xFFF ; TODO: may not be 0xB200 !!! |
@@: |
jz .skip |
; read cluster di |
;.read: |
;conv cluster di to abs. sector ax |
; ax = (N-2) * BPB_SecPerClus + FirstDataSector |
mov ax, di |
sub ax, 2 |
xor bx, bx |
mov bl, byte [BPB_SecPerClus] |
mul bx |
add ax, word [FirstDataSector] |
call conv_abs_to_THS |
pop bx |
push bx |
mov al, byte [BPB_SecPerClus] ; number of sectors in cluster |
call boot_read_floppy |
push es |
push ds |
pop es |
pusha |
; |
mov ax, word [BPB_BytsPerSec] |
xor cx, cx |
mov cl, byte [BPB_SecPerClus] |
mul cx |
shr ax, 1 ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2 |
mov cx, ax ; number of words to copy (count words in cluster) |
; |
mov ah, 0x87 |
int 0x15 ; copy data |
test ah, ah |
popa |
pop es |
jnz sayerr_floppy |
; skip cluster di |
.skip: |
mov ax, word [BPB_BytsPerSec] |
xor cx, cx |
mov cl, byte [BPB_SecPerClus] |
mul cx |
and eax, 0ffffh ; ax - count of bytes in cluster |
add dword [si+8*3+2], eax |
mov ax, word [end_of_FAT] ; max cluster number |
pusha |
; draw percentage |
; total clusters: ax |
; read clusters: di |
xchg ax, di |
mov cx, 100 |
mul cx |
div di |
aam |
xchg al, ah |
add ax, '00' |
mov si, pros |
cmp [si], ax |
jz @f |
mov [si], ax |
call printplain |
@@: |
popa |
inc di |
cmp di, word [end_of_FAT] ; max number of cluster |
jnz .read_loop |
pop bx ; clear stack |
ok_sys_on_floppy: |
mov si, backspace2 |
call printplain |
mov si, okt |
call printplain |
no_sys_on_floppy: |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov dx, 0x3f2 ; floppy motor off |
mov al, 0 |
out dx, al |
; SET GRAPHICS |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/booteng.inc |
---|
0,0 → 1,110 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
$Revision$ |
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 |
;s_bpp db 13,10,186," «ã¡¨ 梥â : " |
; .bpp dw "??" |
; db 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 |
;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 - Videomode not found.",0 |
;modena db "Fatal - VBE 0x112+ required.",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 [abcd] 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 |
;modes_msg dw mode4,mode1,mode2,mode3 |
;modevesa20 db " with LFB",0 |
;modevesa12 db ", VESA 1.2 Bnk",0 |
mode0 db "320x200, EGA/CGA 256 colors",13,10,0 |
mode9 db "640x480, VGA 16 colors",13,10,0 |
;probeno_msg db " (standard mode)",0 |
;probeok_msg db " (check nonstandard modes)",0 |
;dma_msg db " [b] Use DMA for HDD access:",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 CRT-monitor, enable VRR in the item [c].",0 |
remark3 db "If the system does not boot, try to disable the item [b].",0 |
remarks dw remark1, remark2, remark3 |
num_remarks = 3 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootet.inc |
---|
0,0 → 1,115 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
$Revision$ |
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 CRT-monitor, enable VRR in the item [c].",0 |
remark3 db "If the system does not boot, try to disable the item [b].",0 |
remarks dw remark1, remark2, remark3 |
num_remarks = 3 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootge.inc |
---|
0,0 → 1,120 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
$Revision$ |
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 CRT-monitor, enable VRR in the item [c].",0 |
remark3 db "If the system does not boot, try to disable the item [b].",0 |
remarks dw remark1, remark2, remark3 |
num_remarks = 3 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootru.inc |
---|
0,0 → 1,91 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;================================================================= |
; |
; BOOT DATA |
; |
;================================================================= |
$Revision$ |
d80x25_bottom: |
db 186,' Kolibri OS ®á®¢ Menuet OS ¨ ¥ ¯à¥¤®áâ ¢«ï¥â ' |
db '¨ª ª¨å £ àa⨩. ',186 |
db 186,' ®¤à®¡¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
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 " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤ ¢ ¢ë¡®à ०¨¬®¢.",0 |
badsect db 13,10,186," 訡ª - ¨áª¥â ¯®¢à¥¦¤¥ . ®¯à®¡ã©â¥ ¤àã£ãî.",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 " ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [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 " ᫨ ã á -¬®¨â®à, ¢ª«îç¨â¥ VRR ¢ ¯ãªâ¥ [c].",0 |
remark3 db " ᫨ ã á ¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ãªâ [b].",0 |
remarks dw remark1, remark2, remark3 |
num_remarks = 3 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc |
---|
0,0 → 1,755 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
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 |
;============================================================================= |
;============================================================================= |
;============================================================================= |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/ru.inc |
---|
0,0 → 1,102 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/preboot.inc |
---|
0,0 → 1,38 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/bootstr.inc |
---|
0,0 → 1,62 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/et.inc |
---|
0,0 → 1,16 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Full ASCII code font |
; only õ and ä added |
; Kaitz |
ET_FNT: |
fontfile file "ETFONT.FNT" |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/shutdown.inc |
---|
0,0 → 1,209 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/rdload.inc |
---|
0,0 → 1,125 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; 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: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot/ETFONT.FNT |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/boot |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/build_ru.bat |
---|
0,0 → 1,4 |
@fasm -m 65535 loader.asm loader |
@echo off |
REM @fasm -m 65535 loader.asm loader > loader.lst |
REM @pause |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/debug_msg.inc |
---|
0,0 → 1,77 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_def_sect.inc |
---|
0,0 → 1,2094 |
; 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. |
;***************************************************************************** |
; â ýòîé ñåêöèè èäåò ðàçáîð ïàðàìåòðîâ óêàçàòåëü íà ñåêöèþ õðàíèòüñÿ â point_default |
;òèïû îøèáîê ïðè îáðàáîòêå ìàêðîñà |
;Ìàêðîñ RamdiskFS |
;/îïðåäåëåíèå ôëàãîâ â çàïèñè êîðíåâîé äèðåêòîðèè |
ATTR_READ_ONLY equ 0x01 |
ATTR_HIDDEN equ 0x02 |
ATTR_SYSTEM equ 0x04 |
ATTR_VOLUME_ID equ 0x08 |
ATTR_DIRECTORY equ 0x10 |
ATTR_ARCHIVE equ 0x20 |
show_error_1 equ 0x1 ;êîí÷èëèñü äàííûå - íå çàïëàíèðîâàííûé êîíåö ñåêöèè |
show_error_2 equ 0x2 ;íåò çàâåðøàþùåãî ñèìâîëà â ðàçìåðå ðàì äèñêà. |
show_error_3 equ 0x4 ; ðàì äèñê áóäåò èìåòü ðàçìåð =64 êá. |
show_error_4 equ 0x8 ; |
macro use_parse_def_sect |
{ |
mov di,point_default |
push ini_data_ |
pop es |
mov si,point_to_point_def |
sub si,2 |
mov cx,[si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ |
xor ax,ax ;îáíóëèì àx äëÿ î÷èñòêè ôëàãîâ |
sub cx,di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð |
mov save_cx_d,cx ;ñîõðàíèì çíà÷åíèå cx ñâîåé ïåðåìåííîé |
;îáíóëèì ïåðåìåííóþ ôëàãîâ, ýòî íåîáõîäèìî, äëÿ òîãî, ÷òî áû èçáåæàòü îáðàáîòêó ïîâòîðÿþùèõñÿ çíà÷åíèé |
mov status_flag,ax |
;;;; |
;ÂÕîä â îáðàáîòêó ïàðñèíãà çíà÷åíèé ñåêöèé. es:di - óêàçàòåëü íà íà÷àëî ñåêöèè cx ðàçìåð ñåêöèè äîñòóïíîé äëÿ ïàðñèíãà |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;ñîãëàøåíèå íå ðàçðóøàåì bp, es, cs, sp |
;use_Loader_Image ;çàãðóçèòü îáðàç âûøå 1 ìá |
use_RamdiskFS |
;ïðîâåðÿåòñÿ ñàìûé ïîñëåäíèé. |
use_LoaderModule ;îñîáåííîñòü - ïåðåäàåò óïðàâëåíèå íà çàãðóæåííûé ìîäóëü. |
} |
macro use_LoaderModule |
;êàê âàðèàíò ñåé÷àñ èñïîëüçóåòñÿ ìîäåëü, ïðè çàãðóçêå ìîäóëÿ íà íåãî ïåðåäàåòñÿ óïðàâëåíèå, ðåøåíèå âðåìåíîå |
;óïðàâëåíèå áóäåò ïåðåäàâàòüñÿ òîëüêî ïîñëå îáðàáîòêè âñåé ñåêöèè |
{ |
local .found_end_str |
mov di,point_default ;restore value |
mov cx,save_cx_d |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_p_LM: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz ._afterLoaderModule ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'L' |
jnz .start_p_LM |
;ïðîâåðêà íà çíà÷åíèå LoaderModule |
; parse_LoaderModule |
mov bx,cx |
mov ax,di |
mov si,parse_LoaderModule |
mov cx,parse_LoaderModule_e - parse_LoaderModule |
repe cmpsb |
jnz .rest_value_loop_LM ;is not compare |
sub bx,parse_LoaderModule_e - parse_LoaderModule ;correct cx |
add bx,cx |
mov cx,bx |
test status_flag,flag_found_LM ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_LM |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
.correct_is_not_set_LM: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .rest_value_loop_LM ;not found param timeout |
cmp ah,byte [es:di-1] ;find '=' |
jnz .rest_value_loop_LM |
repe scasb ;cut ' ' |
inc cx |
dec di |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
push dword [es:di-6] |
lea si,[di-6] |
push word [es:di-2] |
xor ax,ax |
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4],ax |
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì |
;;;;;; ïîèñê êîíöà ñòðî÷êè |
@@: mov al,byte [es:di] |
cmp al,' ' |
jz .found_end_str |
cmp al,0xa |
jz .found_end_str |
cmp al,0xd |
jz .found_end_str |
inc di |
dec cx |
jnz @b |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè |
.found_end_str: |
push word [es:di] |
xor ax,ax |
mov word [es:di],ax |
; xor ax,ax ; function 1 - read file |
mov di,si ;file_data |
inc ax |
push si |
push es |
push es |
pop ds |
push cs |
pop es |
call far dword [es:loader_callback] |
push cs |
pop ds |
pop es |
pop si |
test bx,bx |
jnz .error_LM |
jmp far dword [es:si] |
.error_LM: |
call error.LoaderModule |
.rest_value_loop_LM: |
mov di,ax |
mov cx,bx |
jmp .start_p_LM |
._afterLoaderModule: |
} |
macro use_RamdiskFS |
; ôîðìèðîâàíèå ðàì äèñêà, + îáðàáîòêà âñåãî ñâÿçàííîãî. |
{ |
if DEBUG |
local ._not_memory_in_sys |
;//////// clear window |
mov ax,3 |
int 0x10 |
;\\\\\\\\\ clear window is end |
mov si,ramdiskFS_st |
call printplain |
end if |
; îáíóëèì ðåãèñòð ñîñòîÿíèÿ îøèáîê |
xor ax,ax |
mov show_errors_sect,ax |
use_free_memory ; óçíàåì êàêîãî îáúåìà ó íàñ äîñòóïíà ïàìÿòü. çíà÷åíèå âîçàðàùàåòñÿ â ax |
;óçíàåì ñêîëüêî ó íàñ åñòü ïàìÿòè è ñìîæåì ëè ìû ñôîðìèðîâàòü íóæíîãî ðàçìåðà ðàì äèñê. |
use_RamdiskSize ;çíà÷åíèå âîçâðàùàåòñÿ â bx |
cmp free_ad_memory,bx ; ðàçìåðíîñòü â êá. |
jbe ._not_memory_in_sys |
movzx eax,bx |
shl eax,10 ;*1024 = get size in byte |
mov save_ramdisksize,eax ; ñîðõàíèì ðàçìåð â byte |
get_type_FS ;ïîëó÷èì òèï ôàéëîâîé ñèñòåìû + ñîçäàäèì åå |
._not_memory_in_sys: |
if DEBUG |
;pause |
xor ax,ax |
int 0x16 |
end if |
} |
macro use_RamdiskSize |
{ |
local .start_p_RS |
local .correct_is_not_set_RS |
local .CS |
local .correct_val_RS |
local .correct_size_RS |
local .rest_value_loop_RS |
local .end_get_RS_ERROR_1 |
local .end_get_RS_ERROR_2 |
local ._end_parse_RS |
;îáðàáàòûâàåòñÿ ðàçìåð ôîðìèðóåìîãî ðàì äèñêà |
;çàãðóçèì íà÷àëî ñåêöèè, ò.ê. áóäåì ïðîñìàòðèâàòü ñ íà÷àëà è âñþ ñåêöèþ |
mov di,point_default ;restore value |
mov cx,save_cx_d |
.start_p_RS: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz ._end_parse_RS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'R' |
jnz .start_p_RS |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx,cx |
mov ax,di |
mov si,parse_RamdiskSize |
mov cx,parse_RamdiskSize_e - parse_RamdiskSize |
repe cmpsb |
jnz .rest_value_loop_RS ;is not compare |
sub bx,parse_RamdiskSize_e - parse_RamdiskSize ;correct cx |
add bx,cx |
mov cx,bx |
test status_flag,flag_found_RS ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RS |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
.correct_is_not_set_RS: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .end_get_RS_ERROR_1 ;not found param |
cmp ah,byte [es:di-1] ;find '=' |
jnz .start_p_RS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå. |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
xor bx,bx |
mov cx,5 |
@@: mov al,byte [es:di] |
cmp al,'0' |
jb .CS |
cmp al,'9' |
jbe .correct_val_RS |
.CS: |
cmp al,'K' |
jz .correct_size_RS |
jmp .end_get_RS_ERROR_2 |
.correct_val_RS: |
imul bx,10 |
xor al,0x30 |
add bl,al |
inc di |
loop @b |
.correct_size_RS: |
;âîçìîæåí 1 âàðèàíò, êîãäà ðàçìåð çàäàí â K êèëëîáàéòàõ |
;âíóòðåííûé ôîðìàò äàííûõ ýòî êîë-âî çàïðîùåíîé ïàìÿòè â êá. |
test bx,bx |
jnz @f ;åñëè çíà÷åíèå îòëè÷íî îò 0 |
;;;;;ñîîáùåíèå îá îøèáêå, ðàçìåð "íàéäåíîãî" áëîêà =0 ìèíèìàëüíî ìû äîëæíû |
;óñòàíîâèòü 64 êá ðàçìåð ðàì äèñêà. |
or show_errors_sect,show_error_3 |
mov bx,64 |
@@: |
jmp ._end_parse_RS |
.rest_value_loop_RS: |
mov di,ax |
mov cx,bx |
jmp .start_p_RS |
.end_get_RS_ERROR_1: |
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :( |
or show_errors_sect,show_error_1 |
jmp ._end_parse_RS |
.end_get_RS_ERROR_2: |
or show_errors_sect,show_error_2 |
._end_parse_RS: |
if DEBUG |
pusha |
movzx eax,bx |
mov cx,0x0a |
mov di,RamdiskSize_msg |
mov dword[ds:di],' ' |
mov word [ds:di+4],' ' |
call decode |
;Show size |
mov si,RamdiskSize_msg |
call printplain |
popa |
end if |
} |
macro use_free_memory |
{ |
local _support_function_use_free_memory |
;ìàêðîñ äëÿ ïîëó÷åíèÿ îáùåãî ÷èñëà äîñòóïíîé ïàìÿòè â êá, äëÿ ôîðìèðîâàíèÿ ðàì äèñêà çà ïðåäåëàìè 1 ìá. |
;èñïîëüçóåòñÿ 0õ88 ôóíêöèÿ 0õ15 ïðåðûâàíèÿ |
; åñëè ïîääåðæèâàåòñÿ ôóíêöèÿ, òî â ax çíà÷åíèå â êá, åñëè íåò, òî â ax=0 |
mov ah,0x88 ;ah,0x88 |
int 0x15 |
jnc ._support_function_use_free_memory |
xor ax,ax |
;âîçâðàùàåò â ax ÷èñëî â êá |
._support_function_use_free_memory: |
mov free_ad_memory,ax ; åñëè íå ïîääåðæèâàåòñÿ áèîñîì, òî â ax=0 |
if DEBUG |
pushad |
movzx eax,ax |
mov cx,0x0a |
mov di,free_memory_msg |
mov dword[ds:di],' ' |
mov word [ds:di+4],' ' |
call decode |
;Show size |
mov si,free_memory_msg |
call printplain |
popad |
end if |
} |
macro show_ERRORS |
{ |
} |
macro get_type_FS ;ïîëó÷èòü è ñîçäàòü îáðàç äëÿ çàäàííîé RFS. |
{ |
mov di,point_default ;restore value |
mov cx,save_cx_d |
.start_g_tpe_RFS: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz ._end_parse_FRS ;._end_get_type_RFS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'R' |
jnz .start_g_tpe_RFS |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx,cx |
mov ax,di |
mov si,parse_RamdiskFS |
mov cx,parse_RamdiskFS_e - parse_RamdiskFS |
repe cmpsb |
jnz .start_g_tpe_RFS_rest_v ;is not compare |
sub bx,parse_RamdiskFS_e - parse_RamdiskFS ;correct cx |
add bx,cx |
mov cx,bx |
test status_flag,flag_found_GTRFMS ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_FRS |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
.correct_is_not_set_FRS: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
test cx,cx |
jz .end_get_FRS_ERROR_1 ;not found param |
cmp ah,byte [es:di-1] ;find '=' |
jnz .start_g_tpe_RFS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå. |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov bx,cx |
mov ax,di |
mov si,parse_RFS_FAT |
mov cx,parse_RFS_FAT_e - parse_RFS_FAT |
repe cmpsb |
jnz .krfs_cmp ;is not compare |
make_FAT_RamFS ;ñäåëàòü |
if DEBUG |
pusha |
mov si,make_fat12_RFS_msg |
call printplain |
popa |
end if |
jmp ._end_parse_FRS |
.krfs_cmp: |
mov cx,bx |
mov di,ax |
mov si,parse_RFS_KRFS |
mov cx,parse_RFS_KRFS_e - parse_RFS_KRFS |
repe cmpsb |
; jnz @f ;is not compare |
jmp ._end_parse_FRS |
.start_g_tpe_RFS_rest_v: |
mov cx,bx |
mov di,ax |
jmp .start_g_tpe_RFS |
.end_get_FRS_ERROR_1: |
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :( |
or show_errors_sect,show_error_1 |
jmp ._end_parse_FRS |
.end_get_FRS_ERROR_2: |
or show_errors_sect,show_error_2 |
._end_parse_FRS: |
if DEBUG |
pusha |
mov si,get_type_FS_msg |
call printplain |
popa |
end if |
} |
macro make_FAT_RamFS |
{ |
local .RS1 |
local .fat12 |
local .fat16 |
; ìû äîëæíû ñôîðìèðîâàòü â íà÷àëüíûé îáðàç Ram FS, à ïîòîì çàïèñàòü åãî çà îáëàñòü âûøå 1 ìá.. |
;äëÿ ñëó÷àÿ ñ FAT12 |
; mov di,fat12_buffer ;ds äîëæåí áûòü = cs |
;es:di - óêàçûâàþò íà íà÷àëî áëîêà äëÿ ôîðìèðîâàíèÿ ðàì ôñ. |
use_RamdiskSector ;âîçðàùàåìîå çíà÷åíèå â ax ðàçìåð ñåêòîðà â áàéòàõ |
cmp ax,4096 ;ïî ñïåöèôèêàöèè çíà÷åíèå äîëæíî áûòü â ïðåäåëàõ îò 1 äî 4096 |
ja .RS1 |
test ax,ax |
jnz @f ;îøèáêà åñëè ñþäà ïðûãíóëè âñå òàêè ... |
.RS1: mov word [fat12_buffer.BPB_BytsPerSec],512 |
;;;;;;;;;;ñêàæåì ÷òî ïî äåôîëòó áóäåì þçàòü çíà÷åíèå... |
@@: mov word [fat12_buffer.BPB_BytsPerSec],ax ;òóò âñå îê |
;BPB_SecPerClus êîë-âî ñåêòîðîâ â êëàñòåðå |
use_RamdiskCluster ;âîçðàùàåìîå çíà÷åíèå â al |
cmp al,128 |
ja @f |
; test al,0x1 ;ïðîâåðêà íà êðàòíîñòü ) |
; jnz @f |
mov byte [fat12_buffer.BPB_SecPerClus],al |
;incorrect value will be set dafault |
;íèæå íåêîððåêòíîå çíà÷åíèå â ò.ê. ðàçìåð êðàòåí 2 è â äèàïàçîíå îò 1 äî 128 âêëþ÷èòåëüíî |
; ìû äîëæíû ðóãíóòüñÿ íà ýòî |
;@@: ;mov byte [fat12_buffer.BPB_SecPerClus],1 |
;;;;; îïðåäåëåèì êàêàÿ ó íàñ áóäåò èñïîëüçîâàòüñÿ FAT |
;ïî óñëîâèþ, fat12<4085<=fat16<65525<=fat32 |
; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = êîë-âî ñåêòîðîâ |
movzx eax,word [fat12_buffer.BPB_BytsPerSec] |
movzx ebx,byte [fat12_buffer.BPB_SecPerClus] |
imul ebx,eax ;òóò ðàçìåðíîñòü ñåêòîðà |
mov eax,save_ramdisksize ;ðàçìåð çàïðîøåííîãî ðàì äèñêà â áàéòàõ |
cdq |
idiv ebx |
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx |
;ïîëó÷èì êîë-âî ñåêòîðîâ, è ìîæåì óæå îïðåäåëèòü òèï FAT êîòîðóþ íóæíî äåëàòü. |
cmp eax,4085 |
jb .fat12 |
cmp eax,65525 |
jb .fat16 |
;;;;;;;;;;;;;;;;;;;;;;;; òóò fat32 |
mov set_ramfs,32 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
mov word [fat12_buffer.BPB_RsvdSecCnt],32 |
xor eax,eax |
mov word [fat12_buffer.BPB_RootEntCnt],ax |
mov word [fat12_buffer.BPB_TotSec16],ax |
mov dword [fat12_buffer.BPB_TotSec32],eax |
.fat16: ;fat16 |
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000). |
jmp $ |
mov set_ramfs,16 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
movzx ebx,byte [fat12_buffer.BPB_SecPerClus] |
imul eax,ebx |
cmp eax,0x10000 |
jae @f |
mov word [fat12_buffer.BPB_TotSec16],ax |
mov dword [fat12_buffer.BPB_TotSec32],0 |
@@: |
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ?? |
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî |
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî |
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü. |
mov eax,root_dir_entry_count |
mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) |
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá |
;;;;;;; |
;Äëÿ FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. Äëÿ FAT32 ýòî çíà÷åíèå |
;ðàâíî 0, à êîëè÷åñòâî ñåêòîðîâ îäíîé FAT ñîäåðæèòñÿ â BPB_FATSz32. |
;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec; |
;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); |
;TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs; |
;If(FATType == FAT32) |
; TmpVal2 = TmpVal2 / 2; |
;FATSz = (TMPVal1 + (TmpVal2 - 1)) / TmpVal2; |
;If(FATType == FAT32) { |
; BPB_FATSz16 = 0; |
; BPB_FATSz32 = FATSz; |
;} else { |
; BPB_FATSz16 = LOWORD(FATSz); |
; /* there is no BPB_FATSz32 in a FAT16 BPB */ |
;} |
;===================================== |
;RootDirSectors |
movzx ebx, word [fat12_buffer.BPB_BytsPerSec] |
imul eax,32 |
add eax,ebx |
dec eax |
cdq |
idiv ebx |
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx äëÿ äèñêåòû 1.44 ó íàñ äîëæíî áûòü çíà÷åíèå =14 |
;BPB_ResvdSecCnt + RootDirSectors |
movzx ebx, word [fat12_buffer.BPB_RsvdSecCnt] |
add ebx,eax |
;DskSize ó íàñ ýòî çíà÷åíèå óæå ïîëó÷åíî è äîñòóïíî |
movzx eax,word [fat12_buffer.BPB_TotSec16] ;äîëæåí áûòü â ñåêòîðàõ |
sub eax,ebx |
;TmpVal1=eax |
shl edi,8 ;=edi*256 |
movzx ecx,byte [fat12_buffer.BPB_NumFATs] |
add edi,ecx |
;TmpVal2=edi |
add eax,edi |
dec eax |
cdq |
idiv edi |
;FATSz = ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx |
mov word [fat12_buffer.BPB_FATSz16],ax |
.fat12: ;fat12 |
if DEBUG |
; âûâåäåì â îòëàäêå, ÷òî ñîáèðàåìñÿ äåëàòü îáðàç äèñêà c FS=fat12 |
pushad |
mov si,start_making_FAT12_msg |
call printplain |
popad |
end if |
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000). |
mov set_ramfs,12 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
movzx ebx,byte [fat12_buffer.BPB_SecPerClus] |
imul eax,ebx |
cmp eax,0x10000 |
jae @f |
mov word [fat12_buffer.BPB_TotSec16],ax |
mov dword [fat12_buffer.BPB_TotSec32],0 |
@@: |
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ?? |
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî |
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî |
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü. |
mov eax,root_dir_entry_count |
mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) |
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá |
;;;;;;; |
;DskSize(â ñåêòîðàõ)*12 (ðàçìåðíîñòü ôàéëîâîé ñèñòåìû, ò.å ïðåäïîëîæèì ñêîëüêî áèòîâ ïîòðåáóåòñÿ äëÿ àäðåñàöèè ýòîãî îáúåìà) /8 (÷òî ïîëó÷èòü ðàçìåð â áàéòàõ) |
;ïîëó÷åííîå ÷èñëî îêðóãëÿåì â áîëüøóþ ñòîðîíó êðàòíîå ñåêòîðó ò.å. 512 áàéò Òàêîé ïîäõîä íå óíèâåðñàëåí, íî ïîêà ïîéäåò |
;âîîáùå ó ìåëêîñîôò ýòî âñå ñ÷èòàåòñÿ ðó÷êàìè, íî ìû áóäåì þçàòü òîëüêî ïîä êîîñ ðàì äèñê ñ ôàò12 |
movzx eax, word [fat12_buffer.BPB_TotSec16] |
imul eax,12 |
shr eax,3 ;äåëèì íà 8 íî ò.å. íàì íóæíî äåëèòü åùå è íà 512 èëè áîëåå â çàâèñèìîñòè îò ðàçìåðîâ êëàñòåðà |
movzx ebx,word [fat12_buffer.BPB_BytsPerSec] ;ðàçìåð ñåêòîðà |
cdq |
idiv ebx ;ðàçäåëèì íà ðàçìåð êëàñòåðà |
;ñåé÷àñ ó íàñ â eax çíà÷åíèå åãî íóæíî îêðóãëèòü â áîëüøóþ ñòîðîíó êðàòíîìó 512 áàéòàì |
;ïðèìåíèì ñëåäóþùåå î÷èñòèì and è äîáàâèì 512 áàéò. òàêèì îáðàçîì âûðàâíèì íà 512 áàéò |
;íî ò.ê. âñå ðàâíî äåëèòü íèæíèé êîä íàì íå íóæåí |
; and eax,0xfff200 |
; add eax,0x200 ;äîáàâèì 512 áàéò äëÿ 1.44 äèñêåòû èäåàëüíî ïîäõîäèò )) |
inc ax |
;ïî èäåå äîëæíî íà êàæäóþ ôàò òàáëèöó |
;ðåçåðâèðîâàòüñÿ 9 ñåêòîðîâ ò.å. ïîëó÷àåòñÿ 2*9=18+1 =19 ñåêòîðîâ ò.å. ðóò äèð íàõîäèòüñÿ íà ñ 20 ñåòîðà ò.å. ñ àäðåñà 0õ2600 |
;ñåé÷àñ íóæíî âû÷èñëèòü ñêîëüêî áóäåò ñåêòîðîâ çàíèìàòü ôàò ) íóæíî ðàçäåëèòü íà 512 |
;FATSz = ñåé÷àñ ÷àñòíîå â eax |
mov word [fat12_buffer.BPB_FATSz16],ax |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
get_firstDataSector ;ïîëó÷èòü ñìåùåíèå äî äàííûõ |
;ñîçäàäèì ïåâóþ çàïèñü â ôàò ïî îïðåäåëåííîìó àäðåñó. |
first_create_fat_table |
;çàêèíèì BPB ôàéëîâîé ñèñòåìû çà 1 ìá. |
use_BPB_RAM |
; |
;êîïèðîâàíèå ôàéëà. |
use_RamdiskFile |
;;;; âû÷èñëÿåì óêàçàòåëü íà êîðíåâóþ äèð FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); |
; movzx ebx, [fat12_buffer.BPB_NumFATs] |
; movzx eax,ax |
; imul eax,ebx |
;eax=(BPB_NumFATs * BPB_FATSz16) |
; inc eax |
; BPB_ResvdSecCnt çíà÷åíèå òîëüêî 1 äëÿ fat12/16 |
;â eax óêàçàòåëü íà root dir. äëÿ äèñêåòû fat12 äîëæíî ïîëó÷èòüñÿ ïðè êîë-âî êîïèé fat 1 = 1+ (1*1) =2 èëè 3 |
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 |
} |
macro use_RamdiskSector |
{ |
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ |
mov di,point_default ;restore value |
mov cx,save_cx_d |
.start_RamdiskSector: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz .end_RamdiskSector ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'R' |
jnz .start_RamdiskSector |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx,cx |
mov ax,di |
mov si,parse_RamdiskSector |
mov cx,parse_RamdiskSector_e - parse_RamdiskSector |
repe cmpsb |
jnz .RamdiskSector_rest_val ;is not compare |
sub bx,parse_RamdiskSector_e - parse_RamdiskSector ;correct cx |
add bx,cx |
mov cx,bx |
test status_flag,flag_found_RamdiskSector ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RamdiskSector |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
.correct_is_not_set_RamdiskSector: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .end_get_RamS_ERROR_1 ;not found param |
cmp ah,byte [es:di-1] ;find '=' |
jnz .start_RamdiskSector ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
xor bx,bx |
mov cx,4 |
@@: movzx ax,byte [es:di] |
cmp al,'0' |
jb .end_RamdiskSector |
cmp al,'9' |
ja .end_RamdiskSector |
;;;;;;;;;;;;;;;;;;; |
imul bx,10 |
xor al,0x30 |
add bx,ax |
inc di |
loop @b |
jmp .end_RamdiskSector |
.RamdiskSector_rest_val: |
mov cx,bx |
mov di,ax |
jmp .start_RamdiskSector |
.end_get_RamS_ERROR_1: |
.end_RamdiskSector: |
mov ax,bx |
if DEBUG |
pusha |
movzx eax,bx;save_cx_d;point_default |
mov cx,0x0a |
mov di,RamdiskSector_msg |
mov dword[ds:di],' ' |
mov dword [ds:di+4],' ' |
call decode |
;Show size |
mov si,RamdiskSector_msg |
call printplain |
popa |
end if |
; pop di |
; pop es |
} |
macro use_RamdiskCluster |
{ |
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ |
; push es |
; push di |
mov di,point_default ;restore value |
mov cx,save_cx_d |
; push ini_data_ |
; pop es |
.start_RamdiskCluster: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz .end_RamdiskCluster ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'R' |
jnz .start_RamdiskCluster |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx,cx |
mov ax,di |
mov si,parse_RamdiskCluster |
mov cx,parse_RamdiskCluster_e - parse_RamdiskCluster |
repe cmpsb |
jnz .RamdiskCluster_rest_val ;is not compare |
sub bx,parse_RamdiskCluster_e - parse_RamdiskCluster ;correct cx |
add bx,cx |
mov cx,bx |
test status_flag,flag_found_RamdiskCluster ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RamdiskCluster |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
.correct_is_not_set_RamdiskCluster: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .end_get_RamSC_ERROR_1 ;not found param |
cmp ah,byte [es:di-1] ;find '=' |
jnz .start_RamdiskCluster ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
@@: movzx ax,byte [es:di] |
cmp al,'0' |
jb .end_RamdiskCluster |
cmp al,'9' |
ja .end_RamdiskCluster |
;;;;;;;;;;;;;;;;;;; |
xor al,0x30 |
jmp .end_RamdiskCluster |
.RamdiskCluster_rest_val: |
mov cx,bx |
mov di,ax |
jmp .start_RamdiskCluster |
.end_get_RamSC_ERROR_1: |
.end_RamdiskCluster: |
if DEBUG |
pusha |
mov cx,0x0a |
mov di,RamdiskCluster_msg |
; mov word[ds:di],' ' |
call decode |
;Show size |
mov si,RamdiskCluster_msg |
call printplain |
popa |
end if |
} |
macro use_Loader_Image |
;ïðåäíàçíà÷åí äëÿ çàãðóçêè îáðàçîâ âûøå 1 Ìá. |
;ïåðâîíà÷àëüíàÿ âåðñèÿ çàãðóæàåò îáðàç äèñêåòû 1.44 ìá |
{ |
local .start_p_LI |
local .exit |
local .error_LI |
local .rest_value_loop |
local .found_end_str |
mov di,point_default ;restore value |
mov cx,save_cx_d |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_p_LI: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'L' |
jnz .start_p_LI |
;ïðîâåðêà íà çíà÷åíèå LoaderModule |
; parse_LoaderModule |
mov bx,cx |
mov ax,di |
mov si,parse_LoaderImage |
mov cx,parse_LoaderImage_e - parse_LoaderImage |
repe cmpsb |
jnz .rest_value_loop ;is not compare |
sub bx,parse_LoaderImage_e - parse_LoaderImage ;correct cx |
add bx,cx |
mov cx,bx |
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ |
; jz .correct_is_not_set_LI |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
;.correct_is_not_set_LI: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .rest_value_loop_LI ;not found param timeout |
cmp ah,byte [es:di-1] ;find '=' |
jnz .rest_value_loop_LI |
repe scasb ;cut ' ' |
inc cx |
dec di |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
push dword [es:di-6] |
lea si,[di-6] |
push word [es:di-2] |
xor ax,ax |
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4],ax |
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì |
;;;;;; ïîèñê êîíöà ñòðî÷êè |
@@: mov al,byte [es:di] |
cmp al,' ' |
jz .found_end_str |
cmp al,0xa |
jz .found_end_str |
cmp al,0xd |
jz .found_end_str |
inc di |
dec cx |
jnz @b |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè |
.found_end_str: |
; ÷òåíèå áëîêà ïî 64 êá â ñåãìåíò è çàáðàñûâàíèå åãî âûøå 1 ìá. |
push word [es:di] |
xor ax,ax |
mov word [es:di],ax |
; xor ax,ax ; function 1 - read file |
mov di,si ;file_data |
inc ax |
push si |
push es |
call far dword [loader_callback] |
push cs |
pop ds |
pop es |
pop si |
test bx,bx |
jnz .error_LM |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; çàáðàñûâàíèå áëîêà â 64 êá âûøå 1 ìá. |
mov si,table_15_87 |
push es |
push ds |
pop es |
mov cx, 256*18 |
mov ah, 0x87 |
int 0x15 |
pop es |
pop dx cx |
test ah, ah |
jmp far dword [es:si] |
.rest_value_loop: |
mov di,ax |
mov cx,bx |
jmp .start_p_LI |
.exit: |
} |
macro name_in_root_fat |
;ìàêðîñ, êîòîðûé çàïèñûâàåò èíôîðìàöèþ î çàãðóæåííîì ôàéëå â êîðíåâóþ ôàò òàáëèöó |
{ |
} |
macro use_RamdiskFile |
{ |
;çàãðóçêà ôàéëîâ ñ èñïîëüçîâàíèå callback ñåðâèñà ïåðâè÷íîãî çàãðóç÷èêà |
;èñïîëüçóåòñÿ òîëüêî äëÿ çàãðóçêè íåîáõîäèìûõ è íåáîëüøèõ ôàéëîâ, ò.ê. äîñòàòî÷íî ìåäëåííî ðàáîòàåò |
;äëÿ çàãðóçêè èñïîëüçóåò 0õ87 ôóíêöèþ int 0x15 ïðåðûâàíèÿ - çàãðóçêà áëîêîâ äàííûõ äî 64 êá âûøå 1 ìá |
local .start_loop |
local ._end |
local .rest_value_loop |
local .error |
mov di,point_default ;restore value |
mov cx,save_cx_d |
mov data_offset,0 ;clean offset |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_loop: |
call get_firs_sym ;get first symbol on new line |
test cx,cx |
jz ._end ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al,'R' |
jnz .start_loop |
;ïðîâåðêà íà çíà÷åíèå RamdiskFile |
mov bx,cx |
mov ax,di |
mov si,parse_RamdiskFile |
mov cx,parse_RamdiskFile_e - parse_RamdiskFile |
repe cmpsb |
jnz .rest_value_loop ;is not compare |
sub bx,parse_RamdiskFile_e - parse_RamdiskFile ;correct cx |
add bx,cx |
mov cx,bx |
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ |
; jz .correct_is_not_set_LM |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
;.correct_is_not_set_LM: |
mov ax,0x3d20 ;cut al=' ' ah='=' |
repe scasb |
test ecx,ecx |
jz .rest_value_loop ;not found param timeout |
cmp ah,byte [es:di-1] ;find '=' |
jnz .rest_value_loop |
repe scasb ;cut ' ' |
inc cx |
dec di |
mov save_di_RAMDISK,di |
mov save_cx_RAMDISK,cx |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà RamdiskFile = @menu,@menu |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'@menu',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
; |
@@: mov al,byte [es:di] |
cmp al,',' ; ò.å. èùåì ðàçäåëèòåëü |
jz .found_end_str |
inc di |
dec cx |
jnz @b |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðøåíèÿ ñòðîêè |
.found_end_str: |
; mov al,byte [es:di] |
; cmp al,' ' ; óáèðàåì ïðîáåëû, åñëè îíè åñòü |
; jnz @f |
; inc di |
; dec cx |
; jnz .found_end_str |
;@@: |
mov point_to_dest_file_name,di |
inc di |
;ïðîâåðêà èíäèâèäóàëüíîñòè èìåíè ôàéëà |
check_name_file |
;/restore di - point and cx -size section |
mov di,save_di_RAMDISK |
mov cx,save_cx_RAMDISK |
test al,al |
jnz .start_loop ;åñëè â al çíà÷åíèå íå =0, òî òàêîå èìÿ óæå ñóùåñòâóåò â ñèñòåìå. |
push dword [es:di-6] |
lea si,[di-6] |
push word [es:di-2] |
push di |
xor ax,ax |
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4],ax |
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ÷èòàåì |
mov di,point_to_dest_file_name |
if DEBUG |
pushad |
; mov ax,di |
mov cx,0x0a |
mov di,name_of_seg_get_64 |
mov dword[ds:di],' ' |
mov word[ds:di+4],' ' |
call decode |
;Show size |
mov si,name_of_seg_get_64 |
call printplain |
popad |
end if |
push word [es:di] |
push cx |
xor ax,ax |
mov word [es:di],ax |
; xor ax,ax ; function 1 - read file |
push di |
mov di,si ;file_data |
inc ax |
push si |
push es |
push bp |
push es |
pop ds |
push cs |
pop es |
call far dword [es:loader_callback] |
push cs |
pop ds |
pop bp |
pop es |
pop si |
cmp bx,2 |
ja .error |
; ñåé÷àñ ó íàñ â dx:ax ðàçìåð ôàéëà, êîòîðûé ìû çàãðóçèëè. |
; âîçìîæíà ñèòóàöèÿ, êîãäà â bx=1 ò.å. åñòü åùå äàííûå íà äèñêå |
mov status_flag_loader_f,bx |
shl edx,16 |
mov dx,ax |
; shr edx,10 ;ðàçìåð ôàéëà â êá. |
;;â edx ðàçìåð â áàéòàõ. |
mov save_file_size,edx |
mov eax,edx |
;âîññòàíîâèì ïîëíîñòüþ ôàéë ñöåíàðèÿ |
pop di |
pop cx ;äëèííà îñòàòêà ñ 2-îé ÷àñòüþ èìåíè ò.å. ñ èìåíåì íàçíà÷åíèåì. |
pop word [es:di] |
pop di |
pop word [es:di-2] |
pop dword [es:di-6] |
if DEBUG |
pushad |
mov cx,0x0a |
mov di,RamdiskFile_msg |
mov dword[ds:di],' ' |
call decode |
;Show size |
mov si,RamdiskFile_msg |
call printplain |
popad |
end if |
; çàãðóçèì ÷åìó ó íàñ ðàâåí êëàñòåð |
; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà |
; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;êîë-âî ñåêòîðîâ â êëàñòåðå |
; imul ax,bx |
;ñåé÷àñ â eax ðàçìåð êëàñòåðà (512) áàéò |
;â edx äëèíà ôàéëà â áàéòàõ äî 64 êá |
;çàêèíèì ôàéë çà 1 ìá |
;1 íàì íóæíî ñîñòàâèòü ôàò òàáëèöó ò.å. ïðîèçâåñòè ðàçìåòêó ðàìäèñêà, çàòåì ïåðåíåñåì ïî àäðåñó ôàéë |
;çàïèñàòü èíôîðàìàöèþ î ôàéëå â êîðíåâóþ äèðåêòîðèþ |
register_file_in_fat |
;ïåðåíåñòè çà 1 ìá ñîäåðæèìîå ôàéëà |
move_file_up |
;ïðîâåðèì, çàãðóæåí ëè äî êîíöà ôàéë? ò.å. åñëè ðàçìåð ôàéëà áîëüøå ÷åì 64 êá, òî áóäåò ïîäãðóæàòü îñòàâøèåñÿ áëîêè |
cmp status_flag_loader_f,0x1 |
jnz @f |
;íóæíî äîçàãóçèòü äàííûå ôàéëà è ïåðåíåñòè èõ çà 1-ûé ìá ñîãëàñíî ôàò ñòðóêòóðå |
@@: |
;òóò îðãàíèçîâàí öèêë ïî çàãðóçêå ôàéëîâ â êîðíåâóþ äèðåêòîðèþ |
mov di,save_di_RAMDISK |
mov cx,save_cx_RAMDISK |
if DEBUG |
pusha |
xor ax,ax |
int 0x16 |
popa |
end if |
jmp .start_loop |
.error: |
;call error.LoaderModule |
;fixme! |
.rest_value_loop: |
mov di,ax |
mov cx,bx |
jmp .start_loop |
._end: |
;ïåðåíåñåì çà 1-ûé ìá ôàò è ðóò äèð |
move_up_fat_and_root_d |
;çàãðóçêà áëîêà |
; mov ah,0x87 |
; mov cx, ;size in byte |
;es:si point to descripts |
} |
macro use_BPB_RAM ;çàêèíóòü ñàìûå ïåðâûå 512 áàéò çà 1-é ìá |
;äàííûé ìàêðîñ çàêèäûâàåò BPB ñòðóêòóðó ò.å. ïåðâûå 512 áàéò, ïîêà òîëüêî ôàò12 çà 1 ìá |
{ |
mov ax,fat12_buffer |
mov si,table_15_87 |
add word [si+8*2+2],ax |
push es |
push ds |
pop es |
mov cx,256 ;áóò ñåêòîð óêëàäûâàåòñÿ â 512 áàéò 512/2=256 |
mov ah, 0x87 |
int 0x15 |
pop es |
;add 512 byte for destination adress |
; add dword [si+8*3+2], 512 |
; test ah, ah |
; jz |
if DEBUG |
pusha |
mov ax,word [si+8*2+2] |
mov cx,0x0a |
mov di,BPB_msg |
call decode |
;Show size |
mov si,BPB_msg |
call printplain |
popa |
end if |
} |
macro first_create_fat_table |
;äàííûé ìàêðîñ ñîçäàåò îôîðìëÿåò 3 ïåðâûõ áàéòà fat òàáëèöû, è óñòàíàâëèâàåò óêàçàòåëü íà ñëåäóþùèé áëîê, è âíîñèò 0 çíà÷åíèå |
;äëÿ ñìåùåíèÿ â êîðíåâîé òàáëèöå. |
{ |
mov al,byte [fat12_buffer.BPB_Media] |
push ds |
mov di,info_real_mode_size |
add di,0x1000 |
if DEBUG |
pushad |
mov ax,info_real_mode_size |
add ax,0x1000 |
; mov ax,ds |
mov cx,0xa |
mov di,first_entry_in_fat |
mov dword [di],' ' |
mov word [di+4],' ' |
call decode |
;Show size |
mov si,first_entry_in_fat |
call printplain |
xor ax,ax |
int 0x16 |
popad |
end if |
push di ; push word info_real_mode_size+0x1000 ;cëåäóþùèé ñåãìåíò çà çàãðóæåííûì ó÷àñòêîì |
xor di,di |
mov point_to_free_root,di ;çíà÷åíèå ñìåùåíèÿ =0 â êîðíåâîé ôàò òàáëèöå îïèñàíèÿ |
pop ds ; çàãðóæåí ñëåäóþùèé ñåãìåíò ò.å. ïóñòîé ñåãìåíò |
mov byte [di],al |
or ax,-1 |
inc di |
mov word [di],ax |
pop ds |
mov point_next_fat_str,3 |
if DEBUG |
pushad |
mov ax,point_next_fat_str |
mov cx,0x0a |
mov di,fat_create_msg |
call decode |
;Show size |
mov si,fat_create_msg |
call printplain |
popad |
end if |
} |
macro register_file_in_fat |
;ìàêðîñ ðåãèñòðàöèè ôàéëà â ôàéëîâîé ñòðóêòóðå Fat |
;ïîêà ïîääåðæèâàåòñÿ òîëüêî ôàò12, ïîêà )) |
;âû÷èñëåíèå ñìåæíûõ êëàñòåðîâ è çàíåñåíèå èíôû â fat/ |
{ |
local .step2 |
local .step3 |
local .end |
local .eof_file |
;di point on root dir íà ôðè ñåêöèþ. |
push es |
mov ax,info_real_mode_size |
add ax,0x1000 |
mov es,ax ; push word info_real_mode_size+0x1000 ;ñåãìåíò ñëåäóþùèé çà çàãðóæåííûì áëîêîì â 64 êá |
; îïðåäåëÿåì òèï ôàò ïîêà íå îïðåäåëÿåì, ïîêà òîëüêî ôàò 12 |
; 12 áèò, äëÿ âû÷åñëåíèÿ ñîñåäíèõ êàëàñòåðîâ. |
mov di,firstDataSect ;â ñåêòîðàõ |
sub di,size_root_dir |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di,9 ;imul 512 |
add di,point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ. |
;íåîáõîäèìî âíåñòè çíà÷åíèå â ðóò äèð ò.å. 32 áàéòà |
if DEBUG |
pushad |
; mov ax,point_default |
; mov ax, |
mov cx,0x0a |
mov di,show_db2 |
mov dword[ds:di],' ' |
mov word [ds:di+4],' ' |
call decode |
;Show size |
mov si,show_db2 |
call printplain |
; |
; xor ax,ax |
; int 0x16 |
popad |
end if |
;gs:di - óêàçàòåëü äëÿ âíåñåíèÿ èíôîðàöèè â ðóò îáëàñòü ôàò òàáëèöû èíîðìàöèè î ôàéëå. |
mov si,shot_name_fat |
mov cx,11 |
;çàïèøåì â ñòðóêòóðó èìÿ |
@@: lodsb |
stosb |
loop @b |
;çàïèøåì àòðèáóòû ôàéëà è DIR_NTRes - çàðåçåâðèðîâàííûé áàéò =0 |
xor ax,ax |
mov ah,ATTR_VOLUME_ID |
mov word [es:di],ax |
add di,2 |
;DIR_CrtTimeTenth |
mov byte [es:di],100 |
inc di |
;DIR_CrtTime |
mov word [es:di],0x032b ;äàòà |
add di,2 |
;DIR_CrtDate |
mov word [es:di],0x0 ;âðåìÿ >< |
add di,2 |
;DIR_LstAccDate |
mov word [es:di],0x032b ;äàòà ìîåãî |
add di,2 |
;DIR_FstClusHI |
mov word [es:di],0x0 ;âðåìÿ äëÿ ôàò12 /16 âñåãäà 0 |
add di,2 |
;DIR_WrtTime |
mov word [es:di],0x0 ;âðåìÿ >< |
add di,2 |
;DIR_WrtDate |
mov word [es:di],0x032b |
add di,2 |
mov ax,point_next_fat_str |
mov word [es:di],ax |
add di,2 |
push di |
;DIR_FstClusLO Ìëàäøåå ñëîâî íîìåðà ïåðâîãî êëàñòåðà. |
; mov ax,point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè |
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò |
mov bx,ax |
shr bx,1 |
add ax,bx |
;â àõ ñåé÷àñ FATOffset |
;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec); |
mov bx, word [fat12_buffer.BPB_BytsPerSec] |
cwd |
idiv bx |
;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) ÷åòíûé èëè íå÷åòíûé óêàçàòåëü. |
mov si,ax |
;íàì íóæíî â öèêëå çàïèñàòü âñå êëàñòåðû êîòîðûå áóäóò èñïîëüçîâàíû äëÿ ðàçìåùåíèÿ ôàéëà. |
;óçíàåì ðàçìåð êëàñòåðà. |
movzx eax,word [fat12_buffer.BPB_BytsPerSec] |
movzx ebx,byte [fat12_buffer.BPB_SecPerClus] |
imul eax,ebx |
;ax - ðàçìåð êëàñòåðà. |
;ñåé÷àñ áóäåì çàïèñûâàòü âî âðåìåííûé áóôåð ôàò òàáëèöó äëÿ âûáðàííîãî ôàéëà. Ïîñêîëüêó ìû åãî çàãðóçèëè âîçìîæíî íå ïîëíîñòüþ |
;ìû îáðàáîòàåì çàïèñü äëÿ ôàò ïîëíîñòüþ, â íå çàâèñèìîñòè îò ïðåäåëà áóôåðà ãäå âîçìîæíà ÷àñòü ôàéëà. |
mov ebx,save_file_size ;ðàçìåð ôàéëà â áàéòàõ |
@@: sub ebx,eax |
cmp ebx,eax |
jbe .eof_file |
inc point_next_fat_str |
mov cx,point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè |
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò |
mov dx,ax |
shr dx,1 |
add cx,dx |
test si,0x1 |
jz .step2 |
shl cx,4 |
mov word[es:si],cx |
inc si |
add cx,ax |
jmp @b |
.step2: and cx,0x0FFF |
mov word[es:si],cx |
inc si |
add cx,ax |
jmp @b |
.eof_file: |
mov cx,0x0fff |
test si,0x1 |
jz .step3 |
shl cx,4 |
mov word[es:si],cx |
jmp .end |
.step3: and cx,0x0FFF |
mov word[es:si],cx |
.end: inc point_next_fat_str |
pop di |
;DIR_FileSize 32-áèòíûé DWORD ñîäåðæèò ðàçìåð ôàéëà â áàéòàõ. |
mov eax,save_file_size |
mov dword [es:di],eax |
if DEBUG |
pushad |
mov di,firstDataSect ;â ñåêòîðàõ |
sub di,size_root_dir |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di,9 ;imul 512 |
add di,point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ. |
push di |
mov si,dest_name_fat |
mov cx,11 |
;çàïèøåì â ñòðóêòóðó èìÿ |
@@: mov al,byte [es:di] |
inc di |
mov byte [ds:si],al |
inc si |
loop @b |
mov di,si |
inc di |
pop ax |
mov cx,0xa |
call decode |
mov si,dest_name_fat |
call printplain |
popad |
END IF |
add point_to_free_root,32 ;óâåëèöèì ñìåùåíèå äî ñëåäóþùåãî çíà÷åíèÿ. |
pop es |
} |
macro get_firstDataSector |
;ìàêðîñ äëÿ âû÷èñëåíèÿ ïåâîãî ñåêòîðà äàííûõ ò.å. äàííûõ ôàéëîâ â ôàòå |
;âû÷èñëèì FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; |
{ |
mov ax,word [fat12_buffer.BPB_FATSz16] |
movzx bx,byte [fat12_buffer.BPB_NumFATs] |
imul ax,bx ;9x1=9 |
;ax=BPB_NumFATs * FATSz |
mov bx,word [fat12_buffer.BPB_RootEntCnt] ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) |
shr bx,4 ;imul bx,32 and then div 512 -> in bx size in sectors |
add ax,bx ;9+14=23 |
mov size_root_dir,bx |
movzx bx,byte [fat12_buffer.BPB_RsvdSecCnt] ;add 1 for fat 16/12 |
add ax,bx |
;ax=firstDataSector - ãäå íà÷èíàåòñÿ ïåðâûé ñåêòîðî îò 0 ñåêòîðà â ñåêòîðàõ. - ôàêòè÷åñêè = 24 ñåêòîð |
mov firstDataSect,ax ;ñîõðàíèì äëÿ âû÷èñëåíèÿ |
; ïîëó÷èìçíà÷åíèå êëàñòåðîâ, ýòî îáúåì â êîòîðûé ìû ìîæåì çàïèñàòü äàííûå |
mov bx,word [fat12_buffer.BPB_TotSec16] |
sub bx,ax |
mov ax,bx |
movzx bx,byte [fat12_buffer.BPB_SecPerClus] |
cwd |
idiv bx |
mov DataClasters,ax |
if DEBUG |
pushad |
mov ax,firstDataSect ;ïåðâûé ñåêòîð äàííûõ |
mov cx,0x0a |
mov di,firstDataSect_msg |
call decode |
;Show size |
mov si,firstDataSect_msg |
call printplain |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov ax,size_root_dir ;ðàçìåð ðóò äèð â ñåòîêòîðàõ |
mov cx,0x0a |
mov di,size_root_dir_msg |
call decode |
;Show size |
mov si,size_root_dir_msg |
call printplain |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov ax,DataClasters ;êëàñòåðû |
mov cx,0x0a |
mov di,DataClasters_msg |
call decode |
;Show size |
mov si,DataClasters_msg |
call printplain |
popad |
end if |
} |
macro use_RamdiskPATHS |
;ïàðñèíã ïóòè èñòî÷íèêà ôàéëîâ. |
{ |
} |
macro use_RamdiskPATHD |
;ïàðñèíã ïóòè íàçíà÷åíèÿ ôàéëîâ. |
{ |
} |
macro check_name_file |
;ìàêðîñ ïðîâåðêè èìåíè íà ïîâòîð, èìÿ äîëæíî áûòü óíèêàëüíûì. |
;âõîäíûå äàííûå: es- ñåãìåíò ãäå ëåæèò ôàéë äëÿ ïàðñèíãà ò.å. startos.ini |
;di - óêàçàòåëü íà èìÿ ôàéëà ò.å. es:di óêàçûâàåò íà èìÿ ôàéëà íàçíà÷åíèÿ |
;âûõîäíûå äàííûå eax =-1 èìÿ ñîâïàëî, eax=0 èìÿ íå ñîâïàëî. |
{ |
local .no_equal |
local .exit |
local .loop_size_root_dir |
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè. |
;ïðåîáðàçóåì â àíàëîã ôàò çàïèñè ñòî÷êó ñ èìåíåì íàçíà÷åíèÿ |
convertion_file_name ; ïðåîáðàçîâàëè èìÿ ïî íóæíûì ïðàâèëàì |
test ax,ax |
jnz .exit |
lea si,[shot_name_fat] ; desination name of file |
;âû÷èñëèì óêàçàòåëü íà êîðíåâóþ äèðåêòîðèþ |
mov di,firstDataSect |
sub di,size_root_dir |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di,9 ;imul 512 |
;di= Ýòî ñìåùåíèå îò íà÷àëà áóôåðà äî ðóò äèðåêòîðèè. â ïðåäåëàõ 64 êá. |
;çàãðóçèì çíà÷åíèå - ò.å. êîë-âî ýëåìåíòîâ, êîòîðûå ìû ìîæåì ïðîñìàòðèâàòü. |
mov dx,root_dir_entry_count |
mov ax,info_real_mode_size |
add ax,0x1000 |
mov gs,ax |
.loop_size_root_dir: |
DEBUG1 equ 0 |
if DEBUG1 |
pushad |
push di |
mov eax,dword[gs:di] |
lea si,[check_root_fat_+14] |
mov dword [ds:si],'----' |
mov dword [ds:si+4],'----' |
mov dword [ds:si+8],'----' |
mov dword[ds:si],eax |
mov eax,dword[gs:di+4] |
mov dword[ds:si+4],eax |
mov eax,dword[gs:di+8] |
mov dword[ds:si+8],eax |
; |
xor eax,eax |
mov ax,gs;point_next_fat_str |
mov cx,0x0a |
mov di,check_root_fat_ |
mov dword [di],' ' |
mov word [di+4],' ' |
call decode |
xor eax,eax |
pop ax |
mov di,(check_root_fat_+7) |
mov dword [di],' ' |
mov word [di+4],' ' |
call decode |
;Show size |
lea si,[check_root_fat_] |
call printplain |
lea si,[shot_name_fat] |
call printplain |
xor ax,ax |
int 0x16 |
popad |
end if |
xor bx,bx |
mov cx,11 ;size of name in struct FAT |
@@: |
mov al,byte [ds:si+bx] ;ds:si - point to name of convertion variable. |
mov ah,byte [gs:di+bx] ;gs:di - point to name in fat struct |
inc bx |
if DEBUG |
; pushad |
; lea si,[check_root_fat_+14] |
; mov dword [ds:si],'----' |
; mov word [ds:si],ax |
; call printplain |
; xor ax,ax |
; int 0x16 |
; popad |
end if |
cmp ah,al |
jnz .no_equal |
; dec cx |
; jnz @b |
loop @b |
;.succesfuly: |
;ïå÷àëüíî, òàêîå èìÿ óæå èìååòñÿ :( |
or ax,-1 |
jmp .exit |
.no_equal: |
add di,32 ;fat struct =32 byte |
dec dx |
jnz .loop_size_root_dir |
;.exit_check_name: |
and ax,0 |
.exit: |
if DEBUG |
pushad |
;Show size |
lea si,[check_name_fat_msg_n] |
test ax,ax |
jz @f |
lea si,[check_name_fat_msg_y] |
call printplain |
lea si,[alarm_msg] |
@@: call printplain |
popad |
end if |
} |
macro convertion_file_name |
;ìàêðîñ êîíâåðòàöèè èìåíè, ýòî íóæíî ïîñêîëüêó ôîðìàò ïðåäñòàâëåííûé íå ñîîòâåòñâóåò ôàò è íàïðÿìóþ ðåäêî ìîæíî êîãäà èñïîëüçîâàòü |
;ïðåîáðàçîâàíèå èìåíè òèïà hello.asm â 'HELLO ASM', â ñîîòâåòñòâèè ñ ïðàâèëàìè fat. |
;âõîäíûå ïàðàìåòðû es:di óêàçàòåëü íà èìÿ ôàéëà êîòîðîå íóæíî ïðåîáðàçîâàòü, êîíå÷íûé áóôåð shot_name_fat |
{ |
local .next_step |
local .error |
local .st1 |
local .st2 |
local .st2_l |
local .st3 |
local .st4_s |
local .st4 |
local .st5 |
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè. |
; mov di,point_to_dest_file_name âõîäíîé ïàðàìåòð |
mov si,shot_name_fat |
or first_input,-1 ;ïðè ïåðâîì âõîäå óñòàíàâëèâàåì ôëàã |
mov cx,11 ;äëèííà èìåíè â ñòóêòóðå ôàò òàáëèöû |
@@: |
mov al,byte [es:di] |
cmp al,0xa |
jz .st4_s |
cmp al,0xd |
jz .st4_s |
cmp al,0x20 |
jz .st4_s |
cmp al,0x20 |
jb .error |
cmp al,0x22 |
jz .error |
cmp al,0x2a |
jz .error |
cmp al,0x2b |
jz .error |
cmp al,0x2c |
jz .error |
cmp al,0x2F |
jz .error |
cmp al,0x3a |
jz .error |
cmp al,0x3b |
jz .error |
cmp al,0x3c |
jz .error |
cmp al,0x3d |
jz .error |
cmp al,0x3E |
jz .error |
cmp al,0x3F |
jz .error |
cmp al,0x5b |
jz .error |
cmp al,0x5c |
jz .error |
cmp al,0x5d |
jz .error |
cmp al,0x7c |
jz .error |
cmp first_input,-1 |
jnz .next_step |
and first_input,0 ;ñáîðîñèì ôëàã. |
cmp al,'.' |
jz .error ;îáðàáîòêà òî÷êè, ôàéë íå ìîæåò íà÷èíàòüñÿ ñ òî÷êè |
.next_step: |
cmp al,0x2e |
jnz .st2 ;îáðàáîòêà òî÷êè, â ñåðåäèíå ôàéëà |
;òóò ó íàñ óñòàíîâëåí ðàçäåëèòåëü |
;âñå îñòàëüíåî ìåñòî çàéìóò ïðîáåëû |
mov al,' ' |
;!fixme îáðàáîòàíû íå âñå èñêëþ÷åíèÿ :( |
cmp cl,3 ;ôîðìàò ôàéëà òàêîé GIDGIDIIASM ò.å. gidgidii.asm |
jbe .st2 |
.st3: |
mov byte [si],al |
inc si |
dec cx |
cmp cx,3 |
ja .st3 |
; inc cx |
inc di |
jmp @b |
.st2: |
cmp al,0x60 |
jbe .st2_l |
xor al,0x20 ;ñäåëàåì çàãëàâíûå áóêâû |
.st2_l: mov byte [si],al |
inc di |
inc si |
; dec cx |
; jnz @b |
loop @b |
.st5: xor ax,ax |
jmp @f |
;;;;;;;;ôàéë çàêîí÷èëñÿ, è íóæíî âíåñòè â êîíåö ïðîáåëû |
.st4_s: mov al,' ' |
.st4: mov byte [si],al |
inc si |
loop .st4 |
jmp .st5 |
.error: or ax,-1 |
@@: |
if DEBUG |
pushad |
mov si,convertion_file_name_msg_y |
test ax,ax |
jz @f |
mov si,convertion_file_name_msg_n |
@@: call printplain |
mov si,shot_name_fat |
mov byte [si+12],0 |
call printplain |
popad |
end if |
} |
macro move_file_up |
;ìàêðîñ êîòîðûé ïåðåìåùàåò çà 1 ìá ñ ïðàâèëàìè ôàò äàííûå ôàéëà. |
{ |
local .st1 |
local .correct_on_byte |
;ñåé÷àñ èìååò áûòü ñèòóàöèÿ, êîãäà BPB óæå ïåðåìåùåí çà 1 ìá, ôàò, è ðóò äèð áóäóò ïîçæå ïåðåìåùåíû, |
;à íàì íóæíî âû÷èñëèòü ìåñòî, è ïåðåíåñòè òóäà ñîäåðæèìîå ôàéëà |
;ïîëó÷åíîå çíà÷åíèå óêàçûâàåò â áàéòàõ íà íà÷àëî äàííûõ |
mov ax,info_real_mode_size ; ñåãìåíò ãäå ðàñïîëîæåíû äàííûå |
mov si,table_15_87 |
mov word [si+8*2+2],ax |
;ñìåùåíèå äî äàííûõ óæå çà 1-ì ìá |
movzx eax,firstDataSect |
movzx edx,data_offset |
add eax,edx |
movzx ebx,word [fat12_buffer.BPB_BytsPerSec] |
movzx edx,byte [fat12_buffer.BPB_SecPerClus] |
imul bx,dx ;ïîëó÷èì ðàçìåð êëàñòåðà |
push ebx ;save bx |
imul eax,ebx |
; shl eax,9 ;óìíîæèì íà 512 |
if DEBUG |
pushad |
xor eax,eax |
mov ax,info_real_mode_size |
mov cx,0x0a |
mov di,seg_where_get_data |
mov dword [di],' ' |
mov word [di+4],' ' |
call decode |
;Show size |
mov si,seg_where_get_data |
call printplain |
popad |
end if |
; mov bx,word [fat12_buffer.BPB_BytsPerSec] |
; movzx dx,byte [fat12_buffer.BPB_SecPerClus] |
; imul bx,dx |
; cwd |
; idiv bx |
mov dl,0x10 |
@@: cmp eax,0x00010000 |
jb @f |
sub eax,0x00010000 |
inc dl |
jmp @b |
@@: mov byte [si+8*3+3],dl ;êóäà ïèñàòü |
mov word [si+8*3+2],ax |
mov ecx,save_file_size ;ðàçìåð ôàéëà â áàéòàõ. |
cmp ecx,0x0000ffff ;ðàçìåð áëîêà ò.å. 64 êá |
jbe .correct_on_byte ;êîððåêòèðîâêà íà áàéò çíà÷åíèÿ |
mov ecx,0x00010000 ;65536 |
sub save_file_size,ecx ;îòíèìèì |
; jmp .st1 ;ïîëó÷èì 0õ8000 |
;êîððåêòèðîâêà çíà÷åíèÿ äîëæíà áûòü âûïîëåíåíà íà ðàçìåð êëàñòåðà |
.correct_on_byte: |
;/óçíàåì ðàçìåð êëàñòåðà |
pop eax ;restore size of claster |
push ecx |
@@: inc data_offset |
cmp eax,ecx |
jae @f |
sub ecx,eax |
jmp @b |
@@: pop ecx |
test ecx,0x1 |
jz .st1 |
inc ecx |
.st1: shr ecx,1 ; ïðåîáðàçîâàòü çíà÷åíèå äëÿ 0x87 function |
;ïåðåíåñåì áëîê çà 1 ìá |
push es |
push ds |
pop es |
mov ah, 0x87 |
int 0x15 |
pop es |
if DEBUG |
pusha |
; mov ax,point_next_fat_str |
mov cx,0x0a |
mov di,return_code_af_move |
call decode |
;Show size |
mov si,return_code_af_move |
call printplain |
popa |
end if |
} |
macro move_up_fat_and_root_d |
;ìàêðîñ, êîòîðûé ïîçâîëÿåò ïåðåíåñòè âûøå 1 ìá â ñòðóêòóðó îáðàçà ôàò òàáëèöó è ðóò äèðåêòîðèþ |
{ |
local .st1 |
mov ax,info_real_mode_size |
add ax,0x1000 |
mov si,table_15_87 |
mov word [si+8*2+2],ax |
;ñìåùåíèå äî äàííûõ |
mov ax,512 |
mov word [si+8*3+2],ax |
;fixme! òóò íåîáõîäèìî ñäåëàòü ïîäåðæêó ò.å. ôîðìèðîâàòü ñìåùåíèå ôàéëà â óæå çàïèñàííûõ äàííûõ. |
movzx ecx,word [fat12_buffer.BPB_FATSz16] |
movzx bx,byte [fat12_buffer.BPB_NumFATs] |
imul cx,bx ;9x1=9 |
add cx,size_root_dir ;ðàçìåð êîðíåâîé äèððåêòîðèè |
shl ecx,9 ;imul 512 |
;êîððåêòèðîâêà çíà÷åíèÿ |
test ecx,0x1 |
jz .st1 |
inc ecx |
.st1: shr ecx,1 |
push es |
push ds |
pop es |
mov ah, 0x87 |
int 0x15 |
pop es |
if DEBUG |
pusha |
; mov ax,point_next_fat_str |
mov cx,0x0a |
mov di,return_code_af_fat_m |
call decode |
;Show size |
mov si,return_code_af_fat_m |
call printplain |
popa |
end if |
} |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_proc.inc |
---|
0,0 → 1,524 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/booteng.inc |
---|
0,0 → 1,98 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootru.inc |
---|
0,0 → 1,87 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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,' ®¤à®¡¥¥ ᬮâà¨â¥ ¢ ä ©«¥ 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 " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤ ¢ ¢ë¡®à ०¨¬®¢.",0 |
badsect db 13,10,186," 訡ª - ¨áª¥â ¯®¢à¥¦¤¥ . ®¯à®¡ã©â¥ ¤àã£ãî.",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 " ¦¬¨â¥ [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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm |
---|
0,0 → 1,808 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ETFONT.FNT |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootet.inc |
---|
0,0 → 1,119 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootge.inc |
---|
0,0 → 1,118 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootstr.inc |
---|
0,0 → 1,55 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootvesa.inc |
---|
0,0 → 1,754 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
;============================================================================= |
;============================================================================= |
;============================================================================= |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/build_ru.bat |
---|
0,0 → 1,89 |
@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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/et.inc |
---|
0,0 → 1,14 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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" |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/macros.inc |
---|
0,0 → 1,86 |
; 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] |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/preboot.inc |
---|
0,0 → 1,36 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/rdload.inc |
---|
0,0 → 1,123 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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: |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ru.inc |
---|
0,0 → 1,100 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/shutdown.inc |
---|
0,0 → 1,207 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.asm |
---|
0,0 → 1,317 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.lst |
---|
0,0 → 1,2147 |
flat assembler version 1.68 (65535 kilobytes memory) |
0000: E9 E1 0A jmp start |
0003: 53 65 63 6F 6E 64 61 72 79 20 4C 6F 61 version db 'Secondary Loader v 0.009', 0 |
0010: 64 65 72 20 76 20 30 2E 30 30 39 00 |
001C: 53 65 6C 65 63 74 20 73 65 63 74 69 6F select_section db 'Select section:' |
0029: 6E 3A |
002B: 53 65 63 74 69 6F 6E 20 64 65 73 63 72 section_description db 'Section description:' |
0038: 69 70 74 69 6F 6E 3A |
003F: 53 6F 66 74 20 28 63 29 20 32 30 30 38 soft_mes db 'Soft (c) 2008' |
004C: 3E 46 61 74 61 6C 20 2D 20 43 50 55 20 badprocessor db '>Fatal - CPU 586+ required.', 0 |
0059: 35 38 36 2B 20 72 65 71 75 69 72 65 64 |
0066: 2E 00 |
0068: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f1 db '>Error: cannot load ini file, buffer is full', 0 |
0075: 74 20 6C 6F 61 64 20 69 6E 69 20 66 69 |
0082: 6C 65 2C 20 62 75 66 66 65 72 20 69 73 |
008F: 20 66 75 6C 6C 00 |
0095: 3E 45 72 72 6F 72 3A 20 69 6E 69 20 66 error_ini_f2 db '>Error: ini file not found', 0 |
00A2: 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64 |
00AF: 00 |
00B0: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f3 db '>Error: cannot read ini file', 0 |
00BD: 74 20 72 65 61 64 20 69 6E 69 20 66 69 |
00CA: 6C 65 00 |
00CD: 3E 45 72 72 6F 72 3A 20 75 6E 72 65 63 error_ini_nf db '>Error: unrecognized error when loading ini file', 0 |
00DA: 6F 67 6E 69 7A 65 64 20 65 72 72 6F 72 |
00E7: 20 77 68 65 6E 20 6C 6F 61 64 69 6E 67 |
00F4: 20 69 6E 69 20 66 69 6C 65 00 |
00FE: 3E 4E 6F 74 20 66 6F 75 6E 64 20 73 65 not_found_sec_loader db '>Not found section [loader]', 0 |
010B: 63 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 |
0118: 5D 00 |
011A: 3E 4E 6F 74 20 66 6F 75 6E 64 20 76 61 not_found_def_sect db '>Not found value default in section [loader]', 0 |
0127: 6C 75 65 20 64 65 66 61 75 6C 74 20 69 |
0134: 6E 20 73 65 63 74 69 6F 6E 20 5B 6C 6F |
0141: 61 64 65 72 5D 00 |
0147: 3E 45 72 72 6F 72 20 69 6E 20 73 65 63 default_eq_loader db '>Error in section [loader] parametr default=loader', 0 |
0154: 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 5D |
0161: 20 70 61 72 61 6D 65 74 72 20 64 65 66 |
016E: 61 75 6C 74 3D 6C 6F 61 64 65 72 00 |
017A: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_default db '>Found equal parametr default will be use first value', 0 |
0187: 70 61 72 61 6D 65 74 72 20 64 65 66 61 |
0194: 75 6C 74 20 77 69 6C 6C 20 62 65 20 75 |
01A1: 73 65 20 66 69 72 73 74 20 76 61 6C 75 |
01AE: 65 00 |
01B0: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_timeout db '>Found equal parametr timeout will be use first value', 0 |
01BD: 70 61 72 61 6D 65 74 72 20 74 69 6D 65 |
01CA: 6F 75 74 20 77 69 6C 6C 20 62 65 20 75 |
01D7: 73 65 20 66 69 72 73 74 20 76 61 6C 75 |
01E4: 65 00 |
01E6: 3E 53 65 63 74 69 6F 6E 20 74 69 6D 65 set_default_timeout_val db '>Section timeout has incorrect value, will be use default value', 0 |
01F3: 6F 75 74 20 68 61 73 20 69 6E 63 6F 72 |
0200: 72 65 63 74 20 76 61 6C 75 65 2C 20 77 |
020D: 69 6C 6C 20 62 65 20 75 73 65 20 64 65 |
021A: 66 61 75 6C 74 20 76 61 6C 75 65 00 |
0226: 3E 49 20 77 69 6C 6C 20 75 73 65 20 70 error_ini_common db '>I will use predefined settings and try to boot. Let's hope for the best...' |
0233: 72 65 64 65 66 69 6E 65 64 20 73 65 74 |
0240: 74 69 6E 67 73 20 61 6E 64 20 74 72 79 |
024D: 20 74 6F 20 62 6F 6F 74 2E 20 4C 65 74 |
025A: 27 73 20 68 6F 70 65 20 66 6F 72 20 74 |
0267: 68 65 20 62 65 73 74 2E 2E 2E |
0271: 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B db 13, 10, 'Press any key to continue...', 0 |
027E: 65 79 20 74 6F 20 63 6F 6E 74 69 6E 75 |
028B: 65 2E 2E 2E 00 |
0290: 3E 49 6E 69 20 66 69 6C 65 20 6C 6F 61 load_ini db '>Ini file loaded successfully', 0 |
029D: 64 65 64 20 73 75 63 63 65 73 73 66 75 |
02AA: 6C 6C 79 00 |
02AE: 3E 45 6E 64 20 70 61 72 73 69 6E 67 20 parse_ini_end db '>End parsing ini file', 0 |
02BB: 69 6E 69 20 66 69 6C 65 00 |
02C4: 3E 50 6F 69 6E 74 20 74 6F 20 64 65 66 point_to_default_sec_not_found db '>Point to default section is not found in ini file', 0 |
02D1: 61 75 6C 74 20 73 65 63 74 69 6F 6E 20 |
02DE: 69 73 20 6E 6F 74 20 66 6F 75 6E 64 20 |
02EB: 69 6E 20 69 6E 69 20 66 69 6C 65 00 |
02F7: 3E 49 6E 63 6F 72 65 63 74 20 73 65 63 incorect_section_define db '>Incorect section define not found ']'', 0 |
0304: 74 69 6F 6E 20 64 65 66 69 6E 65 20 6E |
0311: 6F 74 20 66 6F 75 6E 64 20 27 5D 27 00 |
031E: 22 53 65 63 74 69 6F 6E 20 75 6E 6E 61 default_section_name db '"Section unname"' |
032B: 6D 65 22 |
032E: 50 72 65 73 73 20 61 6E 79 20 6B 65 79 start_msg db 'Press any key to change default section, press [Enter] to continue booting' |
033B: 20 74 6F 20 63 68 61 6E 67 65 20 64 65 |
0348: 66 61 75 6C 74 20 73 65 63 74 69 6F 6E |
0355: 2C 20 70 72 65 73 73 20 5B 45 6E 74 65 |
0362: 72 5D 20 74 6F 20 63 6F 6E 74 69 6E 75 |
036F: 65 20 62 6F 6F 74 69 6E 67 |
0378: 6F 72 20 77 61 69 74 20 34 20 73 65 63 time_msg db 'or wait 4 seconds before default continuation' |
0385: 6F 6E 64 73 20 62 65 66 6F 72 65 20 64 |
0392: 65 66 61 75 6C 74 20 63 6F 6E 74 69 6E |
039F: 75 61 74 69 6F 6E |
03A5: 73 65 63 6F 6E 64 73 20 62 65 66 6F 72 time_str db 'seconds before default continuation' |
03B2: 65 20 64 65 66 61 75 6C 74 20 63 6F 6E |
03BF: 74 69 6E 75 61 74 69 6F 6E |
03C8: 53 65 74 20 73 74 61 63 6B 20 26 20 73 stack_msg db 'Set stack & segments is have completed', 0 |
03D5: 65 67 6D 65 6E 74 73 20 69 73 20 68 61 |
03E2: 76 65 20 63 6F 6D 70 6C 65 74 65 64 00 |
03EF: 48 61 76 65 20 6C 6F 61 64 65 64 20 73 show_string db 'Have loaded size:' |
03FC: 69 7A 65 3A |
0400: 20 20 20 20 20 20 00 show_decode db ' ', 0 |
0407: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db1 db ' -Message debug1', 0 |
0414: 67 65 20 64 65 62 75 67 31 00 |
041E: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db2 db ' -Message debug2', 0 |
042B: 67 65 20 64 65 62 75 67 32 00 |
0435: 5B 6C 6F 61 64 65 72 5D 20 69 73 20 66 lm_l_found db '[loader] is found', 0 |
0442: 6F 75 6E 64 00 |
0447: 74 69 6D 65 6F 75 74 20 69 73 20 66 6F lm_lf_timeout db 'timeout is found', 0 |
0454: 75 6E 64 00 |
0458: 6E 61 6D 65 20 64 65 66 61 75 6C 74 20 lm_lf_default db 'name default is found and end parsing section', 0 |
0465: 69 73 20 66 6F 75 6E 64 20 61 6E 64 20 |
0472: 65 6E 64 20 70 61 72 73 69 6E 67 20 73 |
047F: 65 63 74 69 6F 6E 00 |
0486: 66 6F 75 6E 64 20 73 65 63 74 69 6F 6E lm_lf_section db 'found section [', 0 |
0493: 20 5B 00 |
0496: 66 6F 75 6E 64 20 64 65 66 61 75 6C 74 lm_lf_default_f db 'found default parametr', 0 |
04A3: 20 70 61 72 61 6D 65 74 72 00 |
04AD: 73 65 63 74 69 6F 6E 20 5B 6C 6F 61 64 lm_l_end db 'section [loader] is end', 0 |
04BA: 65 72 5D 20 69 73 20 65 6E 64 00 |
04C5: 53 48 4F 57 20 41 4C 4C 20 53 65 63 74 show_all_sect db 'SHOW ALL Sections', 0 |
04D2: 69 6F 6E 73 00 |
04D7: 4E 6F 74 20 73 68 6F 77 20 73 65 63 74 no_show_only_w db 'Not show sections - only work on default sect', 0 |
04E4: 69 6F 6E 73 20 2D 20 6F 6E 6C 79 20 77 |
04F1: 6F 72 6B 20 6F 6E 20 64 65 66 61 75 6C |
04FE: 74 20 73 65 63 74 00 |
0505: 5B 20 6E 6F 74 20 66 6F 75 6E 64 00 _not_found db '[ not found', 0 |
0511: 5B 5D 20 66 6F 75 6E 64 00 _found_1 db '[] found', 0 |
051A: 5B 20 66 6F 75 6E 64 00 _found_2 db '[ found', 0 |
0522: 48 65 6C 6C 6F 20 24 29 00 say_hello db 'Hello $)', 0 |
052B: 53 74 61 72 74 20 75 73 65 5F 52 61 6D ramdiskFS_st db 'Start use_RamdiskFS macros', 0 |
0538: 64 69 73 6B 46 53 20 6D 61 63 72 6F 73 |
0545: 00 |
0546: 20 20 20 20 20 20 20 2D 4B 62 20 61 76 free_memory_msg db ' -Kb availability system free memory', 0 |
0553: 61 69 6C 61 62 69 6C 69 74 79 20 73 79 |
0560: 73 74 65 6D 20 66 72 65 65 20 6D 65 6D |
056D: 6F 72 79 00 |
0571: 20 20 20 20 20 20 20 2D 4B 62 20 65 71 RamdiskSize_msg db ' -Kb equal RamdiskSize', 0 |
057E: 75 61 6C 20 52 61 6D 64 69 73 6B 53 69 |
058B: 7A 65 00 |
058E: 20 20 20 20 20 20 20 20 2D 62 79 74 73 RamdiskSector_msg db ' -byts RamdiskSector', 0 |
059B: 20 52 61 6D 64 69 73 6B 53 65 63 74 6F |
05A8: 72 00 |
05AA: 20 20 20 20 20 20 20 2D 52 61 6D 64 69 RamdiskCluster_msg db ' -RamdiskCluster', 0 |
05B7: 73 6B 43 6C 75 73 74 65 72 00 |
05C1: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 RamdiskFile_msg db ' -size RamdiskFile', 0 |
05CE: 52 61 6D 64 69 73 6B 46 69 6C 65 00 |
05DA: 20 20 20 20 20 20 20 2D 66 69 72 73 74 fat_create_msg db ' -first create fat table, point to next block', 0 |
05E7: 20 63 72 65 61 74 65 20 66 61 74 20 74 |
05F4: 61 62 6C 65 2C 20 70 6F 69 6E 74 20 74 |
0601: 6F 20 6E 65 78 74 20 62 6C 6F 63 6B 00 |
060E: 20 20 20 20 20 20 20 2D 69 6E 20 62 79 BPB_msg db ' -in byte, why we get data from move BPB struct', 0 |
061B: 74 65 2C 20 77 68 79 20 77 65 20 67 65 |
0628: 74 20 64 61 74 61 20 66 72 6F 6D 20 6D |
0635: 6F 76 65 20 42 50 42 20 73 74 72 75 63 |
0642: 74 00 |
0644: 20 20 20 20 20 20 20 2D 66 69 72 73 74 firstDataSect_msg db ' -first data sector, offset to data in sectors', 0 |
0651: 20 64 61 74 61 20 73 65 63 74 6F 72 2C |
065E: 20 6F 66 66 73 65 74 20 74 6F 20 64 61 |
066B: 74 61 20 69 6E 20 73 65 63 74 6F 72 73 |
0678: 00 |
0679: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 size_root_dir_msg db ' -size root dir in sectrors', 0 |
0686: 72 6F 6F 74 20 64 69 72 20 69 6E 20 73 |
0693: 65 63 74 72 6F 72 73 00 |
069B: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 DataClasters_msg db ' -size data in Clasters', 0 |
06A8: 64 61 74 61 20 69 6E 20 43 6C 61 73 74 |
06B5: 65 72 73 00 |
06B9: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 check_name_fat_msg db ' -if -1 name is present, else 0 then not present name', 0 |
06C6: 20 6E 61 6D 65 20 69 73 20 70 72 65 73 |
06D3: 65 6E 74 2C 20 65 6C 73 65 20 30 20 74 |
06E0: 68 65 6E 20 6E 6F 74 20 70 72 65 73 65 |
06ED: 6E 74 20 6E 61 6D 65 00 |
06F5: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 convertion_file_name_msg db ' -if -1, then destination name is bad', 0 |
0702: 2C 20 74 68 65 6E 20 64 65 73 74 69 6E |
070F: 61 74 69 6F 6E 20 6E 61 6D 65 20 69 73 |
071C: 20 62 61 64 00 |
0721: 2D 4D 61 6B 65 20 46 41 54 31 32 20 52 make_fat12_RFS_msg db '-Make FAT12 Ram FS', 0 |
072E: 61 6D 20 46 53 00 |
0734: 2D 45 6E 64 20 6D 61 6B 65 20 52 61 6D get_type_FS_msg db '-End make RamDisk', 0 |
0741: 44 69 73 6B 00 |
0746: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_move db ' -return code after 0x87 int 0x15, move block', 0 |
0753: 6F 64 65 20 61 66 74 65 72 20 30 78 38 |
0760: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D |
076D: 6F 76 65 20 62 6C 6F 63 6B 00 |
0777: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc', 0 |
0784: 6F 64 65 20 61 66 74 65 72 20 30 78 38 |
0791: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D |
079E: 6F 76 65 20 66 61 74 20 73 74 72 75 63 |
07AB: 00 |
07AC: 5B 6C 6F 61 64 65 72 5D parse_loader db '[loader]' |
07B4: 74 69 6D 65 6F 75 74 parse_l_timeout db 'timeout' |
07BB: 64 65 66 61 75 6C 74 parse_l_default db 'default' |
07C2: 61 6D 65 parse_name db 'ame' |
07C5: 64 65 73 63 72 69 70 74 parse_descript db 'descript' |
07CD: 4C 6F 61 64 65 72 4D 6F 64 75 6C 65 parse_LoaderModule db 'LoaderModule' |
07D9: 52 61 6D 64 69 73 6B 53 69 7A 65 parse_RamdiskSize db 'RamdiskSize' |
07E4: 52 61 6D 64 69 73 6B 46 53 parse_RamdiskFS db 'RamdiskFS' |
07ED: 52 61 6D 64 69 73 6B 53 65 63 74 6F 72 parse_RamdiskSector db 'RamdiskSector' |
07FA: 52 61 6D 64 69 73 6B 43 6C 75 73 74 65 parse_RamdiskCluster db 'RamdiskCluster' |
0807: 72 |
0808: 46 41 54 parse_RFS_FAT db 'FAT' |
080B: 4B 52 46 53 parse_RFS_KRFS db 'KRFS' |
080F: 4C 6F 61 64 65 72 49 6D 61 67 65 parse_Loader_Image db 'LoaderImage' |
081A: 52 61 6D 64 69 73 6B 46 69 6C 65 parse_RamdiskFile db 'RamdiskFile' |
0825: 66 39 C8 cmp eax, ecx |
0828: 72 0D jb @f |
082A: 66 31 D2 xor edx, edx |
082D: 66 F7 F1 div ecx |
0830: 66 52 push edx |
0832: E8 F0 FF call decode |
0835: 66 58 pop eax |
0837: 0C 30 or al, 0x30 |
0839: 88 05 mov [ ds : di ], al |
083B: 47 inc di |
083C: C3 ret |
083D: B4 0E mov ah, 0Eh |
083F: B7 00 mov bh, 0 |
0841: CD 10 int 10h |
0843: C3 ret |
0844: 60 pusha |
0845: AC lodsb |
0846: E8 F4 FF call putchar |
0849: AC lodsb |
084A: 3C 00 cmp al, 0 |
084C: 75 F8 jnz @b |
084E: B0 0D mov al, 13 |
0850: E8 EA FF call putchar |
0853: B0 0A mov al, 10 |
0855: E8 E5 FF call putchar |
0858: 61 popa |
0859: C3 ret |
085A: B4 00 mov ah, 0 |
085C: CD 16 int 16h |
085E: 38 D8 cmp al, bl |
0860: 72 F8 jb getkey |
0862: 38 F8 cmp al, bh |
0864: 77 F4 ja getkey |
0866: 50 push ax |
0867: E8 D3 FF call putchar |
086A: 58 pop ax |
086B: 83 E0 0F and ax, 0Fh |
086E: 75 02 jnz @f |
0870: B0 0A mov al, 10 |
0872: C3 ret |
0873: 26 8A 05 mov al, byte [ es : di ] |
0876: 47 inc di |
0877: 49 dec cx |
0878: E3 20 jcxz .exit |
087A: 3C 0A cmp al, 0xa |
087C: 74 0A jz ._entry |
087E: 3C 3B cmp al, ';' |
0880: 75 F1 jnz .start |
0882: B0 0A mov al, 0xa |
0884: F2 repnz |
0885: AE scasb |
0886: E3 12 jcxz .exit |
0888: 26 8A 05 mov al, byte [ es : di ] |
088B: 3C 20 cmp al, ' ' |
088D: 75 07 jnz .not_space |
088F: F3 repe |
0890: AE scasb |
0891: 4F dec di |
0892: 41 inc cx |
0893: 26 8A 05 mov al, byte [ es : di ] |
0896: 3C 3B cmp al, ';' |
0898: 74 E8 jz .first_com |
089A: C3 ret |
089B: 56 push si |
089C: 68 00 20 push ini_data_ |
089F: 07 pop es |
08A0: B0 5D mov al, ']' |
08A2: F2 repnz |
08A3: AE scasb |
08A4: 85 C9 test cx, cx |
08A6: 0F 84 0F 02 jz error.incorect_section_def |
08AA: B0 6E mov al, 'n' |
08AC: F2 repnz |
08AD: AE scasb |
08AE: E3 69 jcxz .not_name_sec_fb |
08B0: BE C2 07 mov si, parse_name |
08B3: 51 push cx |
08B4: 57 push di |
08B5: B9 03 00 mov cx, parse_name_e - parse_name |
08B8: F3 repe |
08B9: A6 cmpsb |
08BA: 5F pop di |
08BB: 59 pop cx |
08BC: 74 02 jz .yaaa_find_value |
08BE: EB EC jmp .find_val_name_fb |
08C0: 83 E9 03 sub cx, parse_name_e - parse_name |
08C3: 83 C7 03 add di, parse_name_e - parse_name |
08C6: B8 20 3D mov ax, 0x3d20 |
08C9: F3 repe |
08CA: AE scasb |
08CB: 85 C9 test cx, cx |
08CD: 74 4A jz .not_name_sec_fb |
08CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
08D3: 75 D5 jnz .find_val_name_fb1 |
08D5: F3 repe |
08D6: AE scasb |
08D7: 41 inc cx |
08D8: 4F dec di |
08D9: 06 push es |
08DA: 1F pop ds |
08DB: 68 00 B8 push 0xb800 |
08DE: 07 pop es |
08DF: 31 C0 xor ax, ax |
08E1: B8 20 07 mov ax, 0x0720 |
08E4: B9 27 00 mov cx, 39 |
08E7: 89 FE mov si, di |
08E9: 89 D7 mov di, dx |
08EB: 83 EF 02 sub di, 2 |
08EE: F3 rep |
08EF: AB stosw |
08F0: 89 D7 mov di, dx |
08F2: B4 0F mov ah, color_sym_white |
08F4: B9 24 00 mov cx, 36 |
08F7: AC lodsb |
08F8: 83 EF 02 sub di, 2 |
08FB: 3C 22 cmp al, '"' |
08FD: 74 04 jz @f |
08FF: 3C 27 cmp al, ''' |
0901: 75 12 jnz .end_sh_name_sec |
0903: AC lodsb |
0904: AB stosw |
0905: AC lodsb |
0906: 3C 22 cmp al, '"' |
0908: 74 0B jz .end_sh_name_sec |
090A: 3C 27 cmp al, ''' |
090C: 74 07 jz .end_sh_name_sec |
090E: E2 F4 loop @b |
0910: B0 7D mov al, '}' |
0912: B4 0E mov ah, color_sym_yellow |
0914: AB stosw |
0915: 0E push cs |
0916: 1F pop ds |
0917: 5E pop si |
0918: C3 ret |
0919: 0E push cs |
091A: 1F pop ds |
091B: BF 1E 03 mov di, default_section_name |
091E: EB BB jmp .def_sect_name |
0920: 8B 7E F4 mov di, point_default |
0923: 68 00 20 push ini_data_ |
0926: 07 pop es |
0927: 89 F9 mov cx, di |
0929: 89 CB mov bx, cx |
092B: FD std |
092C: B0 0A mov al, 0xa |
092E: F2 repnz |
092F: AE scasb |
0930: E3 25 jcxz .go_ |
0932: 89 7E C6 mov find_sec_di, di |
0935: 89 F9 mov cx, di |
0937: 29 CB sub bx, cx |
0939: 89 D9 mov cx, bx |
093B: FC cld |
093C: E8 34 FF call get_firs_sym |
093F: E3 0D jcxz ._not_section |
0941: 3B 7E F6 cmp di, point_loader |
0944: 74 08 jz ._not_section |
0946: 3C 5B cmp al, '[' |
0948: 75 04 jnz ._not_section |
094A: 89 7E F4 mov point_default, di |
094D: C3 ret |
094E: 8B 7E C6 mov di, find_sec_di |
0951: 89 F9 mov cx, di |
0953: 89 CB mov bx, cx |
0955: EB D4 jmp .find_start_section |
0957: FC cld |
0958: 89 D9 mov cx, bx |
095A: 26 8A 05 mov al, byte [ es : di ] |
095D: 68 6A 09 push word .f_go |
0960: 3C 20 cmp al, ' ' |
0962: 74 03 jz @f |
0964: E9 2F FF jmp get_firs_sym.not_space |
0967: E9 21 FF jmp get_firs_sym.first_sp |
096A: E3 E1 jcxz .exit_scan_sect |
096C: 3B 7E F6 cmp di, point_loader |
096F: 74 DC jz .exit_scan_sect |
0971: 3C 5B cmp al, '[' |
0973: 75 D8 jnz .exit_scan_sect |
0975: 89 7E F4 mov point_default, di |
0978: C3 ret |
0979: 8B 7E F4 mov di, point_default |
097C: 68 00 20 push ini_data_ |
097F: 07 pop es |
0980: 8B 4E FE mov cx, save_cx |
0983: 29 F9 sub cx, di |
0985: EB 17 jmp .let_s_go |
0987: 68 00 20 push ini_data_ |
098A: 07 pop es |
098B: 8B 4E FE mov cx, save_cx |
098E: 26 8A 05 mov al, byte [ es : di ] |
0991: 68 A1 09 push word .let_s_go_ret |
0994: 3C 20 cmp al, ' ' |
0996: 74 03 jz @f |
0998: E9 FB FE jmp get_firs_sym.not_space |
099B: E9 ED FE jmp get_firs_sym.first_sp |
099E: E8 D2 FE call get_firs_sym |
09A1: E3 0C jcxz .exit_scan_sect |
09A3: 3C 5B cmp al, '[' |
09A5: 75 F7 jnz .let_s_go |
09A7: 3B 7E F6 cmp di, point_loader |
09AA: 74 F2 jz .let_s_go |
09AC: 89 7E F4 mov point_default, di |
09AF: C3 ret |
09B0: 8D 76 F2 lea si, point_to_hframe |
09B3: BF 22 03 mov di, 962 - 160 |
09B6: 8B 56 F4 mov dx, point_default |
09B9: B9 12 00 mov cx, 18 |
09BC: 8B 1C mov bx, [ si ] |
09BE: 81 C7 A0 00 add di, 160 |
09C2: 39 D3 cmp bx, dx |
09C4: 74 05 jz .clean_cursor_ |
09C6: 83 EE 02 sub si, 2 |
09C9: E2 F1 loop .clean_show_cur |
09CB: 68 00 B8 push 0xb800 |
09CE: 07 pop es |
09CF: 50 push ax |
09D0: 89 76 CA mov point_to_point_def, si |
09D3: 31 C0 xor ax, ax |
09D5: B8 20 07 mov ax, 0x0720 |
09D8: AB stosw |
09D9: 83 C7 44 add di, 68 |
09DC: AB stosw |
09DD: 58 pop ax |
09DE: C3 ret |
09DF: B4 00 mov ah, 0 |
09E1: CD 1A int 1Ah |
09E3: 91 xchg ax, cx |
09E4: 66 C1 E0 10 shl eax, 10h |
09E8: 92 xchg ax, dx |
09E9: C3 ret |
09EA: 1E push ds |
09EB: 0E push cs |
09EC: 1F pop ds |
09ED: 9C pushf |
09EE: FF 1E D4 1A call far dword [ old_timer ] |
09F2: 66 60 pushad |
09F4: E8 E8 FF call gettime |
09F7: 66 2B 06 D8 1A sub eax, dword [ start_timer ] |
09FC: 8B 1E D2 1A mov bx, word [ value_timeout ] |
0A00: 6B DB 12 imul bx, 18 |
0A03: 29 C3 sub bx, ax |
0A05: 76 1F jbe .timergo |
0A07: 06 push es |
0A08: 68 00 B8 push 0xb800 |
0A0B: 07 pop es |
0A0C: 89 D8 mov ax, bx |
0A0E: BB 12 00 mov bx, 18 |
0A11: 31 D2 xor dx, dx |
0A13: F7 F3 div bx |
0A15: BB 0A 00 mov bx, 10 |
0A18: BF 96 0E mov di, 3734 |
0A1B: E8 24 00 call .decode |
0A1E: 31 C0 xor ax, ax |
0A20: AB stosw |
0A21: 07 pop es |
0A22: 66 61 popad |
0A24: 1F pop ds |
0A25: CF iret |
0A26: 6A 00 push 0 |
0A28: 07 pop es |
0A29: 66 A1 D4 1A mov eax, dword [ old_timer ] |
0A2D: 26 66 A3 20 00 mov [ es : 8 * 4 ], eax |
0A32: 66 A3 DC 1A mov dword [ timer_ ], eax |
0A36: 8B 26 E0 1A mov sp, word [ start_stack ] |
0A3A: 8B 2E E2 1A mov bp, word [ save_bp_from_timer ] |
0A3E: FB sti |
0A3F: E9 D8 06 jmp parse_start.parse_run_only |
0A42: 39 D8 cmp ax, bx |
0A44: 72 09 jb @f |
0A46: 31 D2 xor dx, dx |
0A48: F7 F3 div bx |
0A4A: 52 push dx |
0A4B: E8 F4 FF call .decode |
0A4E: 58 pop ax |
0A4F: 0C 30 or al, 0x30 |
0A51: 50 push ax |
0A52: B4 09 mov ah, 9 |
0A54: AB stosw |
0A55: 58 pop ax |
0A56: C3 ret |
0A57: 8B 5E C8 mov bx, point_to_eframe |
0A5A: 8D 76 F2 lea si, point_to_hframe |
0A5D: BA C6 03 mov dx, 966 |
0A60: 39 DE cmp si, bx |
0A62: 72 12 jb ._show_space_fb |
0A64: 8B 3C mov di, [ si ] |
0A66: 83 EE 02 sub si, 2 |
0A69: 8B 0C mov cx, [ si ] |
0A6B: 29 F9 sub cx, di |
0A6D: E8 2B FE call show_name_section |
0A70: 81 C2 A0 00 add dx, 160 |
0A74: EB EA jmp .home_show_fb |
0A76: 83 EA 04 sub dx, 4 |
0A79: 68 00 B8 push 0xb800 |
0A7C: 07 pop es |
0A7D: 81 FA 64 0E cmp dx, 0xE64 |
0A81: 77 12 ja .exit_show_fb |
0A83: 89 D7 mov di, dx |
0A85: 31 C0 xor ax, ax |
0A87: B8 20 07 mov ax, 0x0720 |
0A8A: B9 27 00 mov cx, 39 |
0A8D: F3 rep |
0A8E: AB stosw |
0A8F: 81 C2 A0 00 add dx, 160 |
0A93: EB E8 jmp @b |
0A95: C3 ret |
0A96: 89 C7 mov di, ax |
0A98: 89 D9 mov cx, bx |
0A9A: FF 66 FC jmp ret_on_ch |
0A9D: C9 leave |
0A9E: BE 1A 01 mov si, not_found_def_sect |
0AA1: E9 F4 00 jmp err_show_ini |
0AA4: C9 leave |
0AA5: BE FE 00 mov si, not_found_sec_loader |
0AA8: E9 ED 00 jmp err_show_ini |
0AAB: C9 leave |
0AAC: BE 47 01 mov si, default_eq_loader |
0AAF: E9 E6 00 jmp err_show_ini |
0AB2: C9 leave |
0AB3: BE C4 02 mov si, point_to_default_sec_not_found |
0AB6: E9 DF 00 jmp err_show_ini |
0AB9: C9 leave |
0ABA: BE F7 02 mov si, incorect_section_define |
0ABD: E9 D8 00 jmp err_show_ini |
0AC0: 68 00 B8 push word 0xb800 |
0AC3: 07 pop es |
0AC4: C3 ret |
0AC5: 00 00 00 20 file_data dw 0x0, ini_data_ |
0AC9: 10 00 size_data dw 16 |
0ACB: 6B 6F 72 64 2F 73 74 61 72 74 6F 73 2E name_ini_f db 'kord/startos.ini', 0 |
0AD8: 69 6E 69 00 |
0ADC: 00 00 00 00 loader_callback dd ? |
0AE0: 00 00 load_drive dw ? |
0AE2: 00 00 load_ft dw ? |
0AE4: 2E 89 36 DC 0A mov word [ cs : loader_callback ], si |
0AE9: 2E 8C 1E DE 0A mov word [ cs : loader_callback + 2 ], ds |
0AEE: 2E A3 E0 0A mov word [ cs : load_drive ], ax |
0AF2: 2E 89 1E E2 0A mov word [ cs : load_ft ], bx |
0AF7: 8C C8 mov ax, cs |
0AF9: 8E D0 mov ss, ax |
0AFB: 31 E4 xor sp, sp |
0AFD: 8E D8 mov ds, ax |
0AFF: 8E C0 mov es, ax |
0B01: FC cld |
0B02: FB sti |
0B03: B8 03 00 mov ax, 3 |
0B06: CD 10 int 0x10 |
0B08: BE 03 00 mov si, version |
0B0B: E8 36 FD call printplain |
0B0E: B0 23 mov al, '#' |
0B10: B9 50 00 mov cx, 80 |
0B13: E8 27 FD call putchar |
0B16: E2 FB loop @b |
0B18: BE C8 03 mov si, stack_msg |
0B1B: E8 26 FD call printplain |
0B1E: 31 DB xor bx, bx |
0B20: 8E DB mov ds, bx |
0B22: FF 77 1A push word [ bx + 6 * 4 + 2 ] |
0B25: FF 77 18 push word [ bx + 6 * 4 ] |
0B28: C7 47 18 4A 0B mov word [ bx + 6 * 4 ], ud16 |
0B2D: 8C 4F 1A mov word [ bx + 6 * 4 + 2 ], cs |
0B30: 66 31 C0 xor eax, eax |
0B33: 0F A2 cpuid |
0B35: 66 85 C0 test eax, eax |
0B38: 74 10 jz cpubad |
0B3A: 66 31 C0 xor eax, eax |
0B3D: 40 inc ax |
0B3E: 0F A2 cpuid |
0B40: F6 C2 10 test dl, 10h |
0B43: 74 05 jz cpubad |
0B45: F6 C2 20 test dl, 20h |
0B48: 75 12 jnz cpugood |
0B4A: 8F 06 18 00 pop word [ 6 * 4 ] |
0B4E: 8F 06 1A 00 pop word [ 6 * 4 + 2 ] |
0B52: 0E push cs |
0B53: 1F pop ds |
0B54: BE 4C 00 mov si, badprocessor |
0B57: E8 EA FC call printplain |
0B5A: EB FE jmp $ |
0B5C: 66 8F 06 18 00 pop dword [ 6 * 4 ] |
0B61: 0E push cs |
0B62: 1F pop ds |
0B63: 66 0F B7 E4 movzx esp, sp |
0B67: B9 03 00 mov cx, loop_read_startos_file |
0B6C: 31 C0 xor ax, ax |
0B6E: BF C5 0A mov di, file_data |
0B71: 40 inc ax |
0B72: 51 push cx |
0B73: FF 1E DC 0A call far dword [ loader_callback ] |
0B77: 59 pop cx |
0B78: 0E push cs |
0B79: 0E push cs |
0B7A: 1F pop ds |
0B7B: 07 pop es |
0B7C: 85 DB test bx, bx |
0B7E: 74 28 jz check_conf_file |
0B80: 49 dec cx |
0B81: 75 E9 jnz load_startos_file |
0B83: BE 68 00 mov si, error_ini_f1 |
0B86: 4B dec bx |
0B87: 74 0F jz err_show_ini |
0B89: BE 95 00 mov si, error_ini_f2 |
0B8C: 4B dec bx |
0B8D: 74 09 jz err_show_ini |
0B8F: BE B0 00 mov si, error_ini_f3 |
0B92: 4B dec bx |
0B93: 74 03 jz err_show_ini |
0B95: BE CD 00 mov si, error_ini_nf |
0B98: E8 A9 FC call printplain |
0B9B: BE 26 02 mov si, error_ini_common |
0B9E: E8 A3 FC call printplain |
0BA1: 31 C0 xor ax, ax |
0BA3: CD 16 int 16h |
0BA5: EB FE jmp $ |
0BA8: 50 push ax |
0BA9: B9 0A 00 mov cx, 0x0a |
0BAC: BF 00 04 mov di, show_decode |
0BAF: E8 73 FC call decode |
0BB2: BE EF 03 mov si, show_string |
0BB5: E8 8C FC call printplain |
0BB8: BE 90 02 mov si, load_ini |
0BBB: E8 86 FC call printplain |
0BBE: 59 pop cx |
0BBF: C8 00 01 00 enter 256, 0 |
0BC3: 89 2E E2 1A mov word [ save_bp_from_timer ], bp |
0BC7: 89 4E FE mov save_cx, cx |
0BCA: C4 3E C5 0A les di, dword [ file_data ] |
0BCE: 31 C0 xor ax, ax |
0BD0: 89 46 F8 mov status_flag, ax |
0BD3: C7 46 C4 00 30 mov info_real_mode_size, ini_data_ + 0x1000 |
0BD8: FC cld |
0BD9: C7 46 FC EE 0B mov ret_on_ch, .start |
0BDE: 26 8A 05 mov al, byte [ es : di ] |
0BE1: 68 F1 0B push word .first_ret |
0BE4: 3C 20 cmp al, ' ' |
0BE6: 74 03 jz .first_sp_1 |
0BE8: E9 AB FC jmp get_firs_sym.not_space |
0BEB: E9 9D FC jmp get_firs_sym.first_sp |
0BEE: E8 82 FC call get_firs_sym |
0BF1: 85 C9 test cx, cx |
0BF3: 0F 84 AD FE jz error.not_loader |
0BF7: 3C 5B cmp al, '[' |
0BF9: 74 02 jz .parse_loader |
0BFB: EB F1 jmp .start |
0BFD: 89 CB mov bx, cx |
0BFF: 89 F8 mov ax, di |
0C01: BE AC 07 mov si, parse_loader |
0C04: B9 08 00 mov cx, parse_loader_e - parse_loader |
0C07: F3 repe |
0C08: A6 cmpsb |
0C09: 0F 85 89 FE jnz error.rest_value |
0C0D: 89 46 F6 mov point_loader, ax |
0C10: 83 EB 08 sub bx, parse_loader_e - parse_loader |
0C13: 01 CB add bx, cx |
0C15: 89 D9 mov cx, bx |
0C17: 60 pusha |
0C18: BE 35 04 mov si, lm_l_found |
0C1B: E8 26 FC call printplain |
0C1E: 61 popa |
0C1F: 89 FA mov dx, di |
0C21: E8 4F FC call get_firs_sym |
0C24: E3 04 jcxz .loader_f_end |
0C26: 3C 5B cmp al, '[' |
0C28: 75 F7 jnz @b |
0C2A: 29 CB sub bx, cx |
0C2C: 89 D7 mov di, dx |
0C2E: 89 D9 mov cx, bx |
0C30: C7 46 FC 35 0C mov ret_on_ch, .get_next_str |
0C35: E8 3B FC call get_firs_sym |
0C38: 85 C9 test cx, cx |
0C3A: 0F 84 57 01 jz .end_loader |
0C3E: 3C 74 cmp al, 't' |
0C40: 0F 84 DE 00 jz .loader_timeout |
0C44: 3C 64 cmp al, 'd' |
0C46: 75 ED jnz .get_next_str |
0C48: 89 CB mov bx, cx |
0C4A: 89 F8 mov ax, di |
0C4C: BE BB 07 mov si, parse_l_default |
0C4F: B9 07 00 mov cx, parse_l_default_e - parse_l_default |
0C52: F3 repe |
0C53: A6 cmpsb |
0C54: 0F 85 3E FE jnz error.rest_value |
0C58: 83 EB 07 sub bx, parse_l_default_e - parse_l_default |
0C5B: 01 CB add bx, cx |
0C5D: 89 D9 mov cx, bx |
0C5F: F7 46 F8 01 00 test status_flag, flag_found_default |
0C64: 74 08 jz .correct_is_not_set |
0C66: BE 7A 01 mov si, found_equal_default |
0C69: E8 D8 FB call printplain |
0C6C: EB C7 jmp .get_next_str |
0C6E: B8 20 3D mov ax, 0x3d20 |
0C71: F3 repe |
0C72: AE scasb |
0C73: 85 C9 test cx, cx |
0C75: 0F 84 1C 01 jz .end_loader |
0C79: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
0C7D: 75 B6 jnz .get_next_str |
0C7F: F3 repe |
0C80: AE scasb |
0C81: 41 inc cx |
0C82: 4F dec di |
0C83: 89 CB mov bx, cx |
0C85: 89 FA mov dx, di |
0C87: 26 8A 05 mov al, byte [ es : di ] |
0C8A: 47 inc di |
0C8B: 49 dec cx |
0C8C: 85 C9 test cx, cx |
0C8E: 0F 84 0B FE jz error.error_get_size_d_sect |
0C92: 3C 20 cmp al, ' ' |
0C94: 74 F1 jz @b |
0C96: 3C 0D cmp al, 0xd |
0C98: 74 04 jz .found_size_d_sect |
0C9A: 3C 0A cmp al, 0xa |
0C9C: 75 E9 jnz @b |
0C9E: 41 inc cx |
0C9F: 89 D8 mov ax, bx |
0CA1: 29 CB sub bx, cx |
0CA3: 89 5E FA mov save_cx_d, bx |
0CA6: 89 D7 mov di, dx |
0CA8: 89 D9 mov cx, bx |
0CAA: 89 C3 mov bx, ax |
0CAC: 89 D0 mov ax, dx |
0CAE: BE AC 07 mov si, parse_loader |
0CB1: 46 inc si |
0CB2: F3 repe |
0CB3: A6 cmpsb |
0CB4: 75 03 jnz .check_section |
0CB6: E9 F2 FD jmp error.default_eq_loader |
0CB9: 89 D9 mov cx, bx |
0CBB: 89 C7 mov di, ax |
0CBD: 89 FE mov si, di |
0CBF: 57 push di |
0CC0: 51 push cx |
0CC1: 8B 4E FE mov cx, save_cx |
0CC4: C4 3E C5 0A les di, dword [ file_data ] |
0CC8: 26 8A 05 mov al, byte [ es : di ] |
0CCB: 68 DB 0C push word .first_ret_d |
0CCE: 3C 20 cmp al, ' ' |
0CD0: 74 03 jz .first_sp_1_d |
0CD2: E9 C1 FB jmp get_firs_sym.not_space |
0CD5: E9 B3 FB jmp get_firs_sym.first_sp |
0CD8: E8 98 FB call get_firs_sym |
0CDB: E3 38 jcxz .correct_exit |
0CDD: 3C 5B cmp al, '[' |
0CDF: 74 02 jz .found_sect_d |
0CE1: EB F5 jmp .start_d |
0CE3: 89 CB mov bx, cx |
0CE5: 89 F8 mov ax, di |
0CE7: 56 push si |
0CE8: 8B 4E FA mov cx, save_cx_d |
0CEB: 06 push es |
0CEC: 1F pop ds |
0CED: 47 inc di |
0CEE: F3 repe |
0CEF: A6 cmpsb |
0CF0: 0E push cs |
0CF1: 1F pop ds |
0CF2: 5E pop si |
0CF3: 75 1A jnz .not_compare_d_s |
0CF5: 26 80 3D 5D cmp byte [ es : di ], ']' |
0CF9: 75 14 jnz .not_compare_d_s |
0CFB: 83 4E F8 01 or status_flag, flag_found_default |
0CFF: 59 pop cx |
0D00: 5F pop di |
0D01: 89 46 F4 mov point_default, ax |
0D04: 60 pusha |
0D05: BE 96 04 mov si, lm_lf_default_f |
0D08: E8 39 FB call printplain |
0D0B: 61 popa |
0D0C: E9 26 FF jmp .get_next_str |
0D0F: 89 D9 mov cx, bx |
0D11: 89 C7 mov di, ax |
0D13: EB C3 jmp .start_d |
0D15: 59 pop cx |
0D16: 5F pop di |
0D17: 60 pusha |
0D18: BE 58 04 mov si, lm_lf_default |
0D1B: E8 26 FB call printplain |
0D1E: 61 popa |
0D1F: E9 13 FF jmp .get_next_str |
0D22: 89 CB mov bx, cx |
0D24: 89 F8 mov ax, di |
0D26: BE B4 07 mov si, parse_l_timeout |
0D29: B9 07 00 mov cx, parse_l_timeout_e - parse_l_timeout |
0D2C: F3 repe |
0D2D: A6 cmpsb |
0D2E: 0F 85 64 FD jnz error.rest_value |
0D32: 83 EB 07 sub bx, parse_l_timeout_e - parse_l_timeout |
0D35: 01 CB add bx, cx |
0D37: 89 D9 mov cx, bx |
0D39: F7 46 F8 02 00 test status_flag, flag_found_timeout |
0D3E: 74 09 jz .correct_is_not_set_t |
0D40: BE B0 01 mov si, found_equal_timeout |
0D43: E8 FE FA call printplain |
0D46: E9 EC FE jmp .get_next_str |
0D49: B8 20 3D mov ax, 0x3d20 |
0D4C: F3 repe |
0D4D: AE scasb |
0D4E: E3 35 jcxz .timeout_sec_end_d |
0D50: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
0D54: 0F 85 DD FE jnz .get_next_str |
0D58: F3 repe |
0D59: AE scasb |
0D5A: 41 inc cx |
0D5B: 4F dec di |
0D5C: 51 push cx |
0D5D: 31 DB xor bx, bx |
0D5F: B9 02 00 mov cx, 2 |
0D62: 26 8A 05 mov al, byte [ es : di ] |
0D65: 3C 30 cmp al, '0' |
0D67: 72 0B jb .end_get_val_t |
0D69: 3C 39 cmp al, '9' |
0D6B: 77 07 ja .end_get_val_t |
0D6D: 6B DB 0A imul bx, 10 |
0D70: 34 30 xor al, 0x30 |
0D72: 00 C3 add bl, al |
0D74: 47 inc di |
0D75: E2 EB loop @b |
0D77: 89 1E D2 1A mov word [ value_timeout ], bx |
0D7B: 60 pusha |
0D7C: BE 47 04 mov si, lm_lf_timeout |
0D7F: E8 C2 FA call printplain |
0D82: 61 popa |
0D83: EB 0C jmp @f |
0D85: C7 06 D2 1A 05 00 mov word [ value_timeout ], default_timeout_value |
0D8B: BE E6 01 mov si, set_default_timeout_val |
0D8E: E8 B3 FA call printplain |
0D91: 59 pop cx |
0D92: E9 A0 FE jmp .get_next_str |
0D95: 60 pusha |
0D96: BE AD 04 mov si, lm_l_end |
0D99: E8 A8 FA call printplain |
0D9C: 61 popa |
0D9D: 31 C0 xor ax, ax |
0D9F: CD 16 int 16h |
0DA1: 60 pusha |
0DA2: A1 D2 1A mov ax, word [ value_timeout ] |
0DA5: B9 0A 00 mov cx, 0x0a |
0DA8: BF 07 04 mov di, show_db1 |
0DAB: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' |
0DB2: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' |
0DB7: E8 6B FA call decode |
0DBA: BE 07 04 mov si, show_db1 |
0DBD: E8 84 FA call printplain |
0DC0: 61 popa |
0DC1: 85 C0 test ax, ax |
0DC3: 0F 84 53 03 jz .parse_run_only |
0DC7: 60 pusha |
0DC8: BE C5 04 mov si, show_all_sect |
0DCB: E8 76 FA call printplain |
0DCE: 61 popa |
0DCF: B0 F6 mov al, 0xf6 |
0DD1: E6 60 out 0x60, al |
0DD3: 31 C9 xor cx, cx |
0DD5: E4 64 in al, 64h |
0DD7: 24 02 and al, 00000010b |
0DD9: E0 FA loopnz .wait_loop |
0DDB: B0 F3 mov al, 0xf3 |
0DDD: E6 60 out 0x60, al |
0DDF: 31 C9 xor cx, cx |
0DE1: E4 64 in al, 64h |
0DE3: A8 02 test al, 2 |
0DE5: E0 FA loopnz @b |
0DE7: B0 00 mov al, 0 |
0DE9: E6 60 out 0x60, al |
0DEB: 31 C9 xor cx, cx |
0DED: E4 64 in al, 64h |
0DEF: A8 02 test al, 2 |
0DF1: E0 FA loopnz @b |
0DF3: E8 E9 FB call gettime |
0DF6: 66 A3 D8 1A mov dword [ start_timer ], eax |
0DFA: C7 06 DC 1A EA 09 mov word [ timer_ ], newtimer |
0E00: 8C 0E DE 1A mov word [ timer_ + 2 ], cs |
0E04: FA cli |
0E05: 6A 00 push 0 |
0E07: 07 pop es |
0E08: 26 66 FF 36 20 00 push dword [ es : 8 * 4 ] |
0E0E: 66 8F 06 D4 1A pop dword [ old_timer ] |
0E13: 66 FF 36 DC 1A push dword [ timer_ ] |
0E18: 26 66 8F 06 20 00 pop dword [ es : 8 * 4 ] |
0E1E: FB sti |
0E1F: C7 46 BE 12 00 mov save_descript_size, 18 |
0E24: 31 C0 xor ax, ax |
0E26: B8 20 07 mov ax, 0x0720 |
0E29: 68 00 B8 push 0xb800 |
0E2C: 07 pop es |
0E2D: 31 FF xor di, di |
0E2F: B9 D0 07 mov cx, 25 * 80 |
0E32: F3 rep |
0E33: AB stosw |
0E34: BF A4 00 mov di, 164 |
0E37: BE 03 00 mov si, version |
0E3A: B9 19 00 mov cx, version_end - version |
0E3D: B4 0E mov ah, color_sym_yellow |
0E3F: AC lodsb |
0E40: AB stosw |
0E41: E2 FC loop @b |
0E43: BF 1E 01 mov di, 286 |
0E46: B4 0C mov ah, color_sym_pink |
0E48: B0 4B mov al, 'K' |
0E4A: AB stosw |
0E4B: B0 20 mov al, ' ' |
0E4D: AB stosw |
0E4E: B4 07 mov ah, color_sym_lightgray |
0E50: BE 3F 00 mov si, soft_mes |
0E53: B9 0D 00 mov cx, soft_mes_end - soft_mes |
0E56: AC lodsb |
0E57: AB stosw |
0E58: E2 FC loop @b |
0E5A: BF E0 01 mov di, 480 |
0E5D: B4 0E mov ah, color_sym_yellow |
0E5F: B0 C4 mov al, 'Ä' |
0E61: B9 3D 00 mov cx, 61 |
0E64: F3 rep |
0E65: AB stosw |
0E66: BF 24 03 mov di, 804 |
0E69: BE 1C 00 mov si, select_section |
0E6C: B9 0F 00 mov cx, select_section_end - select_section |
0E6F: B4 07 mov ah, color_sym_lightgray |
0E71: AC lodsb |
0E72: AB stosw |
0E73: E2 FC loop @b |
0E75: BF 70 03 mov di, 880 |
0E78: BE 2B 00 mov si, section_description |
0E7B: B9 14 00 mov cx, section_description_end - section_description |
0E7E: AC lodsb |
0E7F: AB stosw |
0E80: E2 FC loop @b |
0E82: 8B 4E FE mov cx, save_cx |
0E85: C4 3E C5 0A les di, dword [ file_data ] |
0E89: 89 FE mov si, di |
0E8B: 89 CB mov bx, cx |
0E8D: BA 12 00 mov dx, size_show_section |
0E90: 26 8A 05 mov al, byte [ es : di ] |
0E93: 68 B9 0E push word .first_ret_bl_sc |
0E96: 3C 20 cmp al, ' ' |
0E98: 74 03 jz .first_bl_sc |
0E9A: E9 F9 F9 jmp get_firs_sym.not_space |
0E9D: E9 EB F9 jmp get_firs_sym.first_sp |
0EA0: E8 D0 F9 call get_firs_sym |
0EA3: 85 C9 test cx, cx |
0EA5: 0F 84 09 FC jz error.correct_exit_bl |
0EA9: 3C 5B cmp al, '[' |
0EAB: 75 F3 jnz .start_hbl |
0EAD: 89 FE mov si, di |
0EAF: 89 CB mov bx, cx |
0EB1: BA 12 00 mov dx, size_show_section |
0EB4: EB 09 jmp .analisist_al |
0EB6: E8 BA F9 call get_firs_sym |
0EB9: 85 C9 test cx, cx |
0EBB: 0F 84 F3 FB jz error.correct_exit_bl |
0EBF: 3C 5B cmp al, '[' |
0EC1: 75 F3 jnz .start_bl |
0EC3: 3B 7E F6 cmp di, point_loader |
0EC6: 74 EE jz .start_bl |
0EC8: 3B 7E F4 cmp di, point_default |
0ECB: 74 05 jz .save_point_def |
0ECD: 4A dec dx |
0ECE: 75 E6 jnz .start_bl |
0ED0: EB CE jmp .start_hbl |
0ED2: 89 F7 mov di, si |
0ED4: 89 D9 mov cx, bx |
0ED6: 8D 76 F2 lea si, point_to_hframe |
0ED9: BA 13 00 mov dx, size_show_section + 1 |
0EDC: 26 8A 05 mov al, byte [ es : di ] |
0EDF: 68 EF 0E push word .first_ret_mfb |
0EE2: 3C 20 cmp al, ' ' |
0EE4: 74 03 jz .first_bl_mbf |
0EE6: E9 AD F9 jmp get_firs_sym.not_space |
0EE9: E9 9F F9 jmp get_firs_sym.first_sp |
0EEC: E8 84 F9 call get_firs_sym |
0EEF: E3 13 jcxz .val_buff_comp |
0EF1: 3C 5B cmp al, '[' |
0EF3: 75 F7 jnz .start_mfb |
0EF5: 3B 7E F6 cmp di, point_loader |
0EF8: 74 F2 jz .start_mfb |
0EFA: 89 3C mov [ si ], di |
0EFC: 83 EE 02 sub si, 2 |
0EFF: 4A dec dx |
0F00: 75 EA jnz .start_mfb |
0F02: EB 08 jmp @f |
0F04: FF 76 FE push save_cx |
0F07: 8F 04 pop word [ si ] |
0F09: 83 EE 02 sub si, 2 |
0F0C: 83 C6 04 add si, 4 |
0F0F: 89 76 C8 mov point_to_eframe, si |
0F12: E8 42 FB call show_bl_sc_sect |
0F15: 8D 76 F2 lea si, point_to_hframe |
0F18: BF 22 03 mov di, 962 - 160 |
0F1B: 8B 46 F4 mov ax, point_default |
0F1E: B9 12 00 mov cx, size_show_section |
0F21: 8B 1C mov bx, [ si ] |
0F23: 81 C7 A0 00 add di, 160 |
0F27: 39 C3 cmp bx, ax |
0F29: 74 05 jz .show_cursor_activ |
0F2B: 83 EE 02 sub si, 2 |
0F2E: E2 F1 loop .home_show_cur |
0F30: 89 76 CA mov point_to_point_def, si |
0F33: B8 10 04 mov ax, ( color_sym_red * 0x100 + 0x10 ) |
0F36: AB stosw |
0F37: 83 C7 44 add di, 68 |
0F3A: 40 inc ax |
0F3B: AB stosw |
0F3C: 8B 7E F4 mov di, point_default |
0F3F: 68 00 20 push ini_data_ |
0F42: 8B 76 CA mov si, point_to_point_def |
0F45: 07 pop es |
0F46: 83 EE 02 sub si, 2 |
0F49: 8B 0C mov cx, [ si ] |
0F4B: 29 F9 sub cx, di |
0F4D: E8 23 F9 call get_firs_sym |
0F50: 85 C9 test cx, cx |
0F52: 0F 84 91 00 jz .exit?0Pz |
0F56: 3C 64 cmp al, 'd' |
0F58: 75 F3 jnz .start_p_sh_d?0Py |
0F5A: 89 CB mov bx, cx |
0F5C: 89 F8 mov ax, di |
0F5E: BE C5 07 mov si, parse_descript |
0F61: B9 08 00 mov cx, parse_descript_e - parse_descript |
0F64: F3 repe |
0F65: A6 cmpsb |
0F66: 75 78 jnz .rest_value_loop_sh_d?0Q0 |
0F68: 83 EB 08 sub bx, parse_descript_e - parse_descript |
0F6B: 01 CB add bx, cx |
0F6D: 89 D9 mov cx, bx |
0F6F: B8 20 3D mov ax, 0x3d20 |
0F72: F3 repe |
0F73: AE scasb |
0F74: E3 6A jcxz .rest_value_loop_sh_d?0Q0 |
0F76: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
0F7A: 75 64 jnz .rest_value_loop_sh_d?0Q0 |
0F7C: F3 repe |
0F7D: AE scasb |
0F7E: 41 inc cx |
0F7F: 4F dec di |
0F80: 57 push di |
0F81: 5E pop si |
0F82: 06 push es |
0F83: 1F pop ds |
0F84: 68 00 B8 push 0xb800 |
0F87: 07 pop es |
0F88: BF 10 04 mov di, 1040 |
0F8B: BB 12 00 mov bx, 18 |
0F8E: 89 7E C6 mov find_sec_di, di |
0F91: 89 5E FA mov save_cx_d, bx |
0F94: 57 push di |
0F95: 31 C0 xor ax, ax |
0F97: B9 26 00 mov cx, 38 |
0F9A: 57 push di |
0F9B: F3 rep |
0F9C: AB stosw |
0F9D: 5F pop di |
0F9E: 39 5E BE cmp save_descript_size, bx |
0FA1: 74 07 jz @f |
0FA3: 81 C7 A0 00 add di, 160 |
0FA7: 4B dec bx |
0FA8: 75 ED jnz @b |
0FAA: 5F pop di |
0FAB: AC lodsb |
0FAC: B4 0A mov ah, color_sym_lettuce |
0FAE: 3C 22 cmp al, '"' |
0FB0: 74 04 jz .loop_message?0Q2 |
0FB2: 3C 27 cmp al, ''' |
0FB4: 75 20 jnz .end_sh_desc_sec?0Q1 |
0FB6: B9 26 00 mov cx, 38 |
0FB9: AC lodsb |
0FBA: 3C 22 cmp al, '"' |
0FBC: 74 18 jz .end_sh_desc_sec?0Q1 |
0FBE: 3C 27 cmp al, ''' |
0FC0: 74 14 jz .end_sh_desc_sec?0Q1 |
0FC2: AB stosw |
0FC3: E2 F4 loop @b |
0FC5: 81 46 C6 A0 00 add find_sec_di, 160 |
0FCA: 8B 7E C6 mov di, find_sec_di |
0FCD: FF 4E FA dec save_cx_d |
0FD0: 83 7E FA 00 cmp save_cx_d, 0 |
0FD4: 75 E0 jnz .loop_message?0Q2 |
0FD6: FF 76 FA push save_cx_d |
0FD9: 8F 46 BE pop save_descript_size |
0FDC: 0E push cs |
0FDD: 1F pop ds |
0FDE: EB 07 jmp .exit?0Pz |
0FE0: 89 C7 mov di, ax |
0FE2: 89 D9 mov cx, bx |
0FE4: E9 66 FF jmp .start_p_sh_d?0Py |
0FE7: 66 A1 D4 1A mov eax, dword [ old_timer ] |
0FEB: 66 3B 06 DC 1A cmp eax, dword [ timer_ ] |
0FF0: 74 5E jz .interrupt_16 |
0FF2: 31 C0 xor ax, ax |
0FF4: BF 20 0D mov di, 3360 |
0FF7: B9 40 01 mov cx, 80 * 4 |
0FFA: F3 rep |
0FFB: AB stosw |
0FFC: BF 22 0D mov di, 3362 |
0FFF: B4 0C mov ah, color_sym_pink |
1001: B0 DA mov al, 0xDA |
1003: AB stosw |
1004: B0 C4 mov al, 0xc4 |
1006: B9 4C 00 mov cx, 76 |
1009: F3 rep |
100A: AB stosw |
100B: B0 BF mov al, 0xBF |
100D: AB stosw |
100E: 83 C7 04 add di, 4 |
1011: B0 B3 mov al, 0xb3 |
1013: AB stosw |
1014: 81 C7 98 00 add di, 152 |
1018: AB stosw |
1019: 83 C7 04 add di, 4 |
101C: AB stosw |
101D: 81 C7 98 00 add di, 152 |
1021: AB stosw |
1022: 83 C7 04 add di, 4 |
1025: B0 C0 mov al, 0xc0 |
1027: AB stosw |
1028: B0 C4 mov al, 0xc4 |
102A: B9 4C 00 mov cx, 76 |
102D: F3 rep |
102E: AB stosw |
102F: B0 D9 mov al, 0xd9 |
1031: AB stosw |
1032: BE 2E 03 mov si, start_msg |
1035: B9 4A 00 mov cx, start_msg_e - start_msg |
1038: BF C6 0D mov di, 3526 |
103B: AC lodsb |
103C: AB stosw |
103D: E2 FC loop @b |
103F: 83 C7 2C add di, 44 |
1042: BE 78 03 mov si, time_msg |
1045: B9 2D 00 mov cx, time_msg_e - time_msg |
1048: AC lodsb |
1049: AB stosw |
104A: E2 FC loop @b |
104C: 89 26 E0 1A mov word [ start_stack ], sp |
1050: 31 C0 xor ax, ax |
1052: CD 16 int 0x16 |
1054: 66 8B 1E D4 1A mov ebx, dword [ old_timer ] |
1059: 66 3B 1E DC 1A cmp ebx, dword [ timer_ ] |
105E: 74 2A jz @f |
1060: FA cli |
1061: 6A 00 push 0 |
1063: 07 pop es |
1064: 26 66 89 1E 20 00 mov [ es : 8 * 4 ], ebx |
106A: 66 89 1E DC 1A mov dword [ timer_ ], ebx |
106F: FB sti |
1070: 50 push ax |
1071: 68 00 B8 push 0xb800 |
1074: 07 pop es |
1075: 31 C0 xor ax, ax |
1077: B8 20 07 mov ax, 0x0720 |
107A: BF 20 0D mov di, 3360 |
107D: B9 40 01 mov cx, 80 * 4 |
1080: F3 rep |
1081: AB stosw |
1082: 68 00 20 push ini_data_ |
1085: 07 pop es |
1086: E8 CE F9 call show_bl_sc_sect |
1089: 58 pop ax |
108A: E8 23 F9 call clean_active_cursor |
108D: 80 FC 48 cmp ah, 0x48 |
1090: 74 21 jz .up |
1092: 80 FC 50 cmp ah, 0x50 |
1095: 74 3A jz .down |
1097: 80 FC 49 cmp ah, 0x49 |
109A: 74 53 jz .pgup |
109C: 80 FC 51 cmp ah, 0x51 |
109F: 74 5B jz .pgdown |
10A1: 80 FC 47 cmp ah, 0x47 |
10A4: 74 63 jz .home |
10A6: 80 FC 4F cmp ah, 0x4f |
10A9: 74 66 jz .end |
10AB: 3C 0D cmp al, 0xD |
10AD: 0F 85 64 FE jnz .show_active_cursor |
10B1: EB 6F jmp .end_show_all |
10B3: 8B 76 CA mov si, point_to_point_def |
10B6: 83 C6 02 add si, 2 |
10B9: 8D 46 F2 lea ax, point_to_hframe |
10BC: 39 C6 cmp si, ax |
10BE: 77 0B ja @f |
10C0: 89 76 CA mov point_to_point_def, si |
10C3: 8B 04 mov ax, [ si ] |
10C5: 89 46 F4 mov point_default, ax |
10C8: E9 4A FE jmp .show_active_cursor |
10CB: E8 52 F8 call find_before_sect |
10CE: E9 B1 FD jmp .show_all_scr |
10D1: 8B 76 CA mov si, point_to_point_def |
10D4: 8B 46 C8 mov ax, point_to_eframe |
10D7: 83 EE 02 sub si, 2 |
10DA: 39 C6 cmp si, ax |
10DC: 72 0B jb @f |
10DE: 89 76 CA mov point_to_point_def, si |
10E1: 8B 04 mov ax, [ si ] |
10E3: 89 46 F4 mov point_default, ax |
10E6: E9 2C FE jmp .show_active_cursor |
10E9: E8 8D F8 call find_next_sect |
10EC: E9 93 FD jmp .show_all_scr |
10EF: B9 12 00 mov cx, size_show_section |
10F2: 51 push cx |
10F3: E8 2A F8 call find_before_sect |
10F6: 59 pop cx |
10F7: E2 F9 loop @b |
10F9: E9 86 FD jmp .show_all_scr |
10FC: B9 12 00 mov cx, size_show_section |
10FF: 51 push cx |
1100: E8 76 F8 call find_next_sect |
1103: 59 pop cx |
1104: E2 F9 loop @b |
1106: E9 79 FD jmp .show_all_scr |
1109: 31 FF xor di, di |
110B: E8 79 F8 call find_next_sect.h |
110E: E9 71 FD jmp .show_all_scr |
1111: 8B 7E FE mov di, save_cx |
1114: E8 0C F8 call find_before_sect.e |
1117: E9 68 FD jmp .show_all_scr |
111A: 60 pusha |
111B: BE D7 04 mov si, no_show_only_w |
111E: E8 23 F7 call printplain |
1121: 61 popa |
1122: 8B 7E F4 mov di, point_default |
1125: 68 00 20 push ini_data_ |
1128: 07 pop es |
1129: 8B 76 CA mov si, point_to_point_def |
112C: 83 EE 02 sub si, 2 |
112F: 8B 0C mov cx, [ si ] |
1131: 31 C0 xor ax, ax |
1133: 29 F9 sub cx, di |
1135: 89 4E FA mov save_cx_d, cx |
1138: 89 46 F8 mov status_flag, ax |
113B: BE 2B 05 mov si, ramdiskFS_st |
113E: E8 03 F7 call printplain |
1141: 31 C0 xor ax, ax |
1143: 89 46 C0 mov show_errors_sect, ax |
1146: B4 88 mov ah, 0x88 |
1148: CD 15 int 0x15 |
114A: 73 02 jnc ._support_function_use_free_memory |
114C: 31 C0 xor ax, ax |
114E: 89 46 C2 mov free_ad_memory, ax |
1151: 60 pusha |
1152: 66 0F B7 C0 movzx eax, ax |
1156: B9 0A 00 mov cx, 0x0a |
1159: BF 46 05 mov di, free_memory_msg |
115C: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' |
1163: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' |
1168: E8 BA F6 call decode |
116B: BE 46 05 mov si, free_memory_msg |
116E: E8 D3 F6 call printplain |
1171: 61 popa |
1172: 8B 7E F4 mov di, point_default |
1175: 8B 4E FA mov cx, save_cx_d |
1178: E8 F8 F6 call get_firs_sym |
117B: 85 C9 test cx, cx |
117D: 74 6E jz ._end_parse_RS?0k2 |
117F: 3C 52 cmp al, 'R' |
1181: 75 F5 jnz .start_p_RS?0ju |
1183: 89 CB mov bx, cx |
1185: 89 F8 mov ax, di |
1187: BE D9 07 mov si, parse_RamdiskSize |
118A: B9 0B 00 mov cx, parse_RamdiskSize_e - parse_RamdiskSize |
118D: F3 repe |
118E: A6 cmpsb |
118F: 75 4C jnz .rest_value_loop_RS?0jz |
1191: 83 EB 0B sub bx, parse_RamdiskSize_e - parse_RamdiskSize |
1194: 01 CB add bx, cx |
1196: 89 D9 mov cx, bx |
1198: F7 46 F8 02 00 test status_flag, flag_found_RS |
119D: 74 00 jz .correct_is_not_set_RS?0jv |
119F: B8 20 3D mov ax, 0x3d20 |
11A2: F3 repe |
11A3: AE scasb |
11A4: E3 3D jcxz .end_get_RS_ERROR_1?0k0 |
11A6: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
11AA: 75 CC jnz .start_p_RS?0ju |
11AC: F3 repe |
11AD: AE scasb |
11AE: 41 inc cx |
11AF: 4F dec di |
11B0: 31 DB xor bx, bx |
11B2: B9 05 00 mov cx, 5 |
11B5: 26 8A 05 mov al, byte [ es : di ] |
11B8: 3C 30 cmp al, '0' |
11BA: 72 04 jb .CS?0jw |
11BC: 3C 39 cmp al, '9' |
11BE: 76 06 jbe .correct_val_RS?0jx |
11C0: 3C 4B cmp al, 'K' |
11C2: 74 0C jz .correct_size_RS?0jy |
11C4: EB 23 jmp .end_get_RS_ERROR_2?0k1 |
11C6: 6B DB 0A imul bx, 10 |
11C9: 34 30 xor al, 0x30 |
11CB: 00 C3 add bl, al |
11CD: 47 inc di |
11CE: E2 E5 loop @b |
11D0: 85 DB test bx, bx |
11D2: 75 07 jnz @f |
11D4: 83 4E C0 04 or show_errors_sect, show_error_3 |
11D8: BB 40 00 mov bx, 64 |
11DB: EB 10 jmp ._end_parse_RS?0k2 |
11DD: 89 C7 mov di, ax |
11DF: 89 D9 mov cx, bx |
11E1: EB 95 jmp .start_p_RS?0ju |
11E3: 83 4E C0 01 or show_errors_sect, show_error_1 |
11E7: EB 04 jmp ._end_parse_RS?0k2 |
11E9: 83 4E C0 02 or show_errors_sect, show_error_2 |
11ED: 60 pusha |
11EE: 66 0F B7 C3 movzx eax, bx |
11F2: B9 0A 00 mov cx, 0x0a |
11F5: BF 71 05 mov di, RamdiskSize_msg |
11F8: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' |
11FF: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' |
1204: E8 1E F6 call decode |
1207: BE 71 05 mov si, RamdiskSize_msg |
120A: E8 37 F6 call printplain |
120D: 61 popa |
120E: 39 5E C2 cmp free_ad_memory, bx |
1211: 0F 86 80 07 jbe ._not_memory_in_sys?0iL |
1215: 66 0F B7 C3 movzx eax, bx |
1219: 66 C1 E0 0A shl eax, 10 |
121D: 66 89 46 BA mov save_ramdisksize, eax |
1221: 8B 7E F4 mov di, point_default |
1224: 8B 4E FA mov cx, save_cx_d |
1227: E8 49 F6 call get_firs_sym |
122A: 85 C9 test cx, cx |
122C: 0F 84 5D 07 jz ._end_parse_FRS |
1230: 3C 52 cmp al, 'R' |
1232: 75 F3 jnz .start_g_tpe_RFS |
1234: 89 CB mov bx, cx |
1236: 89 F8 mov ax, di |
1238: BE E4 07 mov si, parse_RamdiskFS |
123B: B9 09 00 mov cx, parse_RamdiskFS_e - parse_RamdiskFS |
123E: F3 repe |
123F: A6 cmpsb |
1240: 0F 85 38 07 jnz .start_g_tpe_RFS_rest_v |
1244: 83 EB 09 sub bx, parse_RamdiskFS_e - parse_RamdiskFS |
1247: 01 CB add bx, cx |
1249: 89 D9 mov cx, bx |
124B: F7 46 F8 04 00 test status_flag, flag_found_GTRFMS |
1250: 74 00 jz .correct_is_not_set_FRS |
1252: B8 20 3D mov ax, 0x3d20 |
1255: F3 repe |
1256: AE scasb |
1257: 85 C9 test cx, cx |
1259: 0F 84 26 07 jz .end_get_FRS_ERROR_1 |
125D: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
1261: 75 C4 jnz .start_g_tpe_RFS |
1263: F3 repe |
1264: AE scasb |
1265: 41 inc cx |
1266: 4F dec di |
1267: 89 CB mov bx, cx |
1269: 89 F8 mov ax, di |
126B: BE 08 08 mov si, parse_RFS_FAT |
126E: B9 03 00 mov cx, parse_RFS_FAT_e - parse_RFS_FAT |
1271: F3 repe |
1272: A6 cmpsb |
1273: 0F 85 F7 06 jnz .krfs_cmp |
1277: 8B 7E F4 mov di, point_default |
127A: 8B 4E FA mov cx, save_cx_d |
127D: E8 F3 F5 call get_firs_sym |
1280: 85 C9 test cx, cx |
1282: 74 54 jz .end_RamdiskSector |
1284: 3C 52 cmp al, 'R' |
1286: 75 F5 jnz .start_RamdiskSector |
1288: 89 CB mov bx, cx |
128A: 89 F8 mov ax, di |
128C: BE ED 07 mov si, parse_RamdiskSector |
128F: B9 0D 00 mov cx, parse_RamdiskSector_e - parse_RamdiskSector |
1292: F3 repe |
1293: A6 cmpsb |
1294: 75 3C jnz .RamdiskSector_rest_val |
1296: 83 EB 0D sub bx, parse_RamdiskSector_e - parse_RamdiskSector |
1299: 01 CB add bx, cx |
129B: 89 D9 mov cx, bx |
129D: F7 46 F8 08 00 test status_flag, flag_found_RamdiskSector |
12A2: 74 00 jz .correct_is_not_set_RamdiskSector |
12A4: B8 20 3D mov ax, 0x3d20 |
12A7: F3 repe |
12A8: AE scasb |
12A9: E3 2D jcxz .end_get_RamS_ERROR_1 |
12AB: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
12AF: 75 CC jnz .start_RamdiskSector |
12B1: F3 repe |
12B2: AE scasb |
12B3: 41 inc cx |
12B4: 4F dec di |
12B5: 31 DB xor bx, bx |
12B7: B9 04 00 mov cx, 4 |
12BA: 26 0F B6 05 movzx ax, byte [ es : di ] |
12BE: 3C 30 cmp al, '0' |
12C0: 72 16 jb .end_RamdiskSector |
12C2: 3C 39 cmp al, '9' |
12C4: 77 12 ja .end_RamdiskSector |
12C6: 6B DB 0A imul bx, 10 |
12C9: 34 30 xor al, 0x30 |
12CB: 01 C3 add bx, ax |
12CD: 47 inc di |
12CE: E2 EA loop @b |
12D0: EB 06 jmp .end_RamdiskSector |
12D2: 89 D9 mov cx, bx |
12D4: 89 C7 mov di, ax |
12D6: EB A5 jmp .start_RamdiskSector |
12D8: 89 D8 mov ax, bx |
12DA: 60 pusha |
12DB: 66 0F B7 C3 movzx eax, bx |
12DF: B9 0A 00 mov cx, 0x0a |
12E2: BF 8E 05 mov di, RamdiskSector_msg |
12E5: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' |
12EC: 66 C7 45 04 20 20 20 20 mov dword [ ds : di + 4 ], ' ' |
12F4: E8 2E F5 call decode |
12F7: BE 8E 05 mov si, RamdiskSector_msg |
12FA: E8 47 F5 call printplain |
12FD: 61 popa |
12FE: 3D 00 10 cmp ax, 4096 |
1301: 77 04 ja .RS1?0sn |
1303: 85 C0 test ax, ax |
1305: 75 06 jnz @f |
1307: C7 06 87 1A 00 02 mov word [ fat12_buffer.BPB_BytsPerSec ], 512 |
130D: A3 87 1A mov word [ fat12_buffer.BPB_BytsPerSec ], ax |
1310: 8B 7E F4 mov di, point_default |
1313: 8B 4E FA mov cx, save_cx_d |
1316: E8 5A F5 call get_firs_sym |
1319: 85 C9 test cx, cx |
131B: 74 47 jz .end_RamdiskCluster |
131D: 3C 52 cmp al, 'R' |
131F: 75 F5 jnz .start_RamdiskCluster |
1321: 89 CB mov bx, cx |
1323: 89 F8 mov ax, di |
1325: BE FA 07 mov si, parse_RamdiskCluster |
1328: B9 0E 00 mov cx, parse_RamdiskCluster_e - parse_RamdiskCluster |
132B: F3 repe |
132C: A6 cmpsb |
132D: 75 2F jnz .RamdiskCluster_rest_val |
132F: 83 EB 0E sub bx, parse_RamdiskCluster_e - parse_RamdiskCluster |
1332: 01 CB add bx, cx |
1334: 89 D9 mov cx, bx |
1336: F7 46 F8 16 00 test status_flag, flag_found_RamdiskCluster |
133B: 74 00 jz .correct_is_not_set_RamdiskCluster |
133D: B8 20 3D mov ax, 0x3d20 |
1340: F3 repe |
1341: AE scasb |
1342: E3 20 jcxz .end_get_RamSC_ERROR_1 |
1344: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
1348: 75 CC jnz .start_RamdiskCluster |
134A: F3 repe |
134B: AE scasb |
134C: 41 inc cx |
134D: 4F dec di |
134E: 26 0F B6 05 movzx ax, byte [ es : di ] |
1352: 3C 30 cmp al, '0' |
1354: 72 0E jb .end_RamdiskCluster |
1356: 3C 39 cmp al, '9' |
1358: 77 0A ja .end_RamdiskCluster |
135A: 34 30 xor al, 0x30 |
135C: EB 06 jmp .end_RamdiskCluster |
135E: 89 D9 mov cx, bx |
1360: 89 C7 mov di, ax |
1362: EB B2 jmp .start_RamdiskCluster |
1364: 60 pusha |
1365: B9 0A 00 mov cx, 0x0a |
1368: BF AA 05 mov di, RamdiskCluster_msg |
136B: E8 B7 F4 call decode |
136E: BE AA 05 mov si, RamdiskCluster_msg |
1371: E8 D0 F4 call printplain |
1374: 61 popa |
1375: 3C 80 cmp al, 128 |
1377: 77 6B ja @f |
1379: A2 89 1A mov byte [ fat12_buffer.BPB_SecPerClus ], al |
137C: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] |
1382: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] |
1388: 66 0F AF D8 imul ebx, eax |
138C: 66 8B 46 BA mov eax, save_ramdisksize |
1390: 66 99 cdq |
1392: 66 F7 FB idiv ebx |
1395: 66 3D F5 0F 00 00 cmp eax, 4085 |
139B: 0F 82 8E 00 jb .fat12?0so |
139F: 66 3D F5 FF 00 00 cmp eax, 65525 |
13A5: 72 18 jb .fat16?0sp |
13A7: C7 46 B4 20 00 mov set_ramfs, 32 |
13AC: C7 06 8A 1A 20 00 mov word [ fat12_buffer.BPB_RsvdSecCnt ], 32 |
13B2: 66 31 C0 xor eax, eax |
13B5: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax |
13B8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax |
13BB: 66 A3 9C 1A mov dword [ fat12_buffer.BPB_TotSec32 ], eax |
13BF: EB FE jmp $ |
13C1: C7 46 B4 10 00 mov set_ramfs, 16 |
13C6: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] |
13CC: 66 0F AF C3 imul eax, ebx |
13D0: 66 3D 00 00 01 00 cmp eax, 0x10000 |
13D6: 73 0C jae @f |
13D8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax |
13DB: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 |
13E4: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count |
13EA: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax |
13ED: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] |
13F3: 66 6B C0 20 imul eax, 32 |
13F7: 66 01 D8 add eax, ebx |
13FA: 66 48 dec eax |
13FC: 66 99 cdq |
13FE: 66 F7 FB idiv ebx |
1401: 66 0F B7 1E 8A 1A movzx ebx, word [ fat12_buffer.BPB_RsvdSecCnt ] |
1407: 66 01 C3 add ebx, eax |
140A: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] |
1410: 66 29 D8 sub eax, ebx |
1413: 66 C1 E7 08 shl edi, 8 |
1417: 66 0F B6 0E 8C 1A movzx ecx, byte [ fat12_buffer.BPB_NumFATs ] |
141D: 66 01 CF add edi, ecx |
1420: 66 01 F8 add eax, edi |
1423: 66 48 dec eax |
1425: 66 99 cdq |
1427: 66 F7 FF idiv edi |
142A: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax |
142D: C7 46 B4 0C 00 mov set_ramfs, 12 |
1432: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] |
1438: 66 0F AF C3 imul eax, ebx |
143C: 66 3D 00 00 01 00 cmp eax, 0x10000 |
1442: 73 0C jae @f |
1444: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax |
1447: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 |
1450: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count |
1456: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax |
1459: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] |
145F: 66 6B C0 0C imul eax, 12 |
1463: 66 C1 E8 03 shr eax, 3 |
1467: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] |
146D: 66 99 cdq |
146F: 66 F7 FB idiv ebx |
1472: 40 inc ax |
1473: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax |
1476: A1 92 1A mov ax, word [ fat12_buffer.BPB_FATSz16 ] |
1479: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] |
147E: 0F AF C3 imul ax, bx |
1481: 8B 1E 8D 1A mov bx, word [ fat12_buffer.BPB_RootEntCnt ] |
1485: C1 EB 04 shr bx, 4 |
1488: 01 D8 add ax, bx |
148A: 89 5E B0 mov size_root_dir, bx |
148D: 0F B6 1E 8A 1A movzx bx, byte [ fat12_buffer.BPB_RsvdSecCnt ] |
1492: 01 D8 add ax, bx |
1494: 89 46 AE mov firstDataSect, ax |
1497: 8B 1E 8F 1A mov bx, word [ fat12_buffer.BPB_TotSec16 ] |
149B: 29 C3 sub bx, ax |
149D: 89 D8 mov ax, bx |
149F: 0F B6 1E 89 1A movzx bx, byte [ fat12_buffer.BPB_SecPerClus ] |
14A4: 99 cwd |
14A5: F7 FB idiv bx |
14A7: 89 46 AC mov DataClasters, ax |
14AA: 60 pusha |
14AB: 8B 46 AE mov ax, firstDataSect |
14AE: B9 0A 00 mov cx, 0x0a |
14B1: BF 44 06 mov di, firstDataSect_msg |
14B4: E8 6E F3 call decode |
14B7: BE 44 06 mov si, firstDataSect_msg |
14BA: E8 87 F3 call printplain |
14BD: 8B 46 B0 mov ax, size_root_dir |
14C0: B9 0A 00 mov cx, 0x0a |
14C3: BF 79 06 mov di, size_root_dir_msg |
14C6: E8 5C F3 call decode |
14C9: BE 79 06 mov si, size_root_dir_msg |
14CC: E8 75 F3 call printplain |
14CF: 8B 46 AC mov ax, DataClasters |
14D2: B9 0A 00 mov cx, 0x0a |
14D5: BF 9B 06 mov di, DataClasters_msg |
14D8: E8 4A F3 call decode |
14DB: BE 9B 06 mov si, DataClasters_msg |
14DE: E8 63 F3 call printplain |
14E1: 61 popa |
14E2: A0 91 1A mov al, byte [ fat12_buffer.BPB_Media ] |
14E5: 1E push ds |
14E6: 8B 7E C4 mov di, info_real_mode_size |
14E9: 81 C7 00 10 add di, 0x1000 |
14ED: 57 push di |
14EE: 31 FF xor di, di |
14F0: 89 7E AA mov point_to_free_root, di |
14F3: 1F pop ds |
14F4: 88 05 mov byte [ di ], al |
14F6: 83 C8 FF or ax, - 1 |
14F9: 47 inc di |
14FA: 89 05 mov word [ di ], ax |
14FC: 1F pop ds |
14FD: C7 46 B2 03 00 mov point_next_fat_str, 3 |
1502: 60 pusha |
1503: 8B 46 B2 mov ax, point_next_fat_str |
1506: B9 0A 00 mov cx, 0x0a |
1509: BF DA 05 mov di, fat_create_msg |
150C: E8 16 F3 call decode |
150F: BE DA 05 mov si, fat_create_msg |
1512: E8 2F F3 call printplain |
1515: 61 popa |
1516: B8 7C 1A mov ax, fat12_buffer |
1519: BE 3C 1A mov si, table_15_87 |
151C: 01 44 12 add word [ si + 8 * 2 + 2 ], ax |
151F: 06 push es |
1520: 1E push ds |
1521: 07 pop es |
1522: B9 1F 00 mov cx, 31 |
1525: B4 87 mov ah, 0x87 |
1527: CD 15 int 0x15 |
1529: 07 pop es |
152A: 60 pusha |
152B: 8B 44 12 mov ax, word [ si + 8 * 2 + 2 ] |
152E: B9 0A 00 mov cx, 0x0a |
1531: BF 0E 06 mov di, BPB_msg |
1534: E8 EE F2 call decode |
1537: BE 0E 06 mov si, BPB_msg |
153A: E8 07 F3 call printplain |
153D: 61 popa |
153E: 8B 7E F4 mov di, point_default |
1541: 8B 4E FA mov cx, save_cx_d |
1544: C7 46 A6 00 00 mov data_offset, 0 |
1549: E8 27 F3 call get_firs_sym |
154C: 85 C9 test cx, cx |
154E: 0F 84 B3 03 jz ._end?1D2 |
1552: 3C 52 cmp al, 'R' |
1554: 75 F3 jnz .start_loop?1D1 |
1556: 89 CB mov bx, cx |
1558: 89 F8 mov ax, di |
155A: BE 1A 08 mov si, parse_RamdiskFile |
155D: B9 0B 00 mov cx, parse_RamdiskFile_e - parse_RamdiskFile |
1560: F3 repe |
1561: A6 cmpsb |
1562: 0F 85 98 03 jnz .rest_value_loop?1D3 |
1566: 83 EB 0B sub bx, parse_RamdiskFile_e - parse_RamdiskFile |
1569: 01 CB add bx, cx |
156B: 89 D9 mov cx, bx |
156D: B8 20 3D mov ax, 0x3d20 |
1570: F3 repe |
1571: AE scasb |
1572: 66 85 C9 test ecx, ecx |
1575: 0F 84 85 03 jz .rest_value_loop?1D3 |
1579: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
157D: 0F 85 7D 03 jnz .rest_value_loop?1D3 |
1581: F3 repe |
1582: AE scasb |
1583: 41 inc cx |
1584: 4F dec di |
1585: 89 7E A2 mov save_di_RAMDISK, di |
1588: 89 4E A0 mov save_cx_RAMDISK, cx |
158B: 26 8A 05 mov al, byte [ es : di ] |
158E: 3C 2C cmp al, ',' |
1590: 74 04 jz .found_end_str |
1592: 47 inc di |
1593: 49 dec cx |
1594: 75 F5 jnz @b |
1596: 89 7E A8 mov point_to_dest_file_name, di |
1599: 47 inc di |
159A: BE BA 1A mov si, shot_name_fat |
159D: 83 4E A4 FF or first_input, - 1 |
15A1: B9 0B 00 mov cx, 11 |
15A4: 26 8A 05 mov al, byte [ es : di ] |
15A7: 3C 0A cmp al, 0xa |
15A9: 74 7D jz .st4_s?1GP |
15AB: 3C 0D cmp al, 0xd |
15AD: 74 79 jz .st4_s?1GP |
15AF: 3C 20 cmp al, 0x20 |
15B1: 74 75 jz .st4_s?1GP |
15B3: 3C 20 cmp al, 0x20 |
15B5: 72 7A jb .error?1GK |
15B7: 3C 22 cmp al, 0x22 |
15B9: 74 76 jz .error?1GK |
15BB: 3C 2A cmp al, 0x2a |
15BD: 74 72 jz .error?1GK |
15BF: 3C 2B cmp al, 0x2b |
15C1: 74 6E jz .error?1GK |
15C3: 3C 2C cmp al, 0x2c |
15C5: 74 6A jz .error?1GK |
15C7: 3C 2F cmp al, 0x2F |
15C9: 74 66 jz .error?1GK |
15CB: 3C 3A cmp al, 0x3a |
15CD: 74 62 jz .error?1GK |
15CF: 3C 3B cmp al, 0x3b |
15D1: 74 5E jz .error?1GK |
15D3: 3C 3C cmp al, 0x3c |
15D5: 74 5A jz .error?1GK |
15D7: 3C 3D cmp al, 0x3d |
15D9: 74 56 jz .error?1GK |
15DB: 3C 3E cmp al, 0x3E |
15DD: 74 52 jz .error?1GK |
15DF: 3C 3F cmp al, 0x3F |
15E1: 74 4E jz .error?1GK |
15E3: 3C 5B cmp al, 0x5b |
15E5: 74 4A jz .error?1GK |
15E7: 3C 5C cmp al, 0x5c |
15E9: 74 46 jz .error?1GK |
15EB: 3C 5D cmp al, 0x5d |
15ED: 74 42 jz .error?1GK |
15EF: 3C 7C cmp al, 0x7c |
15F1: 74 3E jz .error?1GK |
15F3: 83 7E A4 FF cmp first_input, - 1 |
15F7: 75 08 jnz .next_step?1GJ |
15F9: 83 66 A4 00 and first_input, 0 |
15FD: 3C 2E cmp al, '.' |
15FF: 74 30 jz .error?1GK |
1601: 3C 2E cmp al, 0x2e |
1603: 75 13 jnz .st2?1GM |
1605: B0 20 mov al, ' ' |
1607: 80 F9 03 cmp cl, 3 |
160A: 76 0C jbe .st2?1GM |
160C: 88 04 mov byte [ si ], al |
160E: 46 inc si |
160F: 49 dec cx |
1610: 83 F9 03 cmp cx, 3 |
1613: 77 F7 ja .st3?1GO |
1615: 47 inc di |
1616: EB 8C jmp @b |
1618: 3C 60 cmp al, 0x60 |
161A: 76 02 jbe .st2_l?1GN |
161C: 34 20 xor al, 0x20 |
161E: 88 04 mov byte [ si ], al |
1620: 47 inc di |
1621: 46 inc si |
1622: E2 80 loop @b |
1624: 31 C0 xor ax, ax |
1626: EB 0C jmp @f |
1628: B0 20 mov al, ' ' |
162A: 88 04 mov byte [ si ], al |
162C: 46 inc si |
162D: E2 FB loop .st4?1GQ |
162F: EB F3 jmp .st5?1GR |
1631: 83 C8 FF or ax, - 1 |
1634: 60 pusha |
1635: B9 0A 00 mov cx, 0x0a |
1638: BF F5 06 mov di, convertion_file_name_msg |
163B: E8 E7 F1 call decode |
163E: BE F5 06 mov si, convertion_file_name_msg |
1641: E8 00 F2 call printplain |
1644: BE BA 1A mov si, shot_name_fat |
1647: C6 44 0C 00 mov byte [ si + 12 ], 0 |
164B: E8 F6 F1 call printplain |
164E: 61 popa |
164F: 85 C0 test ax, ax |
1651: 75 39 jnz .exit?1GI |
1653: BE BA 1A mov si, shot_name_fat |
1656: 8B 7E AE mov di, firstDataSect |
1659: 2B 7E B0 sub di, size_root_dir |
165C: C1 E7 09 shl di, 9 |
165F: BA E0 00 mov dx, root_dir_entry_count |
1662: 8B 46 C4 mov ax, info_real_mode_size |
1665: 05 00 10 add ax, 0x1000 |
1668: 8E E8 mov gs, ax |
166A: B9 0B 00 mov cx, 11 |
166D: 8A 00 mov al, byte [ ds : si + bx ] |
166F: 65 8A 21 mov ah, byte [ gs : di + bx ] |
1672: 43 inc bx |
1673: 38 C4 cmp ah, al |
1675: 75 07 jnz .no_equal?1GH |
1677: E2 F4 loop @b |
1679: 83 C8 FF or ax, - 1 |
167C: EB 0E jmp .exit?1GI |
167E: B9 0B 00 mov cx, 11 |
1681: 31 DB xor bx, bx |
1683: 83 C7 20 add di, 32 |
1686: 4A dec dx |
1687: 75 E4 jnz @b |
1689: 83 E0 00 and ax, 0 |
168C: 60 pusha |
168D: B9 0A 00 mov cx, 0x0a |
1690: BF B9 06 mov di, check_name_fat_msg |
1693: 66 C7 05 20 20 20 20 mov dword [ di ], ' ' |
169A: C7 45 04 20 20 mov word [ di + 4 ], ' ' |
169F: E8 83 F1 call decode |
16A2: BE B9 06 mov si, check_name_fat_msg |
16A5: E8 9C F1 call printplain |
16A8: 61 popa |
16A9: 8B 7E A2 mov di, save_di_RAMDISK |
16AC: 8B 4E A0 mov cx, save_cx_RAMDISK |
16AF: 84 C0 test al, al |
16B1: 0F 85 94 FE jnz .start_loop?1D1 |
16B5: 26 66 FF 75 FA push dword [ es : di - 6 ] |
16BA: 8D 75 FA lea si, [ di - 6 ] |
16BD: 26 FF 75 FE push word [ es : di - 2 ] |
16C1: 57 push di |
16C2: 31 C0 xor ax, ax |
16C4: 26 89 45 FA mov word [ es : di - 6 ], ax |
16C8: 8B 46 C4 mov ax, info_real_mode_size |
16CB: 26 89 45 FC mov word [ es : di - 4 ], ax |
16CF: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 |
16D5: 8B 7E A8 mov di, point_to_dest_file_name |
16D8: 26 FF 35 push word [ es : di ] |
16DB: 51 push cx |
16DC: 31 C0 xor ax, ax |
16DE: 26 89 05 mov word [ es : di ], ax |
16E1: 57 push di |
16E2: 89 F7 mov di, si |
16E4: 40 inc ax |
16E5: 56 push si |
16E6: 06 push es |
16E7: 55 push bp |
16E8: 06 push es |
16E9: 1F pop ds |
16EA: 0E push cs |
16EB: 07 pop es |
16EC: 26 FF 1E DC 0A call far dword [ es : loader_callback ] |
16F1: 0E push cs |
16F2: 1F pop ds |
16F3: 5D pop bp |
16F4: 07 pop es |
16F5: 5E pop si |
16F6: 83 FB 02 cmp bx, 2 |
16F9: 0F 87 01 02 ja .error?1D4 |
16FD: 89 5E 9E mov status_flag_loader_f, bx |
1700: 66 C1 E2 10 shl edx, 16 |
1704: 89 C2 mov dx, ax |
1706: 66 89 56 B6 mov save_file_size, edx |
170A: 66 89 D0 mov eax, edx |
170D: 5F pop di |
170E: 59 pop cx |
170F: 26 8F 05 pop word [ es : di ] |
1712: 5F pop di |
1713: 26 8F 45 FE pop word [ es : di - 2 ] |
1717: 26 66 8F 45 FA pop dword [ es : di - 6 ] |
171C: 60 pusha |
171D: B9 0A 00 mov cx, 0x0a |
1720: BF C1 05 mov di, RamdiskFile_msg |
1723: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' |
172A: E8 F8 F0 call decode |
172D: BE C1 05 mov si, RamdiskFile_msg |
1730: E8 11 F1 call printplain |
1733: 61 popa |
1734: 06 push es |
1735: 8B 46 C4 mov ax, info_real_mode_size |
1738: 05 00 10 add ax, 0x1000 |
173B: 8E C0 mov es, ax |
173D: 8B 7E AE mov di, firstDataSect |
1740: 2B 7E B0 sub di, size_root_dir |
1743: C1 E7 09 shl di, 9 |
1746: 03 7E AA add di, point_to_free_root |
1749: BE BA 1A mov si, shot_name_fat |
174C: B9 0B 00 mov cx, 11 |
174F: AC lodsb |
1750: AA stosb |
1751: E2 FC loop @b |
1753: 31 C0 xor ax, ax |
1755: B4 08 mov ah, ATTR_VOLUME_ID |
1757: 26 89 05 mov word [ es : di ], ax |
175A: 83 C7 02 add di, 2 |
175D: 26 C6 05 64 mov byte [ es : di ], 100 |
1761: 47 inc di |
1762: 26 C7 05 2B 03 mov word [ es : di ], 0x032b |
1767: 83 C7 02 add di, 2 |
176A: 26 C7 05 00 00 mov word [ es : di ], 0x0 |
176F: 83 C7 02 add di, 2 |
1772: 26 C7 05 2B 03 mov word [ es : di ], 0x032b |
1777: 83 C7 02 add di, 2 |
177A: 26 C7 05 00 00 mov word [ es : di ], 0x0 |
177F: 83 C7 02 add di, 2 |
1782: 26 C7 05 00 00 mov word [ es : di ], 0x0 |
1787: 83 C7 02 add di, 2 |
178A: 26 C7 05 2B 03 mov word [ es : di ], 0x032b |
178F: 83 C7 02 add di, 2 |
1792: 8B 46 B2 mov ax, point_next_fat_str |
1795: 26 89 05 mov word [ es : di ], ax |
1798: 83 C7 02 add di, 2 |
179B: 57 push di |
179C: 89 C3 mov bx, ax |
179E: D1 EB shr bx, 1 |
17A0: 01 D8 add ax, bx |
17A2: 8B 1E 87 1A mov bx, word [ fat12_buffer.BPB_BytsPerSec ] |
17A6: 99 cwd |
17A7: F7 FB idiv bx |
17A9: 89 C6 mov si, ax |
17AB: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] |
17B1: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] |
17B7: 66 0F AF C3 imul eax, ebx |
17BB: 66 8B 5E B6 mov ebx, save_file_size |
17BF: 66 29 C3 sub ebx, eax |
17C2: 66 39 C3 cmp ebx, eax |
17C5: 76 29 jbe .eof_file?1US |
17C7: FF 46 B2 inc point_next_fat_str |
17CA: 8B 4E B2 mov cx, point_next_fat_str |
17CD: 89 C2 mov dx, ax |
17CF: D1 EA shr dx, 1 |
17D1: 01 D1 add cx, dx |
17D3: F7 C6 01 00 test si, 0x1 |
17D7: 74 0B jz .step2?1UP |
17D9: C1 E1 04 shl cx, 4 |
17DC: 26 89 0C mov word [ es : si ], cx |
17DF: 46 inc si |
17E0: 01 C1 add cx, ax |
17E2: EB DB jmp @b |
17E4: 81 E1 FF 0F and cx, 0x0FFF |
17E8: 26 89 0C mov word [ es : si ], cx |
17EB: 46 inc si |
17EC: 01 C1 add cx, ax |
17EE: EB CF jmp @b |
17F0: B9 FF 0F mov cx, 0x0fff |
17F3: F7 C6 01 00 test si, 0x1 |
17F7: 74 08 jz .step3?1UQ |
17F9: C1 E1 04 shl cx, 4 |
17FC: 26 89 0C mov word [ es : si ], cx |
17FF: EB 07 jmp .end?1UR |
1801: 81 E1 FF 0F and cx, 0x0FFF |
1805: 26 89 0C mov word [ es : si ], cx |
1808: FF 46 B2 inc point_next_fat_str |
180B: 5F pop di |
180C: 66 8B 46 B6 mov eax, save_file_size |
1810: 26 66 89 05 mov dword [ es : di ], eax |
1814: 66 60 pushad |
1816: 8B 7E AE mov di, firstDataSect |
1819: 2B 7E B0 sub di, size_root_dir |
181C: C1 E7 09 shl di, 9 |
181F: 03 7E AA add di, point_to_free_root |
1822: BE C6 1A mov si, dest_name_fat |
1825: B9 0B 00 mov cx, 11 |
1828: 26 8A 05 mov al, byte [ es : di ] |
182B: 47 inc di |
182C: 88 04 mov byte [ ds : si ], al |
182E: 46 inc si |
182F: E2 F7 loop @b |
1831: 31 C0 xor ax, ax |
1833: 88 04 mov byte [ si ], al |
1835: BE C6 1A mov si, dest_name_fat |
1838: E8 09 F0 call printplain |
183B: 66 61 popad |
183D: 83 46 AA 20 add point_to_free_root, 32 |
1841: 07 pop es |
1842: 8B 46 C4 mov ax, info_real_mode_size |
1845: BE 3C 1A mov si, table_15_87 |
1848: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax |
184B: 66 0F B7 46 AE movzx eax, firstDataSect |
1850: 66 0F B7 56 A6 movzx edx, data_offset |
1855: 66 01 D0 add eax, edx |
1858: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] |
185E: 66 0F B6 16 89 1A movzx edx, byte [ fat12_buffer.BPB_SecPerClus ] |
1864: 0F AF DA imul bx, dx |
1867: 66 53 push ebx |
1869: 66 0F AF C3 imul eax, ebx |
186D: 60 pusha |
186E: B9 0A 00 mov cx, 0x0a |
1871: BF 07 04 mov di, show_db1 |
1874: E8 AE EF call decode |
1877: BE 07 04 mov si, show_db1 |
187A: E8 C7 EF call printplain |
187D: 61 popa |
187E: B2 10 mov dl, 0x10 |
1880: 66 3D 00 00 01 00 cmp eax, 0x00010000 |
1886: 72 0A jb @f |
1888: 66 2D 00 00 01 00 sub eax, 0x00010000 |
188E: FE C2 inc dl |
1890: EB EE jmp @b |
1892: 88 54 1B mov byte [ si + 8 * 3 + 3 ], dl |
1895: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax |
1898: 66 8B 4E B6 mov ecx, save_file_size |
189C: 66 81 F9 FF FF 00 00 cmp ecx, 0x0000ffff |
18A3: 76 0A jbe .correct_on_byte?1cJ |
18A5: 66 B9 00 00 01 00 mov ecx, 0x00010000 |
18AB: 66 29 4E B6 sub save_file_size, ecx |
18AF: 66 58 pop eax |
18B1: 66 51 push ecx |
18B3: FF 46 A6 inc data_offset |
18B6: 66 39 C8 cmp eax, ecx |
18B9: 73 05 jae @f |
18BB: 66 29 C1 sub ecx, eax |
18BE: EB F3 jmp @b |
18C0: 66 59 pop ecx |
18C2: 66 F7 C1 01 00 00 00 test ecx, 0x1 |
18C9: 74 02 jz .st1?1cI |
18CB: 66 41 inc ecx |
18CD: 66 D1 E9 shr ecx, 1 |
18D0: 06 push es |
18D1: 1E push ds |
18D2: 07 pop es |
18D3: B4 87 mov ah, 0x87 |
18D5: CD 15 int 0x15 |
18D7: 07 pop es |
18D8: 60 pusha |
18D9: B9 0A 00 mov cx, 0x0a |
18DC: BF 46 07 mov di, return_code_af_move |
18DF: E8 43 EF call decode |
18E2: BE 46 07 mov si, return_code_af_move |
18E5: E8 5C EF call printplain |
18E8: 61 popa |
18E9: 83 7E 9E 01 cmp status_flag_loader_f, 0x1 |
18ED: 75 00 jnz @f |
18EF: 8B 7E A2 mov di, save_di_RAMDISK |
18F2: 8B 4E A0 mov cx, save_cx_RAMDISK |
18F5: 60 pusha |
18F6: 31 C0 xor ax, ax |
18F8: CD 16 int 0x16 |
18FA: 61 popa |
18FB: E9 4B FC jmp .start_loop?1D1 |
18FE: 89 C7 mov di, ax |
1900: 89 D9 mov cx, bx |
1902: E9 44 FC jmp .start_loop?1D1 |
1905: 8B 46 C4 mov ax, info_real_mode_size |
1908: 05 00 10 add ax, 0x1000 |
190B: BE 3C 1A mov si, table_15_87 |
190E: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax |
1911: B8 00 02 mov ax, 512 |
1914: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax |
1917: 66 0F B7 0E 92 1A movzx ecx, word [ fat12_buffer.BPB_FATSz16 ] |
191D: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] |
1922: 0F AF CB imul cx, bx |
1925: 03 4E B0 add cx, size_root_dir |
1928: 66 C1 E1 09 shl ecx, 9 |
192C: 66 F7 C1 01 00 00 00 test ecx, 0x1 |
1933: 74 02 jz .st1?1ho |
1935: 66 41 inc ecx |
1937: 66 D1 E9 shr ecx, 1 |
193A: 06 push es |
193B: 1E push ds |
193C: 07 pop es |
193D: B4 87 mov ah, 0x87 |
193F: CD 15 int 0x15 |
1941: 07 pop es |
1942: 60 pusha |
1943: B9 0A 00 mov cx, 0x0a |
1946: BF 77 07 mov di, return_code_af_fat_m |
1949: E8 D9 EE call decode |
194C: BE 77 07 mov si, return_code_af_fat_m |
194F: E8 F2 EE call printplain |
1952: 61 popa |
1953: 60 pusha |
1954: B9 0A 00 mov cx, 0x0a |
1957: BF 07 04 mov di, show_db1 |
195A: E8 C8 EE call decode |
195D: BE 07 04 mov si, show_db1 |
1960: E8 E1 EE call printplain |
1963: 61 popa |
1964: 60 pusha |
1965: BE 21 07 mov si, make_fat12_RFS_msg |
1968: E8 D9 EE call printplain |
196B: 61 popa |
196C: EB 1F jmp ._end_parse_FRS |
196E: 89 D9 mov cx, bx |
1970: 89 C7 mov di, ax |
1972: BE 0B 08 mov si, parse_RFS_KRFS |
1975: B9 04 00 mov cx, parse_RFS_KRFS_e - parse_RFS_KRFS |
1978: F3 repe |
1979: A6 cmpsb |
197A: EB 11 jmp ._end_parse_FRS |
197C: 89 D9 mov cx, bx |
197E: 89 C7 mov di, ax |
1980: E9 A4 F8 jmp .start_g_tpe_RFS |
1983: 83 4E C0 01 or show_errors_sect, show_error_1 |
1987: EB 04 jmp ._end_parse_FRS |
1989: 83 4E C0 02 or show_errors_sect, show_error_2 |
198D: 60 pusha |
198E: BE 34 07 mov si, get_type_FS_msg |
1991: E8 B0 EE call printplain |
1994: 61 popa |
1995: 31 C0 xor ax, ax |
1997: CD 16 int 0x16 |
1999: 8B 7E F4 mov di, point_default |
199C: 8B 4E FA mov cx, save_cx_d |
199F: E8 D1 EE call get_firs_sym |
19A2: 85 C9 test cx, cx |
19A4: 0F 84 8E 00 jz ._afterLoaderModule |
19A8: 3C 4C cmp al, 'L' |
19AA: 75 F3 jnz .start_p_LM |
19AC: 89 CB mov bx, cx |
19AE: 89 F8 mov ax, di |
19B0: BE CD 07 mov si, parse_LoaderModule |
19B3: B9 0C 00 mov cx, parse_LoaderModule_e - parse_LoaderModule |
19B6: F3 repe |
19B7: A6 cmpsb |
19B8: 75 75 jnz .rest_value_loop_LM |
19BA: 83 EB 0C sub bx, parse_LoaderModule_e - parse_LoaderModule |
19BD: 01 CB add bx, cx |
19BF: 89 D9 mov cx, bx |
19C1: F7 46 F8 01 00 test status_flag, flag_found_LM |
19C6: 74 00 jz .correct_is_not_set_LM |
19C8: B8 20 3D mov ax, 0x3d20 |
19CB: F3 repe |
19CC: AE scasb |
19CD: E3 60 jcxz .rest_value_loop_LM |
19CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] |
19D3: 75 5A jnz .rest_value_loop_LM |
19D5: F3 repe |
19D6: AE scasb |
19D7: 41 inc cx |
19D8: 4F dec di |
19D9: 26 66 FF 75 FA push dword [ es : di - 6 ] |
19DE: 8D 75 FA lea si, [ di - 6 ] |
19E1: 26 FF 75 FE push word [ es : di - 2 ] |
19E5: 31 C0 xor ax, ax |
19E7: 26 89 45 FA mov word [ es : di - 6 ], ax |
19EB: 8B 46 C4 mov ax, info_real_mode_size |
19EE: 26 89 45 FC mov word [ es : di - 4 ], ax |
19F2: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 |
19F8: 26 8A 05 mov al, byte [ es : di ] |
19FB: 3C 20 cmp al, ' ' |
19FD: 74 0C jz .found_end_str?1mb |
19FF: 3C 0A cmp al, 0xa |
1A01: 74 08 jz .found_end_str?1mb |
1A03: 3C 0D cmp al, 0xd |
1A05: 74 04 jz .found_end_str?1mb |
1A07: 47 inc di |
1A08: 49 dec cx |
1A09: 75 ED jnz @b |
1A0B: 26 FF 35 push word [ es : di ] |
1A0E: 31 C0 xor ax, ax |
1A10: 26 89 05 mov word [ es : di ], ax |
1A13: 89 F7 mov di, si |
1A15: 40 inc ax |
1A16: 56 push si |
1A17: 06 push es |
1A18: 06 push es |
1A19: 1F pop ds |
1A1A: 0E push cs |
1A1B: 07 pop es |
1A1C: 26 FF 1E DC 0A call far dword [ es : loader_callback ] |
1A21: 0E push cs |
1A22: 1F pop ds |
1A23: 07 pop es |
1A24: 5E pop si |
1A25: 85 DB test bx, bx |
1A27: 75 03 jnz .error_LM |
1A29: 26 FF 2C jmp far dword [ es : si ] |
1A2C: E8 91 F0 call error.LoaderModule |
1A2F: 89 C7 mov di, ax |
1A31: 89 D9 mov cx, bx |
1A33: E9 69 FF jmp .start_p_LM |
1A36: EB FE jmp $ |
1A38: E9 6A F1 jmp ini_loaded |
1A3C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A44: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A4C: FF FF db 0xff, 0xff |
1A4E: 00 10 db 0x0, 0x10 |
1A50: 00 93 00 00 db 0x00, 0x93, 0x0, 0x0 |
1A54: FF FF 00 00 10 93 00 00 db 0xff, 0xff, 0x0, 0x00, 0x10, 0x93, 0x0, 0x0 |
1A5C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A64: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A6C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A74: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 |
1A7C: 90 90 90 .BS_jmpBoot db 0x90, 0x90, 0x90 |
1A7F: 4B 20 53 79 53 20 36 34 .BS_OEMName db 'K SyS 64' |
1A87: 00 02 .BPB_BytsPerSec dw 512 |
1A89: 01 .BPB_SecPerClus db 0x1 |
1A8A: 01 00 .BPB_RsvdSecCnt dw 0x1 |
1A8C: 01 .BPB_NumFATs db 0x1 |
1A8D: 00 02 .BPB_RootEntCnt dw 512 |
1A8F: 00 00 .BPB_TotSec16 dw 0x0 |
1A91: F0 .BPB_Media db 0xF0 |
1A92: 00 00 .BPB_FATSz16 dw 0x0 |
1A94: 00 00 .BPB_SecPerTrk dw 0x0 |
1A96: 00 00 .BPB_NumHeads dw 0x0 |
1A98: 00 00 00 00 .BPB_HiddSec dd 0x0 |
1A9C: 00 00 00 00 .BPB_TotSec32 dd 0x0 |
1AA0: 52 .BS_DrvNum db 'R' |
1AA1: 00 .BS_Reserved1 db 0x0 |
1AA2: 29 .BS_BootSig db 0x29 |
1AA3: 52 46 4B 53 .BS_VolID db 'RFKS' |
1AA7: 52 41 4D 20 44 49 53 4B 20 46 53 .BS_VolLab db 'RAM DISK FS' |
1AB2: 46 41 54 31 32 20 20 20 .BS_FilSysType db 'FAT12 ' |
1ABA: shot_name_fat rb 11 |
1AC5: rb 1 |
1AC6: dest_name_fat rb 12 |
1AD2: value_timeout rw 1 |
1AD4: old_timer rd 1 |
1AD8: start_timer rd 1 |
1ADC: timer_ rd 1 |
1AE0: start_stack rw 1 |
1AE2: save_bp_from_timer rw 1 |
3 passes, 0.8 seconds, 6842 bytes. |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_equ.inc |
---|
0,0 → 1,98 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/startos.ini |
---|
0,0 → 1,98 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/build.bat |
---|
0,0 → 1,20 |
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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/floppy.asc |
---|
0,0 → 1,49 |
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-$ |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/mkfloppy.inc |
---|
0,0 → 1,90 |
; --------------------------------------------------------------------------- |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/build.bat |
---|
0,0 → 1,2 |
@fasm -m 65535 kordldr.win.asm kordldr.win |
@pause |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/fat.inc |
---|
0,0 → 1,509 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.asm |
---|
0,0 → 1,921 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.txt |
---|
0,0 → 1,391 |
; 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. Äîáàâëÿåò ñåêòîð â êîíåö ñïèñêà (ñàìûé íîâûé âõîä). |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/ntfs.inc |
---|
0,0 → 1,587 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.asm |
---|
0,0 → 1,1024 |
; 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. |
;***************************************************************************** |
jmp far 0:real_start |
; special text |
org $+0x7C00 |
real_start: |
; initialize |
xor ax, ax |
mov ss, ax |
mov sp, 0x7C00 |
mov ds, ax |
mov es, ax |
cld |
sti |
mov [bootdrive], dl |
; check LBA support |
mov ah, 41h |
mov bx, 55AAh |
int 13h |
mov si, aNoLBA |
jc err_ |
cmp bx, 0AA55h |
jnz err_ |
test cl, 1 |
jz err_ |
; get file system information |
; scan for Primary Volume Descriptor |
db 66h |
push 10h-1 |
pop eax |
pvd_scan_loop: |
mov cx, 1 |
inc eax |
mov bx, 0x1000 |
call read_sectors |
jnc @f |
fatal_read_err: |
mov si, aReadError |
err_: |
call out_string |
mov si, aPressAnyKey |
call out_string |
xor ax, ax |
int 16h |
int 18h |
jmp $ |
@@: |
push ds |
pop es |
cmp word [bx+1], 'CD' |
jnz pvd_scan_loop |
cmp word [bx+3], '00' |
jnz pvd_scan_loop |
cmp byte [bx+5], '1' |
jnz pvd_scan_loop |
; we have found ISO9660 descriptor, look for type |
cmp byte [bx], 1 ; Primary Volume Descriptor? |
jz pvd_found |
cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? |
jnz pvd_scan_loop |
; Volume Descriptor Set Terminator reached, no PVD found - fatal error |
mov si, no_pvd |
jmp err_ |
pvd_found: |
add bx, 80h |
mov ax, [bx] |
mov [lb_size], ax |
; calculate number of logical blocks in one sector |
mov ax, 800h |
cwd |
div word [bx] |
mov [lb_per_sec], ax |
; get location of root directory |
mov di, root_location |
movzx eax, byte [bx+1Dh] |
add eax, [bx+1Eh] |
stosd |
; get memory size |
int 12h |
mov si, nomem_str |
cmp ax, 71000h / 400h |
jb err_ |
shr ax, 1 |
sub ax, 60000h / 800h |
mov [size_rest], ax |
mov [free_ptr], 60000h / 800h |
; load path table |
; if size > 62K => it's very strange, avoid using it |
; if size > (size of cache)/2 => avoid using it too |
mov ecx, [bx+4] |
cmp ecx, 0x10000 - 0x800 |
ja nopathtable |
shr ax, 1 |
cmp ax, 0x20 |
jae @f |
shl ax, 11 |
cmp cx, ax |
ja nopathtable |
@@: |
; size is ok, try to load it |
mov [pathtable_size], cx |
mov eax, [bx+12] |
xor edx, edx |
div dword [lb_per_sec] |
imul dx, [bx] |
mov [pathtable_start], dx |
add cx, dx |
call cx_to_sectors |
xor bx, bx |
push 6000h |
pop es |
call read_sectors |
jc nopathtable |
; path table has been loaded |
inc [use_path_table] |
sub [size_rest], cx |
add [free_ptr], cx |
nopathtable: |
; init cache |
mov ax, [size_rest] |
mov [cache_size], ax |
mov ax, [free_ptr] |
mov [cache_start], ax |
; load secondary loader |
mov di, secondary_loader_info |
call load_file |
test bx, bx |
jnz noloader |
; set registers for secondary loader |
mov ah, [bootdrive] |
mov al, 'c' |
mov bx, 'is' |
mov si, callback |
jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 |
noloader: |
mov si, aKernelNotFound |
jmp err_ |
read_sectors: |
; es:bx = pointer to data |
; eax = first sector |
; cx = number of sectors |
pushad |
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 |
db 66h |
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, [cs:bootdrive] |
mov ah, 42h |
int 13h |
jc diskreaderr |
; restore stack |
add sp, 10h |
; increase current sector & buffer; decrease number of sectors |
movzx esi, cx |
mov ax, es |
shl cx, 7 |
add ax, cx |
mov es, ax |
pop cx |
pop ax |
add eax, esi |
sub cx, si |
jnz do_read_sectors |
pop ds |
popad |
ret |
diskreaderr: |
add sp, 10h + 2*2 |
pop ds |
popad |
stc |
out_string.ret: |
ret |
out_string: |
; in: ds:si -> ASCIIZ string |
lodsb |
test al, al |
jz .ret |
mov ah, 0Eh |
mov bx, 7 |
int 10h |
jmp out_string |
aNoLBA db 'The drive does not support LBA!',0 |
aReadError db 'Read error',0 |
no_pvd db 'Primary Volume Descriptor not found!',0 |
nomem_str db 'No memory',0 |
aPressAnyKey db 13,10,'Press any key...',13,10,0 |
load_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 = 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) |
; parse path to the file |
lea si, [di+6] |
mov eax, [cs:root_location] |
cmp [cs:use_path_table], 0 |
jz parse_dir |
; scan for path in path table |
push di |
push 6000h |
pop es |
mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table |
mov dx, 1 ; dx = number of current entry in path table, start from 1 |
mov cx, [cs:pathtable_size] |
pathtable_newparent: |
mov bx, dx ; bx = number of current parent in path table: root = 1 |
scan_path_table_e: |
call is_last_component |
jnc path_table_scanned |
scan_path_table_i: |
cmp word [es:di+6], bx |
jb .next |
ja path_table_notfound |
call test_filename1 |
jc .next |
@@: |
lodsb |
cmp al, '/' |
jnz @b |
jmp pathtable_newparent |
.next: |
; go to next entry |
inc dx |
movzx ax, byte [es:di] |
add ax, 8+1 |
and al, not 1 |
add di, ax |
sub cx, ax |
ja scan_path_table_i |
path_table_notfound: |
pop di |
mov ax, -1 |
mov dx, ax |
mov bx, 2 ; file not found |
ret |
path_table_scanned: |
movzx eax, byte [es:di+1] |
add eax, [es:di+2] |
pop di |
parse_dir: |
; eax = logical block, ds:di -> information structure, ds:si -> file name |
; was the folder already read? |
push di ds |
push cs |
pop ds |
mov [cur_desc_end], 2000h |
mov bx, cachelist |
.scan1: |
mov bx, [bx+2] |
cmp bx, cachelist |
jz .notfound |
cmp [bx+4], eax |
jnz .scan1 |
.found: |
; yes; delete this item from the list (the following code will append this item to the tail) |
mov di, [bx] |
push word [bx+2] |
pop word [di+2] |
mov di, [bx+2] |
push word [bx] |
pop word [di] |
mov di, bx |
jmp .scan |
.notfound: |
; no; load first sector of the folder to get its size |
push eax |
push si |
mov si, 1 |
call load_phys_sector_for_lb_force |
mov bx, si |
pop si |
pop eax |
jnc @f |
; read error - return |
.readerr: |
pop ds |
.readerr2: |
pop di |
mov ax, -1 |
mov dx, ax |
mov bx, 3 |
ret |
@@: |
; first item of the folder describes the folder itself |
; do not cache too big folders: size < 64K and size <= (total cache size)/2 |
cmp word [bx+12], 0 |
jnz .nocache |
mov cx, [cache_size] ; cx = cache size in sectors |
shr cx, 1 ; cx = (cache size)/2 |
cmp cx, 0x20 |
jae @f |
shl cx, 11 |
cmp [bx+10], cx |
ja .nocache |
@@: |
; we want to cache this folder; get space for it |
mov cx, [bx+10] |
call cx_to_sectors |
jnz .yescache |
.nocache: |
push dword [bx+10] |
pop dword [cur_nocache_len] |
call lb_to_sector |
push ds |
pop es |
pop ds |
.nocache_loop: |
push eax |
mov dx, 1800h |
call scan_for_filename_in_sector |
mov cx, dx |
pop eax |
jnc .j_scandone |
sub cx, bx |
sub word [es:cur_nocache_len], cx |
sbb word [es:cur_nocache_len+2], 0 |
jb .j_scandone |
ja @f |
cmp word [es:cur_nocache_len], 0 |
jz .j_scandone |
@@: |
mov cx, 1 |
inc eax |
push es |
mov bx, 1000h |
call read_sectors |
pop es |
jc .readerr2 |
jmp .nocache_loop |
.j_scandone: |
jmp .scandone |
.yescache: |
push bx |
mov bx, [cachelist.head] |
.freeloop: |
cmp cx, [size_rest] |
jbe .sizeok |
@@: |
; if we are here: there is not enough free space, so we must delete old folders' data |
; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). |
; one loop iteration: delete data of one folder |
pusha |
mov dx, [bx+10] |
mov es, dx ; es = segment of folder data to be deleted |
xor di, di |
mov ax, [bx+8] |
add ax, 0x7FF |
rcr ax, 1 |
shr ax, 10 |
push ax |
shl ax, 11-4 ; get number of paragraphs in folder data to be deleted |
mov cx, [cache_size] |
add cx, [cache_start] |
push ds |
push ax |
add ax, dx |
mov ds, ax |
pop ax |
shl cx, 11-4 |
sub cx, dx ; cx = number of paragraphs to be moved |
push si |
xor si, si |
; move cx paragraphs from ds:si to es:di to get free space in the end of cache |
@@: |
sub cx, 1000h |
jbe @f |
push cx |
mov cx, 8000h |
rep movsw |
mov cx, ds |
add cx, 1000h |
mov ds, cx |
mov cx, es |
add cx, 1000h |
mov es, cx |
pop cx |
jmp @b |
@@: |
add cx, 1000h |
shl cx, 3 |
rep movsw |
pop si |
pop ds |
; correct positions in cache for existing items |
mov cx, 80h |
mov di, 8400h |
.correct: |
cmp [di+10], dx |
jbe @f |
sub [di+10], ax |
@@: |
add di, 12 |
loop .correct |
; some additional space is free now |
pop ax |
add [size_rest], ax |
sub [free_ptr], ax |
; add cache item to the list of free items |
mov dx, [bx] |
mov ax, [free_cache_item] |
mov [bx], ax |
mov [free_cache_item], bx |
mov bx, dx |
; current iteration done |
popa |
jmp .freeloop |
.sizeok: |
mov [cachelist.head], bx |
mov word [bx+2], cachelist |
; allocate new item in cache |
mov di, [free_cache_item] |
test di, di |
jz .nofree |
push word [di] |
pop [free_cache_item] |
jmp @f |
.nofree: |
mov di, [last_cache_item] |
add [last_cache_item], 12 |
@@: |
pop bx |
push si di |
; mov [di+4], eax ; start of folder |
scasd |
stosd |
push ax |
mov ax, [free_ptr] |
shl ax, 11-4 |
mov [di+10-8], ax |
mov es, ax |
pop ax |
add [free_ptr], cx |
sub [size_rest], cx |
; read folder data |
; first sector is already in memory, 0000:bx |
pusha |
mov cx, [bx+10] |
mov [di+8-8], cx ; folder size in bytes |
mov si, bx |
xor di, di |
mov cx, 0x1800 |
sub cx, si |
rep movsb |
pop ax |
push di |
popa |
; read rest of folder |
mov esi, dword [lb_per_sec] |
add eax, esi |
dec si |
not si |
and ax, si |
mov si, word [bx+10] |
mov bx, di |
pop di |
sub si, bx |
jbe @f |
mov [cur_limit], esi |
call read_many_bytes |
pop si |
jnc .scan |
jmp .readerr |
@@: |
pop si |
.scan: |
; now we have required cache item; append it to the end of list |
mov bx, [cachelist.tail] |
mov [cachelist.tail], di |
mov [di+2], bx |
mov word [di], cachelist |
mov [bx], di |
; scan for given filename |
mov es, [di+10] |
mov dx, [di+8] |
pop ds |
xor bx, bx |
call scan_for_filename_in_sector |
.scandone: |
push cs |
pop es |
mov bx, 2000h |
cmp bx, [es:cur_desc_end] |
jnz filefound |
j_notfound: |
jmp path_table_notfound |
filefound: |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
@@: |
mov cl, [es:bx+8] |
test al, al |
jz @f |
; parse next component of file name |
test cl, 2 ; directory? |
jz j_notfound |
mov eax, [es:bx] |
pop di |
jmp parse_dir |
@@: |
test cl, 2 ; directory? |
jnz j_notfound ; do not allow read directories as regular files |
; ok, now load the file |
pop di |
les bx, [di] |
call normalize |
movzx esi, word [di+4] ; esi = limit in 4K blocks |
shl esi, 12 ; esi = limit in bytes |
push cs |
pop ds |
mov [cur_limit], esi |
mov di, 2000h |
loadloop: |
and [cur_start], 0 |
.loadnew: |
mov esi, [cur_limit] |
mov eax, [cur_start] |
add esi, eax |
mov [overflow], 1 |
sub esi, [di+4] |
jb @f |
xor esi, esi |
dec [overflow] |
@@: |
add esi, [di+4] ; esi = number of bytes to read |
mov [cur_start], esi |
sub esi, eax |
jz .loadcontinue |
xor edx, edx |
div dword [lb_size] ; eax = number of logical blocks to skip, |
mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block |
cmp byte [di+10], 0 |
jnz .interleaved |
add eax, [di] |
; read esi bytes from logical block eax to buffer es:bx |
call read_many_bytes.with_first |
jc .readerr3 |
.loadcontinue: |
mov [cur_chunk], di |
add di, 11 |
cmp di, [cur_desc_end] |
jae @f |
cmp [cur_limit], 0 |
jnz loadloop |
@@: |
mov bx, [overflow] |
.calclen: |
; calculate length of file |
xor ax, ax |
xor dx, dx |
mov di, 2000h |
@@: |
add ax, [di+4] |
adc dx, [di+6] |
add di, 11 |
cmp di, [cur_desc_end] |
jb @b |
ret |
.interleaved: |
mov [cur_unit_limit], esi |
push esi |
; skip first blocks |
movzx ecx, byte [di+9] ; Unit Size |
movzx esi, byte [di+10] ; Interleave Gap |
add si, cx |
mov edx, [di] |
@@: |
sub eax, ecx |
jb @f |
add edx, esi |
jmp @b |
@@: |
add ecx, eax ; ecx = number of logical blocks to skip |
lea eax, [ecx+edx] ; eax = first logical block |
pop esi |
.interleaved_loop: |
; get number of bytes in current file unit |
push eax |
movzx eax, byte [di+9] |
sub ax, cx |
imul eax, dword [lb_size] |
cmp eax, esi |
ja .i2 |
.i1: |
xchg esi, eax |
.i2: |
pop eax |
sub [cur_unit_limit], esi |
push eax |
; read esi bytes from logical block eax to buffer es:bx |
call read_many_bytes.with_first |
pop eax |
jnc @f |
.readerr3: |
mov bx, 3 |
jmp .calclen |
@@: |
mov esi, [cur_unit_limit] |
test esi, esi |
jz .loadcontinue |
movzx ecx, byte [di+9] ; add Unit Size |
add cl, byte [di+10] ; add Interleave Gap |
adc ch, 0 |
add eax, ecx |
xor cx, cx |
mov [first_byte], cx |
jmp .interleaved_loop |
cx_to_sectors: |
add cx, 7FFh |
rcr cx, 1 |
shr cx, 10 |
ret |
is_last_component: |
; in: ds:si -> name |
; out: CF set <=> current component is not last (=> folder) |
push si |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
stc |
@@: |
pop si |
ret |
test_filename1: |
; in: ds:si -> filename, es:di -> path table item |
; out: CF set <=> no match |
pusha |
mov cl, [es:di] |
add di, 8 |
jmp test_filename2.start |
test_filename2: |
; in: ds:si -> filename, es:bx -> directory item |
; out: CF set <=> no match |
pusha |
mov cl, [es:bx+32] |
lea di, [bx+33] |
.start: |
mov ch, 0 |
@@: |
lodsb |
test al, al |
jz .test1 |
cmp al, '/' |
jz .test1 |
call toupper |
mov ah, al |
mov al, [es:di] |
call toupper |
inc di |
cmp al, ah |
loopz @b |
jnz .next1 |
; if we have reached this point: current name is done |
lodsb |
test al, al |
jz .ret |
cmp al, '/' |
jz .ret |
; if we have reached this point: current name is done, but input name continues |
; so they do not match |
jmp .next1 |
.test1: |
; if we have reached this point: input name is done, but current name continues |
; "filename.ext;version" in ISO-9660 represents file "filename.ext" |
; "filename." and "filename.;version" are also possible for "filename" |
cmp byte [es:di], '.' |
jnz @f |
inc di |
dec cx |
jz .ret |
@@: |
cmp byte [es:di], ';' |
jnz .next1 |
jmp .ret |
.next1: |
stc |
.ret: |
popa |
ret |
toupper: |
; in: al=symbol |
; out: al=symbol in uppercase |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
ja .ret |
sub al, 'a'-'A' |
.ret: |
ret |
scan_for_filename_in_sector: |
; in: ds:si->filename, es:bx->folder data, dx=limit |
; out: CF=0 if found |
push bx |
.loope: |
push bx |
.loop: |
cmp bx, dx |
jae .notfound |
cmp byte [es:bx], 0 |
jz .loopd |
test byte [es:bx+25], 4 ; ignore files with Associated bit |
jnz .next |
call test_filename2 |
jc .next |
push ds es di |
push es |
pop ds |
push cs |
pop es |
mov di, [es:cur_desc_end] |
movzx eax, byte [bx+1] |
add eax, [bx+2] |
stosd ; first logical block |
mov eax, [bx+10] |
stosd ; length |
mov al, [bx+25] |
stosb ; flags |
mov ax, [bx+26] |
stosw ; File Unit size, Interleave Gap size |
mov [es:cur_desc_end], di |
cmp di, 3000h |
pop di es ds |
jae .done |
test byte [es:bx+25], 80h |
jz .done |
.next: |
add bl, [es:bx] |
adc bh, 0 |
jmp .loop |
.loopd: |
mov ax, bx |
pop bx |
@@: |
add bx, [cs:lb_size] |
jz .done2 |
cmp bx, ax |
jb @b |
jmp .loope |
.notfound: |
stc |
.done: |
pop bx |
.done2: |
pop bx |
ret |
lb_to_sector: |
xor edx, edx |
div dword [lb_per_sec] |
ret |
load_phys_sector_for_lb_force: |
; in: eax = logical block, ds=0 |
; in: si=0 - accept 0 logical blocks, otherwise force read at least 1 |
; out: 0000:1000 = physical sector data; si -> logical block |
; out: eax = next physical sector |
; out: CF=1 if read error |
; destroys cx |
; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector |
call lb_to_sector |
or si, dx |
jnz @f |
mov si, 1800h |
jmp .done |
@@: |
mov si, 1000h |
imul dx, [lb_size] |
add si, dx |
mov cx, 1 |
push es bx |
push ds |
pop es |
mov bx, 1000h |
call read_sectors |
pop bx es |
inc eax |
.done: |
ret |
normalize: |
; in: es:bx = far pointer |
; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) |
push ax bx |
mov ax, es |
shr bx, 4 |
add ax, bx |
mov es, ax |
pop bx ax |
and bx, 0x0F |
ret |
read_many_bytes: |
and [first_byte], 0 |
read_many_bytes.with_first: |
; read esi bytes from logical block dx:ax to buffer es:bx |
; out: CF=1 <=> disk error |
push di |
; load first physical sector |
push bx si |
mov si, [first_byte] |
call load_phys_sector_for_lb_force |
jnc @f |
pop si bx |
.ret: |
pop di |
ret |
@@: |
add si, [first_byte] |
mov ecx, 1800h |
sub cx, si |
mov ebx, esi |
pop bx |
sub ebx, ecx |
jnc @f |
add cx, bx |
xor ebx, ebx |
@@: |
pop di |
sub [cur_limit], ecx |
rep movsb |
mov esi, ebx |
mov bx, di |
call normalize |
; load other physical sectors |
; read esi bytes from physical sector eax to buffer es:bx |
test esi, esi |
jz .ret |
push esi |
add esi, 0x7FF |
and si, not 0x7FF |
cmp esi, [cur_limit] |
jbe .okplace |
.noplace: |
sub esi, 800h |
.okplace: |
shr esi, 11 ; si = number of sectors |
mov cx, si |
jz @f |
call read_sectors |
@@: |
pop esi |
jc .ret |
movzx ecx, cx |
add eax, ecx |
shl ecx, 11 |
sub [cur_limit], ecx |
sub esi, ecx |
jc .big |
jz .nopost |
push bx es |
push ds |
pop es |
mov bx, 1000h |
mov cx, 1 |
call read_sectors |
pop es di |
jc .ret2 |
mov cx, si |
mov si, 1000h |
sub word [cur_limit], cx |
sbb word [cur_limit+2], 0 |
rep movsb |
mov bx, di |
call normalize |
.nopost: |
clc |
.ret2: |
pop di |
ret |
.big: |
mov ax, es |
sub ax, 80h |
mov es, ax |
add bx, 800h |
add bx, si |
call normalize |
sub [cur_limit], esi |
jmp .nopost |
; Callback function for secondary loader |
callback: |
; in: ax = function number; only function 1 is defined for now |
dec ax |
jz callback_readfile |
dec ax |
jz callback_continueread |
stc ; unsupported function |
retf |
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 |
clc ; function is supported |
retf |
callback_continueread: |
; function 2: continue to 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) |
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error |
; out: dx:ax = file size |
les bx, [di] |
call normalize |
movzx esi, word [di+4] ; si = limit in 4K blocks |
shl esi, 12 ; bp:si = limit in bytes |
push cs |
pop ds |
mov [cur_limit], esi |
mov di, [cur_chunk] |
call loadloop.loadnew |
clc ; function is supported |
retf |
secondary_loader_info: |
dw 0, 0x1000 |
dw 0x30000 / 0x1000 |
db 'kord/loader',0 |
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 |
align 2 |
cachelist: |
.head dw cachelist |
.tail dw cachelist |
free_cache_item dw 0 |
last_cache_item dw 0x8400 |
use_path_table db 0 |
bootdrive db ? |
align 2 |
lb_size dw ? ; Logical Block size in bytes |
dw 0 ; to allow access dword [lb_size] |
lb_per_sec dw ? ; Logical Blocks per physical sector |
dw 0 ; to allow access dword [lb_per_sec] |
free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) |
size_rest dw ? ; free space in cache (in blocks) |
cache_size dw ? |
cache_start dw ? |
pathtable_size dw ? |
pathtable_start dw ? |
root_location dd ? |
cur_desc_end dw ? |
cur_nocache_len dd ? |
cur_limit dd ? |
cur_unit_limit dd ? |
overflow dw ? |
cur_chunk dw ? |
first_byte dw ? |
cur_start dd ? |
;times 83FEh-$ db 0 |
db 43h |
; just to make file 2048 bytes long :) |
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' |
dw 0xAA55 ; this is not required for CD, but to be consistent... |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/build.bat |
---|
0,0 → 1,2 |
@fasm -m 65535 bootsect.asm bootsect.bin |
@pause |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.txt |
---|
0,0 → 1,418 |
; 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. Åñëè æå íåò, òî ñ÷èòûâàþòñÿ âñå ñåêòîðà, êðîìå ïîñëåäíåãî, ïîñëå ÷åãî |
ïîñëåäíèé ñåêòîð ñ÷èòûâàåòñÿ îòäåëüíî âî âðåìåííóþ îáëàñòü, è óæå |
îòòóäà íóæíàÿ ÷àñòü äàííûõ êîïèðóåòñÿ â áóôåð. |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.asm |
---|
0,0 → 1,392 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/build.bat |
---|
0,0 → 1,3 |
@fasm -m 65535 bootsect.asm bootsect.bin |
@fasm -m 65535 kordldr.f1x.asm kordldr.f1x |
@pause |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm |
---|
0,0 → 1,667 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.txt |
---|
0,0 → 1,360 |
; 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. |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.asm |
---|
0,0 → 1,358 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/build.bat |
---|
0,0 → 1,3 |
@fasm -m 65535 bootsect.asm bootsect.bin |
@fasm -m 65535 kordldr.f32.asm kordldr.f32 |
@pause |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/kordldr.f32.asm |
---|
0,0 → 1,672 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.txt |
---|
0,0 → 1,333 |
; 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. |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32 |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/PrimaryLoader.txt |
---|
0,0 → 1,91 |
; 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 íå áóäóò ìîäèôèöèðîâàíû ÿäðîì. |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot_st.inc |
---|
0,0 → 1,68 |
; 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: |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/listing.inc |
---|
0,0 → 1,635 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse.inc |
---|
0,0 → 1,118 |
; 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 |
} |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_any.inc |
---|
0,0 → 1,683 |
; 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: |
} |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_dat.inc |
---|
0,0 → 1,56 |
; 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: |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_loader.inc |
---|
0,0 → 1,332 |
; 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 |
} |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_err.inc |
---|
0,0 → 1,66 |
; 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 |
/kernel/tags/kolibri0.7.7.0/sec_loader/trunk |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sec_loader |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/memmap.inc |
---|
0,0 → 1,248 |
; |
; MEMORY MAP |
; |
; Boot: |
; |
; 0:9000 byte bits per pixel |
; 0:9001 word scanline length |
; 0:9008 word vesa video mode |
; 0:900A word X res |
; 0:900C word Y res |
; 0:9010 byte mouse port - not used |
; 0:9014 dword Vesa 1.2 pm bank switch |
; 0:9018 dword Vesa 2.0 LFB address |
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration |
; 0:901D byte not used anymore (0 or 1 : enable system log display) |
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled |
; 0:901F byte DMA write : 1=yes, 2=no |
; 0:9020 8bytes pci data |
; 0:9030 byte VRR start enabled 1, 2-no |
; 0:9031 word IDEContrRegsBaseAddr |
; 0x9040 - dword - entry point of APM BIOS |
; 0x9044 - word - version (BCD) |
; 0x9046 - word - flags |
; 0:907F byte number of BIOS hard disks |
; 0:9080 Nbytes BIOS hard disks |
; 0:9100 word available physical memory map: number of blocks |
; 0:9104 available physical memory map: blocks |
; |
; Runtime: |
; |
; 0x00000000 -> 0x7FFFFFFF application 2Gb |
; 0x80000000 -> 0FFF physical page zero - do not write |
; (used by int 13h in some configurations) |
; |
; 0x80001000 -> 2FFF window_data - 256 entries |
; |
; 0000 dword x start |
; 0004 dword y start |
; 0008 dword x size |
; 000C dword y size |
; 0010 dword color of work area |
; 0014 dword color of grab bar |
; 0018 dword color of frames |
; 001C dword window flags, +30 = window drawn, +31 redraw flag |
; |
; 3000 -> 4FFF task list - 256 entries |
; |
; 00 dword process count |
; 04 dword no of processes |
; 10 dword base of running process at 0x3000+ |
; |
; 20 dword application event mask |
; 24 dword PID - process identification number |
; 2a byte slot state: 0=running, 1,2=suspended |
; 3=zombie, 4=terminate, |
; 5=waiting for event, 9 = not used |
; 2e byte window number on screen |
; 30 dword exact position in memory |
; 34 dword counter sum |
; 38 dword time stamp counter add |
; 3c dword cpu usage in cpu timer tics |
; |
; |
; 5000 -> 68FF free |
; 6900 -> 6EFF saved picture under mouse pointer |
; |
; 6F00 -> 6FFF free |
; |
; 7000 -> 7FFF used CD driver |
; |
; 8000 -> A3FF used FLOPPY driver |
; |
; A400 -> B0FF free |
; B100 -> B307 IDT for int_0x00..int_0x40 |
; B308 -> BFFF free |
; C000 -> C3FF window stack C000 no of windows - all in words |
; C402 -> C7FF window position in stack |
; D000 -> D1FF FDC controller |
; D200 -> D3FF FDC controller for Fat12 |
; D400 -> DFFF free |
; E000 byte multitasking started |
; E020 dword putpixel address |
; E024 dword getpixel address |
; E030 dword Vesa 1.2 pm bank switch address |
; F200 dword mousepicture -pointer |
; F204 dword mouse appearance counter |
; F300 dword x & y temp for windowmove |
; F400 byte no of keys in buffer |
; F401 byte 'buffer' |
; F402 -> F4FF reserved for keys |
; F500 byte no of buttons in buffer |
; F501 dword 'buffer' |
; F502 -> F5FF reserved for buttons |
; F600 dword tsc / second |
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2 |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
; FB28 high bits temp |
; FB30 color temp |
; FB40 byte buttons down |
; FB44 byte 0 mouse down -> do not draw |
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under |
; FBF1 byte bits per pixel |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
; FE00 dword screen x size |
; FE04 dword screen y size |
; FE08 dword screen y multiplier |
; FE0C dword screen mode |
; FE80 dword address of LFB in physical |
; FE84 dword address of applications memory start in physical |
; FE88 dword address of button list |
; FE8C dword memory to use |
; FF00 byte 1 = system shutdown request |
; FF01 dword free |
; FFF0 byte 1 = redraw background request from app |
; FFF1 byte 1 = diskette int occur |
; FFF2 write and read bank in screen |
; FFF4 byte 0 if first mouse draw & do not return picture under |
; FFF5 byte 1 do not draw pointer |
; FFFF byte do not change task for 1/100 sec. |
; |
; 0x80010000 -> 6CBFF kernel, 32-bit run-time code (up to 371 Kb) |
; 0x8006CC00 -> 6DBFF stack at boot time (4Kb) |
; |
; 0x8006DC00 -> 6E5FF basic text font II |
; 0x8006E600 -> 6Efff basic text font I |
; 0x8006F000 -> 6FFFF main page directory |
; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79) |
; 0x80080000 -> 8FFFF additional app info, in 256 byte steps - 256 entries |
; |
; 00 11db name of app running |
; 0x10 dword pointer to fpu save area |
; 0x14 dword event count |
; 0x18 dword user fpu exceptoins handler |
; 0x1c dword user sse exceptions handler |
; 20 dword PL0 stack base |
; 24 dword user heap base |
; 28 dword user heap top |
; 2c dword window cursor handle |
; 30 dword first event in list |
; 34 dword last event in list |
; 38 dword first kernel object in list |
; 3c dword last kernel object in list |
; 40 dword thread esp |
; 44 dword io permission map page 0 |
; 48 dword io permission map page 1 |
; 4c dword debug state: 1= load debug registers |
; 50 dword current directory ptr |
; 54 dword wait timeout |
; 58 dword thread TSS._esp0 (= pl0 stack base + size except for V86) |
; 5C-7F unused |
; |
; 80 dword address of random shaped window area |
; 84 byte shape area scale |
; 88 dword free |
; 8C dword application memory size |
; 90 dword window X position save |
; 94 dword window Y position save |
; 98 dword window X size save |
; 9C dword window Y size save |
; A0 dword IPC memory start |
; A4 dword IPC memory size |
; A8 dword event bits: mouse, stack,.. |
; AC dword 0 or debugger slot |
; B0 dword free |
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes |
; B8 dword physical address of directory table |
; BC dword address of debug event memory |
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 |
; |
; 0x80090000 -> 9FFFF tmp |
; 0x800A0000 -> AFFFF screen access area |
; 0x800B0000 -> FFFFF bios rest in peace -area |
; 0x80100000 -> 27FFFF diskette image |
; 0x80280000 -> 281FFF ramdisk fat |
; 0x80282000 -> 283FFF floppy fat |
; |
; 0x80284000 -> 28BFFF HDD DMA AREA |
; 0x8028C000 -> 297FFF free (48 Kb) |
; |
; 0x80298000 -> 29ffff auxiliary table for background smoothing code |
; |
; 0x802A0000 -> 2B00ff wav device data |
; 0x802C0000 -> 2C3fff button info |
; |
; 0000 word number of buttons |
; first button entry at 0x10 |
; +0000 word process number |
; +0002 word button id number : bits 00-15 |
; +0004 word x start |
; +0006 word x size |
; +0008 word y start |
; +000A word y size |
; +000C word button id number : bits 16-31 |
; |
; 0x802C4000 -> 2CFFFF free (48Kb) |
; |
; 0x802D0000 -> 2DFFFF reserved port area |
; |
; 0000 dword no of port areas reserved |
; 0010 dword process id |
; dword start port |
; dword end port |
; dword 0 |
; |
; 0x802E0000 -> 2EFFFF irq data area |
; 0x802F0000 -> 2FFFFF low memory save |
; |
; 0x80300000 -> 31FFFF tcp memory 128 Kb |
; 0x80320000 -> 327FFF tcp memory 32 Kb |
; |
; 0x80328000 -> 32FFFF !vrr driver 32 Kb |
; 0x80330000 -> 377FFF skin data |
; 0x80338000 -> 33AFFF draw data - 256 entries |
; 00 dword draw limit - x start |
; 04 dword draw limit - y start |
; 08 dword draw limit - x end |
; 0C dword draw limit - y end |
; 0x8033C000 -> 47BFFF display info |
; 0x8047CF80 -> 47CFFF TSS 128 bytes |
; 0x8047D000 -> 47EFFF IO map for (8192*8)=65536 ports |
; 0x8047F000 -> 48FFFF page map max 128 Kb |
; |
; 0x80800000 -> kernel heap |
; 0x81FFFFFF heap min limit |
; 0xFDBFFFFF heap max limit |
; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb |
; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb |
; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb |
; 0xFE800000 -> 0xFFFFFFFF kernel LFB part 24 Mb |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/init.inc |
---|
0,0 → 1,437 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
MEM_WB equ 6 ;write-back memory |
MEM_WC equ 1 ;write combined memory |
MEM_UC equ 0 ;uncached memory |
align 4 |
proc mem_test |
; if we have BIOS with fn E820, skip the test |
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0 |
jnz .ret |
mov eax, cr0 |
and eax, not (CR0_CD+CR0_NW) |
or eax, CR0_CD ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
xor edi, edi |
mov ebx, 'TEST' |
@@: |
add edi, 0x100000 |
xchg ebx, dword [edi] |
cmp dword [edi], 'TEST' |
xchg ebx, dword [edi] |
je @b |
and eax, not (CR0_CD+CR0_NW) ;enable caching |
mov cr0, eax |
inc dword [BOOT_VAR-OS_BASE + 0x9100] |
xor eax, eax |
mov [BOOT_VAR-OS_BASE + 0x9104], eax |
mov [BOOT_VAR-OS_BASE + 0x9108], eax |
mov [BOOT_VAR-OS_BASE + 0x910C], edi |
mov [BOOT_VAR-OS_BASE + 0x9110], eax |
.ret: |
ret |
endp |
align 4 |
proc init_mem |
; calculate maximum allocatable address and number of allocatable pages |
mov edi, BOOT_VAR-OS_BASE + 0x9104 |
mov ecx, [edi-4] |
xor esi, esi ; esi will hold total amount of memory |
xor edx, edx ; edx will hold maximum allocatable address |
.calcmax: |
; round all to pages |
mov eax, [edi] |
test eax, 0xFFF |
jz @f |
neg eax |
and eax, 0xFFF |
add [edi], eax |
adc dword [edi+4], 0 |
sub [edi+8], eax |
sbb dword [edi+12], 0 |
jc .unusable |
@@: |
and dword [edi+8], not 0xFFF |
jz .unusable |
; ignore memory after 4 Gb |
cmp dword [edi+4], 0 |
jnz .unusable |
mov eax, [edi] |
cmp dword [edi+12], 0 |
jnz .overflow |
add eax, [edi+8] |
jnc @f |
.overflow: |
mov eax, 0xFFFFF000 |
@@: |
cmp edx, eax |
jae @f |
mov edx, eax |
@@: |
sub eax, [edi] |
mov [edi+8], eax |
add esi, eax |
jmp .usable |
.unusable: |
and dword [edi+8], 0 |
.usable: |
add edi, 20 |
loop .calcmax |
.calculated: |
mov [MEM_AMOUNT-OS_BASE], esi |
mov [pg_data.mem_amount-OS_BASE], esi |
shr esi, 12 |
mov [pg_data.pages_count-OS_BASE], esi |
shr edx, 12 |
add edx, 31 |
and edx, not 31 |
shr edx, 3 |
mov [pg_data.pagemap_size-OS_BASE], edx |
add edx, (sys_pgmap-OS_BASE)+4095 |
and edx, not 4095 |
mov [tmp_page_tabs], edx |
mov edx, esi |
and edx, -1024 |
cmp edx, (OS_BASE/4096) |
jbe @F |
mov edx, (OS_BASE/4096) |
jmp .set |
@@: |
cmp edx, (HEAP_BASE+HEAP_MIN_SIZE)/4096 |
jae .set |
mov edx, (HEAP_BASE+HEAP_MIN_SIZE)/4096 |
.set: |
mov [pg_data.kernel_pages-OS_BASE], edx |
shr edx, 10 |
mov [pg_data.kernel_tables-OS_BASE], edx |
xor eax, eax |
mov edi, sys_pgdir-OS_BASE |
mov ecx, 4096/4 |
cld |
rep stosd |
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20) |
bt [cpu_caps-OS_BASE], CAPS_PSE |
jnc .no_PSE |
mov ebx, cr4 |
or ebx, CR4_PSE |
mov eax, PG_LARGE+PG_SW |
mov cr4, ebx |
dec [pg_data.kernel_tables-OS_BASE] |
mov [edx], eax |
add eax, 0x00400000 |
add edx, 4 |
mov eax, 0x400000+PG_SW |
mov ecx, [tmp_page_tabs] |
sub ecx, 0x400000 |
shr ecx, 12 ;ecx/=4096 |
jmp .map_low |
.no_PSE: |
mov eax, PG_SW |
mov ecx, [tmp_page_tabs] |
shr ecx, 12 |
.map_low: |
mov edi, [tmp_page_tabs] |
@@: ; |
stosd |
add eax, 0x1000 |
dec ecx |
jnz @B |
mov ecx, [pg_data.kernel_tables-OS_BASE] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov ecx, [pg_data.kernel_tables-OS_BASE] |
mov eax, [tmp_page_tabs] |
or eax, PG_SW |
mov edi, edx |
.map_kernel_tabs: |
stosd |
add eax, 0x1000 |
dec ecx |
jnz .map_kernel_tabs |
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE |
mov edi, (sys_pgdir-OS_BASE) |
lea esi, [edi+(OS_BASE shr 20)] |
movsd |
movsd |
ret |
endp |
align 4 |
proc init_page_map |
; mark all memory as unavailable |
mov edi, sys_pgmap-OS_BASE |
mov ecx, [pg_data.pagemap_size-OS_BASE] |
shr ecx, 2 |
xor eax, eax |
cld |
rep stosd |
; scan through memory map and mark free areas as available |
mov ebx, BOOT_VAR-OS_BASE + 0x9104 |
mov edx, [ebx-4] |
.scanmap: |
mov ecx, [ebx+8] |
shr ecx, 12 ; ecx = number of pages |
jz .next |
mov edi, [ebx] |
shr edi, 12 ; edi = first page |
mov eax, edi |
neg eax |
shr edi, 5 |
add edi, sys_pgmap-OS_BASE |
and eax, 31 |
jz .startok |
sub ecx, eax |
jbe .onedword |
push ecx |
mov ecx, eax |
xor eax, eax |
inc eax |
shl eax, cl |
dec eax |
or [edi], eax |
add edi, 4 |
pop ecx |
.startok: |
push ecx |
shr ecx, 5 |
or eax, -1 |
rep stosd |
pop ecx |
and ecx, 31 |
not eax |
shl eax, cl |
or [edi], eax |
jmp .next |
.onedword: |
add ecx, eax |
@@: |
dec eax |
bts [edi], eax |
loop @b |
.next: |
add ebx, 20 |
dec edx |
jnz .scanmap |
; mark kernel memory as allocated (unavailable) |
mov ecx, [tmp_page_tabs] |
mov edx, [pg_data.pages_count-OS_BASE] |
shr ecx, 12 |
add ecx, [pg_data.kernel_tables-OS_BASE] |
sub edx, ecx |
mov [pg_data.pages_free-OS_BASE], edx |
mov edi, sys_pgmap-OS_BASE |
mov ebx, ecx |
shr ecx, 5 |
xor eax, eax |
rep stosd |
not eax |
mov ecx, ebx |
and ecx, 31 |
shl eax, cl |
and [edi], eax |
add edi, OS_BASE |
mov [page_start-OS_BASE], edi; |
mov ebx, sys_pgmap |
add ebx, [pg_data.pagemap_size-OS_BASE] |
mov [page_end-OS_BASE], ebx |
mov [pg_data.pg_mutex-OS_BASE], 0 |
ret |
endp |
align 4 |
init_BIOS32: |
mov edi, 0xE0000 |
.pcibios_nxt: |
cmp dword[edi], '_32_' ; "magic" word |
je .BIOS32_found |
.pcibios_nxt2: |
add edi, 0x10 |
cmp edi, 0xFFFF0 |
je .BIOS32_not_found |
jmp .pcibios_nxt |
.BIOS32_found: ; magic word found, check control summ |
movzx ecx, byte[edi + 9] |
shl ecx, 4 |
mov esi, edi |
xor eax, eax |
cld ; paranoia |
@@: lodsb |
add ah, al |
loop @b |
jnz .pcibios_nxt2 ; control summ must be zero |
; BIOS32 service found ! |
mov ebp, [edi + 4] |
mov [bios32_entry], ebp |
; check PCI BIOS present |
mov eax, '$PCI' |
xor ebx, ebx |
push cs ; special for 'ret far' from BIOS |
call ebp |
test al, al |
jnz .PCI_BIOS32_not_found |
; çäåñü ñîçäàþòñÿ äèñêðèïòîðû äëÿ PCI BIOS |
add ebx, OS_BASE |
dec ecx |
mov [(pci_code_32-OS_BASE)], cx ;limit 0-15 |
mov [(pci_data_32-OS_BASE)], cx ;limit 0-15 |
mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15 |
mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15 |
shr ebx, 16 |
mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23 |
mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23 |
shr ecx, 16 |
and cl, 0x0F |
mov ch, bh |
add cx, D32 |
mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 & |
mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31 |
mov [(pci_bios_entry-OS_BASE)], edx |
; jmp .end |
.PCI_BIOS32_not_found: |
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat |
.BIOS32_not_found: |
.end: |
ret |
align 4 |
proc test_cpu |
locals |
cpu_type dd ? |
cpu_id dd ? |
cpu_Intel dd ? |
cpu_AMD dd ? |
endl |
xor eax, eax |
mov [cpu_type], eax |
mov [cpu_caps-OS_BASE], eax |
mov [cpu_caps+4-OS_BASE], eax |
pushfd |
pop eax |
mov ecx, eax |
xor eax, 0x40000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
mov [cpu_type], CPU_386 |
jz .end_cpuid |
push ecx |
popfd |
mov [cpu_type], CPU_486 |
mov eax, ecx |
xor eax, 0x200000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
je .end_cpuid |
mov [cpu_id], 1 |
xor eax, eax |
cpuid |
mov [cpu_vendor-OS_BASE], ebx |
mov [cpu_vendor+4-OS_BASE], edx |
mov [cpu_vendor+8-OS_BASE], ecx |
cmp ebx, dword [intel_str-OS_BASE] |
jne .check_AMD |
cmp edx, dword [intel_str+4-OS_BASE] |
jne .check_AMD |
cmp ecx, dword [intel_str+8-OS_BASE] |
jne .check_AMD |
mov [cpu_Intel], 1 |
cmp eax, 1 |
jl .end_cpuid |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
.end_cpuid: |
mov eax, [cpu_type] |
ret |
.check_AMD: |
cmp ebx, dword [AMD_str-OS_BASE] |
jne .unknown |
cmp edx, dword [AMD_str+4-OS_BASE] |
jne .unknown |
cmp ecx, dword [AMD_str+8-OS_BASE] |
jne .unknown |
mov [cpu_AMD], 1 |
cmp eax, 1 |
jl .unknown |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
.unknown: |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/build.bat |
---|
0,0 → 1,142 |
@echo off |
cls |
set languages=en ru ge et |
set drivers=sound sis infinity ensoniq ps2mouse com_mouse uart ati2d vmode |
set targets=all kernel drivers skins clean |
call :Check_Target %1 |
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 |
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 goto :eof |
echo Language '%res%' is incorrect |
echo Enter valid language [ %languages% ]: |
set /P res="> |
goto Check_Lang_loop |
goto :eof |
:Check_Target |
set res=%1 |
:Check_Target_loop |
for %%a in (%targets%) do if %%a==%res% set target=%res% |
if defined target goto :eof |
echo Target '%res%' is incorrect |
echo Enter valid target [ %targets% ]: |
set /P res="> |
goto Check_Target_loop |
goto :eof |
:Target_kernel |
echo *** building kernel with language '%lang%' ... |
if not exist bin mkdir bin |
echo lang fix %lang% > lang.inc |
fasm -m 65536 kernel.asm bin\kernel.mnt |
if not %errorlevel%==0 goto :Error_FasmFailed |
erase lang.inc |
goto :eof |
: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 |
kpack >nul 2>&1 |
if %errorlevel%==9009 goto :Error_KpackFailed |
echo * |
echo ############################################## |
echo * |
echo Kpack KolibriOS drivers? |
echo * |
set /P res=[y/n]? |
if "%res%"=="y" ( |
echo * |
echo Compressing system |
echo * |
for %%a in (bin\drivers\*.obj) do ( |
echo ================== kpack %%a |
kpack %%a |
if not %errorlevel%==0 goto :Error_KpackFailed |
) |
) |
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 >nul 2>&1 |
echo. |
pause |
exit 1 |
:Error_KpackFailed |
echo *** NOTICE *** |
echo If you want to pack all applications you may |
echo place "kpack" in accessible directory or system %PATH%. |
echo You can get this tool from KolibriOS distribution kit. |
pause |
exit 1 |
:Exit_OK |
echo. |
echo all operations have been done |
pause |
exit 0 |
/kernel/tags/kolibri0.7.7.0/macros.inc |
---|
0,0 → 1,106 |
__REV = 0 |
macro $Revision a { |
match =: Num =$,a \{ |
if __REV < Num |
__REV = Num |
end if |
\} |
} |
$Revision$ |
; 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 |
} |
include 'kglobals.inc' |
; \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] |
macro Mov op1,op2,op3 ; op1 = op2 = op3 |
{ |
mov op2,op3 |
mov op1,op2 |
} |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/makefile |
---|
0,0 → 1,48 |
FASM=fasm |
FLAGS=-m 65536 |
languages=en|ru|ge|et |
drivers_src=sound sis infinity uart ati2d vmode com_mouse |
skins_src=default |
.PHONY: all kernel drivers skins clean |
all: kernel drivers skins |
kernel: check_lang |
@echo "*** building kernel with language '$(lang)' ..." |
@mkdir -p bin |
@echo "lang fix $(lang)" > lang.inc |
@echo "--- building 'bin/kernel.mnt' ..." |
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt |
@rm -f lang.inc |
drivers: |
@echo "*** building drivers ..." |
@mkdir -p bin/drivers |
@cd drivers; for f in $(drivers_src); do \ |
echo "--- building 'bin/drivers/$${f}.obj' ..."; \ |
$(FASM) $(FLAGS) $${f}.asm ../bin/drivers/$${f}.obj; \ |
done |
@mv bin/drivers/vmode.obj bin/drivers/vmode.mdr |
skins: |
@echo "*** building skins ..." |
@mkdir -p bin/skins |
@cd skin; for f in $(skins_src); do \ |
echo "--- building 'bin/skins/$${f}.skn' ..."; \ |
$(FASM) $(FLAGS) $${f}.asm ../bin/skins/$${f}.skn; \ |
done |
check_lang: |
@case "$(lang)" in \ |
$(languages)) \ |
;; \ |
*) \ |
echo "*** error: language is incorrect or not specified"; \ |
exit 1; \ |
;; \ |
esac |
clean: |
rm -rf bin |
rm -f lang.inc |
/kernel/tags/kolibri0.7.7.0/sound/playnote.inc |
---|
0,0 → 1,164 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PLAYNOTE.INC version 1.1 22 November 2003 ;; |
;; ;; |
;; Player Notes for Speaker PC ;; |
;; subfunction #55 from function #55 Menuet OS ;; |
;; ;; |
;; Copyright 2003 VaStaNi ;; |
;; vastani@ukr.net ;; |
;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;; |
;; ;; |
;; Note: playnote.txt ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
align 4 |
sound_interface: |
cmp eax, edi ; this is subfunction #55 ? |
jne retFunc55 ; if no then return. |
cmp byte [sound_flag],0 |
jne retFunc55 |
movzx eax, byte [countDelayNote] |
or al, al ; player is busy ? |
jnz retFunc55 ; return counter delay Note |
mov [memAdrNote],edx |
call get_pid |
mov [pidProcessNote],eax |
xor eax, eax ; Ok! EAX = 0 |
retFunc55: |
mov [esp+36], eax ; return value EAX for application |
ret |
iglobal |
align 4 |
kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562 |
dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF |
memAdrNote dd 0 |
pidProcessNote dd 0 |
slotProcessNote dd 0 |
count_timer_Note dd 1 |
mem8253r42 dw 0 |
countDelayNote db 0 |
endg |
playNote: |
; jmp NotPlayNotes |
mov esi, [memAdrNote] |
or esi, esi ; ESI = 0 ? - OFF Notes Play ? |
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure |
cmp eax, [count_timer_Note] |
jb NotPlayNotes |
push eax |
inc eax |
mov [count_timer_Note], eax |
mov al, [countDelayNote] |
dec al ; decrement counter Delay for Playing Note |
jz NewLoadNote@Delay |
cmp al, 0xFF ; this is first Note Play ? |
jne NextDelayNote |
;This is FIRST Note, save counter channel 2 chip 8253 |
mov al, 0xB6 ; control byte to timer chip 8253 |
out 0x43, al ; Send it to the control port chip 8253 |
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253 |
mov ah, al ; AH = Lower byte counter channel 2 |
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253 |
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253 |
NewLoadNote@Delay: |
cld |
; lodsb ; load AL - counter Delay |
call ReadNoteByte |
or al, al ; THE END ? |
jz EndPlayNote |
cmp al, 0x81 |
jnc NoteforOctave |
mov [countDelayNote], al |
; lodsw ; load AX - counter for Note! |
call ReadNoteByte |
mov ah,al |
call ReadNoteByte |
xchg al,ah |
jmp pokeNote |
EndPlayNote: ; THE END Play Notes! |
in al, 0x61 ; Get contents of system port B chip 8255 |
and al, 0xFC ; Turn OFF timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253 |
xchg al, ah ; reverse byte in word |
out 0x42, al ; restore Lower byte counter channel 2 |
mov al, ah ; AL = Upper byte counter channel 2 |
out 0x42, al ; restore Upper byte channel 2 |
xor eax, eax ; EAX = 0 |
mov [memAdrNote], eax ; clear header control Delay-Note string |
NextDelayNote: |
mov [countDelayNote], al ; save new counter delay Note |
pop eax |
NotPlayNotes: |
RET |
NoteforOctave: |
sub al, 0x81 ; correction value for delay Note |
mov [countDelayNote], al ; save counter delay this new Note |
; lodsb ; load pack control code |
call ReadNoteByte |
cmp al, 0xFF ; this is PAUSE ? |
jne packCode ; no, this is PACK CODE |
in al, 0x61 ; Get contents of system port B chip 8255 |
and al, 0xFC ; Turn OFF timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
jmp saveESI |
packCode: |
mov cl, al ; save code |
and al, 0xF ; clear upper bits |
dec al ; correction |
add al, al ; transform number to offset constant |
movsx eax, al ; EAX - offset |
add eax, dword kontrOctave ; EAX - address from constant |
mov ax, [eax] ; read constant |
shr cl, 4 ; transform for number Octave |
shr ax, cl ; calculate from Note this Octave! |
pokeNote: |
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253 |
mov al, ah |
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253 |
in al, 0x61 ; Get contents of system port B chip 8255 |
or al, 3 ; Turn ON timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
saveESI: |
; mov [memAdrNote], esi ; save new header control Delay-Note string |
pop eax |
RET |
ReadNoteByte: |
;result: |
; al - note |
push eax |
push ebx |
push ecx |
push edx |
mov eax,[pidProcessNote] |
call pid_to_slot |
test eax,eax |
jz .failed |
lea ebx,[esp+12] |
mov ecx,1 |
mov edx,[memAdrNote] |
inc [memAdrNote] |
call read_process_memory |
.failed: |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
;------------------- END CODE ------------------- |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/sound |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/bootloader/boot_fat12.asm |
---|
0,0 → 1,287 |
; FAT12 boot sector for Kolibri OS |
; |
; Copyright (C) Alex Nogueira Teixeira |
; Copyright (C) Diamond |
; Copyright (C) Dmitry Kartashov aka shurf |
; |
; Distributed under GPL, see file COPYING for details |
; |
; Version 1.0 |
lf equ 0ah |
cr equ 0dh |
pos_read_tmp equ 0700h ;position for temporary read |
boot_program equ 07c00h ;position for boot code |
seg_read_kernel equ 01000h ;segment to kernel read |
jmp start_program |
nop |
; Boot Sector and BPB Structure |
include 'floppy1440.inc' |
;include 'floppy2880.inc' |
;include 'floppy1680.inc' |
;include 'floppy1743.inc' |
start_program: |
xor ax,ax |
mov ss,ax |
mov sp,boot_program |
push ss |
pop ds |
; print loading string |
mov si,loading+boot_program |
loop_loading: |
lodsb |
or al,al |
jz read_root_directory |
mov ah,0eh |
mov bx,7 |
int 10h |
jmp loop_loading |
read_root_directory: |
push ss |
pop es |
; calculate some disk parameters |
; - beginning sector of RootDir |
mov ax,word [BPB_FATSz16+boot_program] |
xor cx,cx |
mov cl,byte [BPB_NumFATs+boot_program] |
mul cx |
add ax,word [BPB_RsvdSecCnt+boot_program] |
mov word [FirstRootDirSecNum+boot_program],ax ; 19 |
mov si,ax |
; - count of sectors in RootDir |
mov bx,word [BPB_BytsPerSec+boot_program] |
mov cl,5 ; divide ax by 32 |
shr bx,cl ; bx = directory entries per sector |
mov ax,word [BPB_RootEntCnt+boot_program] |
xor dx,dx |
div bx |
mov word [RootDirSecs+boot_program],ax ; 14 |
; - data start |
add si,ax ; add beginning sector of RootDir and count sectors in RootDir |
mov word [data_start+boot_program],si ; 33 |
; reading root directory |
; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! |
mov ah,2 ; read |
push ax |
mov ax,word [FirstRootDirSecNum+boot_program] |
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
pop ax |
mov bx,pos_read_tmp ; es:bx read buffer |
call read_sector |
mov si,bx ; read buffer address: es:si |
mov ax,[RootDirSecs+boot_program] |
mul word [BPB_BytsPerSec+boot_program] |
add ax,si ; AX = end of root dir. in buffer pos_read_tmp |
; find kernel file in root directory |
loop_find_dir_entry: |
push si |
mov cx,11 |
mov di,kernel_name+boot_program |
rep cmpsb ; compare es:si and es:di, cx bytes long |
pop si |
je found_kernel_file |
add si,32 ; next dir. entry |
cmp si,ax ; end of directory |
jb loop_find_dir_entry |
file_error_message: |
mov si,error_message+boot_program |
loop_error_message: |
lodsb |
or al,al |
jz freeze_pc |
mov ah,0eh |
mov bx,7 |
int 10h |
jmp loop_error_message |
freeze_pc: |
jmp $ ; endless loop |
; === KERNEL FOUND. LOADING... === |
found_kernel_file: |
mov bp,[si+01ah] ; first cluster of kernel file |
; <diamond> |
mov [cluster1st+boot_program],bp ; starting cluster of kernel file |
; <\diamond> |
; reading first FAT table |
mov ax,word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number |
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
mov bx,pos_read_tmp ; es:bx read position |
mov ah,2 ; ah=2 (read) |
mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) |
call read_sector |
jc file_error_message ; read error |
mov ax,seg_read_kernel |
mov es,ax |
xor bx,bx ; es:bx = 1000h:0000h |
; reading kernel file |
loop_obtains_kernel_data: |
; read one cluster of file |
call obtain_cluster |
jc file_error_message ; read error |
; add one cluster length to segment:offset |
push bx |
mov bx,es |
mov ax,word [BPB_BytsPerSec+boot_program] ;\ |
movsx cx,byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! |
mul cx ; | out this from loop !!! |
shr ax,4 ;/ |
add bx,ax |
mov es,bx |
pop bx |
mov di,bp |
shr di,1 |
pushf |
add di,bp ; di = bp * 1.5 |
add di,pos_read_tmp |
mov ax,[di] ; read next entry from FAT-chain |
popf |
jc move_4_right |
and ax,0fffh |
jmp verify_end_sector |
move_4_right: |
mov cl,4 |
shr ax,cl |
verify_end_sector: |
cmp ax,0ff8h ; last cluster |
jae execute_kernel |
mov bp,ax |
jmp loop_obtains_kernel_data |
execute_kernel: |
; <diamond> |
mov ax,'KL' |
push 0 |
pop ds |
mov si,loader_block+boot_program |
; </diamond> |
push word seg_read_kernel |
push word 0 |
retf ; jmp far 1000:0000 |
;------------------------------------------ |
; loading cluster from file to es:bx |
obtain_cluster: |
; bp - cluster number to read |
; carry = 0 -> read OK |
; carry = 1 -> read ERROR |
; print one dot |
push bx |
mov ax,0e2eh ; ah=0eh (teletype), al='.' |
xor bh,bh |
int 10h |
; convert cluster number to sector number |
mov ax,bp ; data cluster to read |
sub ax,2 |
xor bx,bx |
mov bl,byte [BPB_SecPerClus+boot_program] |
mul bx |
add ax,word [data_start+boot_program] |
pop bx |
writesec: |
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
patchhere: |
mov ah,2 ; ah=2 (read) |
mov al,byte [BPB_SecPerClus+boot_program] ; al=(one cluster) |
call read_sector |
retn |
;------------------------------------------ |
;------------------------------------------ |
; read sector from disk |
read_sector: |
push bp |
mov bp,20 ; try 20 times |
newread: |
dec bp |
jz file_error_message |
push ax bx cx dx |
int 13h |
pop dx cx bx ax |
jc newread |
pop bp |
retn |
;------------------------------------------ |
; 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+boot_program] |
xor dx,dx |
div bx |
inc dx |
mov cl, dl ; cl = sector number |
mov bx,word [BPB_NumHeads+boot_program] |
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 |
;------------------------------------------ |
loading db cr,lf,'Starting system ',00h |
error_message db 13,10 |
kernel_name db 'KERNEL MNT ?',cr,lf,00h |
FirstRootDirSecNum dw ? |
RootDirSecs dw ? |
data_start dw ? |
; <diamond> |
write1st: |
push cs |
pop ds |
mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 |
mov ax,[cluster1st+boot_program] |
push 1000h |
pop es |
xor bx,bx |
call writesec |
mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 |
retf |
cluster1st dw ? |
loader_block: |
db 1 |
dw 0 |
dw write1st+boot_program |
dw 0 |
; <\diamond> |
times 0x1fe-$ db 00h |
db 55h,0aah ;boot signature |
/kernel/tags/kolibri0.7.7.0/bootloader/floppy1440.inc |
---|
0,0 → 1,19 |
BS_OEMName db 'KOLIBRI ' ; db 8 |
BPB_BytsPerSec dw 512 ; bytes per sector |
BPB_SecPerClus db 1 ; sectors per cluster |
BPB_RsvdSecCnt dw 1 ; number of reserver sectors |
BPB_NumFATs db 2 ; count of FAT data structures |
BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) |
BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk) |
BPB_Media db 0f0h ; f0 - used for removable media |
BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT |
BPB_SecPerTrk dw 18 ; sectors per track |
BPB_NumHeads dw 2 ; number of heads |
BPB_HiddSec dd 0 ; count of hidden sectors |
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) |
BS_DrvNum db 0 ; int 13h drive number |
BS_Reserved db 0 ; reserved |
BS_BootSig db 29h ; Extended boot signature |
BS_VolID dd 0 ; Volume serial number |
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) |
BS_FilSysType db 'FAT12 ' ; file system type (db 8) |
/kernel/tags/kolibri0.7.7.0/bootloader/floppy1680.inc |
---|
0,0 → 1,19 |
BS_OEMName db 'KOLIBRI ' ; db 8 |
BPB_BytsPerSec dw 512 ; bytes per sector |
BPB_SecPerClus db 1 ; sectors per cluster |
BPB_RsvdSecCnt dw 1 ; number of reserver sectors |
BPB_NumFATs db 2 ; count of FAT data structures |
BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors) |
BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk) |
BPB_Media db 0f0h ; f0 - used for removable media |
BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT |
BPB_SecPerTrk dw 21 ; sectors per track |
BPB_NumHeads dw 2 ; number of heads |
BPB_HiddSec dd 0 ; count of hidden sectors |
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) |
BS_DrvNum db 0 ; int 13h drive number |
BS_Reserved db 0 ; reserved |
BS_BootSig db 29h ; Extended boot signature |
BS_VolID dd 0 ; Volume serial number |
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) |
BS_FilSysType db 'FAT12 ' ; file system type (db 8) |
/kernel/tags/kolibri0.7.7.0/bootloader/floppy1743.inc |
---|
0,0 → 1,19 |
BS_OEMName db 'KOLIBRI ' ; db 8 |
BPB_BytsPerSec dw 512 ; bytes per sector |
BPB_SecPerClus db 1 ; sectors per cluster |
BPB_RsvdSecCnt dw 1 ; number of reserver sectors |
BPB_NumFATs db 2 ; count of FAT data structures |
BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) |
BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk) |
BPB_Media db 0f0h ; f0 - used for removable media |
BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT |
BPB_SecPerTrk dw 21 ; sectors per track |
BPB_NumHeads dw 2 ; number of heads |
BPB_HiddSec dd 0 ; count of hidden sectors |
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) |
BS_DrvNum db 0 ; int 13h drive number |
BS_Reserved db 0 ; reserved |
BS_BootSig db 29h ; Extended boot signature |
BS_VolID dd 0 ; Volume serial number |
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) |
BS_FilSysType db 'FAT12 ' ; file system type (db 8) |
/kernel/tags/kolibri0.7.7.0/bootloader/floppy2880.inc |
---|
0,0 → 1,19 |
BS_OEMName db 'KOLIBRI ' ; db 8 |
BPB_BytsPerSec dw 512 ; bytes per sector |
BPB_SecPerClus db 2 ; sectors per cluster |
BPB_RsvdSecCnt dw 1 ; number of reserver sectors |
BPB_NumFATs db 2 ; count of FAT data structures |
BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors) |
BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk) |
BPB_Media db 0f0h ; f0 - used for removable media |
BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT |
BPB_SecPerTrk dw 36 ; sectors per track |
BPB_NumHeads dw 2 ; number of heads |
BPB_HiddSec dd 0 ; count of hidden sectors |
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) |
BS_DrvNum db 0 ; int 13h drive number |
BS_Reserved db 0 ; reserved |
BS_BootSig db 29h ; Extended boot signature |
BS_VolID dd 0 ; Volume serial number |
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) |
BS_FilSysType db 'FAT12 ' ; file system type (db 8) |
/kernel/tags/kolibri0.7.7.0/bootloader/readme |
---|
0,0 → 1,43 |
£à㧮çë© á¥ªâ®à ¤«ï ®«¨¡à¨ (FAT12, ¤¨áª¥â ) |
- ¯¨á ¨¥ |
®§¢®«ï¥â § £à㦠âì KERNEL.MNT á ¤¨áª¥â/®¡à §®¢ |
®¡êñ¬®¬ 1.44M, 1.68M, 1.72M ¨ 2.88M |
«ï ¢ë¡®à ®¡êñ¬ ¤¨áª , ¤«ï ª®â®à®£® ¤® ᮡà âì |
§ £à㧮çë© á¥ªâ®à, ¥®¡å®¤¨¬® ¢ ä ©«¥ boot_fat12.asm |
à ᪮¬¬¥â¨à®¢ âì áâப㠢¨¤ : |
include 'floppy????.inc' |
¤«ï ¥®¡å®¤¨¬®£® ®¡êñ¬ ¤¨áª . ®áâã¯ë¥ ¢ ਠâë: |
floppy1440.inc, |
floppy1680.inc, |
floppy1743.inc ¨ floppy2880.inc |
- ¡®àª |
fasm boot_fat12.asm |
- «ï § ¯¨á¨ § £à㧮箣® ᥪâ®à ¤¨áª/®¡à § ¯®¤ Linux |
¬®¦® ¢®á¯®«ì§®¢ âìáï á«¥¤ãî饩 ª®¬ ¤®©: |
dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc |
--------------------------------------------------------------------- |
Floppy FAT12 boot sector for KolibriOS. |
- Description |
Allows booting KERNEL.MNT floppies/images |
with volumes of 1.44M, 1.68M, 1.72M and 2.88M |
To select the volume of the disk, which should gather |
boot sector, it was necessary in file boot_fat12.asm |
uncomment line: |
include 'floppy????. inc' |
for the necessary disk volume. Available options is: |
floppy1440.inc, |
floppy1680.inc, |
floppy1743.inc and floppy2880.inc |
- Compile |
fasm boot_fat12.asm |
- To write boot sector to the floppy/image under Linux |
you can use the following command: |
dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc |
/kernel/tags/kolibri0.7.7.0/make.sh |
---|
0,0 → 1,33 |
#!/bin/bash |
# This script does for linux the same as build.bat for DOS, |
# it compiles the KoOS kernel, hopefully ;-) |
CLANG=$1; |
usage() |
{ |
echo "Usage: make.sh [en|ru|ge|et]" |
exit 1 |
} |
compile() |
{ |
fasm -m 65536 kernel.asm bin/kernel.mnt |
rm -f lang.inc |
exit 0 |
} |
if [ ! $CLANG ] ; then |
usage |
fi |
for i in "en" "ru" "ge" "et"; do |
if [ $i == $CLANG ] ; then |
echo "lang fix $i" > lang.inc |
compile |
fi |
done |
usage |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc |
---|
0,0 → 1,483 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; PCI32.INC ;; |
;; ;; |
;; 32 bit PCI driver code ;; |
;; ;; |
;; Version 0.3 April 9, 2007 ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; Mihailov Ilia, ghost.nsk@gmail.com ;; |
;; Credits: ;; |
;; Ralf Brown ;; |
;; Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;*************************************************************************** |
; Function |
; pci_api: |
; |
; Description |
; entry point for system PCI calls |
;*************************************************************************** |
align 4 |
pci_api: |
cmp [pci_access_enabled],1 |
jne no_pci_access_for_applications |
or al,al |
jnz pci_fn_1 |
; PCI function 0: get pci version (AH.AL) |
movzx eax,word [BOOT_VAR+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[BOOT_VAR+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[BOOT_VAR+0x9020] |
ret |
pci_fn_3: |
cmp al,4 |
jz pci_read_reg ;byte |
cmp al,5 |
jz pci_read_reg ;word |
cmp al,6 |
jz pci_read_reg ;dword |
cmp al,8 |
jz pci_write_reg ;byte |
cmp al,9 |
jz pci_write_reg ;word |
cmp al,10 |
jz pci_write_reg ;dword |
no_pci_access_for_applications: |
mov eax,-1 |
ret |
;*************************************************************************** |
; Function |
; pci_make_config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ah |
; device+func in bh (dddddfff) |
; register in bl |
; |
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) |
;*************************************************************************** |
align 4 |
pci_make_config_cmd: |
shl eax,8 ; move bus to bits 16-23 |
mov ax,bx ; combine all |
and eax,0xffffff |
or eax,0x80000000 |
ret |
;*************************************************************************** |
; Function |
; pci_read_reg: |
; |
; Description |
; read a register from the PCI config space into EAX/AX/AL |
; IN: ah=bus,device+func=bh,register address=bl |
; number of bytes to read (1,2,4) coded into AL, bits 0-1 |
; (0 - byte, 1 - word, 2 - dword) |
;*************************************************************************** |
align 4 |
pci_read_reg: |
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
je pci_read_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; get requested DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl ; add to port address first 2 bits of register address |
or esi,esi |
jz pci_read_byte1 |
cmp esi,1 |
jz pci_read_word1 |
cmp esi,2 |
jz pci_read_dword1 |
jmp pci_fin_read1 |
pci_read_byte1: |
in al,dx |
jmp pci_fin_read1 |
pci_read_word1: |
in ax,dx |
jmp pci_fin_read1 |
pci_read_dword1: |
in eax,dx |
jmp pci_fin_read1 |
pci_fin_read1: |
; restore configuration control |
xchg eax,[esp] |
mov dx,0xcf8 |
out dx,eax |
pop eax |
pop esi |
ret |
pci_read_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_read_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
or esi,esi |
jz pci_read_byte2 |
cmp esi,1 |
jz pci_read_word2 |
cmp esi,2 |
jz pci_read_dword2 |
jmp pci_fin_read2 |
pci_read_byte2: |
in al,dx |
jmp pci_fin_read2 |
pci_read_word2: |
in ax,dx |
jmp pci_fin_read2 |
pci_read_dword2: |
in eax,dx |
; jmp pci_fin_read2 |
pci_fin_read2: |
; restore configuration space |
xchg eax,[esp] |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
pop eax |
pop esi |
ret |
pci_read_reg_err: |
xor eax,eax |
dec eax |
ret |
;*************************************************************************** |
; Function |
; pci_write_reg: |
; |
; Description |
; write a register from ECX/CX/CL into the PCI config space |
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, |
; value to write in ecx |
; number of bytes to write (1,2,4) coded into AL, bits 0-1 |
; (0 - byte, 1 - word, 2 - dword) |
;*************************************************************************** |
align 4 |
pci_write_reg: |
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
je pci_write_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state into ecx |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; write DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl |
mov eax,ecx |
or esi,esi |
jz pci_write_byte1 |
cmp esi,1 |
jz pci_write_word1 |
cmp esi,2 |
jz pci_write_dword1 |
jmp pci_fin_write1 |
pci_write_byte1: |
out dx,al |
jmp pci_fin_write1 |
pci_write_word1: |
out dx,ax |
jmp pci_fin_write1 |
pci_write_dword1: |
out dx,eax |
jmp pci_fin_write1 |
pci_fin_write1: |
; restore configuration control |
pop eax |
mov dl,0xf8 |
out dx,eax |
xor eax,eax |
pop esi |
ret |
pci_write_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_write_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
; write register |
mov eax,ecx |
or esi,esi |
jz pci_write_byte2 |
cmp esi,1 |
jz pci_write_word2 |
cmp esi,2 |
jz pci_write_dword2 |
jmp pci_fin_write2 |
pci_write_byte2: |
out dx,al |
jmp pci_fin_write2 |
pci_write_word2: |
out dx,ax |
jmp pci_fin_write2 |
pci_write_dword2: |
out dx,eax |
jmp pci_fin_write2 |
pci_fin_write2: |
; restore configuration space |
pop eax |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
xor eax,eax |
pop esi |
ret |
pci_write_reg_err: |
xor eax,eax |
dec eax |
ret |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) |
pci_emu_dat: times 30*10 db 0 |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
align 4 |
sys_pcibios: |
xchg ebx, eax |
xchg ecx, eax |
xchg edx, eax |
xchg esi, eax |
xchg edi, eax |
cmp [pci_access_enabled], 1 |
jne .unsupported_func |
cmp [pci_bios_entry], 0 |
jz .emulate_bios |
push ds |
mov ax, pci_data_sel |
mov ds, ax |
mov eax, ebp |
mov ah, 0B1h |
call pword [cs:pci_bios_entry] |
pop ds |
jmp .return |
;-=-=-=-=-=-=-=-= |
.emulate_bios: |
cmp ebp, 1 ; PCI_FUNCTION_ID |
jnz .not_PCI_BIOS_PRESENT |
mov edx, 'PCI ' |
mov al, [OS_BASE+0x2F0000 + 0x9020] |
mov bx, [OS_BASE+0x2F0000 + 0x9022] |
mov cl, [OS_BASE+0x2F0000 + 0x9021] |
xor ah, ah |
jmp .return_abcd |
.not_PCI_BIOS_PRESENT: |
cmp ebp, 2 ; FIND_PCI_DEVICE |
jne .not_FIND_PCI_DEVICE |
mov ebx, pci_emu_dat |
..nxt: cmp [ebx], dx |
jne ..no |
cmp [ebx + 2], cx |
jne ..no |
dec si |
jns ..no |
mov bx, [ebx + 4] |
xor ah, ah |
jmp .return_ab |
..no: cmp word[ebx], 0 |
je ..dev_not_found |
add ebx, 10 |
jmp ..nxt |
..dev_not_found: |
mov ah, 0x86 ; DEVICE_NOT_FOUND |
jmp .return_a |
.not_FIND_PCI_DEVICE: |
cmp ebp, 3 ; FIND_PCI_CLASS_CODE |
jne .not_FIND_PCI_CLASS_CODE |
mov esi, pci_emu_dat |
shl ecx, 8 |
..nxt2: cmp [esi], ecx |
jne ..no2 |
mov bx, [esi] |
xor ah, ah |
jmp .return_ab |
..no2: cmp dword[esi], 0 |
je ..dev_not_found |
add esi, 10 |
jmp ..nxt2 |
.not_FIND_PCI_CLASS_CODE: |
cmp ebp, 8 ; READ_CONFIG_* |
jb .not_READ_CONFIG |
cmp ebp, 0x0A |
ja .not_READ_CONFIG |
mov eax, ebp |
mov ah, bh |
mov edx, edi |
mov bh, bl |
mov bl, dl |
call pci_read_reg |
mov ecx, eax |
xor ah, ah ; SUCCESSFUL |
jmp .return_abc |
.not_READ_CONFIG: |
cmp ebp, 0x0B ; WRITE_CONFIG_* |
jb .not_WRITE_CONFIG |
cmp ebp, 0x0D |
ja .not_WRITE_CONFIG |
lea eax, [ebp+1] |
mov ah, bh |
mov edx, edi |
mov bh, bl |
mov bl, dl |
call pci_write_reg |
xor ah, ah ; SUCCESSFUL |
jmp .return_abc |
.not_WRITE_CONFIG: |
.unsupported_func: |
mov ah, 0x81 ; FUNC_NOT_SUPPORTED |
.return:mov dword[esp + 8 ], edi |
mov dword[esp + 12], esi |
.return_abcd: |
mov dword[esp + 28], edx |
.return_abc: |
mov dword[esp + 32], ecx |
.return_ab: |
mov dword[esp + 24], ebx |
.return_a: |
mov dword[esp + 36], eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc |
---|
0,0 → 1,51 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/bus/pci |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/bus |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/data16.inc |
---|
0,0 → 1,55 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
flm db 0 |
preboot_lfb db 0 |
preboot_bootlog db 0 |
boot_drive db 0 |
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007] |
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê |
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1 |
align 4 |
old_ints_h: |
dw 0x400 |
dd 0 |
dw 0 |
kernel_restart_bootblock: |
db 1 ; version |
dw 1 ; floppy image is in memory |
dd 0 ; cannot save parameters |
; table for move to extended memory (int 15h, ah=87h) |
align 8 |
movedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,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 |
fwmovedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,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 |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/imports.inc |
---|
0,0 → 1,27 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;============================================================================ |
; |
; External kernel dependencies |
; |
;============================================================================ |
$Revision$ |
align 4 |
@IMPORT: |
library \ |
libini,'libini.obj' |
import libini, \ |
ini.lib_init,'lib_init',\ |
ini.get_str,'ini.get_str',\ |
ini.enum_keys,'ini.enum_keys',\ |
ini.get_int,'ini.get_int' |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/kglobals.inc |
---|
0,0 → 1,69 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;------------------------------------------------------------------ |
; use "iglobal" for inserting initialized global data definitions. |
;------------------------------------------------------------------ |
macro iglobal { |
IGlobals equ IGlobals, |
macro __IGlobalBlock { } |
macro iglobal_nested { |
IGlobals equ IGlobals, |
macro __IGlobalBlock \{ } |
;------------------------------------------------------------- |
; use 'uglobal' for inserting uninitialized global definitions. |
; even when you define some data values, these variables |
; will be stored as uninitialized data. |
;------------------------------------------------------------- |
macro uglobal { |
UGlobals equ UGlobals, |
macro __UGlobalBlock { } |
macro uglobal_nested { |
UGlobals equ UGlobals, |
macro __UGlobalBlock \{ } |
endg fix } ; Use endg for ending iglobal and uglobal blocks. |
endg_nested fix \} |
macro IncludeIGlobals{ |
macro IGlobals dummy,[n] \{ __IGlobalBlock |
purge __IGlobalBlock \} |
match I, IGlobals \{ I \} } |
macro IncludeUGlobals{ |
macro UGlobals dummy,[n] \{ |
\common |
\local begin, size |
begin = $ |
virtual at $ |
\forward |
__UGlobalBlock |
purge __UGlobalBlock |
\common |
size = $ - begin |
end virtual |
rb size |
\} |
match U, UGlobals \{ U \} } |
macro IncludeAllGlobals { |
IncludeIGlobals |
IncludeUGlobals |
} |
iglobal |
endg |
uglobal |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/proc32.inc |
---|
0,0 → 1,271 |
$Revision$ |
; Macroinstructions for defining and calling procedures |
macro stdcall proc,[arg] ; directly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call proc } |
macro invoke proc,[arg] ; indirectly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call [proc] } |
macro ccall proc,[arg] ; directly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call proc |
if size@ccall |
add esp,size@ccall |
end if } |
macro cinvoke proc,[arg] ; indirectly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call [proc] |
if size@ccall |
add esp,size@ccall |
end if } |
macro proc [args] ; define procedure |
{ common |
match name params, args> |
\{ define@proc name,<params \} } |
prologue@proc equ prologuedef |
macro prologuedef procname,flag,parmbytes,localbytes,reglist |
{ if parmbytes | localbytes |
push ebp |
mov ebp,esp |
if localbytes |
sub esp,localbytes |
end if |
end if |
irps reg, reglist \{ push reg \} } |
epilogue@proc equ epiloguedef |
macro epiloguedef procname,flag,parmbytes,localbytes,reglist |
{ irps reg, reglist \{ reverse pop reg \} |
if parmbytes | localbytes |
leave |
end if |
if (flag and 10000b) | (parmbytes=0) |
retn |
else |
retn parmbytes |
end if } |
macro define@proc name,statement |
{ local params,flag,regs,parmbytes,localbytes,current |
if used name |
name: |
match =stdcall args, statement \{ params equ args |
flag = 11b \} |
match =stdcall, statement \{ params equ |
flag = 11b \} |
match =c args, statement \{ params equ args |
flag = 10001b \} |
match =c, statement \{ params equ |
flag = 10001b \} |
match =params, params \{ params equ statement |
flag = 0 \} |
virtual at ebp+8 |
match =uses reglist=,args, params \{ regs equ reglist |
params equ args \} |
match =regs =uses reglist, regs params \{ regs equ reglist |
params equ \} |
match =regs, regs \{ regs equ \} |
match =,args, params \{ defargs@proc args \} |
match =args@proc args, args@proc params \{ defargs@proc args \} |
parmbytes = $ - (ebp+8) |
end virtual |
name # % = parmbytes/4 |
all@vars equ |
current = 0 |
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \} |
macro locals |
\{ virtual at ebp-localbytes+current |
macro label . \\{ deflocal@proc .,:, \\} |
struc db [val] \\{ \common deflocal@proc .,db,val \\} |
struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
macro endl |
\{ purge label |
restruc db,dw,dp,dd,dt,dq |
restruc rb,rw,rp,rd,rt,rq |
restruc byte,word,dword,pword,tword,qword |
current = $-(ebp-localbytes) |
end virtual \} |
macro ret operand |
\{ match any, operand \\{ retn operand \\} |
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> |
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
end if \} } |
macro defargs@proc [arg] |
{ common |
if ~ arg eq |
forward |
local ..arg,current@arg |
match argname:type, arg |
\{ current@arg equ argname |
label ..arg type |
argname equ ..arg |
if dqword eq type |
dd ?,?,?,? |
else if tbyte eq type |
dd ?,?,? |
else if qword eq type | pword eq type |
dd ?,? |
else |
dd ? |
end if \} |
match =current@arg,current@arg |
\{ current@arg equ arg |
arg equ ..arg |
..arg dd ? \} |
common |
args@proc equ current@arg |
forward |
restore current@arg |
common |
end if } |
macro deflocal@proc name,def,[val] |
{ common |
match vars, all@vars \{ all@vars equ all@vars, \} |
all@vars equ all@vars name |
forward |
local ..var,..tmp |
..var def val |
match =?, val \{ ..tmp equ \} |
match any =dup (=?), val \{ ..tmp equ \} |
match tmp : value, ..tmp : val |
\{ tmp: end virtual |
initlocal@proc ..var,def value |
virtual at tmp\} |
common |
match first rest, ..var, \{ name equ first \} } |
macro initlocal@proc name,def |
{ virtual at name |
def |
size@initlocal = $ - name |
end virtual |
position@initlocal = 0 |
while size@initlocal > position@initlocal |
virtual at name |
def |
if size@initlocal - position@initlocal < 2 |
current@initlocal = 1 |
load byte@initlocal byte from name+position@initlocal |
else if size@initlocal - position@initlocal < 4 |
current@initlocal = 2 |
load word@initlocal word from name+position@initlocal |
else |
current@initlocal = 4 |
load dword@initlocal dword from name+position@initlocal |
end if |
end virtual |
if current@initlocal = 1 |
mov byte [name+position@initlocal],byte@initlocal |
else if current@initlocal = 2 |
mov word [name+position@initlocal],word@initlocal |
else |
mov dword [name+position@initlocal],dword@initlocal |
end if |
position@initlocal = position@initlocal + current@initlocal |
end while } |
macro endp |
{ purge ret,locals,endl |
finish@proc |
purge finish@proc |
restore regs@proc |
match all,args@proc \{ restore all \} |
restore args@proc |
match all,all@vars \{ restore all \} } |
macro local [var] |
{ common |
locals |
forward done@local equ |
match varname[count]:vartype, var |
\{ match =BYTE, vartype \\{ varname rb count |
restore done@local \\} |
match =WORD, vartype \\{ varname rw count |
restore done@local \\} |
match =DWORD, vartype \\{ varname rd count |
restore done@local \\} |
match =PWORD, vartype \\{ varname rp count |
restore done@local \\} |
match =QWORD, vartype \\{ varname rq count |
restore done@local \\} |
match =TBYTE, vartype \\{ varname rt count |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
rq count+count |
restore done@local \\} |
match , done@local \\{ virtual |
varname vartype |
end virtual |
rb count*sizeof.\#vartype |
restore done@local \\} \} |
match :varname:vartype, done@local:var |
\{ match =BYTE, vartype \\{ varname db ? |
restore done@local \\} |
match =WORD, vartype \\{ varname dw ? |
restore done@local \\} |
match =DWORD, vartype \\{ varname dd ? |
restore done@local \\} |
match =PWORD, vartype \\{ varname dp ? |
restore done@local \\} |
match =QWORD, vartype \\{ varname dq ? |
restore done@local \\} |
match =TBYTE, vartype \\{ varname dt ? |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
dq ?,? |
restore done@local \\} |
match , done@local \\{ varname vartype |
restore done@local \\} \} |
match ,done@local |
\{ var |
restore done@local \} |
common |
endl } |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/unpacker.inc |
---|
0,0 → 1,527 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; void __stdcall unpack(void* packed_data, void* unpacked_data); |
unpack: |
pushad |
mov esi, [esp+32+4] |
mov edi, [esp+32+8] |
mov eax, [esi+8] |
and al, 0xC0 |
cmp al, 0xC0 |
jz .failed |
mov eax, [esi+8] |
push eax |
add esi, 12 |
and al, not 0xC0 |
dec eax |
jz .lzma |
.failed: |
pop eax |
popad |
ret 8 |
.lzma: |
call .lzma_unpack |
.common: |
pop eax |
test al, 0x80 |
jnz .ctr1 |
test al, 0x40 |
jz .ok |
lodsd |
mov ecx, eax |
jecxz .ok |
mov dl, [esi] |
mov esi, [esp+32+8] |
.c1: |
lodsb |
sub al, 0E8h |
cmp al, 1 |
ja .c1 |
cmp byte [esi], dl |
jnz .c1 |
lodsd |
; "bswap eax" is not supported on i386 |
shr ax, 8 |
ror eax, 16 |
xchg al, ah |
sub eax, esi |
add eax, [esp+32+8] |
mov [esi-4], eax |
loop .c1 |
.ok: |
popad |
ret 8 |
.ctr1: |
lodsd |
mov ecx, eax |
jecxz .ok |
mov dl, [esi] |
mov esi, [esp+32+8] |
.c2: |
lodsb |
@@: |
cmp al, 0xF |
jnz .f |
lodsb |
cmp al, 80h |
jb @b |
cmp al, 90h |
jb @f |
.f: |
sub al, 0E8h |
cmp al, 1 |
ja .c2 |
@@: |
cmp byte [esi], dl |
jnz .c2 |
lodsd |
shr ax, 8 |
ror eax, 16 |
xchg al, ah |
sub eax, esi |
add eax, [esp+32+8] |
mov [esi-4], eax |
loop .c2 |
jmp .ok |
.lzma_unpack: |
.pb = 2 ; pos state bits |
.lp = 0 ; literal pos state bits |
.lc = 3 ; literal context bits |
.posStateMask = ((1 shl .pb)-1) |
.literalPosMask = ((1 shl .lp)-1) |
.kNumPosBitsMax = 4 |
.kNumPosStatesMax = (1 shl .kNumPosBitsMax) |
.kLenNumLowBits = 3 |
.kLenNumLowSymbols = (1 shl .kLenNumLowBits) |
.kLenNumMidBits = 3 |
.kLenNumMidSymbols = (1 shl .kLenNumMidBits) |
.kLenNumHighBits = 8 |
.kLenNumHighSymbols = (1 shl .kLenNumHighBits) |
.LenChoice = 0 |
.LenChoice2 = 1 |
.LenLow = 2 |
.LenMid = (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits)) |
.LenHigh = (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits)) |
.kNumLenProbs = (.LenHigh + .kLenNumHighSymbols) |
.kNumStates = 12 |
.kNumLitStates = 7 |
.kStartPosModelIndex = 4 |
.kEndPosModelIndex = 14 |
.kNumFullDistances = (1 shl (.kEndPosModelIndex/2)) |
.kNumPosSlotBits = 6 |
.kNumLenToPosStates = 4 |
.kNumAlignBits = 4 |
.kAlignTableSize = (1 shl .kNumAlignBits) |
.kMatchMinLen = 2 |
.IsMatch = 0 |
.IsRep = (.IsMatch + (.kNumStates shl .kNumPosBitsMax)) |
.IsRepG0 = (.IsRep + .kNumStates) |
.IsRepG1 = (.IsRepG0 + .kNumStates) |
.IsRepG2 = (.IsRepG1 + .kNumStates) |
.IsRep0Long = (.IsRepG2 + .kNumStates) |
.PosSlot = (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax)) |
.SpecPos = (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits)) |
.Align_ = (.SpecPos + .kNumFullDistances - .kEndPosModelIndex) |
.Lencoder = (.Align_ + .kAlignTableSize) |
.RepLencoder = (.Lencoder + .kNumLenProbs) |
.Literal = (.RepLencoder + .kNumLenProbs) |
.LZMA_BASE_SIZE = 1846 ; must be ==Literal |
.LZMA_LIT_SIZE = 768 |
.kNumTopBits = 24 |
.kTopValue = (1 shl .kNumTopBits) |
.kNumBitModelTotalBits = 11 |
.kBitModelTotal = (1 shl .kNumBitModelTotalBits) |
.kNumMoveBits = 5 |
push edi |
; int state=0; |
xor ebx, ebx |
mov [.previousByte], bl |
; unsigned rep0=1,rep1=1,rep2=1,rep3=1; |
mov eax, 1 |
mov edi, .rep0 |
stosd |
stosd |
stosd |
stosd |
; int len=0; |
; result=0; |
mov ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp)) |
mov eax, .kBitModelTotal/2 |
mov edi, [.p] |
rep stosd |
; RangeDecoderInit |
; rd->ExtraBytes = 0 |
; rd->Buffer = stream |
; rd->BufferLim = stream+bufferSize |
; rd->Range = 0xFFFFFFFF |
pop edi |
mov ebp, [esi-8] ; dest_length |
add ebp, edi ; ebp = destination limit |
lodsd |
; rd->code_ = eax |
mov [.code_], eax |
or [.range], -1 |
.main_loop: |
cmp edi, ebp |
jae .main_loop_done |
mov edx, edi |
and edx, .posStateMask |
mov eax, ebx |
shl eax, .kNumPosBitsMax+2 |
lea eax, [.IsMatch*4 + eax + edx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
jc .1 |
movzx eax, [.previousByte] |
if .literalPosMask |
mov ah, dl |
and ah, .literalPosMask |
end if |
shr eax, 8-.lc |
imul eax, .LZMA_LIT_SIZE*4 |
add eax, .Literal*4 |
add eax, [.p] |
cmp ebx, .kNumLitStates |
jb .literal |
xor edx, edx |
sub edx, [.rep0] |
mov dl, [edi + edx] |
call .LzmaLiteralDecodeMatch |
jmp @f |
.literal: |
call .LzmaLiteralDecode |
@@: |
mov [.previousByte], al |
stosb |
mov al, bl |
cmp bl, 4 |
jb @f |
mov al, 3 |
cmp bl, 10 |
jb @f |
mov al, 6 |
@@: sub bl, al |
jmp .main_loop |
.1: |
lea eax, [.IsRep*4 + ebx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
jnc .10 |
lea eax, [.IsRepG0*4 + ebx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
jc .111 |
mov eax, ebx |
shl eax, .kNumPosBitsMax+2 |
lea eax, [.IsRep0Long*4 + eax + edx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
jc .1101 |
cmp bl, 7 |
setae bl |
lea ebx, [9 + ebx + ebx] |
xor edx, edx |
sub edx, [.rep0] |
mov al, [edi + edx] |
stosb |
mov [.previousByte], al |
jmp .main_loop |
.111: |
lea eax, [.IsRepG1*4 + ebx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
mov eax, [.rep1] |
jnc .l3 |
.l1: |
lea eax, [.IsRepG2*4 + ebx*4] |
add eax, [.p] |
call .RangeDecoderBitDecode |
mov eax, [.rep2] |
jnc .l2 |
xchg [.rep3], eax |
.l2: |
push [.rep1] |
pop [.rep2] |
.l3: |
xchg eax, [.rep0] |
mov [.rep1], eax |
.1101: |
mov eax, .RepLencoder*4 |
add eax, [.p] |
call .LzmaLenDecode |
cmp bl, 7 |
setc bl |
adc bl, bl |
xor bl, 3 |
add bl, 8 |
jmp .repmovsb |
.10: |
mov eax, [.rep0] |
xchg eax, [.rep1] |
xchg eax, [.rep2] |
xchg eax, [.rep3] |
cmp bl, 7 |
setc bl |
adc bl, bl |
xor bl, 3 |
add bl, 7 |
mov eax, .Lencoder*4 |
add eax, [.p] |
call .LzmaLenDecode |
mov eax, .kNumLenToPosStates-1 |
cmp eax, ecx |
jb @f |
mov eax, ecx |
@@: |
push ecx |
mov ecx, .kNumPosSlotBits |
shl eax, cl |
shl eax, 2 |
add eax, .PosSlot*4 |
add eax, [.p] |
call .RangeDecoderBitTreeDecode |
mov [.rep0], ecx |
cmp ecx, .kStartPosModelIndex |
jb .l6 |
push ecx |
mov eax, ecx |
and eax, 1 |
shr ecx, 1 |
or eax, 2 |
dec ecx |
shl eax, cl |
mov [.rep0], eax |
pop edx |
cmp edx, .kEndPosModelIndex |
jae .l5 |
sub eax, edx |
shl eax, 2 |
add eax, (.SpecPos - 1)*4 |
add eax, [.p] |
call .RangeDecoderReverseBitTreeDecode |
add [.rep0], ecx |
jmp .l6 |
.l5: |
sub ecx, .kNumAlignBits |
call .RangeDecoderDecodeDirectBits |
mov ecx, .kNumAlignBits |
shl eax, cl |
add [.rep0], eax |
mov eax, .Align_*4 |
add eax, [.p] |
call .RangeDecoderReverseBitTreeDecode |
add [.rep0], ecx |
.l6: |
pop ecx |
inc [.rep0] |
jz .main_loop_done |
.repmovsb: |
add ecx, .kMatchMinLen |
push esi |
mov esi, edi |
sub esi, [.rep0] |
rep movsb |
pop esi |
mov al, [edi-1] |
mov [.previousByte], al |
jmp .main_loop |
.main_loop_done: |
ret |
.RangeDecoderBitDecode: |
; in: eax->prob |
; out: CF=bit; destroys eax |
push edx |
mov edx, [.range] |
shr edx, .kNumBitModelTotalBits |
imul edx, [eax] |
cmp [.code_], edx |
jae .ae |
mov [.range], edx |
mov edx, .kBitModelTotal |
sub edx, [eax] |
shr edx, .kNumMoveBits |
add [eax], edx |
clc |
.n: |
lahf |
cmp [.range], .kTopValue |
jae @f |
shl [.range], 8 |
shl [.code_], 8 |
lodsb |
mov byte [.code_], al |
@@: |
sahf |
pop edx |
ret |
.ae: |
sub [.range], edx |
sub [.code_], edx |
mov edx, [eax] |
shr edx, .kNumMoveBits |
sub [eax], edx |
stc |
jmp .n |
.RangeDecoderDecodeDirectBits: |
; in: ecx=numTotalBits |
; out: eax=result; destroys edx |
xor eax, eax |
.l: |
shr [.range], 1 |
shl eax, 1 |
mov edx, [.code_] |
sub edx, [.range] |
jb @f |
mov [.code_], edx |
or eax, 1 |
@@: |
cmp [.range], .kTopValue |
jae @f |
shl [.range], 8 |
shl [.code_], 8 |
push eax |
lodsb |
mov byte [.code_], al |
pop eax |
@@: |
loop .l |
ret |
.LzmaLiteralDecode: |
; in: eax->probs |
; out: al=byte; destroys edx |
push ecx |
mov ecx, 1 |
@@: |
push eax |
lea eax, [eax+ecx*4] |
call .RangeDecoderBitDecode |
pop eax |
adc cl, cl |
jnc @b |
.LzmaLiteralDecode.ret: |
mov al, cl |
pop ecx |
ret |
.LzmaLiteralDecodeMatch: |
; in: eax->probs, dl=matchByte |
; out: al=byte; destroys edx |
push ecx |
mov ecx, 1 |
.LzmaLiteralDecodeMatch.1: |
add dl, dl |
setc ch |
push eax |
lea eax, [eax+ecx*4+0x100*4] |
call .RangeDecoderBitDecode |
pop eax |
adc cl, cl |
jc .LzmaLiteralDecode.ret |
xor ch, cl |
test ch, 1 |
mov ch, 0 |
jnz @b |
jmp .LzmaLiteralDecodeMatch.1 |
.LzmaLenDecode: |
; in: eax->prob, edx=posState |
; out: ecx=len |
push eax |
add eax, .LenChoice*4 |
call .RangeDecoderBitDecode |
pop eax |
jnc .0 |
push eax |
add eax, .LenChoice2*4 |
call .RangeDecoderBitDecode |
pop eax |
jc @f |
mov ecx, .kLenNumMidBits |
shl edx, cl |
lea eax, [eax + .LenMid*4 + edx*4] |
call .RangeDecoderBitTreeDecode |
add ecx, .kLenNumLowSymbols |
ret |
@@: |
add eax, .LenHigh*4 |
mov ecx, .kLenNumHighBits |
call .RangeDecoderBitTreeDecode |
add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols |
ret |
.0: |
mov ecx, .kLenNumLowBits |
shl edx, cl |
lea eax, [eax + .LenLow*4 + edx*4] |
.RangeDecoderBitTreeDecode: |
; in: eax->probs,ecx=numLevels |
; out: ecx=length; destroys edx |
push ebx |
mov edx, 1 |
mov ebx, edx |
@@: |
push eax |
lea eax, [eax+edx*4] |
call .RangeDecoderBitDecode |
pop eax |
adc dl, dl |
add bl, bl |
loop @b |
sub dl, bl |
pop ebx |
mov ecx, edx |
ret |
.RangeDecoderReverseBitTreeDecode: |
; in: eax->probs,ecx=numLevels |
; out: ecx=length; destroys edx |
push ebx ecx |
mov edx, 1 |
xor ebx, ebx |
@@: |
push eax |
lea eax, [eax+edx*4] |
call .RangeDecoderBitDecode |
lahf |
adc edx, edx |
sahf |
rcr ebx, 1 |
pop eax |
loop @b |
pop ecx |
rol ebx, cl |
mov ecx, ebx |
pop ebx |
ret |
uglobal |
align 4 |
;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) |
unpack.p dd ? |
unpack.code_ dd ? |
unpack.range dd ? |
unpack.rep0 dd ? |
unpack.rep1 dd ? |
unpack.rep2 dd ? |
unpack.rep3 dd ? |
unpack.previousByte db ? |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/vmodeld.inc |
---|
0,0 → 1,35 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; |
; Load of videomode driver in memory |
; |
; (driver is located at VMODE_BASE - 32kb) // if this area not occuped anything |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
; LOAD VIDEOMODE DRIVER |
; If vmode.mdr file not found |
or eax,-1 ; Driver ID = -1 (not present in system) |
mov [VMODE_BASE],eax ; |
mov [VMODE_BASE+0x100],byte 0xC3 ; Instruction RETN - driver loop |
stdcall read_file, vmode, VMODE_BASE, 0, 0x8000 ;{SPraid.simba} |
; mov esi, vmode |
; xor ebx, ebx |
; mov ecx, 0x8000 ; size of memory area for driver |
; mov edx, VMODE_BASE ; Memory position of driver |
; xor ebp, ebp |
; call fs_RamdiskRead |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/default.asm |
---|
0,0 → 1,38 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include 'me_skin.inc' |
SKIN_PARAMS \ |
height = bmp_base.height,\ ; skin height |
margins = [5:1:43:1],\ ; margins [left:top:right:bottom] |
colors active = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x0054e7],\ ; border frame color |
colors inactive = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x1a8acc],\ ; border frame color |
dtp = 'myblue.dtp' ; dtp colors |
SKIN_BUTTONS \ |
close = [-21:3][16:16],\ ; buttons coordinates |
minimize = [-39:3][16:16] ; [left:top][width:height] |
SKIN_BITMAPS \ |
left active = bmp_left,\ ; skin bitmaps pointers |
left inactive = bmp_left1,\ |
oper active = bmp_oper,\ |
oper inactive = bmp_oper1,\ |
base active = bmp_base,\ |
base inactive = bmp_base1 |
BITMAP bmp_left ,'left.bmp' ; skin bitmaps |
BITMAP bmp_oper ,'oper.bmp' |
BITMAP bmp_base ,'base.bmp' |
BITMAP bmp_left1,'left_1.bmp' |
BITMAP bmp_oper1,'oper_1.bmp' |
BITMAP bmp_base1,'base_1.bmp' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/me_skin.inc |
---|
0,0 → 1,242 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;============================================================================ |
; This file should be used to generate skins of new standard |
;============================================================================ |
; skin file structure: |
;---------------------------------------------------------------------------- |
; header: |
; dd 'SKIN' |
; dd = version (1 for now) |
; dd @ params |
; dd @ buttons |
; dd @ bitmaps |
; ... |
;---------------------------------------------------------------------------- |
; NOTE: order of sections listed below is insignificant |
; since they're identified by pointer in above header |
;---------------------------------------------------------------------------- |
; ... |
; params: |
; dd = skin height |
; dw = right margin |
; dw = left margin |
; dw = bottom margin |
; dw = top margin |
; dd = inner line color |
; dd = outer line color |
; dd = frame color |
; dd = dtp file size |
; ?? = dtp file itself |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; buttons: |
; dd = button type (1 = close, 2 = minimize) |
; dw = left button coord (could be negative) |
; dw = top button coord (could be negative) |
; dw = button width |
; dw = button height |
; ... etc for all buttons |
; dd = 0 (end of buttons list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmaps: |
; dw = bitmap kind (1 = left, 2 = oper, 3 = base) |
; dw = bitmap type (1 = active, 0 = inactive) |
; dd @ bitmap |
; ... etc for all bitmaps |
; dd 0 (end of bitmaps list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmap: |
; dd = bitmap width |
; dd = bitmap height |
; ?? = raw bitmap data |
; ... etc for all bitmaps |
; ... |
;============================================================================ |
dd 'SKIN',1,__params__,__buttons__,__bitmaps__ |
struc BITMAPFILEHEADER { |
.bfType dw ? ; WORD |
.bfSize dd ? ; DWORD |
.bfReserved1 dw ? ; WORD |
.bfReserved2 dw ? ; WORD |
.bfOffBits dd ? ; DWORD |
} |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
struc _bmp { |
.h BITMAPFILEHEADER |
.i BITMAPINFOHEADER |
} |
virtual at 0 |
_bmp _bmp |
end virtual |
macro BITMAP _name*,_fname* |
{ |
local w,h,a,r,g,b |
virtual at 0 |
file _fname |
load w dword from _bmp.i.biWidth |
load h dword from _bmp.i.biHeight |
end virtual |
align 4 |
label _name |
.width = w |
.height = h |
dd w,h |
a=54+(w*3+(w mod 4))*(h-1) |
size = $ |
repeat h |
repeat w |
virtual at 0 |
file _fname |
load r from a+0 |
load g from a+1 |
load b from a+2 |
end virtual |
db r,g,b |
a=a+3 |
end repeat |
a=a-w*3*2-(w mod 4) |
end repeat |
} |
macro define_colors name,[col,val] |
{ |
common |
local a,b,c |
forward |
match =binner,col \{ a = val \} |
match =bouter,col \{ b = val \} |
match =bframe,col \{ c = val \} |
common |
name equ a,b,c |
} |
macro SKIN_PARAMS [a] |
{ |
common |
local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz |
__params__: |
forward |
match qq == ww,a |
\{ |
match =height,qq \\{ _height = ww \\} |
match =margins,qq \\{ |
match [q1:q2:q3:q4],ww |
\\\{ |
_margins equ q3,q1,q4,q2 |
\\\} |
\\} |
match =colors =active,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =colors =inactive,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors_1,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =dtp,qq \\{ _dtp equ ww \\} |
\} |
common |
dd _height |
dw _margins |
dd _colors,_colors_1 |
virtual at 0 |
file _dtp |
_dtp_sz = $ |
end virtual |
dd _dtp_sz |
file _dtp |
} |
macro SKIN_BUTTONS [a] |
{ |
common |
local btn |
__buttons__: |
forward |
match qq == ww,a |
\{ |
btn = 0 |
match =close,qq \\{ btn = 1 \\} |
match =minimize,qq \\{ btn = 2 \\} |
match [q1:q2][q3:q4],ww |
\\{ |
if btn <> 0 |
dd btn |
dw q1,q2,q3,q4 |
end if |
\\} |
\} |
common |
dd 0 |
} |
macro SKIN_BITMAPS [a] |
{ |
common |
local bmp |
__bitmaps__: |
forward |
match qq == ww,a |
\{ |
bmp=-1 |
match qqq =active,qq \\{ bmp = 1 \\} |
match qqq =inactive,qq \\{ bmp = 0 \\} |
match =left qqq,qq |
\\{ |
if bmp >= 0 |
dw 1,bmp |
dd ww |
end if |
\\} |
match =oper qqq,qq |
\\{ |
if bmp >= 0 |
dw 2,bmp |
dd ww |
end if |
\\} |
match =base qqq,qq |
\\{ |
if bmp >= 0 |
dw 3,bmp |
dd ww |
end if |
\\} |
\} |
common |
dd 0 |
} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/base.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/base_1.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/left.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/left_1.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/myblue.dtp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/oper.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin/oper_1.bmp |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.7.0/skin |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
/kernel/tags/kolibri0.7.7.0/sys.conf |
---|
0,0 → 1,18 |
[path] |
/rd/1=/sys |
/rd/1/dll=/sys/lib |
[net] |
active=1 |
addr=192.168.1.2 |
mask=255.255.255.0 |
gate=192.168.1.1 |
[gui] |
mouse_speed=1 |
mouse_delay=0x00A |
[dev] |
sb16=0x220 |
sound_dma=1 |
midibase=0x320 |
/kernel/tags/kolibri0.7.7.0/COPYING.TXT |
---|
0,0 → 1,347 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
675 Mass Ave, Cambridge, MA 02139, USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
Appendix: How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) 19yy <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) 19yy name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/kernel/tags/kolibri0.7.7.0/. |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |