From 2a2b5a8ff893fd16a9c6939bcd3ea6f6fa87d2e7 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Mon, 28 Jul 2008 06:29:05 +0000 Subject: [PATCH] use e820 smap git-svn-id: svn://kolibrios.org@837 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/kolibri_pe/COPYING.TXT | 347 ++ kernel/branches/kolibri_pe/blkdev/cd_drv.inc | 901 +++ kernel/branches/kolibri_pe/blkdev/cdrom.inc | 271 + kernel/branches/kolibri_pe/blkdev/fdc.inc | 71 + kernel/branches/kolibri_pe/blkdev/flp_drv.inc | 625 ++ kernel/branches/kolibri_pe/blkdev/hd_drv.inc | 928 +++ .../branches/kolibri_pe/blkdev/ide_cache.inc | 922 +++ kernel/branches/kolibri_pe/blkdev/rd.inc | 2262 +++++++ kernel/branches/kolibri_pe/blkdev/rdsave.inc | 32 + kernel/branches/kolibri_pe/boot/ETFONT.FNT | Bin 0 -> 4096 bytes kernel/branches/kolibri_pe/boot/bootcode.inc | 1205 ++++ kernel/branches/kolibri_pe/boot/booteng.inc | 110 + kernel/branches/kolibri_pe/boot/bootet.inc | 115 + kernel/branches/kolibri_pe/boot/bootge.inc | 120 + kernel/branches/kolibri_pe/boot/bootru.inc | 91 + kernel/branches/kolibri_pe/boot/bootstr.inc | 62 + kernel/branches/kolibri_pe/boot/bootvesa.inc | 743 +++ kernel/branches/kolibri_pe/boot/et.inc | 16 + kernel/branches/kolibri_pe/boot/preboot.inc | 38 + kernel/branches/kolibri_pe/boot/rdload.inc | 125 + kernel/branches/kolibri_pe/boot/ru.inc | 102 + kernel/branches/kolibri_pe/boot/shutdown.inc | 209 + .../kolibri_pe/bootloader/boot_fat12.asm | 287 + .../kolibri_pe/bootloader/floppy1440.inc | 19 + .../kolibri_pe/bootloader/floppy1680.inc | 19 + .../kolibri_pe/bootloader/floppy1743.inc | 19 + .../kolibri_pe/bootloader/floppy2880.inc | 19 + kernel/branches/kolibri_pe/bootloader/readme | 43 + kernel/branches/kolibri_pe/build.bat | 105 + kernel/branches/kolibri_pe/bus/pci/pci16.inc | 51 + kernel/branches/kolibri_pe/bus/pci/pci32.inc | 483 ++ kernel/branches/kolibri_pe/const.inc | 654 ++ kernel/branches/kolibri_pe/core/conf_lib.inc | 297 + kernel/branches/kolibri_pe/core/debug.inc | 475 ++ kernel/branches/kolibri_pe/core/dll.inc | 1210 ++++ kernel/branches/kolibri_pe/core/export.inc | 39 + kernel/branches/kolibri_pe/core/exports.inc | 163 + kernel/branches/kolibri_pe/core/ext_lib.inc | 317 + kernel/branches/kolibri_pe/core/fpu.inc | 288 + kernel/branches/kolibri_pe/core/heap.inc | 1300 ++++ kernel/branches/kolibri_pe/core/malloc.inc | 1003 ++++ kernel/branches/kolibri_pe/core/memory.inc | 1303 ++++ kernel/branches/kolibri_pe/core/peload.inc | 316 + kernel/branches/kolibri_pe/core/sched.inc | 380 ++ kernel/branches/kolibri_pe/core/string.inc | 188 + kernel/branches/kolibri_pe/core/sync.inc | 119 + kernel/branches/kolibri_pe/core/sys32.inc | 787 +++ kernel/branches/kolibri_pe/core/syscall.inc | 262 + kernel/branches/kolibri_pe/core/taskman.inc | 1111 ++++ kernel/branches/kolibri_pe/core/v86.inc | 949 +++ kernel/branches/kolibri_pe/data16.inc | 55 + kernel/branches/kolibri_pe/data32.inc | 462 ++ .../branches/kolibri_pe/detect/biosdisk.inc | 76 + kernel/branches/kolibri_pe/detect/dev_fd.inc | 30 + .../branches/kolibri_pe/detect/dev_hdcd.inc | 384 ++ kernel/branches/kolibri_pe/detect/disks.inc | 15 + .../branches/kolibri_pe/detect/getcache.inc | 201 + .../branches/kolibri_pe/detect/sear_par.inc | 153 + kernel/branches/kolibri_pe/docs/apm.txt | 518 ++ .../branches/kolibri_pe/docs/loader_doc.txt | 88 + kernel/branches/kolibri_pe/docs/sysfuncr.txt | 4553 ++++++++++++++ kernel/branches/kolibri_pe/docs/sysfuncs.txt | 4513 ++++++++++++++ kernel/branches/kolibri_pe/drivers/ati2d.asm | 1607 +++++ kernel/branches/kolibri_pe/drivers/codec.inc | 283 + .../branches/kolibri_pe/drivers/com_mouse.asm | 374 ++ .../branches/kolibri_pe/drivers/ensoniq.asm | 1177 ++++ .../branches/kolibri_pe/drivers/imports.inc | 89 + .../branches/kolibri_pe/drivers/infinity.asm | 1307 ++++ kernel/branches/kolibri_pe/drivers/main.inc | 164 + .../branches/kolibri_pe/drivers/mix_mmx.inc | 247 + .../branches/kolibri_pe/drivers/mix_sse2.inc | 145 + kernel/branches/kolibri_pe/drivers/mixer.asm | 1263 ++++ kernel/branches/kolibri_pe/drivers/proc32.inc | 268 + .../kolibri_pe/drivers/ps2m_iofuncs.inc | 141 + .../branches/kolibri_pe/drivers/ps2m_irqh.inc | 120 + .../branches/kolibri_pe/drivers/ps2mouse.asm | 270 + kernel/branches/kolibri_pe/drivers/r500hw.inc | 1268 ++++ .../kolibri_pe/drivers/sb16/CONFIG.INC | 41 + .../branches/kolibri_pe/drivers/sb16/SB16.INC | 239 + .../branches/kolibri_pe/drivers/sb16/sb16.asm | 375 ++ .../branches/kolibri_pe/drivers/sceletone.asm | 177 + kernel/branches/kolibri_pe/drivers/sis.asm | 1307 ++++ kernel/branches/kolibri_pe/drivers/sound.asm | 1473 +++++ kernel/branches/kolibri_pe/drivers/uart.asm | 972 +++ .../branches/kolibri_pe/drivers/usb/urb.inc | 115 + .../branches/kolibri_pe/drivers/usb/usb.asm | 435 ++ kernel/branches/kolibri_pe/drivers/vmode.asm | 736 +++ kernel/branches/kolibri_pe/fdo.inc | 434 ++ kernel/branches/kolibri_pe/fs/fat12.inc | 2269 +++++++ kernel/branches/kolibri_pe/fs/fat32.inc | 2921 +++++++++ kernel/branches/kolibri_pe/fs/fs.inc | 797 +++ kernel/branches/kolibri_pe/fs/fs_lfn.inc | 1079 ++++ kernel/branches/kolibri_pe/fs/iso9660.inc | 757 +++ kernel/branches/kolibri_pe/fs/ntfs.inc | 1815 ++++++ kernel/branches/kolibri_pe/fs/parse_fn.inc | 236 + kernel/branches/kolibri_pe/fs/part_set.inc | 477 ++ kernel/branches/kolibri_pe/gui/button.inc | 647 ++ kernel/branches/kolibri_pe/gui/event.inc | 701 +++ kernel/branches/kolibri_pe/gui/font.inc | 132 + kernel/branches/kolibri_pe/gui/mouse.inc | 250 + kernel/branches/kolibri_pe/gui/skincode.inc | 467 ++ kernel/branches/kolibri_pe/gui/skindata.inc | 64 + kernel/branches/kolibri_pe/gui/window.inc | 1817 ++++++ kernel/branches/kolibri_pe/hid/keyboard.inc | 343 ++ kernel/branches/kolibri_pe/hid/mousedrv.inc | 458 ++ kernel/branches/kolibri_pe/hid/set_dtc.inc | 201 + kernel/branches/kolibri_pe/imports.inc | 27 + kernel/branches/kolibri_pe/init.inc | 356 ++ kernel/branches/kolibri_pe/kernel.asm | 5255 +++++++++++++++++ kernel/branches/kolibri_pe/kernel32.inc | 275 + kernel/branches/kolibri_pe/kglobals.inc | 69 + kernel/branches/kolibri_pe/macros.inc | 100 + kernel/branches/kolibri_pe/make.sh | 33 + kernel/branches/kolibri_pe/makefile | 48 + kernel/branches/kolibri_pe/memmap.inc | 245 + .../kolibri_pe/network/eth_drv/arp.inc | 558 ++ .../network/eth_drv/drivers/3c59x.inc | 2390 ++++++++ .../network/eth_drv/drivers/i8255x.inc | 760 +++ .../network/eth_drv/drivers/pcnet32.inc | 848 +++ .../network/eth_drv/drivers/rtl8029.inc | 959 +++ .../network/eth_drv/drivers/rtl8139.inc | 621 ++ .../network/eth_drv/drivers/rtl8169.inc | 1210 ++++ .../network/eth_drv/drivers/sis900.inc | 1158 ++++ .../kolibri_pe/network/eth_drv/ethernet.inc | 460 ++ .../kolibri_pe/network/eth_drv/pci.inc | 351 ++ kernel/branches/kolibri_pe/network/icmp.inc | 193 + kernel/branches/kolibri_pe/network/ip.inc | 200 + kernel/branches/kolibri_pe/network/queue.inc | 220 + kernel/branches/kolibri_pe/network/socket.inc | 934 +++ kernel/branches/kolibri_pe/network/stack.inc | 1021 ++++ kernel/branches/kolibri_pe/network/tcp.inc | 1302 ++++ kernel/branches/kolibri_pe/network/udp.inc | 173 + kernel/branches/kolibri_pe/proc32.inc | 271 + kernel/branches/kolibri_pe/skin/base.bmp | Bin 0 -> 584 bytes kernel/branches/kolibri_pe/skin/base_1.bmp | Bin 0 -> 584 bytes kernel/branches/kolibri_pe/skin/default.asm | 38 + kernel/branches/kolibri_pe/skin/left.bmp | Bin 0 -> 670 bytes kernel/branches/kolibri_pe/skin/left_1.bmp | Bin 0 -> 670 bytes kernel/branches/kolibri_pe/skin/me_skin.inc | 242 + kernel/branches/kolibri_pe/skin/myblue.dtp | Bin 0 -> 40 bytes kernel/branches/kolibri_pe/skin/oper.bmp | Bin 0 -> 2694 bytes kernel/branches/kolibri_pe/skin/oper_1.bmp | Bin 0 -> 2694 bytes kernel/branches/kolibri_pe/sound/playnote.inc | 164 + kernel/branches/kolibri_pe/sys.conf | 18 + kernel/branches/kolibri_pe/unpacker.inc | 527 ++ kernel/branches/kolibri_pe/video/arrow.cur | Bin 0 -> 766 bytes kernel/branches/kolibri_pe/video/cursors.inc | 782 +++ kernel/branches/kolibri_pe/video/vesa12.inc | 983 +++ kernel/branches/kolibri_pe/video/vesa20.inc | 1181 ++++ kernel/branches/kolibri_pe/video/vga.inc | 450 ++ kernel/branches/kolibri_pe/vmodeint.inc | 57 + kernel/branches/kolibri_pe/vmodeld.inc | 35 + 152 files changed, 87521 insertions(+) create mode 100644 kernel/branches/kolibri_pe/COPYING.TXT create mode 100644 kernel/branches/kolibri_pe/blkdev/cd_drv.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/cdrom.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/fdc.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/flp_drv.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/hd_drv.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/ide_cache.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/rd.inc create mode 100644 kernel/branches/kolibri_pe/blkdev/rdsave.inc create mode 100644 kernel/branches/kolibri_pe/boot/ETFONT.FNT create mode 100644 kernel/branches/kolibri_pe/boot/bootcode.inc create mode 100644 kernel/branches/kolibri_pe/boot/booteng.inc create mode 100644 kernel/branches/kolibri_pe/boot/bootet.inc create mode 100644 kernel/branches/kolibri_pe/boot/bootge.inc create mode 100644 kernel/branches/kolibri_pe/boot/bootru.inc create mode 100644 kernel/branches/kolibri_pe/boot/bootstr.inc create mode 100644 kernel/branches/kolibri_pe/boot/bootvesa.inc create mode 100644 kernel/branches/kolibri_pe/boot/et.inc create mode 100644 kernel/branches/kolibri_pe/boot/preboot.inc create mode 100644 kernel/branches/kolibri_pe/boot/rdload.inc create mode 100644 kernel/branches/kolibri_pe/boot/ru.inc create mode 100644 kernel/branches/kolibri_pe/boot/shutdown.inc create mode 100644 kernel/branches/kolibri_pe/bootloader/boot_fat12.asm create mode 100644 kernel/branches/kolibri_pe/bootloader/floppy1440.inc create mode 100644 kernel/branches/kolibri_pe/bootloader/floppy1680.inc create mode 100644 kernel/branches/kolibri_pe/bootloader/floppy1743.inc create mode 100644 kernel/branches/kolibri_pe/bootloader/floppy2880.inc create mode 100644 kernel/branches/kolibri_pe/bootloader/readme create mode 100644 kernel/branches/kolibri_pe/build.bat create mode 100644 kernel/branches/kolibri_pe/bus/pci/pci16.inc create mode 100644 kernel/branches/kolibri_pe/bus/pci/pci32.inc create mode 100644 kernel/branches/kolibri_pe/const.inc create mode 100644 kernel/branches/kolibri_pe/core/conf_lib.inc create mode 100644 kernel/branches/kolibri_pe/core/debug.inc create mode 100644 kernel/branches/kolibri_pe/core/dll.inc create mode 100644 kernel/branches/kolibri_pe/core/export.inc create mode 100644 kernel/branches/kolibri_pe/core/exports.inc create mode 100644 kernel/branches/kolibri_pe/core/ext_lib.inc create mode 100644 kernel/branches/kolibri_pe/core/fpu.inc create mode 100644 kernel/branches/kolibri_pe/core/heap.inc create mode 100644 kernel/branches/kolibri_pe/core/malloc.inc create mode 100644 kernel/branches/kolibri_pe/core/memory.inc create mode 100644 kernel/branches/kolibri_pe/core/peload.inc create mode 100644 kernel/branches/kolibri_pe/core/sched.inc create mode 100644 kernel/branches/kolibri_pe/core/string.inc create mode 100644 kernel/branches/kolibri_pe/core/sync.inc create mode 100644 kernel/branches/kolibri_pe/core/sys32.inc create mode 100644 kernel/branches/kolibri_pe/core/syscall.inc create mode 100644 kernel/branches/kolibri_pe/core/taskman.inc create mode 100644 kernel/branches/kolibri_pe/core/v86.inc create mode 100644 kernel/branches/kolibri_pe/data16.inc create mode 100644 kernel/branches/kolibri_pe/data32.inc create mode 100644 kernel/branches/kolibri_pe/detect/biosdisk.inc create mode 100644 kernel/branches/kolibri_pe/detect/dev_fd.inc create mode 100644 kernel/branches/kolibri_pe/detect/dev_hdcd.inc create mode 100644 kernel/branches/kolibri_pe/detect/disks.inc create mode 100644 kernel/branches/kolibri_pe/detect/getcache.inc create mode 100644 kernel/branches/kolibri_pe/detect/sear_par.inc create mode 100644 kernel/branches/kolibri_pe/docs/apm.txt create mode 100644 kernel/branches/kolibri_pe/docs/loader_doc.txt create mode 100644 kernel/branches/kolibri_pe/docs/sysfuncr.txt create mode 100644 kernel/branches/kolibri_pe/docs/sysfuncs.txt create mode 100644 kernel/branches/kolibri_pe/drivers/ati2d.asm create mode 100644 kernel/branches/kolibri_pe/drivers/codec.inc create mode 100644 kernel/branches/kolibri_pe/drivers/com_mouse.asm create mode 100644 kernel/branches/kolibri_pe/drivers/ensoniq.asm create mode 100644 kernel/branches/kolibri_pe/drivers/imports.inc create mode 100644 kernel/branches/kolibri_pe/drivers/infinity.asm create mode 100644 kernel/branches/kolibri_pe/drivers/main.inc create mode 100644 kernel/branches/kolibri_pe/drivers/mix_mmx.inc create mode 100644 kernel/branches/kolibri_pe/drivers/mix_sse2.inc create mode 100644 kernel/branches/kolibri_pe/drivers/mixer.asm create mode 100644 kernel/branches/kolibri_pe/drivers/proc32.inc create mode 100644 kernel/branches/kolibri_pe/drivers/ps2m_iofuncs.inc create mode 100644 kernel/branches/kolibri_pe/drivers/ps2m_irqh.inc create mode 100644 kernel/branches/kolibri_pe/drivers/ps2mouse.asm create mode 100644 kernel/branches/kolibri_pe/drivers/r500hw.inc create mode 100644 kernel/branches/kolibri_pe/drivers/sb16/CONFIG.INC create mode 100644 kernel/branches/kolibri_pe/drivers/sb16/SB16.INC create mode 100644 kernel/branches/kolibri_pe/drivers/sb16/sb16.asm create mode 100644 kernel/branches/kolibri_pe/drivers/sceletone.asm create mode 100644 kernel/branches/kolibri_pe/drivers/sis.asm create mode 100644 kernel/branches/kolibri_pe/drivers/sound.asm create mode 100644 kernel/branches/kolibri_pe/drivers/uart.asm create mode 100644 kernel/branches/kolibri_pe/drivers/usb/urb.inc create mode 100644 kernel/branches/kolibri_pe/drivers/usb/usb.asm create mode 100644 kernel/branches/kolibri_pe/drivers/vmode.asm create mode 100644 kernel/branches/kolibri_pe/fdo.inc create mode 100644 kernel/branches/kolibri_pe/fs/fat12.inc create mode 100644 kernel/branches/kolibri_pe/fs/fat32.inc create mode 100644 kernel/branches/kolibri_pe/fs/fs.inc create mode 100644 kernel/branches/kolibri_pe/fs/fs_lfn.inc create mode 100644 kernel/branches/kolibri_pe/fs/iso9660.inc create mode 100644 kernel/branches/kolibri_pe/fs/ntfs.inc create mode 100644 kernel/branches/kolibri_pe/fs/parse_fn.inc create mode 100644 kernel/branches/kolibri_pe/fs/part_set.inc create mode 100644 kernel/branches/kolibri_pe/gui/button.inc create mode 100644 kernel/branches/kolibri_pe/gui/event.inc create mode 100644 kernel/branches/kolibri_pe/gui/font.inc create mode 100644 kernel/branches/kolibri_pe/gui/mouse.inc create mode 100644 kernel/branches/kolibri_pe/gui/skincode.inc create mode 100644 kernel/branches/kolibri_pe/gui/skindata.inc create mode 100644 kernel/branches/kolibri_pe/gui/window.inc create mode 100644 kernel/branches/kolibri_pe/hid/keyboard.inc create mode 100644 kernel/branches/kolibri_pe/hid/mousedrv.inc create mode 100644 kernel/branches/kolibri_pe/hid/set_dtc.inc create mode 100644 kernel/branches/kolibri_pe/imports.inc create mode 100644 kernel/branches/kolibri_pe/init.inc create mode 100644 kernel/branches/kolibri_pe/kernel.asm create mode 100644 kernel/branches/kolibri_pe/kernel32.inc create mode 100644 kernel/branches/kolibri_pe/kglobals.inc create mode 100644 kernel/branches/kolibri_pe/macros.inc create mode 100755 kernel/branches/kolibri_pe/make.sh create mode 100644 kernel/branches/kolibri_pe/makefile create mode 100644 kernel/branches/kolibri_pe/memmap.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/arp.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/3c59x.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/i8255x.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/pcnet32.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8029.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8139.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8169.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/drivers/sis900.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/ethernet.inc create mode 100644 kernel/branches/kolibri_pe/network/eth_drv/pci.inc create mode 100644 kernel/branches/kolibri_pe/network/icmp.inc create mode 100644 kernel/branches/kolibri_pe/network/ip.inc create mode 100644 kernel/branches/kolibri_pe/network/queue.inc create mode 100644 kernel/branches/kolibri_pe/network/socket.inc create mode 100644 kernel/branches/kolibri_pe/network/stack.inc create mode 100644 kernel/branches/kolibri_pe/network/tcp.inc create mode 100644 kernel/branches/kolibri_pe/network/udp.inc create mode 100644 kernel/branches/kolibri_pe/proc32.inc create mode 100644 kernel/branches/kolibri_pe/skin/base.bmp create mode 100644 kernel/branches/kolibri_pe/skin/base_1.bmp create mode 100644 kernel/branches/kolibri_pe/skin/default.asm create mode 100644 kernel/branches/kolibri_pe/skin/left.bmp create mode 100644 kernel/branches/kolibri_pe/skin/left_1.bmp create mode 100644 kernel/branches/kolibri_pe/skin/me_skin.inc create mode 100644 kernel/branches/kolibri_pe/skin/myblue.dtp create mode 100644 kernel/branches/kolibri_pe/skin/oper.bmp create mode 100644 kernel/branches/kolibri_pe/skin/oper_1.bmp create mode 100644 kernel/branches/kolibri_pe/sound/playnote.inc create mode 100644 kernel/branches/kolibri_pe/sys.conf create mode 100644 kernel/branches/kolibri_pe/unpacker.inc create mode 100644 kernel/branches/kolibri_pe/video/arrow.cur create mode 100644 kernel/branches/kolibri_pe/video/cursors.inc create mode 100644 kernel/branches/kolibri_pe/video/vesa12.inc create mode 100644 kernel/branches/kolibri_pe/video/vesa20.inc create mode 100644 kernel/branches/kolibri_pe/video/vga.inc create mode 100644 kernel/branches/kolibri_pe/vmodeint.inc create mode 100644 kernel/branches/kolibri_pe/vmodeld.inc diff --git a/kernel/branches/kolibri_pe/COPYING.TXT b/kernel/branches/kolibri_pe/COPYING.TXT new file mode 100644 index 000000000..f6213b69c --- /dev/null +++ b/kernel/branches/kolibri_pe/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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/kernel/branches/kolibri_pe/blkdev/cd_drv.inc b/kernel/branches/kolibri_pe/blkdev/cd_drv.inc new file mode 100644 index 000000000..5516e0b5a --- /dev/null +++ b/kernel/branches/kolibri_pe/blkdev/cd_drv.inc @@ -0,0 +1,901 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;********************************************************** +; Непосредственная работа с устройством СD (ATAPI) +;********************************************************** +; Автор части исходного текста Кулаков Владимир Геннадьевич +; Адаптация, доработка и разработка Mario79 + +; Максимальное количество повторений операции чтения +MaxRetr equ 10 +; Предельное время ожидания готовности к приему команды +; (в тиках) +BSYWaitTime equ 1000 ;2 +NoTickWaitTime equ 0xfffff + +;************************************************* +;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * +;* Считываются данные пользователя, информация * +;* субканала и контрольная информация * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* CDSectorAddress - адрес считываемого сектора. * +;* Данные считывается в массив CDDataBuf. * +;************************************************* +ReadCD: + 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 + popa + ret + +;******************************************** +;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * +;* Многократное повторение чтения при сбоях * +;******************************************** +ReadCDWRetr: +;----------------------------------------------------------- +; input : eax = block to read +; ebx = destination +;----------------------------------------------------------- + pushad + mov eax,[CDSectorAddress] + mov ebx,[CDDataBuf_pointer] + call cd_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_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: +; Подать команду + call ReadCD + cmp [DevErrorCode],0 + je @@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 + cmp eax,0 + je @@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: + popad + ret + + +; Универсальные процедуры, обеспечивающие выполнение +; пакетных команд в режиме PIO + +; Максимально допустимое время ожидания реакции +; устройства на пакетную команду (в тиках) +MaxCDWaitTime equ 1000 ;200 ;10 секунд + +; Область памяти для формирования пакетной команды +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 + +;**************************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * +;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет; * +;* CDBlockSize - размер принимаемого блока данных. * +;**************************************************** +SendPacketDatCommand: + pushad + mov [DevErrorCode],0 +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать ATA-команду передачи пакетной команды + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + ; Загрузить размер передаваемого блока + mov AX,[CDBlockSize] + mov [ATACylinder],AX + mov [ATAHead],0 + mov [ATACommand],0A0h + call SendCommandToHDD_1 + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End_8 ;закончить, сохранив код ошибки + +; Ожидание готовности дисковода к приему +; пакетной команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h + mov ecx,NoTickWaitTime +@@WaitDevice0: + cmp [timer_ticks_enable],0 + jne @f + dec ecx + cmp ecx,0 + je @@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 + cmp ecx,0 + je @@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 + ; Успешное завершение приема данных + jmp @@End_8 + +; Записать код ошибки +@@Err1_1: + mov [DevErrorCode],1 + jmp @@End_8 +@@Err6_temp: + mov [DevErrorCode],7 + jmp @@End_8 +@@Err6: + mov [DevErrorCode],6 +@@End_8: + popad + ret + + + +;*********************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * +;* Входные параметры передаются через * +;* глобальные перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет. * +;*********************************************** +SendPacketNoDatCommand: + pushad + mov [DevErrorCode],0 +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать ATA-команду передачи пакетной команды + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + mov [ATACylinder],0 + mov [ATAHead],0 + mov [ATACommand],0A0h + call SendCommandToHDD_1 + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@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 @@End_9 +; Ожидание подтверждения приема команды + 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 + jmp @@End_9 + +; Записать код ошибки +@@Err1_3: + mov [DevErrorCode],1 + jmp @@End_9 +@@Err6_1: + mov [DevErrorCode],6 +@@End_9: + popad + ret + +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска (0 или 1); * +;* ATAFeatures - "особенности"; * +;* ATASectorCount - количество секторов; * +;* ATASectorNumber - номер начального сектора; * +;* ATACylinder - номер начального цилиндра; * +;* ATAHead - номер начальной головки; * +;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * +;* ATACommand - код команды. * +;* После успешного выполнения функции: * +;* в ATABasePortAddr - базовый адрес HDD; * +;* в DevErrorCode - ноль. * +;* При возникновении ошибки в DevErrorCode будет * +;* возвращен код ошибки. * +;**************************************************** +SendCommandToHDD_1: + pushad + mov [DevErrorCode],0 +; Проверить значение кода режима + 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 + cmp ecx,0 + je @@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 + jmp @@End_10 +; Записать код ошибки +@@Err1_4: + mov [DevErrorCode],1 + jmp @@End_10 +@@Err2_4: + mov [DevErrorCode],2 + jmp @@End_10 +@@Err3_4: + mov [DevErrorCode],3 + jmp @@End_10 +@@Err4_4: + mov [DevErrorCode],4 + jmp @@End_10 +@@Err5_4: + mov [DevErrorCode],5 +; Завершение работы программы +@@End_10: +; sti + popad + ret + +;************************************************* +;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* 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 + je .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 - номер диска на канале. * +;************************************************* +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 + +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 + +;************************************************* +;* Получить сообщение о событии или состоянии * +;* устройства * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* 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: +; Очистить буфер пакетной команды + mov [PacketCommand],dword 0 + mov [PacketCommand+4],dword 0 + mov [PacketCommand+8],dword 0 + ret diff --git a/kernel/branches/kolibri_pe/blkdev/cdrom.inc b/kernel/branches/kolibri_pe/blkdev/cdrom.inc new file mode 100644 index 000000000..d7a937066 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/blkdev/fdc.inc b/kernel/branches/kolibri_pe/blkdev/fdc.inc new file mode 100644 index 000000000..65f4af940 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/blkdev/flp_drv.inc b/kernel/branches/kolibri_pe/blkdev/flp_drv.inc new file mode 100644 index 000000000..d3911bebb --- /dev/null +++ b/kernel/branches/kolibri_pe/blkdev/flp_drv.inc @@ -0,0 +1,625 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + +;***************************************** +;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * +;***************************************** +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 + diff --git a/kernel/branches/kolibri_pe/blkdev/hd_drv.inc b/kernel/branches/kolibri_pe/blkdev/hd_drv.inc new file mode 100644 index 000000000..016f4a216 --- /dev/null +++ b/kernel/branches/kolibri_pe/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} diff --git a/kernel/branches/kolibri_pe/blkdev/ide_cache.inc b/kernel/branches/kolibri_pe/blkdev/ide_cache.inc new file mode 100644 index 000000000..453cbf6a2 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/blkdev/rd.inc b/kernel/branches/kolibri_pe/blkdev/rd.inc new file mode 100644 index 000000000..263503103 --- /dev/null +++ b/kernel/branches/kolibri_pe/blkdev/rd.inc @@ -0,0 +1,2262 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + 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 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} diff --git a/kernel/branches/kolibri_pe/blkdev/rdsave.inc b/kernel/branches/kolibri_pe/blkdev/rdsave.inc new file mode 100644 index 000000000..2e9396e41 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/boot/ETFONT.FNT b/kernel/branches/kolibri_pe/boot/ETFONT.FNT new file mode 100644 index 0000000000000000000000000000000000000000..ca248381dcd0871bce51f90323ec6a8069d84f62 GIT binary patch literal 4096 zcmZu!&5GMr6uzXOm2jpzwHcgE7g>q~98rV^LSLbqu0&GQEJT=g@Nkvk&jj&MM(l z`^)|QV!PifcCKhaWpZRQkCL(vqcq)aw^5WTKT0c1?l6WS5(#(Dw7nn$L_C`2&z|Kn zod+-8fB5kJLiyv-w~yxyXf7Jk9F#^dAo%3TNenu@xf1;5#hVwPU$)l^8Hl3GbemqP z{M*IV&92?uTrJ)*`(7{_PuuBu6x>ts6sn`j9Cl<5guC$HTwY$jen7;yth1!3>mmv3 zQUv%)DHDivh(67yU<|4M^aSb*B3)q{DwlP{S)0W@b#8Jo;brI(2KGkfq46q5es7N>CUO@h7y&Y9+xulAT zV3f?E3#9caYZ0$iCvcDkL15(#kJF-Q;qqAKw$d|t@4O_VE9UqlkqM{UM^W`Z|Y!&1SP+sDDS4kd_=0`8%wD zl2-hk;50u+go|_Cpl(+XGtY~i@Z0?P%lXUfd9L|VoMkt?`J1}VzZXoF*qqv<#mAHi zf6S|)+wa#fHJ`)iweW8;CU39)+_oquNcCUewwsR~=3EohcsV{&q5dgo1k< z635DS=wPSGvF}%@Y@aY>K2=ln{?8TNHjev^MP=q;>G!L<$}-9}7J=7L)>r_RzhhV` zAg=qHgvuJ5!1zh=bH+8&{DMCt@um#9g+qTaBmJ6REX|}}{~&N9YzGkXg2|AV1)%aG zj2V^>=RUPa@Un}0P3o;*vwu{CE*{~RehHX=wx!pzyjveUA1lD-AI0$|n=_c6N704M0HeLmbskxep}l1rp-uwGEM zJ|=yA>~c3)9}(UR35BcmC;2|E$%1qkGDq(8F}1}u&ro~oR}gAulWMhkMe@!~i>7HQ zBOe)xzf>R27K+Cm)MN3tqbp7^q&WZh+f+nk zH_#!*E0`3kV&ai=K*dV%*FOwDKmIZN{Qc|j!m?cJAy`CeZ6UY_N?bn@)azSF0Ayu8gf{~06xfxXGZ z`)l#3oZNcx>iEgQe6LUZi4OC7STCPH{u9)@n142Ob3peGNaY6Zy4iZQTCL@L?&!bO zszEK-Gztv^@k3-P=VQ6va7H{N8_fY zSlhFm#|hSC?z8a6IL=N z{d-|+LXXeBiJ?QHiHC+CzrqWx=gv1z-S`P;Z0hNxU3JH845LZnE5!ZKi`s)WZ-Z#l h_IRIstring + 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 + +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 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' + 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 +.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 + +; 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+22] + mov word [BPB_FATSz16], ax + mov ax, word [es:bx+17] + mov word [BPB_RootEntCnt], ax + mov ax, word [es:bx+11] + mov word [BPB_BytsPerSec], 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 +; count of clusters in FAT12 ((size_of_FAT*2)/3) + mov ax, word [BPB_FATSz16] + mov cx, word [BPB_BytsPerSec] + 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 + + +; GET SMAP + + xor ebx, ebx + mov es, bx + + mov edi, 0x9104 + mov ecx, 20 + mov edx, 0x534D4150 +@@: + mov [es:0x9100], ebx + mov eax, 0xe820 + int 0x15 + + jc .nosmap + cmp eax, 0x534D4150 + jne .nosmap + + test ebx, ebx + jz .nosmap + + add edi, ecx + jmp @B + +.nosmap: + +; 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 diff --git a/kernel/branches/kolibri_pe/boot/booteng.inc b/kernel/branches/kolibri_pe/boot/booteng.inc new file mode 100644 index 000000000..aa7fc2f3f --- /dev/null +++ b/kernel/branches/kolibri_pe/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 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 diff --git a/kernel/branches/kolibri_pe/boot/bootet.inc b/kernel/branches/kolibri_pe/boot/bootet.inc new file mode 100644 index 000000000..ea6d5f1a2 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 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 diff --git a/kernel/branches/kolibri_pe/boot/bootge.inc b/kernel/branches/kolibri_pe/boot/bootge.inc new file mode 100644 index 000000000..6867aa7df --- /dev/null +++ b/kernel/branches/kolibri_pe/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 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 diff --git a/kernel/branches/kolibri_pe/boot/bootru.inc b/kernel/branches/kolibri_pe/boot/bootru.inc new file mode 100644 index 000000000..619c780f8 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 "…б«Ё г ‚ б LCD-¬®­Ёв®а, ®вЄ«озЁвҐ VRR ў Їг­ЄвҐ [c] - ®­ ‚ ¬ ­Ґ ­г¦Ґ­.",0 +remark3 db "…б«Ё г ‚ б ­Ґ Јаг§Ёвбп бЁб⥬ , Ї®Їа®Ўг©вҐ ®вЄ«озЁвм Їг­Єв [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/branches/kolibri_pe/boot/bootstr.inc b/kernel/branches/kolibri_pe/boot/bootstr.inc new file mode 100644 index 000000000..bf71fb7a9 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/boot/bootvesa.inc b/kernel/branches/kolibri_pe/boot/bootvesa.inc new file mode 100644 index 000000000..a07732491 --- /dev/null +++ b/kernel/branches/kolibri_pe/boot/bootvesa.inc @@ -0,0 +1,743 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 +; 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 + + @@: + 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 + push word [preboot_graph] + pop word [cursor_pos] + 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 +.exit: 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 word[ds:_r1+21],' ' + mov word[ds:_r1+50],' ' + + mov word[ds:_r2+21],' ' + mov word[ds:_r2+45],' ' + + mov word[ds:_rs+21],' ' + mov word[ds:_rs+46],' ' +; 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 ; 㬥­миЁвм DX, + 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 + +;============================================================================= +;============================================================================= +;============================================================================= + diff --git a/kernel/branches/kolibri_pe/boot/et.inc b/kernel/branches/kolibri_pe/boot/et.inc new file mode 100644 index 000000000..83fc44f2b --- /dev/null +++ b/kernel/branches/kolibri_pe/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" + diff --git a/kernel/branches/kolibri_pe/boot/preboot.inc b/kernel/branches/kolibri_pe/boot/preboot.inc new file mode 100644 index 000000000..7ac41a2b0 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 2 ; 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 2 ; 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 diff --git a/kernel/branches/kolibri_pe/boot/rdload.inc b/kernel/branches/kolibri_pe/boot/rdload.inc new file mode 100644 index 000000000..b9c9c9656 --- /dev/null +++ b/kernel/branches/kolibri_pe/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: diff --git a/kernel/branches/kolibri_pe/boot/ru.inc b/kernel/branches/kolibri_pe/boot/ru.inc new file mode 100644 index 000000000..aa59d6f6a --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/boot/shutdown.inc b/kernel/branches/kolibri_pe/boot/shutdown.inc new file mode 100644 index 000000000..3e3679caf --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + + diff --git a/kernel/branches/kolibri_pe/bootloader/boot_fat12.asm b/kernel/branches/kolibri_pe/bootloader/boot_fat12.asm new file mode 100644 index 000000000..1c01e8e97 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + ; + 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: + ; + mov ax,'KL' + push 0 + pop ds + mov si,loader_block+boot_program + ; + 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 ? + +; +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 diff --git a/kernel/branches/kolibri_pe/bootloader/floppy1440.inc b/kernel/branches/kolibri_pe/bootloader/floppy1440.inc new file mode 100644 index 000000000..678e2d35f --- /dev/null +++ b/kernel/branches/kolibri_pe/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) diff --git a/kernel/branches/kolibri_pe/bootloader/floppy1680.inc b/kernel/branches/kolibri_pe/bootloader/floppy1680.inc new file mode 100644 index 000000000..ef754de8d --- /dev/null +++ b/kernel/branches/kolibri_pe/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) diff --git a/kernel/branches/kolibri_pe/bootloader/floppy1743.inc b/kernel/branches/kolibri_pe/bootloader/floppy1743.inc new file mode 100644 index 000000000..bd777301f --- /dev/null +++ b/kernel/branches/kolibri_pe/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) diff --git a/kernel/branches/kolibri_pe/bootloader/floppy2880.inc b/kernel/branches/kolibri_pe/bootloader/floppy2880.inc new file mode 100644 index 000000000..8a52c059c --- /dev/null +++ b/kernel/branches/kolibri_pe/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) diff --git a/kernel/branches/kolibri_pe/bootloader/readme b/kernel/branches/kolibri_pe/bootloader/readme new file mode 100644 index 000000000..bbcc50f2e --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/build.bat b/kernel/branches/kolibri_pe/build.bat new file mode 100644 index 000000000..becb36ebb --- /dev/null +++ b/kernel/branches/kolibri_pe/build.bat @@ -0,0 +1,105 @@ +@echo off + +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 +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 diff --git a/kernel/branches/kolibri_pe/bus/pci/pci16.inc b/kernel/branches/kolibri_pe/bus/pci/pci16.inc new file mode 100644 index 000000000..211fabf2f --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/bus/pci/pci32.inc b/kernel/branches/kolibri_pe/bus/pci/pci32.inc new file mode 100644 index 000000000..e9752b2d1 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/const.inc b/kernel/branches/kolibri_pe/const.inc new file mode 100644 index 000000000..61c886543 --- /dev/null +++ b/kernel/branches/kolibri_pe/const.inc @@ -0,0 +1,654 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 0xE0000000 + +window_data equ OS_BASE + +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) +WinMapAddress equ (OS_BASE+0x033C000) +display_data equ (OS_BASE+0x033C000) ;1024*1280=0x140000 + +virtual at (OS_BASE+0x047CF80) + tss TSS +end virtual + +sys_pgmap equ (OS_BASE+0x047F000) + +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 0x3000 ;(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 + +;;;;;;;;;;;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 ? +} +virtual at 0 + CURSOR CURSOR +end virtual + +CURSOR_SIZE equ 32 + +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 +} +EVENT_SIZE equ 52 + +virtual at 0 + EVENT EVENT +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 ;main service handler +} + +SRV_FD_OFFSET equ 0x18 +SRV_SIZE equ 44 + +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 + diff --git a/kernel/branches/kolibri_pe/core/conf_lib.inc b/kernel/branches/kolibri_pe/core/conf_lib.inc new file mode 100644 index 000000000..d2342a1c9 --- /dev/null +++ b/kernel/branches/kolibri_pe/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$ + + +conf_path_sect: db 'path',0 + +conf_fname db '/sys/sys.conf',0 + +; 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 + +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 + +;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 + +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 + +; 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 diff --git a/kernel/branches/kolibri_pe/core/debug.inc b/kernel/branches/kolibri_pe/core/debug.inc new file mode 100644 index 000000000..f0aa56981 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/debug.inc @@ -0,0 +1,475 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + btr dword [eax+10h], ecx ; clear L 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 flag + add ecx, ecx + mov [eax+ecx], edx ; set DR + 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 + +debug_exc: + test byte [esp+8+2], 2 + jnz v86_debug_exc +; int 1 = #DB + save_ring3_context + cld + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov eax, dr6 + push eax + xor eax, eax + mov dr6, eax +; test if debugging + cli + mov eax, [current_slot] + mov eax, [eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + add esp, 0x20+4 + mov [error_interrupt], 1 + call show_error_parameters + mov edx, [TASK_BASE] + mov byte [edx+TASKDATA.state], 4 + jmp change_task +.debug: +; we are debugged process, notify debugger and suspend ourself +; eax=debugger PID + pop edx + mov ebx, dr7 + mov cl, not 1 +.l1: + test bl, 1 + jnz @f + and dl, cl +@@: + shr ebx, 2 + add cl, cl + inc ecx + cmp cl, not 10h + jnz .l1 + push edx ; DR6 image + mov ecx, [TASK_BASE] + push dword [ecx+TASKDATA.pid] ; PID + push 12 + pop ecx + push 3 ; 3 = debug exception + call debugger_notify + pop ecx + pop ecx + pop ecx + mov edx, [TASK_BASE] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task + restore_ring3_context + iretd diff --git a/kernel/branches/kolibri_pe/core/dll.inc b/kernel/branches/kolibri_pe/core/dll.inc new file mode 100644 index 000000000..d54157fc6 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/dll.inc @@ -0,0 +1,1210 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. 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 + + 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] + mov eax, 1 + ret +.err: + 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_SIZE + 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_SIZE + 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_SIZE + call malloc ;call alloc_service + test eax, eax + jz .fail + + push esi + push edi + mov edi, eax + mov esi, [name] + mov ecx, 16/4 + rep movsd + pop edi + pop esi + + mov [eax+SRV.magic], ' SRV' + mov [eax+SRV.size], SRV_SIZE + + 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 ebx, [pSym] + mov eax, [ebx+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 + stdcall unpack, [file], eax + 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], 16 + 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, 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, coff:dword, sec:dword, sym:dword + locals + n_sec dd ? + endl + + mov eax, [coff] + movzx ebx, [eax+CFH.nSections] + mov [n_sec], ebx +.fix_sec: + mov esi, [sec] + mov edi, [esi+CFS.PtrReloc] + add edi, [coff] + + movzx ecx, [esi+CFS.NumReloc] + test ecx, ecx + jz .next +.next_reloc: + 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], edx + add edi, 10 + dec ecx + jnz .next_reloc +.next: + add [sec], 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/.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] + 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] + add ebx, 20 + stdcall fix_coff_relocs, [coff], ebx, [sym] + + mov ebx, [coff] + 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] + 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 + +align 4 +proc load_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 + + call init_heap + stdcall user_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 + ; add edi, new_app_base + mov ecx, [eax+CFS.SizeOfRawData] + cld + rep movsb +.next: + add edi, 15 ;-new_app_base + and edi, -16 + 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, new_app_base + 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 + +align 4 +proc stop_all_services + + 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_SIZE + jne .next + + mov ebx, [edx+SRV.entry] + mov edx, [edx+SRV.fd] + test ebx, ebx + jz .next + + push edx + stdcall ebx, dword -1 + pop edx + jmp .next +.done: + ret +endp + +; 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 + + + + diff --git a/kernel/branches/kolibri_pe/core/export.inc b/kernel/branches/kolibri_pe/core/export.inc new file mode 100644 index 000000000..edb5c373b --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + } diff --git a/kernel/branches/kolibri_pe/core/exports.inc b/kernel/branches/kolibri_pe/core/exports.inc new file mode 100644 index 000000000..61812fc16 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/exports.inc @@ -0,0 +1,163 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + szSelectHwCursor db 'SelectHwCursor',0 + szSetHwCursor db 'SetHwCursor',0 + szHwCursorRestore db 'HwCursorRestore', 0 + szHwCursorCreate db 'HwCursorCreate', 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 + dd szRaiseEvent , raise_event + dd szWaitEvent , wait_event + dd szDestroyEvent , destroy_event + dd szClearEvent , clear_event + + dd szLoadCursor , load_cursor ;stdcall + + dd szSelectHwCursor , select_hw_cursor ;import stdcall + dd szSetHwCursor , set_hw_cursor ;import stdcall + dd szHwCursorRestore , hw_restore ;import + dd szHwCursorCreate , create_cursor ;import + + 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 + 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 + diff --git a/kernel/branches/kolibri_pe/core/ext_lib.inc b/kernel/branches/kolibri_pe/core/ext_lib.inc new file mode 100644 index 000000000..673bd5c6a --- /dev/null +++ b/kernel/branches/kolibri_pe/core/ext_lib.inc @@ -0,0 +1,317 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;============================================================================ +; +; External kernel dependencies (libraries) loading +; +;============================================================================ + +$Revision$ + + +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 diff --git a/kernel/branches/kolibri_pe/core/fpu.inc b/kernel/branches/kolibri_pe/core/fpu.inc new file mode 100644 index 000000000..15d901a10 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/fpu.inc @@ -0,0 +1,288 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 +e7: ;#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 + +reg_eip equ ebp+4 +reg_cs equ ebp+8 +reg_eflags equ ebp+12 +reg_esp equ ebp+16 +reg_ss equ ebp+20 + +align 4 +except_16: ;fpu native exceptions handler + test byte [esp+8+2], 2 + jnz v86_except_16 + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [CURRENT_TASK] + shl ebx, 8 + + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [edx], ecx + mov [reg_esp], edx + mov dword [reg_eip], eax + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + +.default: + pop edx + pop ecx + pop ebx + pop eax + leave + + save_ring3_context ;debugger support + + mov bl, 16 + jmp exc_c + +align 4 +except_19: ;sse exceptions handler + test byte [esp+8+2], 2 + jnz v86_except_19 + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [current_slot] + + mov eax, [ebx+APPDATA.sse_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [edx], ecx + mov [reg_esp], edx + mov dword [reg_eip], eax + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + +.default: + pop edx + pop ecx + pop ebx + pop eax + leave + + save_ring3_context ;debugger support + + mov bl, 19 + jmp exc_c + +restore reg_eip +restore reg_cs +restore reg_eflags +restore reg_esp +restore reg_ss + + diff --git a/kernel/branches/kolibri_pe/core/heap.inc b/kernel/branches/kolibri_pe/core/heap.inc new file mode 100644 index 000000000..9e28032db --- /dev/null +++ b/kernel/branches/kolibri_pe/core/heap.inc @@ -0,0 +1,1300 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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/4 + 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, [MEM_AMOUNT] + sub ecx, (HEAP_BASE - OS_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], 4095 + 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 +; param +; eax= required size +; +; retval +; edi= memory block descriptor +; ebx= descriptor index +align 4 +get_large_block: + mov edx, -1 + mov ecx, eax + shr ecx, 22 + dec ecx + cmp ecx, 31 + jle .get_index + mov ecx, 31 +.get_index: + shl edx, cl + and edx, [large_block_mask] +.find: + bsf edi, edx + mov ebx, edi + mov edi, [large_block_list+edi*4] +.check_size: + cmp eax, [edi+block_size] + ja .next + ret +.next: + mov edi, [edi+list_fd] + test edi, edi + jnz .check_size +.fail: + 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 + + +align 4 +proc alloc_large stdcall, size:dword + local block_ind:DWORD + + push ebx + push esi + push edi + + mov eax, [size] + add eax, 0x3FFFFF + and eax, not 0x3FFFFF + mov [size], eax + + ; mov ebx, heap_mutex + ; call wait_mutex ;ebx + + ; cmp eax, [heap_free] + ; ja .error + + call get_large_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 + test 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, 22 + dec eax + cmp eax, 31 + jna @f + mov eax, 31 +@@: + cmp eax, [block_ind] + je .m_eq_ind + + remove_from_list edi + + mov ecx, [block_ind] + mov [large_block_list+ecx*4], edx + + test edx, edx + jnz @f + btr [large_block_mask], ecx +@@: + mov edx, [large_block_list+eax*4] + mov [edi+list_fd], edx + test edx, edx + jz @f + mov [edx+list_bk], edi +@@: + mov [large_block_list+eax*4], edi + bts [large_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 [large_block_list+ebx*4], edx + and edx, edx + jnz @f + btr [large_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 + +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_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 + 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 diff --git a/kernel/branches/kolibri_pe/core/malloc.inc b/kernel/branches/kolibri_pe/core/malloc.inc new file mode 100644 index 000000000..0b9bfd3b8 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/malloc.inc @@ -0,0 +1,1003 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 +; +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 + ret +.small: + +; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) + + cmp [mst.treemap], 0 + je .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 + +align 4 +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 + +align 4 +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 + +align 4 + +; param +; esi= chunk +; ebx= size + +align 4 +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<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 + +align 4 +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 + +align 4 +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 + +align 4 +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<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 + +align 4 +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 + + + + diff --git a/kernel/branches/kolibri_pe/core/memory.inc b/kernel/branches/kolibri_pe/core/memory.inc new file mode 100644 index 000000000..24987b1ad --- /dev/null +++ b/kernel/branches/kolibri_pe/core/memory.inc @@ -0,0 +1,1303 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 kernel_alloc, 0x280000 + mov [LFBAddress], eax + 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, 0x00800000 + 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 + + 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: + 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 +proc page_fault_handler + + test byte [esp+12+2], 2 + jnz v86_page_fault + + .err_code equ ebp+32 + .err_addr equ ebp-4 + + pushad + mov ebp, esp + mov eax, cr2 + push eax + + mov ax, app_data + mov ds, ax + mov es, ax + + inc [pg_data.pages_faults] + +; xchg bx,bx +; jmp .exit + + mov ebx, [.err_addr] + mov eax, [.err_code] + + cmp ebx, OS_BASE + jb .user_space ;страница в памяти приложения ; + + cmp ebx, page_tabs + jb .kernel_space ;страница в памяти ядра + + cmp ebx, kernel_tabs + jb .alloc;.app_tabs ;таблицы страниц приложения ; + ;просто создадим одну + + cmp ebx, LFB_BASE + jb .core_tabs ;таблицы страниц ядра + ;Ошибка +.lfb: + ;область LFB + ;Ошибка + jmp .fail + +align 4 +.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,[ebp-4],eax,dword PG_UW + + mov edi, [ebp-4] + and edi, 0xFFFFF000 + mov ecx, 1024 + xor eax, eax + cld + rep stosd +.exit: + mov esp, ebp + popad + add esp, 4 + iretd + +.err_access: +;никогда не происходит + jmp .fail + +.kernel_space: + test eax, PG_MAP + jz .fail ;страница не присутствует + + test eax, 4 ;U/S + 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,[ebp-4],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 + rep movsd + jmp .exit + + +;не обрабатываем. Ошибка + +.core_tabs: +.fail: + mov esp, ebp + popad + add esp, 4 + +; iretd + + save_ring3_context ;debugger support + + mov bl, 14 + jmp exc_c + iretd +endp + +align 4 +proc map_mem stdcall, lin_addr:dword,pdir:dword,\ + ofs:dword,buf_size:dword + mov eax, [buf_size] + test eax, eax + jz .exit + + mov eax, [pdir] + 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: mov eax, [esi+edx*4] + and eax, 0xFFFFF000 + jz .exit + stdcall map_page,edi,eax,PG_UW + 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: + ret +endp + +align 4 +proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ + ofs:dword,buf_size:dword + mov eax, [buf_size] + test eax, eax + jz .exit + + mov eax, [pdir] + and eax, 0xFFFFF000 + + stdcall map_page,[proc_mem_pdir],eax,dword 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,dword 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: mov eax, [esi+edx*4] +; and eax, 0xFFFFF000 +; test eax, eax +; jz .exit + stdcall map_page,edi,eax,dword PG_UW + add edi, 0x1000 + inc edx + dec ecx + jnz .map +.exit: + 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 eax esi edi + add esi,0x1000 + stdcall alloc_kernel_space,esi + mov ecx, eax + pop edi esi eax +@@: + mov [used_buf], ecx + stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\ + edi, esi + + 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 ebx, new_app_base + cmp ebx, OS_BASE + jae .fail + + mov eax, [pg_data.pages_count] + mov [ebx], eax + shl eax, 12 + mov [esp+36], eax + mov ecx, [pg_data.pages_free] + mov [ebx+4], ecx + mov edx, [pg_data.pages_faults] + mov [ebx+8], edx + mov esi, [heap_size] + mov [ebx+12], esi + mov edi, [heap_free] + mov [ebx+16], edi + mov eax, [heap_blocks] + mov [ebx+20], eax + mov ecx, [free_blocks] + mov [ebx+24], ecx + ret +.fail: + mov dword [esp+36], -1 + ret + +align 4 +new_services: + + cmp eax,4 + jle sys_sheduler + + cmp eax, 11 + jb .fail + ja @f + + call init_heap + mov [esp+36], eax + ret +@@: + cmp eax, 12 + ja @f + + stdcall user_alloc, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 13 + ja @f + stdcall user_free, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 14 + ja @f + cmp ebx, OS_BASE + jae .fail + stdcall get_event_ex, ebx, ecx + mov [esp+36], eax + ret +@@: + cmp eax, 15 + ja @f + mov ecx, [current_slot] + mov eax, [ecx+APPDATA.fpu_handler] + mov [ecx+APPDATA.fpu_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 16 + ja @f + + test ebx, ebx + jz .fail + cmp ebx, OS_BASE + jae .fail + stdcall get_service, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 17 + ja @f + call srv_handlerEx ;ebx + mov [esp+36], eax + ret +@@: + cmp eax, 18 + ja @f + mov ecx, [current_slot] + mov eax, [ecx+APPDATA.sse_handler] + mov [ecx+APPDATA.sse_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 19 + ja @f + cmp ebx, OS_BASE + jae .fail + stdcall load_library, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 20 + ja @F + mov eax, ecx + call user_realloc + mov [esp+36], eax + ret +@@: + cmp eax, 21 ;for test purposes only + ja @f ;will be removed soon + cmp ebx, OS_BASE + jae .fail + + stdcall load_PE, ebx + + test eax, eax + jz @F + + mov esi, eax + stdcall eax, DRV_ENTRY + + test eax, eax + jz @F + + mov [eax+SRV.entry], esi + +@@: + mov [esp+36], eax + 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 ; + push eax + + xor edx, edx + xor eax, eax + mov ecx, 0x2FF + wrmsr ;disable all MTRR + + mov eax, [MEM_AMOUNT] +; round eax up to next power of 2 + dec eax + bsr ecx, eax + mov eax, 2 + shl eax, cl + stdcall set_mtrr, edx,edx,eax,MEM_WB + stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC + xor edx, edx + xor eax, eax + mov ecx, 0x204 + mov ebx, 6 +@@: + wrmsr ;disable unused MTRR + inc ecx + wrmsr + inc ecx + dec ebx + jnz @b + + wbinvd ;again invalidate + + pop eax + or eax, 0x800 ;set default memtype to UC + and al, 0xF0 + mov ecx, 0x2FF + wrmsr ;and enable MTRR + + mov eax, cr0 + and eax, not 0x60000000 + mov cr0, eax ; enable caching +.exit: + ret +endp + +align 4 +proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword + + xor edx, edx + mov eax, [base] + or eax, [mem_type] + mov ecx, [reg] + lea ecx, [0x200+ecx*2] + 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 + 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 + + diff --git a/kernel/branches/kolibri_pe/core/peload.inc b/kernel/branches/kolibri_pe/core/peload.inc new file mode 100644 index 000000000..5d1a32c22 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/peload.inc @@ -0,0 +1,316 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + 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 +\ + select_hw_cursor, 'SelectHwCursor', \ ; stdcall + set_hw_cursor, 'SetHwCursor', \ ; stdcall + hw_restore, 'HwCursorRestore', \ ; + create_cursor, 'HwCursorCreate', \ ; +\ + 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 +\ + reg_service, 'RegService', \ ; stdcall + user_alloc, 'UserAlloc', \ ; stdcall + user_free, 'UserFree', \ ; stdcall + unmap_pages, 'UnmapPages', \ ; eax, ecx + sys_msg_board_str, 'SysMsgBoardStr' + + + diff --git a/kernel/branches/kolibri_pe/core/sched.inc b/kernel/branches/kolibri_pe/core/sched.inc new file mode 100644 index 000000000..eafda6b84 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/sched.inc @@ -0,0 +1,380 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ax, app_data ; + mov ds, ax + mov es, ax + + inc dword [timer_ticks] + + mov eax, [timer_ticks] + call playNote ; <<<--- Speaker driver + + cmp eax,[next_usage_update] + jb .nocounter + add eax,100 + mov [next_usage_update],eax + call updatecputimes +.nocounter: + cmp [DONT_SWITCH], byte 1 + jne .change_task + + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + mov [DONT_SWITCH], byte 0 + + popad + iretd + +.change_task: + call update_counters + + call find_next_task + mov ecx, eax + + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + test ecx, ecx ; if there is only one running process + jnz .return + + call do_change_task + +.return: + popad + ; popfd + iretd + + +align 4 +change_task: + + pushfd + cli + pushad + + call update_counters + +if 0 + +; \begin{Mario79} + 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 + test eax, eax ; the same task -> skip switch + jnz .return +@@: + mov [DONT_SWITCH],byte 1 + call do_change_task + +.return: + popad + popfd + ret + + +uglobal + align 4 + far_jump: + .offs dd ? + .sel dw ? + context_counter dd ? ;noname & halyavin + next_usage_update dd ? + timer_ticks dd ? + prev_slot dd ? + event_sched dd ? +endg + + +update_counters: + mov edi, [TASK_BASE] + mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add + rdtsc + sub eax, ebx + add eax, [edi+TASKDATA.counter_sum] ; counter sum + mov [edi+TASKDATA.counter_sum], eax +ret + + +; Find next task to execute +; result: ebx = number of the selected task +; eax = 1 if the task is the same +; edi = address of the data for the task in ebx +; [0x3000] = ebx and [0x3010] = edi +; corrupts other regs +find_next_task: + mov ebx, [CURRENT_TASK] + mov edi, [TASK_BASE] + mov [prev_slot], ebx + +.waiting_for_termination: +.waiting_for_reuse: +.waiting_for_event: +.suspended: + cmp ebx, [TASK_COUNT] + jb @f + mov edi, CURRENT_TASK + xor ebx, ebx +@@: + + add edi,0x20 + inc ebx + + mov al, byte [edi+TASKDATA.state] + test al, al + jz .found + cmp al, 1 + jz .suspended + cmp al, 2 + jz .suspended + cmp al, 3 + je .waiting_for_termination + cmp al, 4 + je .waiting_for_termination + cmp al, 9 + je .waiting_for_reuse + + mov [CURRENT_TASK],ebx + mov [TASK_BASE],edi + + cmp al, 5 + jne .noevents + call get_event_for_app + test eax, eax + jnz @f + mov eax, ebx + shl eax, 8 + mov eax, [SLOT_BASE + APPDATA.wait_timeout + eax] + cmp eax, [timer_ticks] + jae .waiting_for_event + xor eax, eax +@@: + mov [event_sched], eax + mov [edi+TASKDATA.state], byte 0 +.noevents: +.found: + mov [CURRENT_TASK],ebx + mov [TASK_BASE],edi + rdtsc ;call _rdtsc + mov [edi+TASKDATA.counter_add],eax + + mov esi, [prev_slot] + xor eax, eax + cmp ebx, esi + sete al +ret + +; param +; ebx = incoming task +; esi = outcomig task + +do_change_task: + + shl ebx, 8 + add ebx, SLOT_BASE + mov [current_slot], ebx + + shl esi, 8 + add esi, SLOT_BASE + + mov [esi+APPDATA.saved_esp], esp + mov esp, [ebx+APPDATA.saved_esp] + +; set thread io map + + mov ecx, [ebx+APPDATA.io_map] + mov edx, [ebx+APPDATA.io_map+4] + mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx + mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx + + mov eax, [ebx+APPDATA.dir_table] + cmp eax, [esi+APPDATA.dir_table] + je @F + mov cr3, eax +@@: + mov eax, [ebx+APPDATA.saved_esp0] + mov [tss._esp0], eax + mov ax, graph_data + mov gs, ax + + mov eax, [CURRENT_TASK] + cmp eax, [fpu_owner] + clts ;clear a task switch flag + je @F + ;and set it again if the owner + mov ecx, cr0 ;of a fpu has changed + or ecx, CR0_TS + mov cr0, ecx +@@: + inc [context_counter] ;noname & halyavin + test [ebx+APPDATA.dbg_state], 1 + jnz @F + ret +@@: + mov eax, [ebx+APPDATA.dbg_regs.dr0] + mov dr0, eax + mov eax, [ebx+APPDATA.dbg_regs.dr1] + mov dr1, eax + mov eax, [ebx+APPDATA.dbg_regs.dr2] + mov dr2, eax + mov eax, [ebx+APPDATA.dbg_regs.dr3] + mov dr3, eax + xor eax, eax + mov dr6, eax + mov eax, [ebx+APPDATA.dbg_regs.dr7] + mov dr7, eax + ret + +align 4 +updatecputimes: + + mov eax,[idleuse] + mov [idleusesec],eax + mov [idleuse],dword 0 + mov ecx, [TASK_COUNT] + mov edi, TASK_DATA +.newupdate: + mov ebx,[edi+TASKDATA.counter_sum] + mov [edi+TASKDATA.cpu_usage],ebx + mov [edi+TASKDATA.counter_sum],dword 0 + add edi,0x20 + dec ecx + jnz .newupdate + + ret + +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 + +rdy_head rd 16 + + +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 + diff --git a/kernel/branches/kolibri_pe/core/string.inc b/kernel/branches/kolibri_pe/core/string.inc new file mode 100644 index 000000000..fc6e35473 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + + diff --git a/kernel/branches/kolibri_pe/core/sync.inc b/kernel/branches/kolibri_pe/core/sync.inc new file mode 100644 index 000000000..03873ade1 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/core/sys32.inc b/kernel/branches/kolibri_pe/core/sys32.inc new file mode 100644 index 000000000..41a3df6d4 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/sys32.inc @@ -0,0 +1,787 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 +idtreg: + dw 8*0x41-1 + dd idts+8 + +build_interrupt_table: + + mov edi, idts+8 + mov esi, sys_int + mov ecx, 0x40 + @@: + lodsd + mov [edi], ax ; lower part of offset + mov [edi+2], word os_code ; segment selector + mov ax, word 10001110b shl 8 ; type: interrupt gate + mov [edi+4], eax + add edi, 8 + loop @b + + ;mov edi,8*0x40+idts+8 + mov dword [edi], (i40 and 0xFFFF) or (os_code shl 16) + mov dword [edi+4], (11101111b shl 8) or (i40 and 0xFFFF0000) + ; type: trap gate + ret + +iglobal + + msg_sel_ker db "kernel", 0 + msg_sel_app db "application", 0 + + sys_int: + dd e0,debug_exc,e2,e3 + dd e4,e5,e6,e7 + dd e8,e9,e10,e11 + dd e12,e13,page_fault_handler,e15 + + dd except_16, e17,e18, except_19 + times 12 dd unknown_interrupt + + 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 + + dd i40 +endg + +macro save_ring3_context +{ + pushad +} +macro restore_ring3_context +{ + popad +} + +; simply return control to interrupted process +unknown_interrupt: + iret + +macro exc_wo_code [num] +{ + forward + e#num : + save_ring3_context + mov bl, num + jmp exc_c +} + +macro exc_w_code [num] +{ + forward + e#num : + add esp, 4 + save_ring3_context + mov bl, num + jmp exc_c +} + +exc_wo_code 0, 2, 3, 4, 5, 6, 9, 15, 18 +exc_w_code 8, 10, 11, 12, 13, 14, 17 + +exc_c: + mov ax, app_data ;исключение + mov ds, ax ;загрузим правильные значени + mov es, ax ;в регистры + +; redirect to V86 manager? (EFLAGS & 0x20000) != 0? + test byte [esp+20h+8+2], 2 + jnz v86_exc_c + +; test if debugging + cli + mov eax, [current_slot] + mov eax, [eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + movzx eax, bl + mov [error_interrupt], eax + call show_error_parameters + add esp, 0x20 + mov edx, [TASK_BASE] + mov [edx + TASKDATA.state], byte 4 + + jmp change_task + +.debug: +; we are debugged process, notify debugger and suspend ourself +; eax=debugger PID + cld + movzx ecx, bl + push ecx + mov ecx, [TASK_BASE] + push dword [ecx+TASKDATA.pid] ; PID of current process + push 12 + pop ecx + push 1 ; 1=exception + call debugger_notify + pop ecx + pop ecx + pop ecx + mov edx, [TASK_BASE] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task + restore_ring3_context + iretd + +iglobal + hexletters db '0123456789ABCDEF' + error_interrupt dd -1 +endg + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +show_error_parameters: + mov eax,[CURRENT_TASK] + shl eax, 5 + DEBUGF 1, "K : Process - forced terminate PID: %x\n", [CURRENT_TASK + TASKDATA.pid + eax] + DEBUGF 1, "K : Exception : %x Error : xxxxxxxx\n", [error_interrupt] + DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [esp + 0x20], [esp - 12 + 0x20], [esp - 4 + 0x20] + DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [esp - 8 + 0x20], [esp - 24 + 0x20], [esp - 28 + 0x20] + DEBUGF 1, "K : EBP : %x EIP : %x ", [esp - 20 + 0x20], [esp + 4 + 0x20] + + mov eax, [esp + 8 + 0x20] + mov edi, msg_sel_app + mov ebx, [esp + 16 + 0x20] + cmp eax, app_code + je @f + mov edi, msg_sel_ker + mov ebx, [esp - 16 + 0x20] +@@: + DEBUGF 1, "ESP : %x\nK : Flags : %x CS : %x (%s)\n", ebx, [esp + 12 + 0x20], eax, edi + ret +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +; irq1 -> hid/keyboard.inc +macro irqh [num] +{ + forward + p_irq#num : + mov edi, num + jmp irqhandler +} + +irqh 2,3,4,5,7,8,9,10,11 + + +p_irq6: + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + 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 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 byte [BOOT_VAR + 0x48E], 0xFF + call [irq15_func] + call ready_for_next_irq_1 + restore_ring3_context + iret + +ready_for_next_irq: + mov [check_idle_semaphore],5 + mov al, 0x20 + out 0x20, al + ret + +ready_for_next_irq_1: + mov [check_idle_semaphore],5 + mov al, 0x20 + out 0xa0,al + out 0x20, al + ret + +irqD: + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + + mov dx,0xf0 + mov al,0 + out dx,al + + mov dx,0xa0 + mov al,0x20 + out dx,al + mov dx,0x20 + out dx,al + + restore_ring3_context + + iret + + +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 + mov [application_table_status],0 + apptsl1: + + pop eax + + ret + +sys_resize_app_memory: + ; eax = 1 - resize + ; ebx = new amount of memory + + cmp eax,1 + jne .no_application_mem_resize + + stdcall new_mem_resize, ebx + mov [esp+36], eax + ret + +.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 + DEBUGF 1,"%s",process_terminating +@@: + 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 + mov eax,[SLOT_BASE+eax+APPDATA.dir_table] + stdcall destroy_app_space, eax + + 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, (tss._io_map_0-OS_BASE+PG_MAP) + je @F + call free_page +@@: + mov eax, [edi+APPDATA.io_map+4] + cmp eax, (tss._io_map_1-OS_BASE+PG_MAP) + 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 + mov [hd1_status], 0 +@@: + cmp [cd_status], esi + jnz @f + call free_cd_channel + mov [cd_status], 0 +@@: + cmp [flp_status], esi + jnz @f + mov [flp_status], 0 +@@: + pop esi + cmp [bgrlockpid], esi + jnz @f + and [bgrlockpid], 0 + mov [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] + + cmp esi,0 + je 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 + + mov [application_table_status],0 + ;mov esi,process_terminated + ;call sys_msg_board_str + DEBUGF 1,"%s",process_terminated + 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 diff --git a/kernel/branches/kolibri_pe/core/syscall.inc b/kernel/branches/kolibri_pe/core/syscall.inc new file mode 100644 index 000000000..2213e80a8 --- /dev/null +++ b/kernel/branches/kolibri_pe/core/syscall.inc @@ -0,0 +1,262 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + mov edi, [esp+28 + 4] + and edi,0xff + call dword [servetable+edi*4] + ret + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSTEM CALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +align 16 +i40: + pushad + cld + and eax, 0xff + call dword [servetable2 + eax * 4] + popad + iretd +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + + and eax, 0xff + 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 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + + and eax, 0xff + 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 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 0 + dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd 0 ; + dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. + dd 0 + dd 0 ; + dd 0 + dd sys_current_directory ; 30-Get/SetCurrentDirectory + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd readmousepos ; 37-GetMousePosition_ScreenRelative,. + dd 0 ; 38-DrawLine + dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. + dd 0 + dd 0 + dd 0 + dd sys_outport ; 43-SendDeviceData + dd 0 + dd 0 + dd syscall_reserveportarea ; 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 sys_resize_app_memory ; 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 new_services ; 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 + dd sys_sendwindowmsg ; 72-Send window message + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; 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 cross_order ; 20-ResetMidi and OutputMidi + dd cross_order ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. + dd cross_order ; 22-setting date,time,clock and alarm-clock + dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent + dd cross_order ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd undefined_syscall ; 25-reserved + dd cross_order ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. + dd undefined_syscall ; 27-reserved + dd undefined_syscall ; 28-reserved + dd sys_date ; 29-GetDate + dd cross_order ; 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 undefined_syscall ; 36-reserved + dd cross_order ; 37-GetMousePosition_ScreenRelative,. + dd syscall_drawline ; 38-DrawLine + dd cross_order ; 39-GetBackgroundSize,ReadBgrData,. + dd set_app_param ; 40-WantEvents + dd syscall_getirqowner ; 41-GetIrqOwner + dd get_irq_data ; 42-ReadIrqData + dd cross_order ; 43-SendDeviceData + dd sys_programirq ; 44-ProgramIrqs + dd reserve_free_irq ; 45-ReserveIrq and FreeIrq + dd cross_order ; 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 cross_order ; 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 cross_order ; 72-Send window message + times 255 - ( ($-servetable2) /4 ) dd undefined_syscall + dd sys_end ; -1-end application + +endg diff --git a/kernel/branches/kolibri_pe/core/taskman.inc b/kernel/branches/kolibri_pe/core/taskman.inc new file mode 100644 index 000000000..7be24451b --- /dev/null +++ b/kernel/branches/kolibri_pe/core/taskman.inc @@ -0,0 +1,1111 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + DEBUGF 1,"%s",new_process_loading + +.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 + 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 + +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' + 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, 1024-(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] +@@: + 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 + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + xor edx,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 + cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses + jnz @f + 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 + cmp edx,1 + jg .exit +;if there isn't threads then clear memory. + + mov eax, [pg_dir] + and eax, not 0xFFF + stdcall map_page,[tmp_task_pdir],eax,dword 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,dword 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],dword 0,dword PG_UNMAP + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + dec [pg_data.pg_mutex] + 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 eax, [slot] + shl eax,8 + mov ebx, [offset] + ; add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [SLOT_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov esi, [offset] + and esi, 0xfff + 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 + + 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 eax, [slot] + shl eax,8 + mov ebx, [offset] + ; add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [SLOT_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov edi, [offset] + and edi, 0xfff + 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 + + 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 + DEBUGF 1,"%s",new_process_loading +.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 + + 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 + DEBUGF 1,"%s",new_process_running + + 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: + push eax + push ebx +.do_wait: + cmp dword [ebx],0 + je .get_lock + call change_task + jmp .do_wait +.get_lock: + mov eax, 1 + xchg eax, [ebx] + test eax, eax + jnz .do_wait + pop ebx + pop eax + ret + +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.fpu_handler], 0 + mov [eax+SLOT_BASE+APPDATA.sse_handler], 0 + +;set default io permission map + mov [eax+SLOT_BASE+APPDATA.io_map],\ + (tss._io_map_0-OS_BASE+PG_MAP) + mov [eax+SLOT_BASE+APPDATA.io_map+4],\ + (tss._io_map_1-OS_BASE+PG_MAP) + + 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 + +; 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], dword irq0.return + 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 + DEBUGF 1,"%s",new_process_running + ret +endp + +include "debug.inc" diff --git a/kernel/branches/kolibri_pe/core/v86.inc b/kernel/branches/kolibri_pe/core/v86.inc new file mode 100644 index 000000000..4ea2cb52d --- /dev/null +++ b/kernel/branches/kolibri_pe/core/v86.inc @@ -0,0 +1,949 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + 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, 101b + 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). + +v86_debug_exc: + pushad + xor eax, eax + mov dr6, eax + mov bl, 1 + jmp v86_exc_c + +v86_page_fault: + add esp, 4 + pushad + mov bl, 14 + jmp v86_exc_c + +v86_except_16: + pushad + mov bl, 16 + jmp v86_exc_c +v86_except_19: + pushad + mov bl, 19 + +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: + mov ax, app_data + mov ds, ax + mov es, ax +; Did we all that we have wanted to do? + 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] + 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 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 + 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 + 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 + push ebx + call update_counters + pop ebx + sub ebx, SLOT_BASE + shr ebx, 8 + mov esi, [CURRENT_TASK] + call do_change_task + popad + iretd diff --git a/kernel/branches/kolibri_pe/data16.inc b/kernel/branches/kolibri_pe/data16.inc new file mode 100644 index 000000000..e6e2e1348 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/data32.inc b/kernel/branches/kolibri_pe/data32.inc new file mode 100644 index 000000000..541b19007 --- /dev/null +++ b/kernel/branches/kolibri_pe/data32.inc @@ -0,0 +1,462 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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?',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_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 + +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 +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 + ;supported videomodes +mode_1280_1024_32: + dw 1280,1024,32,60 +mode_1280_1024_24: + dw 1280,1024,24,60 +mode_1024_768_32: + dw 1024,768,32,60 +mode_1024_768_24: + dw 1024,768,24,60 +mode_800_600_32: + dw 800,600,32,60 +mode_800_600_24: + dw 800,600,24,60 +mode_640_480_32: + dw 640,480,32,60 +mode_640_480_24: + dw 640,480,24,60 +mode_640_480_16: + dw 640,480,16,60 +mode_320_240_8: + dw 320,240,8,60 + +; mike.dld { +db 0 +dd servetable-0x10000 +draw_line dd __sys_draw_line +disable_mouse dd __sys_disable_mouse +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+(new_app_base shr 16)+0xF; + +app_data_l: + dw 0xFFFF + dw 0 + db 0 + db drw3 + dw G32+D32+(new_app_base shr 16)+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 +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 +event_map rb 64 +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 +events rd 1 +event_start rd 1 +event_end rd 1 +event_uid rd 1 +sys_page_map rd 1 +os_stack_seg rd 1 + +srv.fd rd 1 +srv.bk rd 1 + +scr_width rd 1 +scr_height rd 1 + +create_cursor rd 1 +select_hw_cursor rd 1 +set_hw_cursor rd 1 +hw_restore rd 1 + +def_cursor rd 1 +current_cursor rd 1 +hw_cursor rd 1 +cur_def_interl rd 1 +cur_saved_base rd 1 +cur_saved_interl rd 1 +cur_saved_w rd 1 +cur_saved_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 +wraw_bacground_select rb 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 + diff --git a/kernel/branches/kolibri_pe/detect/biosdisk.inc b/kernel/branches/kolibri_pe/detect/biosdisk.inc new file mode 100644 index 000000000..5f3d19eb2 --- /dev/null +++ b/kernel/branches/kolibri_pe/detect/biosdisk.inc @@ -0,0 +1,76 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + mov ax, -1 +@@: + stosw + pop ds + jmp bddc2 +bddl: + mov al, dl + stosb + mov al, 0 + stosb + mov ax, -1 + stosw +bddc2: + cmp cl, [es:0x475] + jae bdde +bddc: + inc dl + jnz bdds +bdde: diff --git a/kernel/branches/kolibri_pe/detect/dev_fd.inc b/kernel/branches/kolibri_pe/detect/dev_fd.inc new file mode 100644 index 000000000..0bf633582 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + cmp cx,0 + jne wait_cmos + in al,0x71 + mov [DRIVE_DATA],al diff --git a/kernel/branches/kolibri_pe/detect/dev_hdcd.inc b/kernel/branches/kolibri_pe/detect/dev_hdcd.inc new file mode 100644 index 000000000..1a956950d --- /dev/null +++ b/kernel/branches/kolibri_pe/detect/dev_hdcd.inc @@ -0,0 +1,384 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 +SectorAddress DD ? + +;************************************************* +;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* 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 + je @@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 ;принять блок данных + jmp @@End +; Записать код ошибки +@@Error1: + mov [DevErrorCode],1 + jmp @@End +@@Error6: + mov [DevErrorCode],6 +@@End: ret + + + +; Стандартные базовые адреса каналов 1 и 2 +StandardATABases DW 1F0h, 170h +; Номер канала +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 DB ? + +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* 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 + je @@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 + jmp @@End_2 +; Записать код ошибки +@@Err1: mov [DevErrorCode],1 + jmp @@End_2 +@@Err2: mov [DevErrorCode],2 + jmp @@End_2 +@@Err3: mov [DevErrorCode],3 + jmp @@End_2 +@@Err4: mov [DevErrorCode],4 + jmp @@End_2 +@@Err5: mov [DevErrorCode],5 +; Завершение работы программы +@@End_2: + 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 + je @@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 + jmp @@End_1 +; Записать код ошибки +@@Error1_1: + mov [DevErrorCode],1 + jmp @@End_1 +@@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 + jmp @@End_3 +; Обработка ошибок +@@Err1_2: mov [DevErrorCode],1 + jmp @@End_3 +@@Err3_2: mov [DevErrorCode],3 + jmp @@End_3 +@@Err4_2: mov [DevErrorCode],4 +; Записать код ошибки +@@End_3: + ret + +EndFindHDD: + diff --git a/kernel/branches/kolibri_pe/detect/disks.inc b/kernel/branches/kolibri_pe/detect/disks.inc new file mode 100644 index 000000000..aba4571cf --- /dev/null +++ b/kernel/branches/kolibri_pe/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' + diff --git a/kernel/branches/kolibri_pe/detect/getcache.inc b/kernel/branches/kolibri_pe/detect/getcache.inc new file mode 100644 index 000000000..a9dc35d62 --- /dev/null +++ b/kernel/branches/kolibri_pe/detect/getcache.inc @@ -0,0 +1,201 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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: + cmp byte [BiosDisksData+ecx*4+2],-1 + jnz .contbd + mov eax,[cache_ide0_size] + mov [esi+cache_ide0_size-cache_ide0],eax + push ecx + mov cl,1 + call get_cache_ide + pop ecx +.contbd: + 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 \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/detect/sear_par.inc b/kernel/branches/kolibri_pe/detect/sear_par.inc new file mode 100644 index 000000000..970f58b34 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/docs/apm.txt b/kernel/branches/kolibri_pe/docs/apm.txt new file mode 100644 index 000000000..5b253195e --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/docs/loader_doc.txt b/kernel/branches/kolibri_pe/docs/loader_doc.txt new file mode 100644 index 000000000..d1e57e4a1 --- /dev/null +++ b/kernel/branches/kolibri_pe/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/ diff --git a/kernel/branches/kolibri_pe/docs/sysfuncr.txt b/kernel/branches/kolibri_pe/docs/sysfuncr.txt new file mode 100644 index 000000000..89f32591f --- /dev/null +++ b/kernel/branches/kolibri_pe/docs/sysfuncr.txt @@ -0,0 +1,4553 @@ +‘€‘’…ЊЌ›… ”“ЌЉ–€€ ЋЏ…ђЂ–€ЋЌЌЋ‰ ‘€‘’…Њ› Kolibri 0.7.1.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. + * ЏаЁ ⥪г饩 ॠ«Ё§ жЁЁ Їа®Ё§®©¤Ґв ­Ґ¬Ґ¤«Ґ­­л© ў®§ўа в Ё§ дг­ЄжЁЁ, + Ґб«Ё б«®¦Ґ­ЁҐ ebx б ⥪гйЁ¬ §­ зҐ­ЁҐ¬ бзҐвзЁЄ  ўаҐ¬Ґ­Ё ўл§®ўҐв + 32-ЎЁв­®Ґ ЇҐаҐЇ®«­Ґ­ЁҐ. + +====================================================================== +=============== ”г­ЄжЁп 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 - Ґб«Ё ЁбЇ®«м§®ў « бм «Ґў п Є­®ЇЄ  ¬лиЁ, Ё«Ё ЎЁв в®© Є­®ЇЄЁ ¬лиЁ, Є®в®а п ЁбЇ®«м§®ў « бм. +‡ ¬Ґз ­Ёп: + * "ЃгдҐа" еа ­Ёв в®«мЄ® ®¤­г Є­®ЇЄг, ЇаЁ ­ ¦ вЁЁ ­®ў®© Є­®ЇЄЁ + Ё­д®а¬ жЁп ® бв а®© вҐапҐвбп. + * ЏаЁ ўл§®ўҐ нв®© дг­ЄжЁЁ ЇаЁ«®¦Ґ­ЁҐ¬ б ­Ґ ЄвЁў­л¬ ®Є­®¬ + ў®§ўа й Ґвбп ®вўҐв "ЎгдҐа Їгбв". + +====================================================================== +==== ”г­ЄжЁп 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 +‡ ¬Ґз ­Ёп: + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ЇаЁ ­ҐўҐа­®¬ + ўл§®ўҐ, ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў Ї®б«Ґ¤гойЁе ўҐабЁпе п¤а . + * Њ®¦­® ЁбЇ®«м§®ў вм Ї®¤дг­ЄжЁо 1, зв®Ўл ­  Ї®б«Ґ¤­Ґ¬ и ЈҐ + § ўҐа襭Ёп а Ў®вл Ї®«м§®ў вҐ«м б ¬ аҐи «, зв® Ґ¬г ­г¦­®. +====================================================================== +======== ”г­ЄжЁп 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, Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм Ў §®ўл© Ї®ав Sound Blaster. = +====================================================================== +“¤ «Ґ­  + +====================================================================== +========= ”г­ЄжЁп 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, Ї®¤дг­ЄжЁп 10 - гбв ­®ўЁвм Є ­ « DMA ¤«п §ўгЄ . ==== +====================================================================== +“¤ «Ґ­ : + +====================================================================== +====================== ”г­ЄжЁп 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. + +====================================================================== +============== ”г­ЄжЁп 25 - гбв ­®ўЁвм Ја®¬Є®бвм SBPro. ============== +====================================================================== +“¤ «Ґ­  + +====================================================================== +===== ”г­ЄжЁп 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, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм Ў §®ўл© Ї®ав Sound Blaster. == +====================================================================== +“¤ «Ґ­  + +====================================================================== +========== ”г­ЄжЁп 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, Ї®¤дг­ЄжЁп 10 - Ї®«гзЁвм Є ­ « DMA ¤«п §ўгЄ . ===== +====================================================================== +“¤ «Ґ­  + +====================================================================== +====================== ”г­ЄжЁп 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. + +====================================================================== +=============== ”г­ЄжЁп 28 - гбв ­®ўЁвм Ја®¬Є®бвм SB16. ============== +====================================================================== +“¤ «Ґ­  + +====================================================================== +================ ”г­ЄжЁп 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 = ¤«Ё­  Ё¬Ґ­Ё ⥪г饩 Ї ЇЄЁ (ўЄ«оз п § ўҐаи ойЁ© 0) +‡ ¬Ґз ­Ёп: + * …б«Ё а §¬Ґа  ЎгдҐа  ­Ґ¤®бв в®з­® ¤«п Є®ЇЁа®ў ­Ёп ўбҐЈ® Ё¬Ґ­Ё, + Є®ЇЁаговбп в®«мЄ® ЇҐаўлҐ (edx-1) Ў ©в + Ё ў Є®­жҐ бв ўЁвбп § ўҐаи ойЁ© 0. + +====================================================================== +============ ”г­ЄжЁп 35 - Їа®зЁв вм 梥в в®зЄЁ ­  нЄа ­Ґ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 35 + * ebx = y*xsize+x, Ј¤Ґ + * (x,y) = Є®®а¤Ё­ вл в®зЄЁ (бзЁв п ®в 0) + * xsize = а §¬Ґа нЄа ­  Ї® Ј®аЁ§®­в «Ё +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 梥в 0x00RRGGBB +‡ ¬Ґз ­Ёп: + * “§­ вм а §¬Ґал нЄа ­  ¬®¦­® ўл§®ў®¬ дг­ЄжЁЁ 14. ЋЎа вЁвҐ ў­Ё¬ ­ЁҐ, + зв® ®­  ўлзЁв Ґв 1 Ё§ ®Ў®Ёе а §¬Ґа®ў. + * Љ ўЁ¤Ґ®Ї ¬пвЁ Ґбвм в Є¦Ґ Їаאַ© ¤®бвгЇ (ЎҐ§ ўл§®ў®ў бЁб⥬­ле + дг­ЄжЁ©) зҐаҐ§ ᥫҐЄв®а gs. Џ а ¬Ґвал ⥪г饣® ўЁ¤Ґ®аҐ¦Ё¬  + ¬®¦­® Ї®«гзЁвм дг­ЄжЁҐ© 61. + +====================================================================== +==================== ”г­ЄжЁп 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 (б¬. бЇЁб®Є б®ЎлвЁ©) + (гбв ­®ў«Ґ­­л© ЎЁв а §аҐи Ґв Ё§ўҐйҐ­ЁҐ ® б®ЎлвЁЁ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Њ бЄ  Ї® 㬮«з ­Ёо (7=111b) а §аҐи Ґв Ё§ўҐйҐ­Ёп ® ЇҐаҐаЁб®ўЄҐ + Ё ­ ¦ вЁпе Є« ўЁи Ё Є­®Ї®Є. + ќв®Ј® ¤®бв в®з­® ¤«п Ў®«миЁ­бвў  ЇаЁ«®¦Ґ­Ё©. + * ‘®ЎлвЁп, § ЇаҐйс­­лҐ ў ¬ бЄҐ, ўбс а ў­® б®еа ­повбп, Ґб«Ё + ЇаЁе®¤пв; ® ­Ёе Їа®бв® ­Ґ Ё§ўҐй ов дг­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё. + * ”г­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё гзЁвлў ов ¬ бЄг ­  ¬®¬Ґ­в + ўл§®ў  дг­ЄжЁЁ,   ­Ґ ­  ¬®¬Ґ­в Ї®бвгЇ«Ґ­Ёп б®®ЎйҐ­Ёп. + +====================================================================== +================= ”г­ЄжЁп 41 - г§­ вм ў« ¤Ґ«мж  IRQ. ================= +====================================================================== +Џ а ¬Ґвал: + * eax = 41 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = PID ў« ¤Ґ«мж  + * eax = 0, Ґб«Ё ў« ¤Ґ«мж  ­Ґв + * eax = -1 ¤«п ­ҐЄ®а४⭮Ј® ebx + +====================================================================== +========== ”г­ЄжЁп 42 - а Ў®в  б ¤ ­­л¬Ё, Ї®«г祭­л¬Ё Ї® IRQ. ======= +====================================================================== + +------------------------ —⥭ЁҐ ¤ ­­ле ------------------------------- +ЏаЁ ў®§­ЁЄ­®ўҐ­ЁЁ IRQ бЁб⥬  ¬®¦Ґв бзЁвлў вм ¤ ­­лҐ Ё§ гЄ § ­­ле +а ­ҐҐ дг­ЄжЁҐ© 44 Ї®ав®ў Ё § ЇЁблў вм нвЁ ¤ ­­лҐ ў ЎгдҐа. +ЋЇЁблў Ґ¬ п дг­ЄжЁп бзЁвлў Ґв ¤ ­­лҐ Ё§ нв®Ј® ЎгдҐа  ў ЎгдҐа +гЄ § ­­л© ў Є зҐб⢥ Ї а ¬Ґва . +Џ а ¬Ґвал: + * eax = 42 - ­®¬Ґа дг­ЄжЁЁ + * bl = ­®¬Ґа IRQ, 0..15 + * bh = ­®¬Ґа Ї®¤дг­ЄжЁЁ, 0 +Ћбв «м­ п з бвм ॣЁбва  ebx ¤®«¦­  Ўлвм ®Ў­г«Ґ­ . + * ecx = гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв ЇаЁ­Ё¬ вмбп ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: (бЁвг жЁо ¬®¦­® а §«ЁзЁвм Ї® §­ зҐ­Ёо eax) + * Ґб«Ё Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 IRQ + (Ё«Ё ­®¬Ґа IRQ § ¤ ­ ­ҐўҐа­®): + * eax = -1 + * Ґб«Ё ¤ ­­ле ­Ґв: + * eax = 0 + * Ґб«Ё ўбс ў Ї®ап¤ЄҐ Ё ¤ ­­лҐ Ўл«Ё: + * eax = а §¬Ґа ¤ ­­ле, Їа®зЁв ­­ле Ё§ ЎгдҐа  (ў Ў ©в е) + +‘¬®ваЁвҐ § ¬Ґз ­Ёп ­Ё¦Ґ. + +------------------------ “§­ вм а §¬Ґа ¤ ­­ле ў ЎгдҐаҐ --------------- +Џ а ¬Ґвал: + * eax = 42 - ­®¬Ґа дг­ЄжЁЁ + * bl = ­®¬Ґа IRQ, 0..15 + * bh = ­®¬Ґа Ї®¤дг­ЄжЁЁ, 1 +Ћбв «м­ п з бвм ॣЁбва  ebx ¤®«¦­  Ўлвм ®Ў­г«Ґ­ . +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: (бЁвг жЁо ¬®¦­® а §«ЁзЁвм Ї® §­ зҐ­Ёо eax) + * Ґб«Ё Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 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 = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * 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 = зЁб«® Ї®«г祭­ле Ў ©в + * 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 = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄ  ­  Їа ўЁ«м­®бвм ен­¤«  ¬Ё­Ё¬ «м­  - ЁбЄ«оз овбп в®«мЄ® + ­Ґ ®зҐ­м ­ҐЇа ўЁ«м­лҐ ­Ґ®вЄалвлҐ ен­¤«л. + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-28, е®вп + ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 5 - ®вЄалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * 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 = бв вгб б®ЄҐв : ®¤­® Ё§ + * 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 = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄ  ­  Їа ўЁ«м­®бвм ен­¤«  ¬Ё­Ё¬ «м­  - ЁбЄ«оз овбп в®«мЄ® + ­Ґ ®зҐ­м ­ҐЇа ўЁ«м­лҐ ­Ґ®вЄалвлҐ ен­¤«л. + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-40, + е®вп ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 8 - § Єалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ­ҐўҐа­л© ен­¤« + * eax = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ ¤«п Ї ЄҐв  § ЄалвЁп б®ЄҐв  + * eax = 0 - гбЇҐи­® + * ў® ¬­®ЈЁе б«гз пе eax а §аги Ґвбп (ў®§ўа й Ґвбп १г«мв в дг­ЄжЁЁ + queue) - ўЁ¤Ё¬®, нв® Ў Ј, Є®в®ал© Ўг¤Ґв ЁбЇа ў«Ґ­ + * 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 = зЁб«® Їа®зЁв ­­ле Ў ©в + * 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, Ї®¤дг­ЄжЁп 0 - § Јаг§Ёвм ¤ ­­лҐ ¤«п SB16. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ (Є®ЇЁагҐвбп 64 ЄЁ«®Ў ©в , ЁбЇ®«м§гҐвбп + бв®«мЄ®, бЄ®«мЄ® гбв ­®ў«Ґ­® Ї®¤дг­ЄжЁҐ© 2) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”®а¬ в Ё а §¬Ґа ¤ ­­ле гбв ­ ў«Ёў овбп Ї®¤дг­ЄжЁҐ© 2. + +====================================================================== +==== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 1 - ­ з вм Їа®ЁЈалў вм ¤ ­­лҐ ­  SB16. === +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤ ­­лҐ ¤®«¦­л Ўлвм § Ја㦥­л Ї®¤дг­ЄжЁҐ© 0 Ё + ®ЇаҐ¤Ґ«с­ Ёе д®а¬ в Ї®¤дг­ЄжЁҐ© 2. + * ”г­ЄжЁп ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, Є®Ј¤  ­ з «®бм Їа®ЁЈалў ­ЁҐ ¤ ­­ле; + Ї®б«Ґ нв®Ј® Їа®ЁЈалў ­ЁҐ Ё¤св ­Ґ§ ўЁбЁ¬® ®в ЇаЁ«®¦Ґ­Ёп (Ё ў®®ЎйҐ + ­Ґ вॡгҐв § Јаг§ЄЁ Їа®жҐбб®а ). + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦­л Ўлвм ®ЇаҐ¤Ґ«Ґ­л Ў §®ўл© Ї®ав SB16 + (Ї®¤дг­ЄжЁҐ© 4 дг­ЄжЁЁ 21) Ё Є ­ « DMA + (Ї®¤дг­ЄжЁҐ© 10 дг­ЄжЁЁ 21). + +====================================================================== +====== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм д®а¬ в ¤ ­­ле SB16. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - гбв ­®ўЁвм а §ап¤­®бвм + * edx = 1 - 8ЎЁв ¬®­® + * edx = 2 - 8ЎЁв бвҐаҐ® + * ecx = 1 - гбв ­®ўЁвм а §¬Ґа ¤ ­­ле + * edx = а §¬Ґа ў Ў ©в е + * ecx = 2 - гбв ­®ўЁвм з бв®вг Їа®ЁЈалў ­Ёп + * edx = з бв®в  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаЁ § Јаг§ЄҐ бЁб⥬л гбв ­ ў«Ёў овбп б«Ґ¤гойЁҐ Ї а ¬Ґвал + Ї® 㬮«з ­Ёо: а §ап¤­®бвм - 8 ЎЁв ¬®­®, а §¬Ґа - 64 ЉЎ, + з бв®в  44100 ѓж. ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ४®¬Ґ­¤гҐвбп пў­® гбв ­ ў«Ёў вм + ­Ґ®Ўе®¤Ё¬лҐ §­ зҐ­Ёп, Ї®бЄ®«мЄг ®­Ё ¬®Ј«Ё Ўлвм ЇҐаҐгбв ­®ў«Ґ­л + Є Є®©-­ЁЎг¤м Їа®Ја ¬¬®©. + +====================================================================== +====================== ”г­ЄжЁп 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 = зЁб«® ЎЁв ­  ЇЁЄбҐ«м, ¤®«¦­® Ўлвм 8, 24 Ё«Ё 32 + * edi = гЄ § вҐ«м ­  Ї «Ёваг (256 梥⮢ 0x00RRGGBB); + ЁЈ­®аЁагҐвбп ЇаЁ esi = 24 Ё 32 + * ebp = ᬥ饭ЁҐ ¤ ­­ле Є ¦¤®© б«Ґ¤го饩 бва®ЄЁ Ё§®Ўа ¦Ґ­Ёп + ®в­®бЁвҐ«м­® ЇаҐ¤л¤г饩 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл Ё§®Ўа ¦Ґ­Ёп - нв® Є®®а¤Ё­ вл ўҐае­ҐЈ® «Ґў®Ј® гЈ«  + Ё§®Ўа ¦Ґ­Ёп ®в­®бЁвҐ«м­® ®Є­ . + * ђ §¬Ґа Ё§®Ўа ¦Ґ­Ёп ў Ў ©в е Ґбвм xsize*ysize. + * Љ ¦¤л© Ў ©в Ё§®Ўа ¦Ґ­Ёп а бб¬ ваЁў Ґвбп Є Є Ё­¤ҐЄб ў Ї «ЁваҐ. + * …б«Ё Ё§®Ўа ¦Ґ­ЁҐ ЁбЇ®«м§гҐв ­Ґ ўбҐ 256 梥⮢,   ¬Ґ­миҐ, + а §¬Ґа Ї «Ёвал ¬®¦Ґв Ўлвм ¬Ґ­миҐ 256. + * ‚л§®ў дг­ЄжЁЁ 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 = гЄ § вҐ«м ­  ЎгдҐа ¤«п Ё­д®а¬ жЁЁ (8 Ў ©в) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв ecx, ᮤҐа¦Ёв б«Ґ¤гойго Ё­д®а¬ жЁо: + * +0: dword: Є®­бв ­в  EV_INTR = 1 + * +4: dword: ¤ ­­лҐ ¤а ©ўҐа  +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп ў® ўаҐ¬п ®¦Ё¤ ­Ёп вॡгҐв ¤®ў®«м­® "вп¦с«ле" + ®ЇҐа жЁ© ЇҐаҐЄ«о祭Ёп Є®­вҐЄбв . + +====================================================================== +== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 15 - гбв ­®ўЁвм ®Ўа Ў®взЁЄ ЁбЄ«о祭Ё© FPU. = +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 15 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx =  ¤аҐб ­®ў®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax =  ¤аҐб бв а®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© + (0, Ґб«Ё ®­ ­Ґ Ўл« гбв ­®ў«Ґ­) + +====================================================================== +=========== ”г­ЄжЁп 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. = +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 18 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx =  ¤аҐб ­®ў®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax =  ¤аҐб бв а®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© + (0, Ґб«Ё ®­ ­Ґ Ўл« гбв ­®ў«Ґ­) + +====================================================================== +============= ”г­ЄжЁп 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. + * ‘®¤Ґа¦Ё¬®Ґ Ї ¬пвЁ ўЇ«®вм ¤® ­ Ё¬Ґ­м襣® Ё§ бв а®Ј® Ё ­®ў®Ј® + а §¬Ґа®ў б®еа ­пҐвбп. + +====================================================================== +======================== ”г­ЄжЁп 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. + +‚ᥠЇ®¤дг­ЄжЁЁ, Єа®¬Ґ 4 Ё 5, ЇаЁ¬Ґ­Ё¬л в®«мЄ® Є Їа®жҐбб ¬/Ї®в®Є ¬, +§ Їг饭­л¬ Ё§ ⥪г饣® дг­ЄжЁҐ© 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 = б«ЁиЄ®¬ ¬­®Ј® Їа®жҐбб®ў diff --git a/kernel/branches/kolibri_pe/docs/sysfuncs.txt b/kernel/branches/kolibri_pe/docs/sysfuncs.txt new file mode 100644 index 000000000..92a1ac9d6 --- /dev/null +++ b/kernel/branches/kolibri_pe/docs/sysfuncs.txt @@ -0,0 +1,4513 @@ +SYSTEM FUNCTIONS of OS Kolibri 0.7.1.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. + * At current implementation there will be an immediate return from + the function, if the addition of ebx with current value of + time counter will call 32-bit overflow. + +====================================================================== +============== 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, function returns: + 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), + and al contain 0 - if used left mouse button or bit of the used another mouse button +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". + +====================================================================== += 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. =========== +====================================================================== +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. + * It is possible to use subfunction 1, that on the last step + the user makes choice himself. +====================================================================== +===== 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 4 - set Sound Blaster base port. ===== +====================================================================== +Removed + +====================================================================== +========== 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 10 - set sound DMA channel. ======== +====================================================================== +Removed + +====================================================================== + 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 25 - set SBPro volume. ================== +====================================================================== +Removed + +====================================================================== +======== 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 4 - get Sound Blaster base port. ===== +====================================================================== +Removed + +====================================================================== +========== 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 10 - get sound DMA channel. ======== +====================================================================== +Removed + +====================================================================== +===================== 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 28 - set SB16 volume. =================== +====================================================================== +Removed + +====================================================================== +=================== 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 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 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: + * function does not return value +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. =============== +====================================================================== + +------------------------ Reading 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 +to the buffer specified as parameter. +Parameters: + * eax = 42 - function number + * bl = IRQ number, 0..15 + * bh = subfunction number, 0 +Other part of register ebx, must be zero. + * ecx = pointer to the receive buffer +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 = byte size of data, read from buffer + +See remarks below. + +------------------------ Get data size ------------------------------- + +Parameters: + * eax = 42 - function number + * bl = IRQ number, 0..15 + * bh = subfunction number, 0 +Other part of register ebx, must be zero. + * ecx = pointer to receive buffer +Returned value: (use value of eax to distinguish) + * if the thread is not IRQ owner (or IRQ number is incorrect): + * eax = -1 + * if all is ok: + * eax = byte 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 + + +====================================================================== +=== 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) + * 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. + * The current implementation does no checks on correctness + (function returns error only if thread tries to close not opened + socket with correct handle). + +====================================================================== +============== 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 + * ebx destroyed +Remarks: + * There is no checks for correctness. + +====================================================================== +========= 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: 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 +Remarks: + * There is no checks for correctness. + +====================================================================== +========== 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 - invalid handle + * eax = 0xffff - not enough memory + * eax = 0 - success + * ebx destroyed +Remarks: + * Check on validity of handle is minimal - only not very incorrect + not opened handles are eliminated. + * 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) + * 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 = 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 destroys +Remarks: + * There is no checks for correctness. + +====================================================================== +========== 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 + * eax = 0xffff - not enough memory + * eax = 0 - success + * ebx destroyed +Remarks: + * Check on validity of handle is minimal - only not very incorrect + not opened handles are eliminated. + * 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 - invalid handle + * eax = 0xffff - not enough memory for socket close packet + * eax = 0 - success + * in many cases eax is destroyed (the result of function 'queue' + is returned) - probably this is bug, which will be corrected + * 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. + * The current implementation does no checks on correctness + (function returns error only if thread tries to close not opened + socket with correct handle). + +====================================================================== +=== 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 + * ebx destroyed +Remakrs: + * There is no check on handle correctness. + +====================================================================== += 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 0 - load data for SB16. ========== +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 0 - subfunction number + * ecx = pointer to data (is copied 64 kilobytes, is used as much as + set by subfunction 2) +Returned value: + * function does not return value +Remarks: + * Format and size of data are set by subfunction 2. + +====================================================================== +======== Function 55, subfunction 1 - begin play data on SB16. ======= +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value +Remarks: + * Previously data must be loaded by subfunction 0 and + their format must be defined by subfunction 2. + * Function returns control, when playing of data began; after that + play goes independently from application (and does not use + processor time at all). + * Previously must be defined SB16 base port + (by subfunction 4 of function 21) and DMA channel + (by subfunction 10 of function 21). + +====================================================================== +======== Function 55, subfunction 2 - set format of SB16 data. ======= +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 2 - subfunction number + * ecx = 0 - set digit capacity + * edx = 1 - 8bit mono + * edx = 2 - 8bit stereo + * ecx = 1 - set data size + * edx = size in bytes + * ecx = 2 - set play frequency + * edx = frequency +Returned value: + * function does not return value +Remarks: + * When the system boots, it sets following default parameters: + digit capacity - 8bit mono, size - 64 Kb, frequency - 44100 Hz. + Nevertheless it is recommended to set necessary values obviously + as they could be reset by some application. + +====================================================================== + 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 8, 24 or 32 + * edi = pointer to palette (256 colors 0x00RRGGBB); + ignored when esi = 24 and 32 + * 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. + * Size of the image in bytes is xsize*ysize. + * Each byte of image is index in the palette. + * If the image uses less than 256 colors, palette size may be + less than 256 too. + * 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 - wait for driver notify. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 14 - subfunction number + * ecx = pointer to the buffer for information (8 bytes) +Returned value: + * buffer pointed to by ecx contains the following information: + * +0: dword: constant EV_INTR = 1 + * +4: dword: driver data +Remarks: + * The current implementation at wait time uses "heavy" operations + of task switch. + +====================================================================== +====== Function 68, subfunction 15 - set FPU exception handler. ====== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 15 - subfunction number + * ecx = address of the new exception handler +Returned value: + * eax = address of the old exception handler (0, if it was not set) + +====================================================================== +============= 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 = determined by driver +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. ====== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 15 - subfunction number + * ecx = address of the new exception handler +Returned value: + * eax = address of the old exception handler (0, if it was not set) + +====================================================================== +=============== 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. + +====================================================================== +====================== 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 except 4 and 5 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 thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 4 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value + +====================================================================== +============= Function 69, subfunction 5 - resume thread. ============ +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 5 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value + +====================================================================== += 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 diff --git a/kernel/branches/kolibri_pe/drivers/ati2d.asm b/kernel/branches/kolibri_pe/drivers/ati2d.asm new file mode 100644 index 000000000..4bed5f0bd --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/ati2d.asm @@ -0,0 +1,1607 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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' + +R500_HW2D equ 0 + +API_VERSION equ 0x01000100 + +STRIDE equ 8 + +VID_ATI equ 0x1002 + +LOAD_FROM_FILE equ 0 +LOAD_FROM_MEM equ 1 +LOAD_INDIRECT equ 2 +LOAD_SYSTEM equ 3 + +SRV_GETVERSION equ 0 + +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 + +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 ? +} +virtual at 0 + CURSOR CURSOR +end virtual + +CURSOR_SIZE equ 32 + +OS_BASE equ 0x80000000 +SLOT_BASE equ (OS_BASE+0x0080000) +LFB_BASE equ 0xFE000000 + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +PCI_MEMORY_MASK equ 0xfffffff0 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +;MMIO equ 0F9000000h +RD_RB3D_CNTL equ 1c3ch + +RD_MEM_CNTL equ 0140h +RD_CRTC_GEN_CNTL equ 0050h +RD_CRTC_CUR_EN equ 10000h +RD_DISPLAY_BASE_ADDR equ 023ch +RD_DEFAULT_OFFSET equ 16e0h + +CUR_HORZ_VERT_OFF equ 0268h +CUR_HORZ_VERT_POSN equ 0264h +CUR_OFFSET equ 0260h + + +RD_RB3D_CNTL equ 1c3ch +RD_RBBM_STATUS equ 0e40h +RD_RBBM_FIFOCNT_MASK equ 007fh +RD_RBBM_ACTIVE equ 80000000h +RD_TIMEOUT equ 2000000 + +RD_DP_GUI_MASTER_CNTL equ 0146ch +RD_DP_BRUSH_BKGD_CLR equ 01478h +RD_DP_BRUSH_FRGD_CLR equ 0147ch +RD_DP_SRC_BKGD_CLR equ 015dch +RD_DP_SRC_FRGD_CLR equ 015d8h +RD_DP_CNTL equ 016c0h +RD_DP_DATATYPE equ 016c4h +RD_DP_WRITE_MASK equ 016cch +RD_DP_SRC_SOURCE_MEMORY equ (2 shl 24) +RD_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24) +RD_DEFAULT_SC_BOTTOM_RIGHT equ 16e8h +RD_GMC_BRUSH_SOLID_COLOR equ (13 shl 4) +RD_DEFAULT_SC_RIGHT_MAX equ 1fffh +RD_DEFAULT_SC_BOTTOM_MAX equ 1fff0000h +RD_GMC_DST_DATATYPE_SHIFT equ 8 + +RD_ROP3_S equ 00cc0000h +RD_ROP3_P equ 00f00000h + +RD_RB2D_DSTCACHE_MODE equ 03428h +RD_RB2D_DSTCACHE_CTLSTAT equ 0342ch +RD_RB2D_DC_FLUSH_ALL equ 000fh +RD_RB2D_DC_BUSY equ 80000000h + +RD_GMC_BRUSH_SOLID_COLOR equ 000000D0h +RD_GMC_SRC_DATATYPE_COLOR equ (3 shl 12) +RD_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28) +RD_GMC_WR_MSK_DIS equ (1 shl 30) + +cmdSolidFill equ 73f036d0h + +RD_DST_PITCH_OFFSET equ 142ch +RD_SRC_PITCH_OFFSET equ 1428h + +RD_DST_X_LEFT_TO_RIGHT equ 1 +RD_DST_Y_TOP_TO_BOTTOM equ 2 +RD_DST_Y_X equ 1438h +RD_DST_WIDTH_HEIGHT equ 1598h +RD_DST_LINE_START equ 1600h +RD_DST_LINE_END equ 1604h +R300_MEM_NUM_CHANNELS_MASK equ 0003h + +macro rdr op1, op2 +{ + mov edi, [ati_io] + mov op1, [edi+op2] +} + +macro BEGIN_RING +{ + mov edi, [rhd.ring_base] + mov edx, [rhd.ring_wp] +} + +macro COMMIT_RING +{ + and edx, 0x1FFF + mov [rhd.ring_wp], edx + + lock add [esp], dword 0 ; Flush writes to ring + + wrr RADEON_CP_RB_WPTR, edx + rdr eax, RADEON_CP_RB_RPTR +} + +macro OUT_PACKET0 reg, count +{ + mov eax, (RADEON_CP_PACKET0 + (count shl 16) + (reg shr 2)) + mov [edi+edx*4], eax + inc edx +} + +macro OUT_PACKET3 pkt, count +{ + mov eax, (RADEON_CP_PACKET3 or pkt or (count shl 16)) + mov [edi+edx*4], eax + inc edx +} + +macro OUT_RING val +{ + mov eax, val + mov [edi+edx*4], eax + inc edx +} + +macro RADEON_WAIT_UNTIL_IDLE +{ + OUT_PACKET0 RADEON_WAIT_UNTIL, 0 + OUT_RING RADEON_WAIT_2D_IDLECLEAN + \ + RADEON_WAIT_3D_IDLECLEAN + \ + RADEON_WAIT_HOST_IDLECLEAN +} + +macro RADEON_PURGE_CACHE +{ + OUT_PACKET0 R5XX_RB3D_DSTCACHE_CTLSTAT, 0 + OUT_RING R5XX_RB3D_DC_FLUSH_ALL +} + +macro RADEON_PURGE_ZCACHE +{ + OUT_PACKET0 RADEON_RB3D_ZCACHE_CTLSTAT, 0 + OUT_RING RADEON_RB3D_ZC_FLUSH_ALL +} + +macro wrr dest, src +{ + mov edi, [ati_io] + mov dword [edi+dest], src +} + +macro rmask dest, val, mask +{ + mov edi, [ati_io] + mov eax, [edi+dest] + and eax, not mask + or eax, (val and mask) + mov [edi+dest], eax +} + +public START +public service_proc +public version + +CURSOR_IMAGE_OFFSET equ 0x00500000 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .restore + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_ati + test eax, eax + jz .fail + + mov ebx, [SelectHwCursor] + mov ecx, [SetHwCursor] + mov edx, [HwCursorRestore] + mov esi, [HwCursorCreate] + + mov [oldSelect], ebx + mov [oldSet], ecx + mov [oldRestore], edx + mov [oldCreate], esi + + call eax + + or eax, -1 + mov [cursor_map], eax + mov [cursor_map+4], eax + mov edx, cursor_map + mov [cursor_start], edx + add edx, 8 + mov [cursor_end], edx + + stdcall RegService, sz_ati_srv, service_proc + test eax, eax + jz .restore + +if R500_HW2D + stdcall RegService, sz_HDraw_srv, r500_HDraw + + mov ebx, START + and ebx, -4096 + mov [eax+0x20], ebx + mov [eax+0x24], dword 0 ;hack +end if + mov ebx, [fnSelect] + mov ecx, [fnSet] + + mov [SelectHwCursor], ebx + mov [SetHwCursor], ecx + mov dword [HwCursorRestore], drv_restore + mov dword [HwCursorCreate], ati_cursor + + ret +.restore: + mov eax, [oldSelect] + mov ebx, [oldSet] + mov ecx, [oldRestore] + mov edx, [oldCreate] + + mov [SelectHwCursor], eax + mov [SetHwCursor], ebx + mov [HwCursorRestore], ecx + mov [HwCursorCreate], edx + + xor eax, eax + ret + +.fail: + if DEBUG + mov esi, msgFail + 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 ebx, [ioctl] + cmp [ebx+io_code], SRV_GETVERSION + jne .fail + + 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_ati + 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: + mov eax, [edi+4] + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc init_r200 + stdcall PciRead32, [bus], [devfn], dword 0x18 + and eax, PCI_MEMORY_MASK + stdcall MapIoMem,eax,0x10000,(PG_SW+PG_NOCACHE) + test eax, eax + jz .fail + + mov [ati_io], eax + mov edi, eax + + mov dword [edi+RD_RB3D_CNTL], 0 + call engRestore + + mov edi, [ati_io] + mov eax, [edi+0x50] + mov ebx,3 + shl ebx,20 + not ebx + and eax,ebx + mov ebx, 2 + shl ebx,20 + or eax, ebx + mov [edi+0x50], eax + + call r200_ShowCursor + + mov [fnSelect], r200_SelectCursor + mov [fnSet], r200_SetCursor + + xor eax, eax + inc eax +.fail: + ret +endp + +if R500_HW2D + include 'r500hw.inc' +end if + +align 4 +proc init_r500 + + stdcall PciRead32, [bus], [devfn], dword 0x18 + and eax, PCI_MEMORY_MASK + stdcall MapIoMem,eax,0x10000,(PG_SW+PG_NOCACHE) + test eax, eax + jz .fail + + mov [ati_io], eax + + mov [fnSelect], r500_SelectCursor + mov [fnSet], r500_SetCursor + + rdr eax, 0x6110 + mov [r500_LFB], eax + +if R500_HW2D + call R5xx2DInit +end if + wrr 0x6410, 0x001F001F + wrr 0x6400, dword (3 shl 8) + + xor eax, eax + inc eax +.fail: + ret +endp + + +align 4 +drv_restore: + ret 8 + + +align 4 +proc r500_SelectCursor stdcall,hcursor:dword + + mov esi, [hcursor] + + mov edx, [esi+CURSOR.base] + sub edx, LFB_BASE + add edx, [r500_LFB] + wrr 0x6408, edx + + mov eax, [esi+CURSOR.hot_x] + shl eax, 16 + mov ax, word [esi+CURSOR.hot_y] + wrr 0x6418, eax + ret +endp + +align 4 +proc r500_SetCursor stdcall, hcursor:dword, x:dword, y:dword + pushfd + cli + + mov esi, [hcursor] + mov edi, [ati_io] + + mov eax, [x] + shl eax, 16 + mov ax, word [y] + + mov [edi+0x6414], eax + or dword [edi+0x6400], 1 + + popfd + ret +endp + +align 4 +r500_ShowCursor: + + mov edi, [ati_io] + or dword [edi+0x6400], 1 + ret + +align 4 +r200_ShowCursor: + mov edi, [ati_io] + + mov eax, [edi+RD_CRTC_GEN_CNTL] + bts eax,16 + mov [edi+RD_CRTC_GEN_CNTL], eax + ret + + +align 4 +proc r200_SelectCursor stdcall,hcursor:dword + + ret +endp + +align 4 +proc r200_SetCursor stdcall, hcursor:dword, x:dword, y:dword + pushfd + cli + + xor eax, eax + xor edx, edx + mov esi, [hcursor] + mov ebx, [x] + mov ecx, [y] + + sub ebx, [esi+CURSOR.hot_x] + jnc @F + neg ebx + mov eax, ebx + shl eax, 16 + xor ebx, ebx +@@: + sub ecx, [esi+CURSOR.hot_y] + jnc @F + neg ecx + mov ax, cx + mov edx, ecx + xor ecx, ecx +@@: + or eax, 0x80000000 + wrr CUR_HORZ_VERT_OFF, eax + + shl ebx, 16 + mov bx, cx + or ebx, 0x80000000 + wrr CUR_HORZ_VERT_POSN, ebx + + shl edx, 8 + add edx, [esi+CURSOR.base] + sub edx, LFBAddress + wrr CUR_OFFSET, edx + popfd + ret +endp + +align 4 +proc video_alloc + + pushfd + cli + mov ebx, [cursor_start] + mov ecx, [cursor_end] +.l1: + bsf eax,[ebx]; + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + popfd + + mov [cursor_start],ebx + sub ebx, cursor_map + lea eax,[eax+ebx*8] + + shl eax,14 + add eax, LFBAddress+CURSOR_IMAGE_OFFSET + ret +endp + +align 4 +video_free: + pushfd + cli + sub eax, LFBAddress+CURSOR_IMAGE_OFFSET + shr eax, 14 + mov ebx, cursor_map + bts [ebx], eax + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [cursor_start], eax + ja @f + popfd + ret +@@: + mov [cursor_start], eax + popfd + ret + +; param +; eax= pid +; ebx= src +; ecx= flags + +align 4 +ati_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_SIZE + call CreateObject + 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 + + call video_alloc + 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 ati_init_cursor, eax, esi + mov eax, [.hcursor] +.fail: + add esp, 12 + ret +.indirect: + shr ebx, 16 + movzx ecx, bh + movzx edx, bl + mov [edi+CURSOR.hot_x], ecx + mov [edi+CURSOR.hot_y], edx + + mov edi, eax + mov ebx, eax + mov ecx, 64*64 + xor eax,eax + cld + rep stosd + mov edi, ebx + + mov esi, [.src] + mov ebx, 32 + cld +@@: + mov ecx, 32 + rep movsd + add edi, 128 + dec ebx + jnz @B + mov eax, [.hcursor] + add esp, 12 + ret + +align 4 +destroy_cursor: + + push eax + mov eax, [eax+CURSOR.base] + call video_free + pop eax + + call DestroyObject + ret + +align 4 +proc ati_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, pCursor + 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 + jmp .copy +.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, pCursor + 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 + jmp .copy +.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, pCursor + 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 + jmp .copy +.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, pCursor + 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 +.copy: + mov edi, [dst] + mov ecx, 64*64 + xor eax,eax + rep stosd + + mov esi, pCursor + mov edi, [dst] + mov ebx, 32 + cld +@@: + mov ecx, 32 + rep movsd + add edi, 128 + dec ebx + jnz @B + ret +endp + +align 4 +proc engFlush + + mov edi, [ati_io] + + mov eax, [edi+RD_RB2D_DSTCACHE_CTLSTAT] + or eax,RD_RB2D_DC_FLUSH_ALL + mov [edi+RD_RB2D_DSTCACHE_CTLSTAT],eax + + mov ecx, RD_TIMEOUT +@@: + mov eax,[edi+RD_RB2D_DSTCACHE_CTLSTAT] + and eax, RD_RB2D_DC_BUSY + jz .exit + + sub ecx,1 + jnz @B +.exit: + ret +endp + + +align 4 +engWaitForFifo: +cnt equ bp+8 + push ebp + mov ebp, esp + + mov edi, [ati_io] + + mov ecx, RD_TIMEOUT +@@: + mov eax, [edi+RD_RBBM_STATUS] + and eax, RD_RBBM_FIFOCNT_MASK + cmp eax, [ebp+8] + jae .exit + + sub ecx,1 + jmp @B + +.exit: + leave + ret 4 + +align 4 +proc engWaitForIdle + + push dword 64 + call engWaitForFifo + + mov edi, [ati_io] + mov ecx ,RD_TIMEOUT +@@: + mov eax, [edi+RD_RBBM_STATUS] + and eax,RD_RBBM_ACTIVE + jz .exit + + sub ecx,1 + jnz @B +.exit: + call engFlush + ret +endp + + +align 4 +proc engRestore + +; push dword 1 +; call engWaitForFifo + +; mov dword [MMIO+RD_RB2D_DSTCACHE_MODE], 0 + + push dword 3 + call engWaitForFifo + + mov edi, [ati_io] + + mov eax, [edi+RD_DISPLAY_BASE_ADDR] + shr eax, 10d + or eax,(64d shl 22d) + mov [edi+RD_DEFAULT_OFFSET],eax + mov [edi+RD_SRC_PITCH_OFFSET],eax + mov [edi+RD_DST_PITCH_OFFSET],eax + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov eax, [edi+RD_DP_DATATYPE] + btr eax, 29d + mov [edi+RD_DP_DATATYPE],eax + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov dword [edi+RD_DEFAULT_SC_BOTTOM_RIGHT],\ + (RD_DEFAULT_SC_RIGHT_MAX or RD_DEFAULT_SC_BOTTOM_MAX) + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov dword [edi+RD_DP_GUI_MASTER_CNTL],\ + (RD_GMC_BRUSH_SOLID_COLOR or \ + RD_GMC_SRC_DATATYPE_COLOR or \ + (6 shl RD_GMC_DST_DATATYPE_SHIFT) or \ + RD_GMC_CLR_CMP_CNTL_DIS or \ + RD_ROP3_P or \ + RD_GMC_WR_MSK_DIS) + + + push dword 7 + call engWaitForFifo + + mov edi, [ati_io] + + mov dword [edi+RD_DST_LINE_START],0 + mov dword [edi+RD_DST_LINE_END], 0 + mov dword [edi+RD_DP_BRUSH_FRGD_CLR], 808000ffh + mov dword [edi+RD_DP_BRUSH_BKGD_CLR], 002020ffh + mov dword [edi+RD_DP_SRC_FRGD_CLR], 808000ffh + mov dword [edi+RD_DP_SRC_BKGD_CLR], 004000ffh + mov dword [edi+RD_DP_WRITE_MASK],0ffffffffh + + call engWaitForIdle + + 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 + +R200M equ 0x5a62 ;R300 +R7000 equ 0x5159 ;R200 +R750M equ 0x4c57 ;M7 mobile rv200 +R8500 equ 0x514C ;R200 +R9000 equ 0x4966 ;RV250 +R9200 equ 0x5961 ;RV280 +R9200SE equ 0x5964 ;RV280 +R9500 equ 0x4144 ;R300 +R9500P equ 0x4E45 ;R300 +R9550 equ 0x4153 ;RV350 +R9600 equ 0x4150 ;RV350 +R9600XT equ 0x4152 ;RV360 +R9700P equ 0x4E44 ;R300 +R9800 equ 0x4E49 ;R350 +R9800P equ 0x4E48 ;R350 +R9800XT equ 0x4E4A ;R360 + + +align 4 + +devices: + dd (R200M shl 16)+VID_ATI, init_r200 ;R300 + dd (R7000 shl 16)+VID_ATI, init_r200 + dd (R750M shl 16)+VID_ATI, init_r200 ;M7 + dd (R8500 shl 16)+VID_ATI, init_r200 + dd (R9000 shl 16)+VID_ATI, init_r200 + dd (0x514D shl 16)+VID_ATI, init_r200 ;R200 9100 + + dd (R9200 shl 16)+VID_ATI, init_r200 + dd (R9200SE shl 16)+VID_ATI, init_r200 + + dd (0x5960 shl 16)+VID_ATI, init_r200 ;RV280 9250 + + dd (R9500 shl 16)+VID_ATI, init_r200 + dd (R9500P shl 16)+VID_ATI, init_r200 + dd (R9550 shl 16)+VID_ATI, init_r200 + + dd (R9600 shl 16)+VID_ATI, init_r200 + dd (R9600XT shl 16)+VID_ATI, init_r200 + dd (0x4155 shl 16)+VID_ATI, init_r200 ;RV350 9600 + dd (0x4151 shl 16)+VID_ATI, init_r200 ;RV350 9600 + dd (0x4E51 shl 16)+VID_ATI, init_r200 ;RV350 9600 + + dd (R9700P shl 16)+VID_ATI, init_r200 + + dd (0x4148 shl 16)+VID_ATI, init_r200 ;R350 9800 + dd (R9800 shl 16)+VID_ATI, init_r200 + dd (R9800P shl 16)+VID_ATI, init_r200 + dd (R9800XT shl 16)+VID_ATI, init_r200 + + dd (0x5B60 shl 16)+VID_ATI, init_r200 ;RV370 X300/X550 + dd (0x5B63 shl 16)+VID_ATI, init_r200 ;RV370 X550 + dd (0x5B62 shl 16)+VID_ATI, init_r200 ;RV380x X600 + dd (0x3E50 shl 16)+VID_ATI, init_r200 ;RV380 X600/X550 + + dd (0x5B4F shl 16)+VID_ATI, init_r200 ;RV410 X700 + dd (0x5B4D shl 16)+VID_ATI, init_r200 ;RV410 X700 + dd (0x5B4B shl 16)+VID_ATI, init_r200 ;RV410 X700 + dd (0x5B4C shl 16)+VID_ATI, init_r200 ;RV410 X700 + + dd (0x4a49 shl 16)+VID_ATI, init_r200 ;R420 X800 PRO/GTO + dd (0x4a4B shl 16)+VID_ATI, init_r200 ;R420 X800 + dd (0x5549 shl 16)+VID_ATI, init_r200 ;R423 X800 + dd (0x4a4A shl 16)+VID_ATI, init_r200 ;R420 X800 + dd (0x554F shl 16)+VID_ATI, init_r200 ;R430 X800 + dd (0x554D shl 16)+VID_ATI, init_r200 ;R430 X800 + dd (0x554E shl 16)+VID_ATI, init_r200 ;R430 X800 + dd (0x5D57 shl 16)+VID_ATI, init_r200 ;R423 X800 XT + dd (0x4A50 shl 16)+VID_ATI, init_r200 ;R420 X800 XT + dd (0x554A shl 16)+VID_ATI, init_r200 ;R423 X800 XT + dd (0x5D4F shl 16)+VID_ATI, init_r200 ;R423 X800/X850 + dd (0x554B shl 16)+VID_ATI, init_r200 ;R423 X800 GT + + dd (0x4B4B shl 16)+VID_ATI, init_r200 ;R481 X850 + dd (0x4B49 shl 16)+VID_ATI, init_r200 ;R481 X850 + dd (0x4B4C shl 16)+VID_ATI, init_r200 ;R481 X850 + + dd (0x5D4D shl 16)+VID_ATI, init_r200 ;R480 X850 + dd (0x5D52 shl 16)+VID_ATI, init_r200 ;R480 X850 + + dd (0x791E shl 16)+VID_ATI, init_r500 ;RS690 X1200 + + dd (0x7140 shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x7142 shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x7146 shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x714D shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x714E shl 16)+VID_ATI, init_r500 ;RV515 X1300 + + dd (0x7183 shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x7187 shl 16)+VID_ATI, init_r500 ;RV515 X1300 + dd (0x718F shl 16)+VID_ATI, init_r500 ;RV515 X1300 + + dd (0x7143 shl 16)+VID_ATI, init_r500 ;RV515 X1550 + dd (0x7147 shl 16)+VID_ATI, init_r500 ;RV515 X1550 + dd (0x715F shl 16)+VID_ATI, init_r500 ;RV515 X1550 + dd (0x7193 shl 16)+VID_ATI, init_r500 ;RV515 X1550 + dd (0x719F shl 16)+VID_ATI, init_r500 ;RV515 X1550 + + dd (0x71C0 shl 16)+VID_ATI, init_r500 ;RV530 X1600 + dd (0x71C1 shl 16)+VID_ATI, init_r500 ;RV535 X1650 + dd (0x71C2 shl 16)+VID_ATI, init_r500 ;RV530 X1600 + dd (0x71C3 shl 16)+VID_ATI, init_r500 ;RV535 X1600 + dd (0x71C6 shl 16)+VID_ATI, init_r500 ;RV530 X1600 + dd (0x71C7 shl 16)+VID_ATI, init_r500 ;RV534 X1650 + + dd (0x7181 shl 16)+VID_ATI, init_r500 ;RV515 X1600 + dd (0x71CD shl 16)+VID_ATI, init_r500 ;RV530 X1600 + + dd (0x7291 shl 16)+VID_ATI, init_r500 ;R580 X1650 + dd (0x7293 shl 16)+VID_ATI, init_r500 ;R580 X1650 + + dd (0x7100 shl 16)+VID_ATI, init_r500 ;RV520 X1800 + dd (0x7109 shl 16)+VID_ATI, init_r500 ;RV520 X1800 + dd (0x710A shl 16)+VID_ATI, init_r500 ;RV520 X1800 GTO + + dd (0x7249 shl 16)+VID_ATI, init_r500 ;RV580 X1900 + dd (0x724B shl 16)+VID_ATI, init_r500 ;RV580 X1900 GT + + dd (0x7240 shl 16)+VID_ATI, init_r500 ;RV580 X1950 + dd (0x7244 shl 16)+VID_ATI, init_r500 ;RV580 X1950 + dd (0x7248 shl 16)+VID_ATI, init_r500 ;RV580 X1950 + + dd (0x7288 shl 16)+VID_ATI, init_r500 ;R580 X1950 GT + dd (0x7280 shl 16)+VID_ATI, init_r500 ;R580 X1950 PRO + + dd (0x94C3 shl 16)+VID_ATI, init_r500 ;RV610 HD 2400 PRO + dd (0x94C1 shl 16)+VID_ATI, init_r500 ;RV610 HD 2400 XT + + dd (0x9589 shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 PRO + dd (0x958A shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 X2 + dd (0x9588 shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 XT + + dd (0x9403 shl 16)+VID_ATI, init_r500 ;R600 HD 2900 PRO + dd (0x9409 shl 16)+VID_ATI, init_r500 ;R600 HD 2900 XT + + + dd 0 ;terminator + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +if R500_HW2D + +align 16 +R5xxRops dd R5XX_ROP3_ZERO, R5XX_ROP3_ZERO ;GXclear + dd R5XX_ROP3_DSa, R5XX_ROP3_DPa ;Gxand + dd R5XX_ROP3_SDna, R5XX_ROP3_PDna ;GXandReverse + dd R5XX_ROP3_S, R5XX_ROP3_P ;GXcopy + dd R5XX_ROP3_DSna, R5XX_ROP3_DPna ;GXandInverted + dd R5XX_ROP3_D, R5XX_ROP3_D ;GXnoop + dd R5XX_ROP3_DSx, R5XX_ROP3_DPx ;GXxor + dd R5XX_ROP3_DSo, R5XX_ROP3_DPo ;GXor + dd R5XX_ROP3_DSon, R5XX_ROP3_DPon ;GXnor + dd R5XX_ROP3_DSxn, R5XX_ROP3_PDxn ;GXequiv + dd R5XX_ROP3_Dn, R5XX_ROP3_Dn ;GXinvert + dd R5XX_ROP3_SDno, R5XX_ROP3_PDno ;GXorReverse + dd R5XX_ROP3_Sn, R5XX_ROP3_Pn ;GXcopyInverted + dd R5XX_ROP3_DSno, R5XX_ROP3_DPno ;GXorInverted + dd R5XX_ROP3_DSan, R5XX_ROP3_DPan ;GXnand + dd R5XX_ROP3_ONE, R5XX_ROP3_ONE ;GXset +end if + + +sz_ati_srv db 'HWCURSOR',0 + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgFail db 'device not found',13,10,0 +msg_neg db 'neg ecx',13,10,0 + +if R500_HW2D + +sz_HDraw_srv db 'HDRAW',0 + +msgR5xx2DFlushtimeout \ + db 'R5xx2DFlush timeout error',13,10,0 +msgR5xxFIFOWaitLocaltimeout \ + db 'R5xxFIFOWaitLocal timeout error', 13, 10,0 +msgR5xx2DIdleLocaltimeout \ + db 'R5xx2DIdleLocal timeout error', 13,10,0 + +align 4 +R520_cp_microcode: +dd 0x4200e000, 0000000000 +dd 0x4000e000, 0000000000 +dd 0x00000099, 0x00000008 +dd 0x0000009d, 0x00000008 +dd 0x4a554b4a, 0000000000 +dd 0x4a4a4467, 0000000000 +dd 0x55526f75, 0000000000 +dd 0x4a7e7d65, 0000000000 +dd 0xe0dae6f6, 0000000000 +dd 0x4ac54a4a, 0000000000 +dd 0xc8828282, 0000000000 +dd 0xbf4acfc1, 0000000000 +dd 0x87b04ad5, 0000000000 +dd 0xb5838383, 0000000000 +dd 0x4a0f85ba, 0000000000 +dd 0x000ca000, 0x00000004 +dd 0x000d0012, 0x00000038 +dd 0x0000e8b4, 0x00000004 +dd 0x000d0014, 0x00000038 +dd 0x0000e8b6, 0x00000004 +dd 0x000d0016, 0x00000038 +dd 0x0000e854, 0x00000004 +dd 0x000d0018, 0x00000038 +dd 0x0000e855, 0x00000004 +dd 0x000d001a, 0x00000038 +dd 0x0000e856, 0x00000004 +dd 0x000d001c, 0x00000038 +dd 0x0000e857, 0x00000004 +dd 0x000d001e, 0x00000038 +dd 0x0000e824, 0x00000004 +dd 0x000d0020, 0x00000038 +dd 0x0000e825, 0x00000004 +dd 0x000d0022, 0x00000038 +dd 0x0000e830, 0x00000004 +dd 0x000d0024, 0x00000038 +dd 0x0000f0c0, 0x00000004 +dd 0x000d0026, 0x00000038 +dd 0x0000f0c1, 0x00000004 +dd 0x000d0028, 0x00000038 +dd 0x0000e000, 0x00000004 +dd 0x000d002a, 0x00000038 +dd 0x0000e000, 0x00000004 +dd 0x000d002c, 0x00000038 +dd 0x0000e000, 0x00000004 +dd 0x000d002e, 0x00000038 +dd 0x0000e000, 0x00000004 +dd 0x000d0030, 0x00000038 +dd 0x0000e000, 0x00000004 +dd 0x000d0032, 0x00000038 +dd 0x0000f180, 0x00000004 +dd 0x000d0034, 0x00000038 +dd 0x0000f393, 0x00000004 +dd 0x000d0036, 0x00000038 +dd 0x0000f38a, 0x00000004 +dd 0x000d0038, 0x00000038 +dd 0x0000f38e, 0x00000004 +dd 0x0000e821, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x00000043, 0x00000018 +dd 0x00cce800, 0x00000004 +dd 0x001b0001, 0x00000004 +dd 0x08004800, 0x00000004 +dd 0x001b0001, 0x00000004 +dd 0x08004800, 0x00000004 +dd 0x001b0001, 0x00000004 +dd 0x08004800, 0x00000004 +dd 0x0000003a, 0x00000008 +dd 0x0000a000, 0000000000 +dd 0x2000451d, 0x00000004 +dd 0x0000e580, 0x00000004 +dd 0x000ce581, 0x00000004 +dd 0x08004580, 0x00000004 +dd 0x000ce581, 0x00000004 +dd 0x00000047, 0x00000008 +dd 0x0000a000, 0000000000 +dd 0x000c2000, 0x00000004 +dd 0x0000e50e, 0x00000004 +dd 0x00032000, 0x00000004 +dd 0x00022051, 0x00000028 +dd 0x00000051, 0x00000024 +dd 0x0800450f, 0x00000004 +dd 0x0000a04b, 0x00000008 +dd 0x0000e565, 0x00000004 +dd 0x0000e566, 0x00000004 +dd 0x00000052, 0x00000008 +dd 0x03cca5b4, 0x00000004 +dd 0x05432000, 0x00000004 +dd 0x00022000, 0x00000004 +dd 0x4ccce05e, 0x00000030 +dd 0x08274565, 0x00000004 +dd 0x0000005e, 0x00000030 +dd 0x08004564, 0x00000004 +dd 0x0000e566, 0x00000004 +dd 0x00000055, 0x00000008 +dd 0x00802061, 0x00000010 +dd 0x00202000, 0x00000004 +dd 0x001b00ff, 0x00000004 +dd 0x01000064, 0x00000010 +dd 0x001f2000, 0x00000004 +dd 0x001c00ff, 0x00000004 +dd 0000000000, 0x0000000c +dd 0x00000072, 0x00000030 +dd 0x00000055, 0x00000008 +dd 0x0000e576, 0x00000004 +dd 0x0000e577, 0x00000004 +dd 0x0000e50e, 0x00000004 +dd 0x0000e50f, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x00000069, 0x00000018 +dd 0x00c0e5f9, 0x000000c2 +dd 0x00000069, 0x00000008 +dd 0x0014e50e, 0x00000004 +dd 0x0040e50f, 0x00000004 +dd 0x00c0006c, 0x00000008 +dd 0x0000e570, 0x00000004 +dd 0x0000e571, 0x00000004 +dd 0x0000e572, 0x0000000c +dd 0x0000a000, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x0000e568, 0x00000004 +dd 0x000c2000, 0x00000004 +dd 0x00000076, 0x00000018 +dd 0x000b0000, 0x00000004 +dd 0x18c0e562, 0x00000004 +dd 0x00000078, 0x00000008 +dd 0x00c00077, 0x00000008 +dd 0x000700c7, 0x00000004 +dd 0x00000080, 0x00000038 +dd 0x0000e5bb, 0x00000004 +dd 0x0000e5bc, 0000000000 +dd 0x0000a000, 0x00000004 +dd 0x0000e821, 0x00000004 +dd 0x0000e800, 0000000000 +dd 0x0000e821, 0x00000004 +dd 0x0000e82e, 0000000000 +dd 0x02cca000, 0x00000004 +dd 0x00140000, 0x00000004 +dd 0x000ce1cc, 0x00000004 +dd 0x050de1cd, 0x00000004 +dd 0x00400000, 0x00000004 +dd 0x0000008f, 0x00000018 +dd 0x00c0a000, 0x00000004 +dd 0x0000008c, 0x00000008 +dd 0x00000091, 0x00000020 +dd 0x4200e000, 0000000000 +dd 0x00000098, 0x00000038 +dd 0x000ca000, 0x00000004 +dd 0x00140000, 0x00000004 +dd 0x000c2000, 0x00000004 +dd 0x00160000, 0x00000004 +dd 0x700ce000, 0x00000004 +dd 0x00140094, 0x00000008 +dd 0x4000e000, 0000000000 +dd 0x02400000, 0x00000004 +dd 0x400ee000, 0x00000004 +dd 0x02400000, 0x00000004 +dd 0x4000e000, 0000000000 +dd 0x000c2000, 0x00000004 +dd 0x0240e51b, 0x00000004 +dd 0x0080e50a, 0x00000005 +dd 0x0080e50b, 0x00000005 +dd 0x00220000, 0x00000004 +dd 0x000700c7, 0x00000004 +dd 0x000000a4, 0x00000038 +dd 0x0080e5bd, 0x00000005 +dd 0x0000e5bb, 0x00000005 +dd 0x0080e5bc, 0x00000005 +dd 0x00210000, 0x00000004 +dd 0x02800000, 0x00000004 +dd 0x00c000ab, 0x00000018 +dd 0x4180e000, 0x00000040 +dd 0x000000ad, 0x00000024 +dd 0x01000000, 0x0000000c +dd 0x0100e51d, 0x0000000c +dd 0x000045bb, 0x00000004 +dd 0x000080a7, 0x00000008 +dd 0x0000f3ce, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x00cc2000, 0x00000004 +dd 0x08c053cf, 0x00000040 +dd 0x00008000, 0000000000 +dd 0x0000f3d2, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x00cc2000, 0x00000004 +dd 0x08c053d3, 0x00000040 +dd 0x00008000, 0000000000 +dd 0x0000f39d, 0x00000004 +dd 0x0140a000, 0x00000004 +dd 0x00cc2000, 0x00000004 +dd 0x08c0539e, 0x00000040 +dd 0x00008000, 0000000000 +dd 0x03c00830, 0x00000004 +dd 0x4200e000, 0000000000 +dd 0x0000a000, 0x00000004 +dd 0x200045e0, 0x00000004 +dd 0x0000e5e1, 0000000000 +dd 0x00000001, 0000000000 +dd 0x000700c4, 0x00000004 +dd 0x0800e394, 0000000000 +dd 0000000000, 0000000000 +dd 0x0000e8c4, 0x00000004 +dd 0x0000e8c5, 0x00000004 +dd 0x0000e8c6, 0x00000004 +dd 0x0000e928, 0x00000004 +dd 0x0000e929, 0x00000004 +dd 0x0000e92a, 0x00000004 +dd 0x000000c8, 0x00000008 +dd 0x0000e928, 0x00000004 +dd 0x0000e929, 0x00000004 +dd 0x0000e92a, 0x00000004 +dd 0x000000cf, 0x00000008 +dd 0xdeadbeef, 0000000000 +dd 0x00000116, 0000000000 +dd 0x000700d3, 0x00000004 +dd 0x080050e7, 0x00000004 +dd 0x000700d4, 0x00000004 +dd 0x0800401c, 0x00000004 +dd 0x0000e01d, 0000000000 +dd 0x02c02000, 0x00000004 +dd 0x00060000, 0x00000004 +dd 0x000000de, 0x00000034 +dd 0x000000db, 0x00000008 +dd 0x00008000, 0x00000004 +dd 0xc000e000, 0000000000 +dd 0x0000e1cc, 0x00000004 +dd 0x0500e1cd, 0x00000004 +dd 0x000ca000, 0x00000004 +dd 0x000000e5, 0x00000034 +dd 0x000000e1, 0x00000008 +dd 0x0000a000, 0000000000 +dd 0x0019e1cc, 0x00000004 +dd 0x001b0001, 0x00000004 +dd 0x0500a000, 0x00000004 +dd 0x080041cd, 0x00000004 +dd 0x000ca000, 0x00000004 +dd 0x000000fb, 0x00000034 +dd 0x0000004a, 0x00000008 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0x000c2000, 0x00000004 +dd 0x001d0018, 0x00000004 +dd 0x001a0001, 0x00000004 +dd 0x000000fb, 0x00000034 +dd 0x0000004a, 0x00000008 +dd 0x0500a04a, 0x00000008 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 +dd 0000000000, 0000000000 + + +end if + +if 0 +msg6100 db '6100: ',0 +msg6104 db '6104: ',0 +msg6108 db '6108: ',0 +msg6110 db '6110: ',0 +msg6120 db '6120: ',0 +msg6124 db '6124: ',0 +msg6128 db '6128: ',0 +msg612C db '612C: ',0 +msg6130 db '6130: ',0 +msg6134 db '6134: ',0 +msg6138 db '6138: ',0 +end if + +buff db 8 dup(0) + db 13,10, 0 + +section '.data' data readable writable align 16 + +pCursor db 4096 dup(?) + +cursor_map rd 2 +cursor_start rd 1 +cursor_end rd 1 + +fnSelect rd 1 +fnSet rd 1 +oldSelect rd 1 +oldSet rd 1 +oldRestore rd 1 +oldCreate rd 1 + +r500_LFB rd 1 + +bus dd ? +devfn dd ? +ati_io dd ? + +if R500_HW2D + +__xmin rd 1 +__xmax rd 1 +__ymin rd 1 +__ymax rd 1 + +rhd RHD + +end if diff --git a/kernel/branches/kolibri_pe/drivers/codec.inc b/kernel/branches/kolibri_pe/drivers/codec.inc new file mode 100644 index 000000000..f79102f69 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + + diff --git a/kernel/branches/kolibri_pe/drivers/com_mouse.asm b/kernel/branches/kolibri_pe/drivers/com_mouse.asm new file mode 100644 index 000000000..4d764fd24 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/com_mouse.asm @@ -0,0 +1,374 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;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 + cmp eax, 0 + jne .label1 + + mov esi, msg_error_attach_int_handler + call Boot_Log +end if + .label1: + mov eax, 0 + mov ebx, 0x3F8 + mov ecx, 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 + 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 + cmp eax, 0 + 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 + je 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 + diff --git a/kernel/branches/kolibri_pe/drivers/ensoniq.asm b/kernel/branches/kolibri_pe/drivers/ensoniq.asm new file mode 100644 index 000000000..d5fe56fc3 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + + diff --git a/kernel/branches/kolibri_pe/drivers/imports.inc b/kernel/branches/kolibri_pe/drivers/imports.inc new file mode 100644 index 000000000..df1ee70f0 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/drivers/infinity.asm b/kernel/branches/kolibri_pe/drivers/infinity.asm new file mode 100644 index 000000000..2e006c935 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/infinity.asm @@ -0,0 +1,1307 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 edx, edx + mov ebx, 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: + 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: + 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: + 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 + + + + + + diff --git a/kernel/branches/kolibri_pe/drivers/main.inc b/kernel/branches/kolibri_pe/drivers/main.inc new file mode 100644 index 000000000..67198c304 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 ? +} + diff --git a/kernel/branches/kolibri_pe/drivers/mix_mmx.inc b/kernel/branches/kolibri_pe/drivers/mix_mmx.inc new file mode 100644 index 000000000..5778cc823 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/drivers/mix_sse2.inc b/kernel/branches/kolibri_pe/drivers/mix_sse2.inc new file mode 100644 index 000000000..aa450a61f --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/drivers/mixer.asm b/kernel/branches/kolibri_pe/drivers/mixer.asm new file mode 100644 index 000000000..6c26671ad --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/mixer.asm @@ -0,0 +1,1263 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ecx, EVENT_WATCHED + xor edx, edx + call RaiseEvent ;eax, ebx, ecx, edx +.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 edx, [event] + + mov dword [edx], RT_INP_EMPTY + mov dword [edx+4], 0 + mov dword [edx+8], ebx + mov dword [edx+12], eax + + mov eax, [ebx+STREAM.notify_event] + test eax, eax + jz .exit + + mov ebx, [ebx+STREAM.notify_id] + xor ecx, ecx + call RaiseEvent ;eax, ebx, ecx, edx +.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 + diff --git a/kernel/branches/kolibri_pe/drivers/proc32.inc b/kernel/branches/kolibri_pe/drivers/proc32.inc new file mode 100644 index 000000000..23c56b03c --- /dev/null +++ b/kernel/branches/kolibri_pe/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, \{ 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: + \\\{ 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 } diff --git a/kernel/branches/kolibri_pe/drivers/ps2m_iofuncs.inc b/kernel/branches/kolibri_pe/drivers/ps2m_iofuncs.inc new file mode 100644 index 000000000..5c5d7d144 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/ps2m_iofuncs.inc @@ -0,0 +1,141 @@ +kbd_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 + + +kbd_write: + + push ecx edx + + mov dl,al + 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 + + +kbd_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 + +mouse_cmd: + mov [mouse_cmd_byte], al + mov [mouse_nr_resends], 5 + .resend: + mov bl, 0xd4 + call kbd_cmd + cmp ah,1 + je .fail + + mov al, [mouse_cmd_byte] + call kbd_write + cmp ah, 1 + je .fail + + call mouse_read + + cmp al, 0xFA + jne .noack + clc + ret + .noack: + cmp al, 0xFE ; resend + jne .noresend + dec [mouse_nr_resends] + jnz .resend + .noresend: + .fail: + stc + ret + + +mouse_read: + mov [mouse_nr_tries], 100 + .repeat: + call kbd_read + cmp ah, 1 + jne .fin + mov esi, 10 + call Sleep + dec [mouse_nr_tries] + jnz .repeat + + stc + ret + + .fin: + clc + ret diff --git a/kernel/branches/kolibri_pe/drivers/ps2m_irqh.inc b/kernel/branches/kolibri_pe/drivers/ps2m_irqh.inc new file mode 100644 index 000000000..ee6cf3eed --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/ps2m_irqh.inc @@ -0,0 +1,120 @@ +;************************************** +;* IRQ HANDLER FOR PS/2 MOUSE * +;************************************** + +proc irq_handler + + call Wait8042BufferEmpty ;clear buffer + in al,0x60 ;get scan-code + + cmp [mouse_byte],0 + je .byte1 + cmp [mouse_byte],1 + je .byte2 + cmp [mouse_byte],2 + je .byte3 + cmp [mouse_byte],3 + je .byte4 + jmp .error + + .byte1: + test al,1000b ;first byte? + jz .error + mov [first_byte],al + inc [mouse_byte] + jmp .exit + + .byte2: + mov [second_byte],al + inc [mouse_byte] + jmp .exit + + .byte3: + mov [third_byte],al + cmp [MouseType],MT_3B + je .full_packet + inc [mouse_byte] + jmp .exit + + .byte4: + mov [fourth_byte],al + + + .full_packet: + mov [mouse_byte],0 + mov al,byte [first_byte] + and eax,7 + mov byte [ButtonState],al + + cmp [MouseType],MT_3B + je .xy_moving + mov al,[fourth_byte] + cmp [MouseType],MT_3BScroll + je .z_moving + + mov ah,al + and ah,00110000b + shr ah,1 + or byte [ButtonState],ah + and al,00001111b + bt eax,3 + jnc .z_moving + or al,11110000b + + .z_moving: + movsx eax,al + mov [ZMoving],eax + + .xy_moving: + mov ah,0 + mov al,[first_byte] + test al,10000b + jz @f + mov ah,0FFh + + @@: + mov al,[second_byte] + cwd + mov [XMoving],eax + + mov ah,0 + mov al,[first_byte] + test al,100000b + jz @f + mov ah,0FFh + + @@: + mov al,[third_byte] + cwd + + @@: + mov [YMoving],eax + stdcall SetMouseData, [ButtonState], [XMoving], [YMoving], [ZMoving], 0 + + + jmp .exit + + .error: + mov [mouse_byte],0 + + .exit: + ret +endp + + +;*********************************************** +;* Waiting for clearing I8042 buffer * +;* Retutned state: * +;* ZF is set - good ending, * +;* ZF is cleared - time-out error. * +;*********************************************** +Wait8042BufferEmpty: + push ecx + xor ecx,ecx + @@: + in al,64h + test al,00000010b + loopnz @b + pop ecx + + ret diff --git a/kernel/branches/kolibri_pe/drivers/ps2mouse.asm b/kernel/branches/kolibri_pe/drivers/ps2mouse.asm new file mode 100644 index 000000000..db7567373 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/ps2mouse.asm @@ -0,0 +1,270 @@ +format MS COFF + +DEBUG equ 0 + +include 'proc32.inc' +include 'imports.inc' + +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 + +MT_3B equ 0 +MT_3BScroll equ 1 +MT_5BScroll equ 2 + +PS2_DRV_VER equ 1 + +section '.flat' code readable align 16 + + +proc START stdcall, state:dword + + cmp [state], DRV_ENTRY + jne .fin + .init: + + call detect_mouse + test eax,eax + jnz .exit + + mov [MouseType],MT_3B + + call try_mode_ID3 + test eax,eax + jnz .stop_try + mov [MouseType],MT_3BScroll + + call try_mode_ID4 + test eax,eax + jnz .stop_try + mov [MouseType],MT_5BScroll + + .stop_try: + + mov bl, 0x20 ; read command byte + call kbd_cmd + cmp ah,1 + je .exit + + call kbd_read + cmp ah,1 + je .exit + + or al, 10b + push eax + mov bl, 0x60 ; write command byte + call kbd_cmd + cmp ah,1 + je .exit + + pop eax + call kbd_write + cmp ah,1 + je .exit + + mov al, 0xF4 ; enable data reporting + call mouse_cmd + + mov bl, 0xAE ; enable keyboard interface + call kbd_cmd + + stdcall AttachIntHandler, 12, irq_handler, dword 0 + stdcall RegService, my_service, service_proc + ret + + .fin: + ;stdcall DetachIntHandler, 12, irq_handler + mov bl, 0xA7 ; disable mouse interface + call kbd_cmd + xor eax, eax + ret + + .exit: + mov bl, 0xA7 ; disable mouse interface + call kbd_cmd + mov bl, 0xAE ; enable keyboard interface + call kbd_cmd + xor eax, eax + ret +endp + +proc service_proc stdcall, ioctl:dword + mov edi, [ioctl] + mov eax, [edi+IOCTL.io_code] + test eax, eax + jz .getversion + cmp eax,1 + jz .gettype + + .err: + or eax, -1 + ret + + .ok: + xor eax, eax + ret + + .getversion: + cmp [edi+IOCTL.out_size], 4 + jb .err + mov edi, [edi+IOCTL.output] + mov dword [edi], PS2_DRV_VER ; version of driver + jmp .ok + .gettype: + cmp [edi+IOCTL.out_size], 4 + jb .err + mov edi, [edi+IOCTL.output] + mov eax,[MouseType] + mov dword [edi], eax ; mouse type + jmp .ok +endp + +detect_mouse: + + mov bl, 0xAD ; disable keyboard interface + call kbd_cmd + cmp ah,1 + je .fail + + mov bl, 0xA8 ; enable mouse interface + call kbd_cmd + cmp ah,1 + je .fail + + mov al, 0xFF ; reset + call mouse_cmd + jc .fail + + call mouse_read + jc .fail + cmp al, 0xAA + jne .fail ; dead mouse + + ; get device ID + call mouse_read + jc .fail + cmp al, 0x00 + jne .fail ; unknown device + xor eax,eax + ret + + .fail: + or eax,-1 + ret + +try_mode_ID3: + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0xC8 ;200d + call mouse_cmd + jc .fail + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0x64 ;100d + call mouse_cmd + jc .fail + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0x50 ;80d + call mouse_cmd + jc .fail + + mov al, 0xF2 ;Get device id + call mouse_cmd + jc .fail + + call mouse_read + jc .fail + cmp al, 0x03 + jne .fail + + xor eax,eax + ret + .fail: + or eax,-1 + ret + +try_mode_ID4: + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0xC8 ;200d + call mouse_cmd + jc .fail + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0xC8 ;100d + call mouse_cmd + jc .fail + mov al, 0xF3 ;Set Sample Rate + call mouse_cmd + jc .fail + mov al, 0x50 ;80d + call mouse_cmd + jc .fail + + mov al, 0xF2 ;Get device id + call mouse_cmd + jc .fail + + call mouse_read + jc .fail + cmp al, 0x04 + jne .fail + + xor eax,eax + ret + + .fail: + or eax,-1 + ret + +include 'ps2m_iofuncs.inc' +include 'ps2m_irqh.inc' + +section '.data' data readable writable align 16 + +version dd 0x00050005 +my_service db 'ps2mouse',0 + +;iofuncs data +mouse_cmd_byte db 0 +mouse_nr_tries db 0 +mouse_nr_resends db 0 + +;hid data +mouse_byte dd 0 + +first_byte db 0 +second_byte db 0 +third_byte db 0 +fourth_byte db 0 + +;main data +MouseType dd 0 + +XMoving dd 0 +YMoving dd 0 +ZMoving dd 0 +ButtonState dd 0 +;timerTicks dd 0 diff --git a/kernel/branches/kolibri_pe/drivers/r500hw.inc b/kernel/branches/kolibri_pe/drivers/r500hw.inc new file mode 100644 index 000000000..32181825b --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/r500hw.inc @@ -0,0 +1,1268 @@ +if 0 + + Copyright 2008 Serge + + The below code is a rework from code in + xf86-video-radeonhd/src/r5xx_accel.c, xf86-video-radeonhd/src/r5xx_xaa.c + + Copyright 2008 Luc Verhaegen + Copyright 2008 Matthias Hopf + Copyright 2008 Egbert Eich + Copyright 2008 Advanced Micro Devices, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + The below code is a rework from code in xf86-video-ati/src/radeon_accel.c + The original license is included below, it has the messed up disclaimer and + an all rights reserved statement. + + + Copyright 2000 ATI Technologies Inc., Markham, Ontario, and + VA Linux Systems Inc., Fremont, California. + + All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation on the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Authors: + Kevin E. Martin + Rickard E. Faith + Alan Hourihane + +end if + +RADEON_CP_ME_RAM_ADDR equ 0x07d4 +RADEON_CP_ME_RAM_RADDR equ 0x07d8 +RADEON_CP_ME_RAM_DATAH equ 0x07dc +RADEON_CP_ME_RAM_DATAL equ 0x07e0 + +RADEON_CP_RB_BASE equ 0x0700 +RADEON_CP_RB_CNTL equ 0x0704 + RADEON_RB_NO_UPDATE equ (1 shl 27) +RADEON_CP_RB_RPTR_ADDR equ 0x070c +RADEON_CP_RB_RPTR equ 0x0710 +RADEON_CP_RB_WPTR equ 0x0714 + +RADEON_CP_CSQ_CNTL equ 0x0740 + RADEON_CSQ_CNT_PRIMARY_MASK equ (0xff shl 0) + RADEON_CSQ_PRIDIS_INDDIS equ (0 shl 28) + RADEON_CSQ_PRIPIO_INDDIS equ (1 shl 28) + RADEON_CSQ_PRIBM_INDDIS equ (2 shl 28) + RADEON_CSQ_PRIPIO_INDBM equ (3 shl 28) + RADEON_CSQ_PRIBM_INDBM equ (4 shl 28) + RADEON_CSQ_PRIPIO_INDPIO equ (15 shl 28) + +RADEON_CP_RB_WPTR_DELAY equ 0x0718 + +RADEON_SCRATCH_UMSK equ 0x0770 +RADEON_SCRATCH_ADDR equ 0x0774 + +RADEON_ISYNC_CNTL equ 0x1724 + RADEON_ISYNC_ANY2D_IDLE3D equ (1 shl 0) + RADEON_ISYNC_ANY3D_IDLE2D equ (1 shl 1) + RADEON_ISYNC_TRIG2D_IDLE3D equ (1 shl 2) + RADEON_ISYNC_TRIG3D_IDLE2D equ (1 shl 3) + RADEON_ISYNC_WAIT_IDLEGUI equ (1 shl 4) + RADEON_ISYNC_CPSCRATCH_IDLEGUI equ (1 shl 5) + +RADEON_AIC_CNTL equ 0x01d0 + RADEON_PCIGART_TRANSLATE_EN equ (1 shl 0) +RADEON_AIC_STAT equ 0x01d4 +RADEON_AIC_PT_BASE equ 0x01d8 +RADEON_AIC_LO_ADDR equ 0x01dc +RADEON_AIC_HI_ADDR equ 0x01e0 +RADEON_AIC_TLB_ADDR equ 0x01e4 +RADEON_AIC_TLB_DATA equ 0x01e8 + +RADEON_WAIT_UNTIL equ 0x1720 + RADEON_WAIT_CRTC_PFLIP equ (1 shl 0) + RADEON_WAIT_2D_IDLE equ (1 shl 14) + RADEON_WAIT_3D_IDLE equ (1 shl 15) + RADEON_WAIT_2D_IDLECLEAN equ (1 shl 16) + RADEON_WAIT_3D_IDLECLEAN equ (1 shl 17) + RADEON_WAIT_HOST_IDLECLEAN equ (1 shl 18) + +D1GRPH_PITCH equ 0x6120 +D1GRPH_X_END equ 0x6134 +D1GRPH_Y_END equ 0x6138 + + +R5XX_DATATYPE_ARGB8888 equ 6 + +R5XX_RB3D_CNTL equ 0x1c3c + +R5XX_RBBM_STATUS equ 0x0e40 + R5XX_RBBM_FIFOCNT_MASK equ 0x007f + R5XX_RBBM_ACTIVE equ (1 shl 31) + +R5XX_RBBM_SOFT_RESET equ 0x00f0 + R5XX_SOFT_RESET_CP equ (1 shl 0) + R5XX_SOFT_RESET_HI equ (1 shl 1) + R5XX_SOFT_RESET_SE equ (1 shl 2) + R5XX_SOFT_RESET_RE equ (1 shl 3) + R5XX_SOFT_RESET_PP equ (1 shl 4) + R5XX_SOFT_RESET_E2 equ (1 shl 5) + R5XX_SOFT_RESET_RB equ (1 shl 6) + R5XX_SOFT_RESET_HDP equ (1 shl 7) + +R5XX_SRC_PITCH_OFFSET equ 0x1428 +R5XX_DST_PITCH_OFFSET equ 0x142c + +R5XX_DP_DATATYPE equ 0x16c4 + R5XX_HOST_BIG_ENDIAN_EN equ (1 shl 29) + +R5XX_DP_CNTL equ 0x16c0 + R5XX_DST_X_LEFT_TO_RIGHT equ (1 shl 0) + R5XX_DST_Y_TOP_TO_BOTTOM equ (1 shl 1) + R5XX_DP_DST_TILE_LINEAR equ (0 shl 3) + R5XX_DP_DST_TILE_MACRO equ (1 shl 3) + R5XX_DP_DST_TILE_MICRO equ (2 shl 3) + R5XX_DP_DST_TILE_BOTH equ (3 shl 3) + +RADEON_RB3D_ZCACHE_CTLSTAT equ 0x3254 + RADEON_RB3D_ZC_FLUSH equ (1 shl 0) + RADEON_RB3D_ZC_FREE equ (1 shl 2) + RADEON_RB3D_ZC_FLUSH_ALL equ 0x5 + RADEON_RB3D_ZC_BUSY equ (1 shl 31) + +R5XX_RB3D_DSTCACHE_CTLSTAT equ 0x325C + R5XX_RB3D_DC_FLUSH equ (3 shl 0) + R5XX_RB3D_DC_FREE equ (3 shl 2) + R5XX_RB3D_DC_FLUSH_ALL equ 0xf + R5XX_RB3D_DC_BUSY equ (1 shl 31) + +R5XX_SURFACE_CNTL equ 0x0b00 + R5XX_SURF_TRANSLATION_DIS equ (1 shl 8) + R5XX_NONSURF_AP0_SWP_16BPP equ (1 shl 20) + R5XX_NONSURF_AP0_SWP_32BPP equ (1 shl 21) + R5XX_NONSURF_AP1_SWP_16BPP equ (1 shl 22) + R5XX_NONSURF_AP1_SWP_32BPP equ (1 shl 23) + +R5XX_DEFAULT_SC_BOTTOM_RIGHT equ 0x16e8 + R5XX_DEFAULT_SC_RIGHT_MAX equ (0x1fff shl 0) + R5XX_DEFAULT_SC_BOTTOM_MAX equ (0x1fff shl 16) + +R5XX_SC_TOP_LEFT equ 0x16ec + R5XX_SC_BOTTOM_RIGHT equ 0x16f0 + R5XX_SC_SIGN_MASK_LO equ 0x8000 + R5XX_SC_SIGN_MASK_HI equ 0x80000000 + +R5XX_DP_GUI_MASTER_CNTL equ 0x146c +R5XX_GMC_SRC_PITCH_OFFSET_CNTL equ (1 shl 0) +R5XX_GMC_DST_PITCH_OFFSET_CNTL equ (1 shl 1) +R5XX_GMC_SRC_CLIPPING equ (1 shl 2) +R5XX_GMC_DST_CLIPPING equ (1 shl 3) +R5XX_GMC_BRUSH_DATATYPE_MASK equ (0x0f shl 4) +R5XX_GMC_BRUSH_8X8_MONO_FG_BG equ (0 shl 4) +R5XX_GMC_BRUSH_8X8_MONO_FG_LA equ (1 shl 4) +R5XX_GMC_BRUSH_1X8_MONO_FG_BG equ (4 shl 4) +R5XX_GMC_BRUSH_1X8_MONO_FG_LA equ (5 shl 4) +R5XX_GMC_BRUSH_32x1_MONO_FG_BG equ (6 shl 4) +R5XX_GMC_BRUSH_32x1_MONO_FG_LA equ (7 shl 4) +R5XX_GMC_BRUSH_32x32_MONO_FG_BG equ (8 shl 4) +R5XX_GMC_BRUSH_32x32_MONO_FG_LA equ (9 shl 4) +R5XX_GMC_BRUSH_8x8_COLOR equ (10 shl 4) +R5XX_GMC_BRUSH_1X8_COLOR equ (12 shl 4) +R5XX_GMC_BRUSH_SOLID_COLOR equ (13 shl 4) +R5XX_GMC_BRUSH_NONE equ (15 shl 4) +R5XX_GMC_DST_8BPP_CI equ (2 shl 8) +R5XX_GMC_DST_15BPP equ (3 shl 8) +R5XX_GMC_DST_16BPP equ (4 shl 8) +R5XX_GMC_DST_24BPP equ (5 shl 8) +R5XX_GMC_DST_32BPP equ (6 shl 8) +R5XX_GMC_DST_8BPP_RGB equ (7 shl 8) +R5XX_GMC_DST_Y8 equ (8 shl 8) +R5XX_GMC_DST_RGB8 equ (9 shl 8) +R5XX_GMC_DST_VYUY equ (11 shl 8) +R5XX_GMC_DST_YVYU equ (12 shl 8) +R5XX_GMC_DST_AYUV444 equ (14 shl 8) +R5XX_GMC_DST_ARGB4444 equ (15 shl 8) +R5XX_GMC_DST_DATATYPE_MASK equ (0x0f shl 8) +R5XX_GMC_DST_DATATYPE_SHIFT equ 8 +R5XX_GMC_SRC_DATATYPE_MASK equ (3 shl 12) +R5XX_GMC_SRC_DATATYPE_MONO_FG_BG equ (0 shl 12) +R5XX_GMC_SRC_DATATYPE_MONO_FG_LA equ (1 shl 12) +R5XX_GMC_SRC_DATATYPE_COLOR equ (3 shl 12) +R5XX_GMC_BYTE_PIX_ORDER equ (1 shl 14) +R5XX_GMC_BYTE_MSB_TO_LSB equ (0 shl 14) +R5XX_GMC_BYTE_LSB_TO_MSB equ (1 shl 14) +R5XX_GMC_CONVERSION_TEMP equ (1 shl 15) +R5XX_GMC_CONVERSION_TEMP_6500 equ (0 shl 15) +R5XX_GMC_CONVERSION_TEMP_9300 equ (1 shl 15) +R5XX_GMC_ROP3_MASK equ (0xff shl 16) +R5XX_DP_SRC_SOURCE_MASK equ (7 shl 24) +R5XX_DP_SRC_SOURCE_MEMORY equ (2 shl 24) +R5XX_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24) +R5XX_GMC_3D_FCN_EN equ (1 shl 27) +R5XX_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28) +R5XX_GMC_AUX_CLIP_DIS equ (1 shl 29) +R5XX_GMC_WR_MSK_DIS equ (1 shl 30) +R5XX_GMC_LD_BRUSH_Y_X equ (1 shl 31) +R5XX_ROP3_ZERO equ 0x00000000 +R5XX_ROP3_DSa equ 0x00880000 +R5XX_ROP3_SDna equ 0x00440000 +R5XX_ROP3_S equ 0x00cc0000 +R5XX_ROP3_DSna equ 0x00220000 +R5XX_ROP3_D equ 0x00aa0000 +R5XX_ROP3_DSx equ 0x00660000 +R5XX_ROP3_DSo equ 0x00ee0000 +R5XX_ROP3_DSon equ 0x00110000 +R5XX_ROP3_DSxn equ 0x00990000 +R5XX_ROP3_Dn equ 0x00550000 +R5XX_ROP3_SDno equ 0x00dd0000 +R5XX_ROP3_Sn equ 0x00330000 +R5XX_ROP3_DSno equ 0x00bb0000 +R5XX_ROP3_DSan equ 0x00770000 +R5XX_ROP3_ONE equ 0x00ff0000 +R5XX_ROP3_DPa equ 0x00a00000 +R5XX_ROP3_PDna equ 0x00500000 +R5XX_ROP3_P equ 0x00f00000 +R5XX_ROP3_DPna equ 0x000a0000 +R5XX_ROP3_D equ 0x00aa0000 +R5XX_ROP3_DPx equ 0x005a0000 +R5XX_ROP3_DPo equ 0x00fa0000 +R5XX_ROP3_DPon equ 0x00050000 +R5XX_ROP3_PDxn equ 0x00a50000 +R5XX_ROP3_PDno equ 0x00f50000 +R5XX_ROP3_Pn equ 0x000f0000 +R5XX_ROP3_DPno equ 0x00af0000 +R5XX_ROP3_DPan equ 0x005f0000 + +R5XX_HOST_PATH_CNTL equ 0x0130 +R5XX_HDP_SOFT_RESET equ (1 shl 26) +R5XX_HDP_APER_CNTL equ (1 shl 23) + +R5XX_RB3D_DSTCACHE_MODE equ 0x3258 +R5XX_RB3D_DC_CACHE_ENABLE equ (0) +R5XX_RB3D_DC_2D_CACHE_DISABLE equ (1) +R5XX_RB3D_DC_3D_CACHE_DISABLE equ (2) +R5XX_RB3D_DC_CACHE_DISABLE equ (3) +R5XX_RB3D_DC_2D_CACHE_LINESIZE_128 equ (1 shl 2) +R5XX_RB3D_DC_3D_CACHE_LINESIZE_128 equ (2 shl 2) +R5XX_RB3D_DC_2D_CACHE_AUTOFLUSH equ (1 shl 8) +R5XX_RB3D_DC_3D_CACHE_AUTOFLUSH equ (2 shl 8) +R200_RB3D_DC_2D_CACHE_AUTOFREE equ (1 shl 10) +R200_RB3D_DC_3D_CACHE_AUTOFREE equ (2 shl 10) +R5XX_RB3D_DC_FORCE_RMW equ (1 shl 16) +R5XX_RB3D_DC_DISABLE_RI_FILL equ (1 shl 24) +R5XX_RB3D_DC_DISABLE_RI_READ equ (1 shl 25) + +R5XX_BRUSH_Y_X equ 0x1474 +R5XX_DP_BRUSH_BKGD_CLR equ 0x1478 +R5XX_DP_BRUSH_FRGD_CLR equ 0x147c +R5XX_BRUSH_DATA0 equ 0x1480 +R5XX_BRUSH_DATA1 equ 0x1484 + +R5XX_SRC_Y_X equ 0x1434 + +R5XX_DST_Y_X equ 0x1438 +R5XX_DST_HEIGHT_WIDTH equ 0x143c +R5XX_DST_WIDTH_HEIGHT equ 0x1598 + +R5XX_DST_LINE_START equ 0x1600 +R5XX_DST_LINE_END equ 0x1604 +R5XX_DST_LINE_PATCOUNT equ 0x1608 + R5XX_BRES_CNTL_SHIFT equ 8 + + +R5XX_DP_SRC_BKGD_CLR equ 0x15dc +R5XX_DP_SRC_FRGD_CLR equ 0x15d8 + +R5XX_DP_WRITE_MASK equ 0x16cc + + +RADEON_CP_PACKET0 equ 0x00000000 + +struc RHD +{ + .control rd 1 + .control_saved rd 1 + .datatype rd 1 + .surface_cntl rd 1 + .dst_pitch_offset rd 1 + .ring_base rd 1 + .ring_rp rd 1 + .ring_wp rd 1 +}; + +R5XX_LOOP_COUNT equ 2000000 + + + +align 4 +R5xxFIFOWaitLocal: + + mov ecx, R5XX_LOOP_COUNT +@@: + rdr ebx, R5XX_RBBM_STATUS + and ebx, R5XX_RBBM_FIFOCNT_MASK + + cmp eax, ebx + jbe .done + loop @B + + mov esi, msgR5xxFIFOWaitLocaltimeout + call SysMsgBoardStr + xor eax, eax + ret +.done: + mov eax, 1 + ret + +align 4 +R5xxFIFOWait: + call R5xxFIFOWaitLocal + test eax, eax + jz .reset + + ret +.reset: + call R5xx2DReset + call R5xx2DSetup + + ret + + +; Wait for the graphics engine to be completely idle: the FIFO has +; drained, the Pixel Cache is flushed, and the engine is idle. This is +; a standard "sync" function that will make the hardware "quiescent". + +align 4 +R5xx2DIdleLocal: + + mov ecx, R5XX_LOOP_COUNT +@@: + rdr eax, R5XX_RBBM_STATUS + and eax, R5XX_RBBM_FIFOCNT_MASK + cmp eax, 0x40 + je @F + loop @B + + mov esi, msgR5xx2DIdleLocaltimeout + call SysMsgBoardStr + xor eax, eax + ret +@@: + mov ecx, R5XX_LOOP_COUNT +@@: + rdr eax, R5XX_RBBM_STATUS + test eax, R5XX_RBBM_ACTIVE + jz .done + loop @B + + mov esi, msgR5xx2DIdleLocaltimeout + call SysMsgBoardStr + xor eax, eax + ret +.done: + call R5xx2DFlush + ret + +align 4 +R5xx2DFlush: + rmask R5XX_RB3D_DSTCACHE_CTLSTAT, R5XX_RB3D_DC_FLUSH_ALL, R5XX_RB3D_DC_FLUSH_ALL + + mov ecx, R5XX_LOOP_COUNT +@@: + rdr eax, R5XX_RB3D_DSTCACHE_CTLSTAT + test eax, R5XX_RB3D_DC_BUSY + jz .done + loop @B +.fail: + mov esi, msgR5xx2DFlushtimeout + call SysMsgBoardStr + xor eax, eax + ret +.done: + mov eax, 1 + ret + +align 4 +proc R5xx2DReset + locals + save rd 1 + tmp rd 1 + endl + + ; The following RBBM_SOFT_RESET sequence can help un-wedge + ; an R300 after the command processor got stuck. + + rdr eax, R5XX_RBBM_SOFT_RESET + mov [save], eax + + or eax, R5XX_SOFT_RESET_CP or \ + R5XX_SOFT_RESET_HI or R5XX_SOFT_RESET_SE or \ + R5XX_SOFT_RESET_RE or R5XX_SOFT_RESET_PP or \ + R5XX_SOFT_RESET_E2 or R5XX_SOFT_RESET_RB + mov [tmp], eax + + wrr R5XX_RBBM_SOFT_RESET, eax + + rdr ebx, R5XX_RBBM_SOFT_RESET + and eax, not (R5XX_SOFT_RESET_CP or R5XX_SOFT_RESET_HI or \ + R5XX_SOFT_RESET_SE or R5XX_SOFT_RESET_RE or \ + R5XX_SOFT_RESET_PP or R5XX_SOFT_RESET_E2 or \ + R5XX_SOFT_RESET_RB) + wrr R5XX_RBBM_SOFT_RESET, eax + rdr ebx, R5XX_RBBM_SOFT_RESET + mov eax, [save] + wrr R5XX_RBBM_SOFT_RESET, eax + rdr ebx, R5XX_RBBM_SOFT_RESET + call R5xx2DFlush + +; Soft resetting HDP thru RBBM_SOFT_RESET register can cause some +; unexpected behaviour on some machines. Here we use +; R5XX_HOST_PATH_CNTL to reset it. + + rdr edx, R5XX_HOST_PATH_CNTL + + rdr ebx, R5XX_RBBM_SOFT_RESET + + or ebx, R5XX_SOFT_RESET_CP or R5XX_SOFT_RESET_HI or R5XX_SOFT_RESET_E2 + + wrr R5XX_RBBM_SOFT_RESET, ebx + + rdr eax, R5XX_RBBM_SOFT_RESET + + wrr R5XX_RBBM_SOFT_RESET, 0 + + rdr ebx, R5XX_RB3D_DSTCACHE_MODE + + or ebx, (1 shl 17) + wrr R5XX_RB3D_DSTCACHE_MODE, ebx + + lea eax, [edx+R5XX_HDP_SOFT_RESET] + wrr R5XX_HOST_PATH_CNTL, eax + + rdr ebx, R5XX_HOST_PATH_CNTL + + wrr R5XX_HOST_PATH_CNTL, edx + + ret +endp + +align 4 +R5xx2DSetup: + +; Setup engine location. This shouldn't be necessary since we +; set them appropriately before any accel ops, but let's avoid +; random bogus DMA in case we inadvertently trigger the engine +; in the wrong place (happened). + + mov eax, 2 + call R5xxFIFOWaitLocal + + mov eax, [rhd.dst_pitch_offset] + wrr R5XX_DST_PITCH_OFFSET, eax + + wrr R5XX_SRC_PITCH_OFFSET, eax + + mov eax, 1 + call R5xxFIFOWaitLocal + + rmask R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN + + mov eax, [rhd.surface_cntl] + wrr R5XX_SURFACE_CNTL, eax + + mov eax, 1 + call R5xxFIFOWaitLocal + + wrr R5XX_DEFAULT_SC_BOTTOM_RIGHT,\ + (R5XX_DEFAULT_SC_RIGHT_MAX or R5XX_DEFAULT_SC_BOTTOM_MAX) + + mov eax, 1 + call R5xxFIFOWaitLocal + + mov eax, [rhd.control] + or eax, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR) + wrr R5XX_DP_GUI_MASTER_CNTL, eax + + mov eax, 5 + call R5xxFIFOWaitLocal + + wrr R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF + + wrr R5XX_DP_BRUSH_BKGD_CLR, 0x00000000 + + wrr R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF + wrr R5XX_DP_SRC_BKGD_CLR, 0x00000000 + wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF + + call R5xx2DIdleLocal + ret + +align 4 +R5xx2DPreInit: + + mov [rhd.control],\ + (R5XX_DATATYPE_ARGB8888 shl R5XX_GMC_DST_DATATYPE_SHIFT) or\ + R5XX_GMC_CLR_CMP_CNTL_DIS or R5XX_GMC_DST_PITCH_OFFSET_CNTL + + mov [rhd.datatype], R5XX_DATATYPE_ARGB8888 + mov [rhd.surface_cntl],0 + + rdr eax, D1GRPH_PITCH + shl eax, 18 + + mov ebx, [r500_LFB] + shr ebx, 10 + or eax, ebx + + mov [rhd.dst_pitch_offset], eax + + ret + +RADEON_BUS_CNTL equ 0x0030 + RADEON_BUS_MASTER_DIS equ (1 shl 6) + +align 4 +R5xxCpInit: + stdcall CreateRingBuffer, 0x8000, PG_SW+PG_NOCACHE + test eax, eax + jz .fail + + mov [rhd.ring_base], eax + call GetPgAddr + + wrr RADEON_CP_RB_BASE, eax + + wrr RADEON_CP_RB_WPTR_DELAY, 0 + + rdr ebx, RADEON_CP_RB_RPTR + wrr RADEON_CP_RB_WPTR, ebx + + mov [rhd.ring_rp], ebx + mov [rhd.ring_wp], ebx + + wrr RADEON_CP_RB_RPTR_ADDR, 0 ;ring buffer read pointer + ;no update + + wrr RADEON_CP_RB_CNTL, RADEON_RB_NO_UPDATE + 12 + wrr RADEON_SCRATCH_UMSK, 0 ;no scratch update + + rdr ebx, RADEON_BUS_CNTL + and ebx, not RADEON_BUS_MASTER_DIS + + wrr RADEON_BUS_CNTL, ebx + + ; wrr RADEON_LAST_FRAME_REG, 0 + ; wrr RADEON_LAST_DISPATCH_REG, 0 + ; wrr RADEON_LAST_CLEAR_REG, 0 + + call R5xx2DIdleLocal + + wrr RADEON_ISYNC_CNTL, RADEON_ISYNC_ANY2D_IDLE3D + \ + RADEON_ISYNC_ANY3D_IDLE2D + \ + RADEON_ISYNC_WAIT_IDLEGUI + \ + RADEON_ISYNC_CPSCRATCH_IDLEGUI +.fail: + ret + +align 4 +load_microcode: + + pushfd + cli + + call R5xx2DIdleLocal + + wrr RADEON_CP_ME_RAM_ADDR, 0 + + lea esi, [R520_cp_microcode] + mov ecx, 256 +@@: + mov eax, [esi] + mov ebx, [esi+4] + wrr RADEON_CP_ME_RAM_DATAH, ebx + wrr RADEON_CP_ME_RAM_DATAL, eax + add esi, 8 + loop @B + + popfd + ret + + +align 4 +R5xx2DInit: + + call R5xx2DPreInit + wrr R5XX_RB3D_CNTL, 0 + + call R5xx2DReset + call R5xx2DSetup + + rdr eax, RADEON_AIC_CNTL ;disable GART + and eax, not RADEON_PCIGART_TRANSLATE_EN + wrr RADEON_AIC_CNTL, eax + + call load_microcode + + call R5xxCpInit + + rdr eax, D1GRPH_X_END + rdr ebx, D1GRPH_Y_END + dec eax + dec ebx + + mov [__xmin], 0 ;set clip + mov [__ymin], 0 + mov [__xmax], eax + mov [__ymax], ebx + + wrr RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM + + ; BEGIN_RING + ; RADEON_PURGE_CACHE + ; RADEON_PURGE_ZCACHE + ; RADEON_WAIT_UNTIL_IDLE + ; COMMIT_RING + + ret + +proc R5xxSetupForSolidFill stdcall,color:dword, rop:dword, planemask:dword + + mov edx, [rop] + mov edx, [R5xxRops+4+edx*8] + or edx, [rhd.control] + or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR) + +; Save for later clipping */ + mov [rhd.control_saved], edx + + mov eax, 4 + call R5xxFIFOWait + + wrr R5XX_DP_GUI_MASTER_CNTL, edx + + mov eax, [color] + wrr R5XX_DP_BRUSH_FRGD_CLR, eax + + mov ebx, [planemask] + wrr R5XX_DP_WRITE_MASK, ebx + + wrr R5XX_DP_CNTL, (R5XX_DST_X_LEFT_TO_RIGHT or R5XX_DST_Y_TOP_TO_BOTTOM) + + ret + endp + +align 4 +proc R5xxSolidFillRect stdcall, x:dword, y:dword, w:dword, h:dword + + mov eax, 3 + call R5xxFIFOWait + + mov eax, [rhd.dst_pitch_offset] + wrr R5XX_DST_PITCH_OFFSET, eax + + mov ebx, [y] + shl ebx, 16 + mov bx, word [x] + wrr R5XX_DST_Y_X, ebx + + mov ecx, [w] + shl ecx, 16 + mov cx, word [h] + wrr R5XX_DST_WIDTH_HEIGHT, ecx + + 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 +SOLID_FILL equ 1 +LINE_2P equ 2 + +align 4 +proc r500_entry stdcall, state:dword + +.close: + ; call r500_close + + xor eax, eax + ret +endp + +CURRENT_TASK equ (OS_BASE+0x0003000) +TASK_COUNT equ (OS_BASE+0x0003004) +WIN_STACK equ (OS_BASE+0x000C000) + + +align 4 +proc r500_HDraw stdcall, ioctl:dword + + mov ebx, [ioctl] + mov eax, [ebx+io_code] + cmp eax, LINE_2P + ja .fail + + 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 +@@: + mov edx, [CURRENT_TASK] + movzx edx, word [WIN_STACK+edx*2] + cmp edx, [TASK_COUNT] + jne .skip ;skip if window inactive + + cmp eax, SOLID_FILL + jne @F + + cmp [ebx+inp_size], 5 + jne .fail + + mov esi, [ebx+input] + call solid_fill +.skip: + xor eax, eax + ret +@@: + cmp eax, LINE_2P + jne @F + + cmp [ebx+inp_size], 5 + jne .fail + + mov esi, [ebx+input] + call solid_line + 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 + +struc FILL +{ + .color rd 1 + .x rd 1 + .y rd 1 + .w rd 1 + .h rd 1 +} + +virtual at 0 + FILL FILL +end virtual + +struc LINE2P +{ + .color rd 1 + .x1 rd 1 + .y1 rd 1 + .x2 rd 1 + .y2 rd 1 +} + +virtual at 0 + LINE2P LINE2P +end virtual + +GXcopy equ 3 + +RADEON_CP_PACKET3 equ 0xC0000000 + +PAINT_MULTI equ 0xC0009A00 + +DST_PITCH_OFFSET_CNTL equ ( 1 shl 1) +BRUSH_SOLID_COLOR equ ( 13 shl 4) +COLOR_ARGB equ ( 6 shl 8) +SRC_DATATYPE_COLOR equ ( 3 shl 12) + +;RADEON_ROP3_P equ + +; esi= input params +align 4 +solid_fill: + + mov ebx, [esi+FILL.x] + mov ecx, [esi+FILL.y] + mov eax, [esi+FILL.w] + mov edx, [esi+FILL.h] + + lea eax, [eax+ebx-1] ;x2 + lea edx, [edx+ecx-1] ;y2 + + push edx ;y2 + push eax ;x2 + + mov eax, esp ;&x2 + lea ebx, [esp+4] ;&y2 + + lea ecx, [esi+FILL.x] + lea edx, [esi+FILL.y] + + push ebx ;&y2 + push eax ;&x2 + push edx ;&y1 + push ecx ;&x1 + + call _BlockClip + add esp, 16 + test eax, eax + jnz .exit + + ;mov edx, [R5xxRops+4+GXcopy*8] + ;or edx, [rhd.control] + ;or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR) + + pushfd + cli + + + BEGIN_RING + OUT_PACKET3 PAINT_MULTI, 4 + OUT_RING (DST_PITCH_OFFSET_CNTL + \ + BRUSH_SOLID_COLOR + \ + COLOR_ARGB + \ + SRC_DATATYPE_COLOR + \ + (1 shl 28)+(1 shl 30) + \ + R5XX_ROP3_P) + + OUT_RING [rhd.dst_pitch_offset] + OUT_RING [esi+FILL.color] + + mov ebx, [esi+FILL.y] + shl ebx, 16 + mov bx, word [esi+FILL.x] + OUT_RING ebx + + mov ecx, [esp+4] ;x2 + sub ecx, [esi+FILL.x] + inc ecx ;w + + mov eax, [esp+8] ;y2 + sub eax, [esi+FILL.y] + inc eax ;h + + shl ecx, 16 + mov cx, ax ;w|h + + OUT_RING ecx + COMMIT_RING + +if 0 +; mov eax, 7 +; call R5xxFIFOWait + +; wrr R5XX_DP_GUI_MASTER_CNTL, edx + +; mov eax, [esi+FILL.color] +; wrr R5XX_DP_BRUSH_FRGD_CLR, eax + +; wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF + +; wrr R5XX_DP_CNTL, (R5XX_DST_X_LEFT_TO_RIGHT or R5XX_DST_Y_TOP_TO_BOTTOM) + +; mov eax, [rhd.dst_pitch_offset] +; wrr R5XX_DST_PITCH_OFFSET, eax + +; mov ebx, [esi+FILL.y] +; shl ebx, 16 +; mov bx, word [esi+FILL.x] +; wrr R5XX_DST_Y_X, ebx + +; mov ecx, [esp+4] ;x2 +; sub ecx, [esi+FILL.x] +; inc ecx ;w + +; mov eax, [esp+8] ;y2 +; sub eax, [esi+FILL.y] +; inc eax ;h + +; shl ecx, 16 +; mov cx, ax ;w|h +; wrr R5XX_DST_WIDTH_HEIGHT, ecx +end if + popfd +.exit: + add esp, 8 + ret + +align 4 +solid_line: + + lea eax, [esi+LINE2P.y2] + lea ebx, [esi+LINE2P.x2] + lea ecx, [esi+LINE2P.y1] + lea edx, [esi+LINE2P.x1] + + push eax + push ebx + push ecx + push edx + + call _LineClip + add esp, 16 + test eax, eax + jnz .exit + + mov edx, [R5xxRops+4+GXcopy*8] + or edx, [rhd.control] + or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR) + + pushfd + cli + + mov eax, 7 + call R5xxFIFOWait + + wrr R5XX_DST_LINE_PATCOUNT, (0x55 shl R5XX_BRES_CNTL_SHIFT) + wrr R5XX_DP_GUI_MASTER_CNTL, edx + + mov eax, [esi+FILL.color] + wrr R5XX_DP_BRUSH_FRGD_CLR, eax + + wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF + + mov eax, [rhd.dst_pitch_offset] + wrr R5XX_DST_PITCH_OFFSET, eax + + mov ebx, [esi+LINE2P.y1] + shl ebx, 16 + mov bx, word [esi+LINE2P.x1] + wrr R5XX_DST_LINE_START, ebx + + mov ecx, [esi+LINE2P.y2] + shl ecx, 16 + mov cx, word [esi+LINE2P.x2] + wrr R5XX_DST_LINE_END, ecx + popfd +.exit: + ret + +align 4 +__L1OutCode: + cmp eax, [__xmin] + mov ecx, edx + setl dl + sal edx, 3 + cmp eax, [__xmax] + jle L9 + or edx, 4 +L9: + cmp ecx, [__ymin] + jge L11 + or edx, 1 +L11: + cmp ecx, [__ymax] + jle L13 + or edx, 2 +L13: + movzx eax, dl + ret + +align 4 +_line_inter: + push ebp + mov ebp, edx + push edi + push esi + push ebx + sub esp, 4 + mov ebx, [eax] + mov [esp], eax + mov edx, [esp+24] + mov edi, [ebp] + sub ecx, ebx + mov eax, ecx + sar eax, 31 + sub edx, edi + mov esi, eax + xor esi, ecx + sub esi, eax + mov eax, [esp+28] + lea ecx, [edx+edx] + sub eax, ebx + cdq + xor eax, edx + sub eax, edx + imul ecx, eax + test ecx, ecx + jle L17 + add ecx, esi + jmp L19 +L17: + sub ecx, esi +L19: + lea edx, [esi+esi] + mov eax, ecx + mov ebx, edx + cdq + idiv ebx + lea eax, [eax+edi] + mov [ebp], eax + mov eax, [esp] + mov edx, [esp+28] + mov [eax], edx + pop eax + pop ebx + pop esi + pop edi + pop ebp + ret + +_LineClip: + push ebp + push edi + push esi + push ebx + mov eax, [esp+24] + mov ecx, [esp+20] + mov ebp, [esp+28] + mov edi, [esp+32] + mov edx, [eax] + mov eax, [ecx] + call __L1OutCode + mov edx, [edi] + mov bl, al + mov eax, [ebp] + call __L1OutCode +L48: + mov esi, eax +L47: + mov eax, esi + and al, bl + jne L23 + mov edx, esi + cmp bl, dl + je L23 + test bl, bl + jne L26 + movsx eax, dl + test al, 1 + je L28 + push [__ymin] + mov ecx, [esp+24] + push dword [ecx] + jmp L51 +L28: + test al, 2 + je L31 + push [__ymax] + mov edx, [esp+24] + push dword [edx] +L51: + mov eax, [esp+32] + mov edx, ebp + mov ecx, [eax] + mov eax, edi + jmp L49 +L31: + test al, 4 + je L33 + push [__xmax] + jmp L52 +L33: + test al, 8 + je L30 + push [__xmin] +L52: + mov edx, [esp+28] + push dword [edx] + mov edx, edi + mov eax, [esp+28] + mov ecx, [eax] + mov eax, ebp +L49: + call _line_inter + pop esi + pop eax +L30: + mov edx, [edi] + mov eax, [ebp] + call __L1OutCode + jmp L48 +L26: + movsx eax, bl + test al, 1 + je L36 + push [__ymin] + jmp L53 +L36: + test al, 2 + je L39 + push [__ymax] +L53: + push dword [ebp] + mov ecx, [edi] + mov edx, [esp+28] + mov eax, [esp+32] + jmp L50 +L39: + test al, 4 + je L41 + push [__xmax] + jmp L54 +L41: + test al, 8 + je L38 + push [__xmin] +L54: + push dword [edi] + mov ecx, [ebp] + mov edx, [esp+32] + mov eax, [esp+28] +L50: + call _line_inter + pop edx + pop ecx +L38: + mov ecx, [esp+24] + mov edx, [ecx] + mov ecx, [esp+20] + mov eax, [ecx] + call __L1OutCode + mov bl, al + jmp L47 +L23: + pop ebx + movsx eax, al + pop esi + pop edi + pop ebp + ret + +align 4 +_block_inter: + test cl, 1 + push ebx + mov ebx, eax + je L57 + mov eax, [__ymin] + jmp L66 +L57: + test cl, 2 + je L60 + mov eax, [__ymax] +L66: + mov [edx], eax + jmp L65 +L60: + test cl, 4 + je L62 + mov eax, [__xmax] + jmp L67 +L62: + and cl, 8 + je L65 + mov eax, [__xmin] +L67: + mov [ebx], eax +L65: + pop ebx + ret + +align 4 +_BlockClip: + push ebp + push edi + push esi + push ebx + mov eax, [esp+24] + mov ecx, [esp+20] + mov ebp, [esp+28] + mov edi, [esp+32] + mov edx, [eax] + mov eax, [ecx] + call __L1OutCode + mov edx, [edi] + mov ebx, eax + mov eax, [ebp] + call __L1OutCode +L80: + mov esi, eax +L79: + test esi, ebx + jne L70 + cmp ebx, esi + je L72 + test ebx, ebx + jne L74 + mov edx, edi + mov eax, ebp + mov ecx, esi + call _block_inter + mov edx, [edi] + mov eax, [ebp] + call __L1OutCode + jmp L80 +L74: + mov edx, [esp+24] + mov ecx, ebx + mov eax, [esp+20] + call _block_inter + mov eax, [esp+24] + mov ecx, [esp+20] + mov edx, [eax] + mov eax, [ecx] + call __L1OutCode + mov ebx, eax + jmp L79 +L72: + mov esi, ebx +L70: + mov eax, esi + and eax, ebx + pop ebx + cwde + pop esi + pop edi + pop ebp + ret diff --git a/kernel/branches/kolibri_pe/drivers/sb16/CONFIG.INC b/kernel/branches/kolibri_pe/drivers/sb16/CONFIG.INC new file mode 100644 index 000000000..d39356ed6 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/sb16/CONFIG.INC @@ -0,0 +1,41 @@ +;flags------------------------------------------------------------ +DEBUG equ 1 ;show messages at debug board +use_cli_sti equ 1 ;driver come 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 +sb_dma_num equ 5 +sb_buffer_size equ 32768 ;really it needs code modifications to change + ;buffer size +sb_out_rate equ 44100 +;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 + diff --git a/kernel/branches/kolibri_pe/drivers/sb16/SB16.INC b/kernel/branches/kolibri_pe/drivers/sb16/SB16.INC new file mode 100644 index 000000000..f48db82ca --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/sb16/SB16.INC @@ -0,0 +1,239 @@ +;-------------------------------- +; 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 + +; 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 bytes + 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 +; 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 \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/drivers/sb16/sb16.asm b/kernel/branches/kolibri_pe/drivers/sb16/sb16.asm new file mode 100644 index 000000000..85fc081c6 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/sb16/sb16.asm @@ -0,0 +1,375 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + dec eax + jz .sb_say_about_found_dsp + mov dword[sb_DSP_description],'2.x ' + dec eax + jz .sb_say_about_found_dsp + mov dword[sb_DSP_description],'Pro ' + dec eax + jz .sb_say_about_found_dsp + mov dword[sb_DSP_description],'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] + call ReservePortArea ;these ports must be mine! +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 + 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 + ret +@@: +; cmp eax,DEV_SET_MASTERVOL +; jne @F +;if DEBUG +; mov esi,msgSetVol +; call SysMsgBoardStr +;end if +; mov eax,[edi+input] +; mov eax,[eax] +; mov [sb_master_vol],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 +; 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 + + stdcall [callback],SB16Buffer0 ;for 32k buffer +; stdcall [callback],SB16Buffer0 ;for 64k buffer +; stdcall [callback],SB16Buffer1 ;for 64k buffer + + xor eax,eax + ret + +.fill_second_half: + stdcall [callback],SB16Buffer1 ;for 32k buffer +; stdcall [callback],SB16Buffer2 ;for 64k buffer +; stdcall [callback],SB16Buffer3 ;for 64k buffer + + 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 +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 + 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 + +;pTempBuf dd 0 + +callback dd 0 + +int_flip_flop dd 0 + +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 + +;sb_master_vol dd 0 + +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 diff --git a/kernel/branches/kolibri_pe/drivers/sceletone.asm b/kernel/branches/kolibri_pe/drivers/sceletone.asm new file mode 100644 index 000000000..4f9df29e5 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/drivers/sis.asm b/kernel/branches/kolibri_pe/drivers/sis.asm new file mode 100644 index 000000000..b0a2e8bee --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/drivers/sound.asm b/kernel/branches/kolibri_pe/drivers/sound.asm new file mode 100644 index 000000000..c77c9a964 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/drivers/uart.asm b/kernel/branches/kolibri_pe/drivers/uart.asm new file mode 100644 index 000000000..8502b4f58 --- /dev/null +++ b/kernel/branches/kolibri_pe/drivers/uart.asm @@ -0,0 +1,972 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + +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 + diff --git a/kernel/branches/kolibri_pe/drivers/usb/urb.inc b/kernel/branches/kolibri_pe/drivers/usb/urb.inc new file mode 100644 index 000000000..d3be5e75b --- /dev/null +++ b/kernel/branches/kolibri_pe/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; +} + diff --git a/kernel/branches/kolibri_pe/drivers/usb/usb.asm b/kernel/branches/kolibri_pe/drivers/usb/usb.asm new file mode 100644 index 000000000..13cbd8133 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/drivers/vmode.asm b/kernel/branches/kolibri_pe/drivers/vmode.asm new file mode 100644 index 000000000..9cb0427bb --- /dev/null +++ b/kernel/branches/kolibri_pe/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: + diff --git a/kernel/branches/kolibri_pe/fdo.inc b/kernel/branches/kolibri_pe/fdo.inc new file mode 100644 index 000000000..c36be1e81 --- /dev/null +++ b/kernel/branches/kolibri_pe/fdo.inc @@ -0,0 +1,434 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; +; 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 + mov edx,..str + sub esp,4*8+4 + else + mov edx,_str + end if + if ~_num eq + if _num eqtype eax + if _num in + 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 + 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 + 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 + 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 + if ~_hex eq eax + mov eax,_hex + end if + mov edx,8 + else if _hex in + if ~_hex eq ax + movzx eax,_hex + end if + shl eax,16 + if (_num eq) + mov edx,4 + end if + else if _hex in + if ~_hex eq al + movzx eax,_hex + end if + shl eax,24 + if (_num eq) + mov edx,2 + end if + end if + else if _hex eqtype 0 + mov eax,_hex + else + add esp,4*8+4 + mov eax,dword _hex + 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 +} diff --git a/kernel/branches/kolibri_pe/fs/fat12.inc b/kernel/branches/kolibri_pe/fs/fat12.inc new file mode 100644 index 000000000..5866494d0 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/fat12.inc @@ -0,0 +1,2269 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + mov eax,0 ; ok read + mov ebx,0 + mov [flp_status],0 + ret +fdc_status_error_1: + mov [flp_status],0 + mov eax,10 + mov ebx,-1 + ret + +fr_noroot_1: + sub esp,32 + call expand_filename +frfloppy_1: + cmp ebx,0 + jne frfl5_1 + mov ebx,1 +frfl5_1: + cmp ecx,0 + jne 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 + cmp dl,0 + jne l.21_1 + dec dh + cmp dh,0 + jne l.20_1 +fdc_status_error_3: + mov eax,5 ; file not found ? + mov 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 + mov eax,0 + mov [flp_status],0 + 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 + cmp edx,0 + je 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 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} diff --git a/kernel/branches/kolibri_pe/fs/fat32.inc b/kernel/branches/kolibri_pe/fs/fat32.inc new file mode 100644 index 000000000..d42ac1bf9 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/fat32.inc @@ -0,0 +1,2921 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + +.noaccess_3: + add esp,4 +.noaccess_1: + add esp,4 +.noaccess_4: + add esp,4*5 + jmp .noaccess_2 + +@@: + 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 + cmp [hd_error],0 + jne .noaccess_1 + pop ebx + 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 + cmp [hd_error],0 + jne .noaccess_3 + + mov eax, ebx + pop ebx + 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_4 + + jmp .new_cluster +.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 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} diff --git a/kernel/branches/kolibri_pe/fs/fs.inc b/kernel/branches/kolibri_pe/fs/fs.inc new file mode 100644 index 000000000..da6f44633 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 err + mov bx,cx + shl cx,1 + jc err + shl cx,1 + jc err + add cx,bx + jc err + cbw + add cx,ax + jc err +i3: + inc edi + jmp i1 +i_exit: + mov ax,cx + clc +i4: + movzx eax,ax + pop edi + pop dx + pop cx + pop bx + ret + +err: + stc + jmp i4 + +partition_string: dd 0 + db 32 diff --git a/kernel/branches/kolibri_pe/fs/fs_lfn.inc b/kernel/branches/kolibri_pe/fs/fs_lfn.inc new file mode 100644 index 000000000..a80e50740 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/fs_lfn.inc @@ -0,0 +1,1079 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. 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 @f + 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/... - 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 +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 + dec eax + jz .set + dec eax + jz .get + ret +.get: +; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len +; for our code: ebx->buffer,ecx=len +@@: + lodsb + test al, al + jnz @b + sub esi, edx + inc esi + mov [esp+36], esi + cmp ecx, esi + jbe @f + mov ecx, esi +@@: + cmp ecx, 1 + jbe .ret + mov esi, edx + mov edi, ebx + mov al, '/' + stosb + dec ecx + dec ecx + rep movsb + mov byte [edi], 0 +.ret: + ret +.set: +; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string +; for our code: ebx->string to set +@@: + inc esi + cmp byte [esi-1], 0 + jnz @b + dec esi + cmp byte [ebx], '/' + jz .set_absolute +; string gives relative path +.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 + mov byte [esi], 0 + add ebx, 3 + jmp .relative +.doset_relative: + add edx, 0x1000 + mov byte [esi], '/' + inc esi + cmp esi, edx + jae .overflow_esi +@@: + mov al, [ebx] + inc ebx + mov [esi], al + inc esi + test al, al + jz .set_ok + cmp esi, edx + jb @b +.overflow_esi: + mov byte [esi-1], 0 ; force null-terminated string +.set_ok: + ret +.set_absolute: + lea esi, [ebx+1] + call process_replace_file_name + mov edi, edx + add edx, 0x1000 +.set_copy: + lodsb + stosb + test al, al + jz .set_part2 +.set_copy_cont: + cmp edi, edx + jb .set_copy +.overflow_edi: + mov byte [edi-1], 0 + ret +.set_part2: + mov esi, ebp + xor ebp, ebp + test esi, esi + jz .set_ok + mov byte [edi-1], '/' + jmp .set_copy_cont diff --git a/kernel/branches/kolibri_pe/fs/iso9660.inc b/kernel/branches/kolibri_pe/fs/iso9660.inc new file mode 100644 index 000000000..1112a1dc6 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/iso9660.inc @@ -0,0 +1,757 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 diff --git a/kernel/branches/kolibri_pe/fs/ntfs.inc b/kernel/branches/kolibri_pe/fs/ntfs.inc new file mode 100644 index 000000000..10d2d96b7 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/ntfs.inc @@ -0,0 +1,1815 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 , dd + 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 diff --git a/kernel/branches/kolibri_pe/fs/parse_fn.inc b/kernel/branches/kolibri_pe/fs/parse_fn.inc new file mode 100644 index 000000000..a1061ca93 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 -> +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_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 diff --git a/kernel/branches/kolibri_pe/fs/part_set.inc b/kernel/branches/kolibri_pe/fs/part_set.inc new file mode 100644 index 000000000..4f28f2194 --- /dev/null +++ b/kernel/branches/kolibri_pe/fs/part_set.inc @@ -0,0 +1,477 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + mov [SECTORS_PER_CLUSTER],eax + + movzx ecx,word [ebx+0xb] ; bytes per sector + 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 diff --git a/kernel/branches/kolibri_pe/gui/button.inc b/kernel/branches/kolibri_pe/gui/button.inc new file mode 100644 index 000000000..d63774bbf --- /dev/null +++ b/kernel/branches/kolibri_pe/gui/button.inc @@ -0,0 +1,647 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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$ + + +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: + + push edi + 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 + + pop edi + +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 [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 [disable_mouse] + 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 + + +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 ................................ diff --git a/kernel/branches/kolibri_pe/gui/event.inc b/kernel/branches/kolibri_pe/gui/event.inc new file mode 100644 index 000000000..4badc179b --- /dev/null +++ b/kernel/branches/kolibri_pe/gui/event.inc @@ -0,0 +1,701 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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$ + + +align 4 +init_events: + stdcall kernel_alloc, 512*EVENT_SIZE + mov [events], eax + xor eax, eax + mov [event_uid], eax + not eax + mov edi, event_map + mov [event_start], edi + mov ecx, 64/4 + cld + rep stosd + mov [event_end], edi + ret + +align 4 +proc alloc_event + + pushfd + cli + mov ebx, [event_start] + mov ecx, [event_end] +.l1: + bsf eax,[ebx] + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + mov [event_start],ebx + inc [event_uid] + + sub ebx, event_map + lea eax,[eax+ebx*8] + + lea ebx, [eax+eax*4] + shl eax,5 + lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE) + add eax, [events] + mov ebx, [event_uid] + popfd + ret +endp + +align 4 +free_event: + sub eax, [events] + mov ecx, EVENT_SIZE + mov ebx, event_map + cdq + div ecx + + pushfd + cli + bts [ebx], eax + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [event_start], eax + ja @f + popfd + ret +@@: + mov [event_start], eax + popfd + ret + +EVENT_WATCHED equ 0x10000000 +EVENT_SIGNALED equ 0x20000000 +MANUAL_RESET equ 0x40000000 +MANUAL_DESTROY equ 0x80000000 + + +; param +; eax= event data +; ebx= flags +; +; retval +; eax= event +; edx= id + +create_event: + .flags equ esp+4 + .data equ esp + + push ebx + push eax + + call alloc_event + test eax, eax + jz .fail + + mov [eax+APPOBJ.magic], 'EVNT' + mov [eax+APPOBJ.destroy], destroy_event.internal + mov [eax+EVENT.id], ebx + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov ebx, [CURRENT_TASK+ebx+4] + mov [eax+APPOBJ.pid], ebx + mov edx, [.flags] + mov [eax+EVENT.state], edx + + mov esi, [.data] + test esi, esi + jz @F + lea edi, [eax+EVENT.code] + mov ecx, 6 + cld + rep movsd +@@: + 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 [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + popfd + mov edx, [eax+EVENT.id] +.fail: + add esp, 8 + ret + +restore .flags +restore .data + +; param +; eax= event +; ebx= id + +destroy_event: + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail +.internal: + mov ebx, [eax+APPOBJ.fd] + mov ecx, [eax+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx +.force: + 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_event ;release object memory +.fail: + ret + +align 4 +proc send_event stdcall pid:dword, event:dword + locals + slot dd ? + endl + + mov eax, [pid] + call pid_to_slot + test eax, eax + jz .fail + + shl eax, 8 + cmp [SLOT_BASE+eax+APPDATA.ev_count], 32 + ja .fail + + mov [slot], eax + + call alloc_event + test eax, eax + jz .fail + + lea edi, [eax+EVENT.code] + mov ecx, 6 + mov esi, [event] + cld + rep movsd + + mov ecx, [slot] + add ecx, SLOT_BASE+APP_EV_OFFSET + + mov [eax+APPOBJ.magic], 'EVNT' + mov [eax+APPOBJ.destroy], destroy_event + mov ebx, [pid] + mov [eax+APPOBJ.pid], ebx + mov [eax+EVENT.state], EVENT_SIGNALED + + pushfd + cli ;insert event into + mov edx, [ecx+APPOBJ.fd] ;events list + mov [eax+APPOBJ.fd], edx ;and set events flag + mov [eax+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + inc [ecx+APPDATA.ev_count-APP_EV_OFFSET] + or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED + popfd +.fail: + ret +endp + +; timeout ignored + +align 4 +proc get_event_ex stdcall, p_ev:dword, timeout:dword + +.wait: + mov edx,[current_slot] +; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0 +; je .switch + + add edx, APP_EV_OFFSET + + mov eax, [edx+APPOBJ.fd] + cmp eax, edx + je .switch + + lea esi, [eax+EVENT.code] + mov edi, [p_ev] ;copy event data + mov ecx, 6 + cld + rep movsd + + and dword [edi-24], 0xFF00FFFF ;clear priority field + ; + test [eax+EVENT.state], MANUAL_RESET + jnz .done + + pushfd + cli ;remove event from events + mov ebx, [eax+APPOBJ.fd] ;list (reset event) + mov ecx, [eax+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + + and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + + dec [edx+APPDATA.ev_count-APP_EV_OFFSET] + jnz @F + and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED +@@: + popfd + + test [eax+EVENT.state], MANUAL_DESTROY + jz .destroy + + add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET) + + pushfd + cli + mov ebx, [edx+APPOBJ.fd] ;insert event into + mov [eax+APPOBJ.fd], ebx ;objects list + mov [eax+APPOBJ.bk], edx + mov [edx+APPOBJ.fd], eax + mov [ebx+APPOBJ.bk], eax + popfd +.done: + ret + +.destroy: + call destroy_event.force + ret +.switch: + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + jmp .wait +endp + +; param +; eax= event +; ebx= id + +align 4 +wait_event: + .event equ esp + push eax +.wait: + cmp [eax+APPOBJ.magic], 'EVNT' + jne .done + cmp [eax+EVENT.id], ebx + jne .done + + test [eax+EVENT.state], EVENT_SIGNALED + jz .switch + + test [eax+EVENT.state], MANUAL_RESET + jnz .done + + mov edx,[current_slot] + + pushfd + cli ;remove event from events + mov ebx, [eax+APPOBJ.fd] ;list (reset event) + mov ecx, [eax+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + dec [edx+APPDATA.ev_count] + jnz @F + and [edx+APPDATA.event_mask], not EVENT_EXTENDED +@@: + and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + popfd + + test [eax+EVENT.state], MANUAL_DESTROY + jz .destroy + + add edx, APP_OBJ_OFFSET + + pushfd + cli + mov ecx, [edx+APPOBJ.fd] ;insert event into + mov [eax+APPOBJ.fd], ecx ;objects list + mov [eax+APPOBJ.bk], edx + mov [edx+APPOBJ.fd], eax + mov [ecx+APPOBJ.bk], eax + popfd +.done: + add esp, 4 + ret +.destroy: + call destroy_event.force + add esp, 4 + ret +.switch: + or [eax+EVENT.state], EVENT_WATCHED + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + mov eax, [.event] + jmp .wait +restore .event + +; param +; eax= event +; ebx= id +; ecx= flags +; edx= event data + +raise_event: + .event equ esp + push eax + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail + + mov eax, [eax+APPOBJ.pid] + call pid_to_slot + test eax, eax + jz .fail + + mov esi, edx + test esi, esi + mov edx, [.event] + jz @F + + push ecx + lea edi, [edx+EVENT.code] + mov ecx, 6 + cld + rep movsd + pop ecx +@@: + test [edx+EVENT.state], EVENT_SIGNALED + jnz .done + + test ecx, EVENT_WATCHED + jz @F + test [edx+EVENT.state], EVENT_WATCHED + jz .done +@@: + shl eax, 8 + add eax, SLOT_BASE+APP_EV_OFFSET + + pushfd + cli + mov ebx, [edx+APPOBJ.fd] + mov ecx, [edx+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx + + mov ecx, [eax+APPOBJ.fd] + mov [edx+APPOBJ.fd], ecx + mov [edx+APPOBJ.bk], eax + mov [eax+APPOBJ.fd], edx + mov [ecx+APPOBJ.bk], edx + or [edx+EVENT.state], EVENT_SIGNALED + + inc [eax+APPDATA.ev_count-APP_EV_OFFSET] + or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED + popfd +.fail: +.done: + add esp, 4 + ret +restore .event + +; param +; eax= event +; ebx= id +align 4 +clear_event: + .event equ esp + push eax + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail + + mov eax, [eax+APPOBJ.pid] + call pid_to_slot + test eax, eax + jz .fail + + shl eax, 8 + add eax, SLOT_BASE+APP_EV_OFFSET + mov edx, [.event] + pushfd + cli ;remove event from events + mov ebx, [edx+APPOBJ.fd] ;list (reset event) + mov ecx, [edx+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + + and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + + dec [eax+APPDATA.ev_count-APP_EV_OFFSET] + jnz @F + and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED +@@: + add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET) + + mov ecx, [eax+APPOBJ.fd] ;insert event into + mov [edx+APPOBJ.fd], ecx ;objects list + mov [edx+APPOBJ.bk], eax + mov [eax+APPOBJ.fd], edx + mov [ecx+APPOBJ.bk], edx + popfd +.fail: +.done: + add esp, 4 + ret +restore .event + +sys_getevent: + + call get_event_for_app + mov [esp + 32],eax + ret + +sys_waitforevent: + or ebx, 0xFFFFFFFF ; infinite timeout + jmp @f + +sys_wait_event_timeout: + add ebx, [timer_ticks] +@@: + mov eax, [current_slot] + mov [eax + APPDATA.wait_timeout], ebx + call get_event_for_app + test eax, eax + jnz eventoccur + + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + + mov eax, [event_sched] +eventoccur: + mov [esp+32], eax + ret + +sys_sendwindowmsg: + dec eax + jnz .ret + cmp ebx, 3 + jz .sendbtn + cmp ebx, 2 + jnz .ret +.sendkey: + pushf + cli + movzx eax, byte [KEY_COUNT] + cmp al, 120 + jae .overflow + inc eax + mov [KEY_COUNT], al + mov [KEY_COUNT+eax], cl + jmp .ok +.overflow: + popf + mov dword [esp+36], 1 + ret +.sendbtn: + pushf + cli + cmp byte [BTN_COUNT], 0 + jnz .overflow + mov byte [BTN_COUNT], 1 + mov [BTN_BUFF], ecx +.ok: + popf + and dword [esp+36], 0 +.ret: + ret + +get_event_for_app: + + pushad + + mov edi,[TASK_BASE] ; WINDOW REDRAW + test [edi+TASKDATA.event_mask], 1 + jz no_eventoccur1 + ;mov edi,[TASK_BASE] + cmp [edi-twdw+WDATA.fl_redraw],byte 0 + je no_eventoccur1 + popad + mov eax,1 + ret + no_eventoccur1: + + ;mov edi,[TASK_BASE] ; KEY IN BUFFER + test [edi+TASKDATA.event_mask],dword 2 + jz no_eventoccur2 + mov ecx, [CURRENT_TASK] + movzx edx,word [WIN_STACK+ecx*2] + mov eax, [TASK_COUNT] + cmp eax,edx + jne no_eventoccur2x + cmp [KEY_COUNT],byte 0 + je no_eventoccur2x + eventoccur2: + popad + mov eax,2 + ret + no_eventoccur2x: + mov eax, hotkey_buffer +@@: + cmp [eax], ecx + jz eventoccur2 + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb @b + no_eventoccur2: + + ;mov edi,[TASK_BASE] ; BUTTON IN BUFFER + test [edi+TASKDATA.event_mask],dword 4 + jz no_eventoccur3 + cmp [BTN_COUNT],byte 0 + je no_eventoccur3 + mov ecx, [CURRENT_TASK] + movzx edx, word [WIN_STACK+ecx*2] + mov eax, [TASK_COUNT] + cmp eax,edx + jnz no_eventoccur3 + popad + mov eax,[BTN_BUFF] + cmp eax,65535 + je no_event_1 + mov eax,3 + ret + + no_event_1: + mov [window_minimize],1 + mov [BTN_COUNT],byte 0 + xor eax, eax + ret + +no_eventoccur3: + + ;mov edi,[TASK_BASE] ; mouse event + mov eax, [CURRENT_TASK] + shl eax, 8 + add eax, SLOT_BASE + test [edi+TASKDATA.event_mask],dword 00100000b + jz no_mouse_event + + test [eax+APPDATA.event_mask],dword 00100000b + jz no_mouse_event + and [eax+APPDATA.event_mask],dword (not 00100000b) + popad + mov eax,6 + ret +no_mouse_event: + + ;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW + test [edi+TASKDATA.event_mask], 16 + jz no_eventoccur5 +; cmp [REDRAW_BACKGROUND],byte 2 +; jnz no_eventoccur5 + test [eax+APPDATA.event_mask], 16 + jz no_eventoccur5 + and [eax+APPDATA.event_mask], not 16 + popad + mov eax,5 + ret +no_eventoccur5: + + ;mov edi,[TASK_BASE] ; IPC + test [edi+TASKDATA.event_mask],dword 01000000b + jz no_ipc + test [eax+APPDATA.event_mask],dword 01000000b + jz no_ipc + and [eax+APPDATA.event_mask],dword 0xffffffff-01000000b + popad + mov eax,7 + ret +no_ipc: + + ;mov edi,[TASK_BASE] ; STACK + test [edi+TASKDATA.event_mask],dword 10000000b + jz no_stack_event + test [eax+APPDATA.event_mask],dword 10000000b + jz no_stack_event + and [eax+APPDATA.event_mask],dword 0xffffffff-10000000b + popad + mov eax,8 + ret +no_stack_event: + + test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG + jz .test_IRQ + test byte [eax+APPDATA.event_mask+1], byte 1 + jz .test_IRQ + and byte [eax+APPDATA.event_mask+1], not 1 + popad + mov eax, 9 + ret + +;.test_ext: +; mov eax, [CURRENT_TASK] +; shl eax, 8 +; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED +; jz .test_IRQ +; popad +; mov eax, 10 +; ret + +.test_IRQ: + cmp dword [edi+TASKDATA.event_mask], 0xFFFF + jbe no_events + + mov esi,IRQ_SAVE ; IRQ'S AND DATA + mov ebx,0x00010000 + xor ecx, ecx + irq_event_test: + mov edi,[TASK_BASE] + test [edi+TASKDATA.event_mask],ebx + jz no_irq_event + mov edi,ecx + shl edi,2 + add edi,irq_owner + mov edx,[edi] + mov eax,[TASK_BASE] + mov eax,[eax+TASKDATA.pid] + cmp edx,eax + jne no_irq_event + cmp [esi],dword 0 + jz no_irq_event + mov eax,ecx + add eax,16 + mov [esp+28],eax + popad + ret + no_irq_event: + add esi,0x1000 + shl ebx,1 + inc ecx + cmp ecx,16 + jb irq_event_test + + no_events: + popad + xor eax, eax + ret + + + diff --git a/kernel/branches/kolibri_pe/gui/font.inc b/kernel/branches/kolibri_pe/gui/font.inc new file mode 100644 index 000000000..997acef26 --- /dev/null +++ b/kernel/branches/kolibri_pe/gui/font.inc @@ -0,0 +1,132 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 [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 diff --git a/kernel/branches/kolibri_pe/gui/mouse.inc b/kernel/branches/kolibri_pe/gui/mouse.inc new file mode 100644 index 000000000..98b38f88c --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/gui/skincode.inc b/kernel/branches/kolibri_pe/gui/skincode.inc new file mode 100644 index 000000000..9e6ffbce9 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + diff --git a/kernel/branches/kolibri_pe/gui/skindata.inc b/kernel/branches/kolibri_pe/gui/skindata.inc new file mode 100644 index 000000000..b2e3c1244 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/gui/window.inc b/kernel/branches/kolibri_pe/gui/window.inc new file mode 100644 index 000000000..aa970f3ce --- /dev/null +++ b/kernel/branches/kolibri_pe/gui/window.inc @@ -0,0 +1,1817 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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$ + + +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 + jne @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, OS_BASE+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 ? + + movsx eax,word [edi+WDATA.box.left] + movsx ebx,word [edi+WDATA.box.top] + movsx ecx,word [edi+WDATA.box.width] + movsx edx,word [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 ................. + jmp @f + bPressedMouseXY_W db 0x0 + @@: +;..................................... end 2/4 : modified by vhanla ................... + mov esi,[TASK_COUNT] + inc esi + +;..................................... start 3/4 : modified by vhanla ................. + push ax + cmp [bPressedMouseXY_W],0 + jnz @f + mov [bPressedMouseXY_W],1 + mov ax,[MOUSE_X] + mov [mx],ax + mov ax,[MOUSE_Y] + mov [my],ax + @@: + pop ax +;..................................... 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 + + ; eax = position in windowing stack + ; redraw must ? + lea esi, [WIN_POS + esi * 2] + call waredraw + 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 + + diff --git a/kernel/branches/kolibri_pe/hid/keyboard.inc b/kernel/branches/kolibri_pe/hid/keyboard.inc new file mode 100644 index 000000000..9d6d0b836 --- /dev/null +++ b/kernel/branches/kolibri_pe/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................................................ \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/hid/mousedrv.inc b/kernel/branches/kolibri_pe/hid/mousedrv.inc new file mode 100644 index 000000000..468215399 --- /dev/null +++ b/kernel/branches/kolibri_pe/hid/mousedrv.inc @@ -0,0 +1,458 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 [set_hw_cursor], 0 + jz @F + pushad + movzx eax,word [X_UNDER] + movzx ebx,word [Y_UNDER] + stdcall [hw_restore], 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 [set_hw_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 + + movzx edx, byte [display_data+ebx+eax] + shl edx, 8 + mov esi, [edx+SLOT_BASE+APPDATA.cursor] + + cmp esi, [current_cursor] + je .draw + + ; cmp [esi+CURSOR.magic], 'CURS' + ; jne .fail + + push esi + call [select_hw_cursor] + mov [current_cursor], esi +.draw: + stdcall [set_hw_cursor], esi + popad + ret +.fail: + mov ecx, [def_cursor] + mov [edx+SLOT_BASE+APPDATA.cursor], ecx + stdcall [set_hw_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, display_data + 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 + diff --git a/kernel/branches/kolibri_pe/hid/set_dtc.inc b/kernel/branches/kolibri_pe/hid/set_dtc.inc new file mode 100644 index 000000000..53539700e --- /dev/null +++ b/kernel/branches/kolibri_pe/hid/set_dtc.inc @@ -0,0 +1,201 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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: + mov ecx,eax + cli + mov al,0x0d + out 0x70,al + in al,0x71 + bt ax,7 + jnc bat_low + cmp ecx,2 ;day of week + jne nosetweek + test ebx,ebx ;test day of week + je wrongtime + cmp ebx,7 + ja wrongtime + mov dx,0x70 + call startstopclk + dec edx + mov al,6 + out dx,al + inc edx + mov al,bl + out dx,al + jmp endsettime + nosetweek: ;set date + cmp ecx,1 + jne nosetdate + cmp bl,0x99 ;test year + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + cmp bh,0x99 ;test month + ja wrongtime + shr ebx,4 + test bh,bh + je wrongtime + cmp bh,0x12 + ja wrongtime + shl ebx,8 + bswap ebx ;ebx=00YYMMDD + test bl,bl ;test day + je wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + shr ebx,4 + cmp bh,2 ;February + jne testday + cmp bl,0x29 + ja wrongtime + jmp setdate + testday: + cmp bh,8 + jb testday1 ;Aug-Dec + bt bx,8 + jnc days31 + jmp days30 + testday1: + bt bx,8 ;Jan-Jul ex.Feb + jnc days30 + days31: + cmp bl,0x31 + ja wrongtime + jmp setdate + days30: + cmp bl,0x30 + ja wrongtime + setdate: + mov dx,0x70 + call startstopclk + dec edx + mov al,7 ;set days + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,8 ;set months + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,9 ;set years + out dx,al + inc edx + shr ebx,8 + mov al,bh + out dx,al + jmp endsettime + nosetdate: ;set time or alarm-clock + cmp ecx,3 + ja wrongtime + cmp bl,0x23 + ja wrongtime + cmp bh,0x59 + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + cmp bh,0x92 + ja wrongtime + shl ebx,4 + bswap ebx ;00HHMMSS + cmp bl,0x59 + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + shr ebx,4 + mov dx,0x70 + call startstopclk + dec edx + cmp ecx,3 + je setalarm + xor eax,eax ;al=0-set seconds + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,2 ;set minutes + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,4 ;set hours + out dx,al + inc edx + shr ebx,8 + mov al,bh + out dx,al + jmp endsettime + setalarm: + mov al,1 ;set seconds for al. + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,3 ;set minutes for al. + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,5 ;set hours for al. + out dx,al + inc edx + shr ebx,8 + mov al,bh + 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 + mov [esp+36],dword 0 + ret + bat_low: + sti + mov [esp+36],dword 2 + ret + wrongtime: + sti + mov [esp+36],dword 1 + ret + +startstopclk: + mov al,0x0b + out dx,al + inc dx + in al,dx + btc ax,7 + out dx,al + ret diff --git a/kernel/branches/kolibri_pe/imports.inc b/kernel/branches/kolibri_pe/imports.inc new file mode 100644 index 000000000..3d94b67a1 --- /dev/null +++ b/kernel/branches/kolibri_pe/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' diff --git a/kernel/branches/kolibri_pe/init.inc b/kernel/branches/kolibri_pe/init.inc new file mode 100644 index 000000000..ddc2cb2aa --- /dev/null +++ b/kernel/branches/kolibri_pe/init.inc @@ -0,0 +1,356 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 + + 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 + mov [MEM_AMOUNT-OS_BASE], edi + + and eax, not (CR0_CD+CR0_NW) ;enable caching + mov cr0, eax + mov eax, edi + ret +endp + +align 4 +proc init_mem + + mov ecx, [0x2F0000 + 0x9100] + test ecx, ecx + jz .nosmap + + xor eax, eax + mov esi, 0x2F0000 + 0x9104 +@@: + cmp dword [esi+16], 1 + jne .next + mov edx, [esi+8] + cmp eax, [esi+8] + ja .next + + mov eax, [esi+8] +.next: + add esi, 20 + loop @B + + mov [MEM_AMOUNT-OS_BASE], eax + jmp @F +.nosmap: + call mem_test + + mov eax, [MEM_AMOUNT-OS_BASE] +@@: + mov [pg_data.mem_amount-OS_BASE], eax + + shr eax, 12 + mov edx, eax + mov [pg_data.pages_count-OS_BASE], eax + shr eax, 3 + mov [pg_data.pagemap_size-OS_BASE], eax + + add eax, (sys_pgmap-OS_BASE)+4095 + and eax, not 4095 + mov [tmp_page_tabs], eax + + cmp edx, (OS_BASE/4096) + jbe @F + mov edx, (OS_BASE/4096) + jmp .set +@@: + cmp edx, (HEAP_MIN_SIZE/4096) + jae .set + mov edx, (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)+ (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 + + mov edi, sys_pgmap-OS_BASE + mov ecx, [pg_data.pagemap_size-OS_BASE] + shr ecx, 2 + or eax, -1 + cld + rep stosd + + 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 + mov [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 + + mov [cpu_type], 0 + xor eax, 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 + diff --git a/kernel/branches/kolibri_pe/kernel.asm b/kernel/branches/kolibri_pe/kernel.asm new file mode 100644 index 000000000..3a1047f3d --- /dev/null +++ b/kernel/branches/kolibri_pe/kernel.asm @@ -0,0 +1,5255 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Copyright (C) KolibriOS team 2004-2008. 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) +;; +;; 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 + +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) +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.1.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 + xor edi, edi + mov ecx,0x10000 / 4 + rep stosd + + call test_cpu + bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc + + call init_BIOS32 +; MEMORY MODEL + + 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 ss,ax + add esp, OS_BASE + + mov ds,bx + mov es,bx + mov fs,bx + 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 + mov al,[BOOT_VAR+0x9000] ; bpp + mov [ScreenBPP],al + + movzx eax,word [BOOT_VAR+0x900A] ; X max + dec eax + mov [Screen_Max_X],eax + mov [screen_workarea.right],eax + movzx eax,word [BOOT_VAR+0x900C] ; Y max + 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 + mov ax,[BOOT_VAR+0x9001] ; for other modes + mov [BytesPerScanLine],ax +@@: + mov esi, BOOT_VAR+0x9080 + movzx ecx, byte [esi-1] + mov [NumBiosDisks], ecx + mov edi, BiosDisksData + rep movsd + +; GRAPHICS ADDRESSES + + mov 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 31–16 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 15–0 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: +; ----------------------------------------- + +; LOAD IDT + + call build_interrupt_table + 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 + + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],dword 1 + mov [TASK_BASE],dword TASK_DATA + mov [current_slot], SLOT_BASE+256 + +; set background + xor eax,eax + inc eax + mov [BgrDrawMode],eax + mov [BgrDataWidth],eax + mov [BgrDataHeight],eax + mov [mem_BACKGROUND],4095 + stdcall kernel_alloc, [mem_BACKGROUND] + mov [img_background], eax + + mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE + +; 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 + mov al, 0xFE + 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' +;!!!!!!!!!!!!!!!!!!!!!!! + + 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: + +; 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 + mov edi, 1 + mov eax, 0x00040000 + 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.fpu_handler], eax + mov dword [SLOT_BASE+APPDATA.sse_handler], 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 + mov dword [SLOT_BASE+256+APPDATA.io_map],\ + (tss._io_map_0-OS_BASE+PG_MAP) + mov dword [SLOT_BASE+256+APPDATA.io_map+4],\ + (tss._io_map_1-OS_BASE+PG_MAP) + + mov esi, fpu_data + mov ecx, 512/4 + cld + rep movsd + + mov dword [SLOT_BASE+256+APPDATA.fpu_handler], eax + mov dword [SLOT_BASE+256+APPDATA.sse_handler], 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 + + ; task list + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],dword 1 + mov [current_slot], SLOT_BASE+256 + mov [TASK_BASE],dword TASK_DATA + mov [TASK_DATA+TASKDATA.wnd_number], 1 ; on screen number + mov [TASK_DATA+TASKDATA.pid], 1 ; process id number + mov [TASK_DATA+TASKDATA.mem_start], 0 ; process base address + + call init_cursors + mov eax, [def_cursor] + mov [SLOT_BASE+APPDATA.cursor],eax + mov [SLOT_BASE+APPDATA.cursor+256],eax + + stdcall load_pe_driver, szAtiHW + + ; READ TSC / SECOND + + mov esi,boot_tsc + call boot_log + cli + call _rdtsc + mov ecx,eax + mov esi,250 ; wait 1/4 a second + call delay_ms + call _rdtsc + sti + sub eax,ecx + shl eax,2 + mov [CPU_FREQ],eax ; save tsc / sec + mov ebx, 1000000 + div ebx + mov [stall_mcs], eax + +; 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,(tss._io_map_0-OS_BASE), PG_MAP + add esi, 0x1000 + stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP + + stdcall map_page,tss._io_map_0,\ + (tss._io_map_0-OS_BASE), PG_MAP + stdcall map_page,tss._io_map_1,\ + (tss._io_map_1-OS_BASE), 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) + je 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 + je 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 + mov [CURRENT_TASK],dword 1 ; 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 ] + +; 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 + +; stdcall init_uart_service, DRV_ENTRY + + 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 + mov edx,esi + mov edi,1 + 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 ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +checkidle: + pushad + + cmp [check_idle_semaphore],0 + jne no_idle_state + + call change_task + mov eax,[idlemem] + mov ebx,[timer_ticks] ;[0xfdf0] + cmp eax,ebx + jnz idle_exit + call _rdtsc + mov ecx,eax + idle_loop: + hlt + cmp [check_idle_semaphore],0 + jne idle_loop_exit + mov eax,[timer_ticks] ;[0xfdf0] + cmp ebx,eax + jz idle_loop + idle_loop_exit: + mov [idlemem],eax + call _rdtsc + sub eax,ecx + mov ebx,[idleuse] + add ebx,eax + mov [idleuse],ebx + + popad + ret + + idle_exit: + + mov ebx,[timer_ticks] ;[0xfdf0] + mov [idlemem],ebx + call change_task + + popad + ret + + no_idle_state: + + dec [check_idle_semaphore] + + mov ebx,[timer_ticks] ;[0xfdf0] + mov [idlemem],ebx + call change_task + + 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: + + pushad + + mov [irq_owner+4*0], 1 ; timer + ;mov [irq_owner+4*1], 1 ; keyboard + mov [irq_owner+4*6], 1 ; floppy diskette + mov [irq_owner+4*13], 1 ; math co-pros + mov [irq_owner+4*14], 1 ; ide I + mov [irq_owner+4*15], 1 ; ide II + + ; RESERVE PORTS + mov edi,1 ; 0x00-0x2d + mov [RESERVED_PORTS],edi + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x0 + mov [RESERVED_PORTS+edi+8],dword 0x2d + + inc dword [RESERVED_PORTS] ; 0x30-0x4d + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x30 + mov [RESERVED_PORTS+edi+8],dword 0x4d + + inc dword [RESERVED_PORTS] ; 0x50-0xdf + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x50 + mov [RESERVED_PORTS+edi+8],dword 0xdf + + inc dword [RESERVED_PORTS] ; 0xe5-0xff + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0xe5 + mov [RESERVED_PORTS+edi+8],dword 0xff + + popad + ret + +setirqreadports: + + mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte + 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 + mov [MOUSE_BUFF_COUNT],byte 0 ; mouse buffer + mov [KEY_COUNT],byte 0 ; keyboard buffer + mov [BTN_COUNT],byte 0 ; button buffer +; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y + + 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 + pop eax + + mov [BTN_ADDR],dword BUTTON_INFO ; address of button list + + ;!! IP 04.02.2005: + mov [next_usage_update], 100 + mov byte [DONT_SWITCH], 0 ; change task if possible + + ret + +;* 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 + pop eax + ret +;* mouse centered - end code- Mario79 + +align 4 + +sys_outport: + + mov edi,ebx ; separate flag for read / write + and ebx,65535 + + mov ecx,[RESERVED_PORTS] + test ecx,ecx + jne sopl8 + mov [esp+36],dword 1 + ret + + sopl8: + mov edx,[TASK_BASE] + mov edx,[edx+0x4] + and ebx,65535 + cld + sopl1: + + mov esi,ecx + shl esi,4 + add esi,RESERVED_PORTS + cmp edx,[esi+0] + jne sopl2 + cmp ebx,[esi+4] + jb sopl2 + cmp ebx,[esi+8] + jg sopl2 + jmp sopl3 + + sopl2: + + dec ecx + jnz sopl1 + mov [esp+36],dword 1 + ret + + sopl3: + + test edi,0x80000000 ; read ? + jnz sopl4 + + mov dx,bx ; write + out dx,al + mov [esp+36],dword 0 + ret + + sopl4: + + mov dx,bx ; read + in al,dx + and eax,0xff + mov [esp+36],dword 0 + mov [esp+24],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 + + cmp ah,0 ; DECIMAL + jne 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 + 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 + + + mov [esp+36],dword 0 + cmp eax,1 ; MIDI + jnz nsyse1 + cmp ebx,0x100 + jb nsyse1 + mov edx,65535 + cmp edx,ebx + jb nsyse1 + mov [midi_base],bx + mov word [mididp],bx + inc bx + mov word [midisp],bx + ret + +iglobal +midi_base dw 0 +endg + + nsyse1: + + cmp eax,2 ; KEYBOARD + jnz nsyse2 + cmp ebx,1 + jnz kbnobase + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap + mov ecx,128 + call memmove + ret + kbnobase: + cmp ebx,2 + jnz kbnoshift + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap_shift + mov ecx,128 + call memmove + ret + kbnoshift: + cmp ebx,3 + jne kbnoalt + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap_alt + mov ecx,128 + call memmove + ret + kbnoalt: + cmp ebx,9 + jnz kbnocountry + mov word [keyboard],cx + ret + kbnocountry: + mov [esp+36],dword 1 + ret + nsyse2: + cmp eax,3 ; CD + jnz nsyse4 + test ebx,ebx + jz nosesl + cmp ebx, 4 + ja nosesl + mov [cd_base],bl + cmp ebx,1 + jnz noprma + mov [cdbase],0x1f0 + mov [cdid],0xa0 + noprma: + cmp ebx,2 + jnz noprsl + mov [cdbase],0x1f0 + mov [cdid],0xb0 + noprsl: + cmp ebx,3 + jnz nosema + mov [cdbase],0x170 + mov [cdid],0xa0 + nosema: + cmp ebx,4 + jnz nosesl + mov [cdbase],0x170 + mov [cdid],0xb0 + nosesl: + ret + +cd_base db 0 + + nsyse4: + + cmp eax,5 ; SYSTEM LANGUAGE + jnz nsyse5 + mov [syslang],ebx + ret + nsyse5: + + cmp eax,7 ; HD BASE + jne nsyse7 + test ebx,ebx + jz nosethd + cmp ebx,4 + ja nosethd + mov [hd_base],bl + cmp ebx,1 + jnz noprmahd + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 +; call set_FAT32_variables + noprmahd: + cmp ebx,2 + jnz noprslhd + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 +; call set_FAT32_variables + noprslhd: + cmp ebx,3 + jnz nosemahd + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 +; call set_FAT32_variables + nosemahd: + cmp ebx,4 + jnz noseslhd + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 +; call set_FAT32_variables + noseslhd: + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel + mov [hd1_status],0 ; free + nosethd: + ret + +iglobal +hd_base db 0 +endg + +nsyse7: + + cmp eax,8 ; HD PARTITION + jne nsyse8 + mov [fat32part],ebx +; call set_FAT32_variables + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel + pusha + call choice_necessity_partition_1 + popa + mov [hd1_status],0 ; free + ret + +nsyse8: + cmp eax,11 ; ENABLE LBA READ + jne no_set_lba_read + and ebx,1 + mov [lba_read_enabled],ebx + ret + +no_set_lba_read: + cmp eax,12 ; ENABLE PCI ACCESS + jne no_set_pci_access + and ebx,1 + mov [pci_access_enabled],ebx + ret + no_set_pci_access: + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'vmodeint.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +sys_setup_err: + mov [esp+36],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 + jne ngsyse1 + movzx eax,[midi_base] + mov [esp+36],eax + ret +ngsyse1: + + cmp eax,2 + jne ngsyse2 + cmp ebx,1 + jnz kbnobaseret + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap + mov ecx,128 + call memmove + ret +kbnobaseret: + cmp ebx,2 + jnz kbnoshiftret + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap_shift + mov ecx,128 + call memmove + ret +kbnoshiftret: + cmp ebx,3 + jne kbnoaltret + mov edi,[TASK_BASE] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap_alt + mov ecx,128 + call memmove + ret +kbnoaltret: + cmp ebx,9 + jnz ngsyse2 + movzx eax,word [keyboard] + mov [esp+36],eax + ret +ngsyse2: + + cmp eax,3 + jnz ngsyse3 + movzx eax,[cd_base] + mov [esp+36],eax + ret +ngsyse3: + cmp eax,5 + jnz ngsyse5 + mov eax,[syslang] + mov [esp+36],eax + ret +ngsyse5: + cmp eax,7 + jnz ngsyse7 + movzx eax,[hd_base] + mov [esp+36],eax + ret +ngsyse7: + cmp eax,8 + jnz ngsyse8 + mov eax,[fat32part] + mov [esp+36],eax + ret +ngsyse8: + cmp eax,9 + jne ngsyse9 + mov eax,[timer_ticks] ;[0xfdf0] + mov [esp+36],eax + ret +ngsyse9: + cmp eax,11 + jnz ngsyse11 + mov eax,[lba_read_enabled] + mov [esp+36],eax + ret +ngsyse11: + cmp eax,12 + jnz ngsyse12 + mov eax,[pci_access_enabled] + mov [esp+36],eax + ret +ngsyse12: + mov [esp+36],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 eax, 7 + ja msset + jmp [mousefn+eax*4] +msscreen: + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov [esp+36],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],eax + ret +msbutton: + movzx eax,byte [BTN_DOWN] + mov [esp+36],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],eax + mov [MOUSE_SCROLL_H],word 0 + mov [MOUSE_SCROLL_V],word 0 + ret + @@: + mov [esp+36],dword 0 + ret +msset: + ret + +app_load_cursor: + ; add ebx, new_app_base + cmp ebx, OS_BASE + jae msset + stdcall load_cursor, ebx, ecx + mov [esp+36], eax + ret + +app_set_cursor: + stdcall set_cursor, ebx + mov [esp+36], eax + ret + +app_delete_cursor: + stdcall delete_cursor, ebx + mov [esp+36], 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 + + +setuart: + + su1: + call is_output + cmp al,0 + 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 + cmp al,0 + jnz su2 + call get_mpu_in + cmp al,0xfe + jnz su2 + su3: + call is_output + cmp al,0 + jnz su3 + mov dx,word [midisp] + mov al,0x3f + out dx,al + + ret + + +align 4 + +sys_midi: + + cmp [mididp],0 + jnz sm0 + mov [esp+36],dword 1 + ret + sm0: + + cmp eax,1 + mov [esp+36],dword 0 + jnz smn1 + call setuart + ret + smn1: + + cmp eax,2 + jnz smn2 + sm10: + call get_mpu_in + call is_output + test al,al + jnz sm10 + mov al,bl + call put_mpu_out + ret + 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 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' +;!!!!!!!!!!!!!!!!!!!!!!!! + +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 + jne nogetsoundflag + movzx eax,byte [sound_flag] ; get sound_flag + mov [esp+32],eax + ret + nogetsoundflag: + cmp ecx,2 + jnz nosoundflag + xor byte [sound_flag], 1 + nosoundflag: + ret + +sysfn_minimize: ; 18.10 = minimize window + mov [window_minimize],1 + ret + +sysfn_getdiskinfo: ; 18.11 = get disk info table + cmp ecx,1 + 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 + 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 + +sysfn_centermouse: ; 18.15 = mouse centered + call mouse_centered + and [esp+32],dword 0 + ret + +sysfn_mouse_acceleration: ; 18.19 = set/get mouse features + cmp ecx,0 ; 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 + jnz .get_mouse_delay + mov [mouse_speed_factor],dx + ret + .get_mouse_delay: + cmp ecx,2 ; get mouse delay + jnz .set_mouse_delay + mov eax,[mouse_delay] + mov [esp+32],eax + ret + .set_mouse_delay: + cmp ecx,3 ; set mouse delay + jnz .set_pointer_position + mov [mouse_delay],edx + ret + .set_pointer_position: + cmp ecx,4 ; set mouse pointer position + 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 + 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,1,0 ; version 0.7.1.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 +bgrlock db 0 +bgrlockpid dd 0 +endg + +sys_background: + + cmp ebx,1 ; BACKGROUND SIZE + jnz nosb1 + cmp ecx,0 + je sbgrr + cmp edx,0 + je sbgrr +@@: + mov al, 1 + xchg [bgrlock], al + test al, al + jz @f + call change_task + jmp @b +@@: + mov [BgrDataWidth],ecx + mov [BgrDataHeight],edx +; mov [bgrchanged],1 + + pushad +; return memory for old background + stdcall kernel_free, [img_background] +; 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 .exit_mem + mov [img_background], eax +.exit_mem: + popad + mov [bgrlock], 0 + + sbgrr: + ret + + nosb1: + + cmp ebx,2 ; SET PIXEL + jnz nosb2 + cmp ecx,[mem_BACKGROUND] + jae nosb2 + mov eax,[img_background] + 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 +; mov [bgrchanged],1 + 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 + ; 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 +@@: + mov al, 1 + xchg [bgrlock], al + test al, al + jz @f + call change_task + jmp @b +@@: + mov eax, [CURRENT_TASK] + mov [bgrlockpid], eax + 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 +@@: + 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: + mov [draw_data+32 + RECT.left],dword 0 + mov [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 + jnz nogb1 + mov eax,[BgrDataWidth] + shl eax,16 + mov ax,[BgrDataHeight] + mov [esp+36],eax + ret + nogb1: + + cmp eax,2 ; PIXEL + jnz nogb2 +; mov edx,0x160000-16 +; cmp edx,ebx +; jbe nogb2 +; mov eax, [ebx+IMG_BACKGROUND] + mov eax,[img_background] + mov eax,[ebx+eax] + + and eax, 0xFFFFFF + mov [esp+36],eax + ret + nogb2: + + cmp eax,4 ; TILED / STRETCHED + jnz nogb4 + mov eax,[BgrDrawMode] + nogb4: + mov [esp+36],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 [disable_mouse] + call sys_set_window + call [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 [disable_mouse] + call sys_set_window + call [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 [disable_mouse] + call sys_set_window + call [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 [disable_mouse] + call sys_set_window + call [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 [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 + + mov word[edi+WDATA.box.width],bx + mov word[edi+WDATA.box.height],cx + sar ebx,16 + sar ecx,16 + mov word[edi+WDATA.box.left],bx + mov word[edi+WDATA.box.top],cx + + call check_window_position + + call set_window_clientbox + + 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: + 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: ;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 +ret +shed_counter: + mov eax,[context_counter] + mov [esp+36],eax +not_supported: +ret +perf_control: + inc eax ;now 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 + +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 + +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 + mov dl, [eax+edx+display_data] ; 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 [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 + + ; all black + + mov edi, [img_background] ;IMG_BACKGROUND ; set background to black + xor eax, eax + mov ecx, 1023 ;0x0fff00 / 4 + cld + rep stosd + + mov edi,display_data ; set os to use all pixels + mov eax,0x01010101 + mov ecx,1280*1024 / 4 + 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 + ; + imul ecx, 33941 + shr ecx, 9 + ; + + 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 [edi + TASKDATA.event_mask], ebx + 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 + + +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 + + +; 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 + 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: + + pushad + + 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 + + cmp ebp,0 ; enable access - ebp = 0 + jne siar1 + +; not ebx +; and [edi],byte bl + btr [edi], eax + + popad + + ret + +siar1: + + bts [edi], eax + ; or [edi],byte bl ; disable access - ebp = 1 + + popad + + ret + +r_f_port_area: + + test eax, eax + jnz free_port_area +; je r_port_area +; jmp free_port_area + +; r_port_area: + + pushad + + cmp ebx,ecx ; beginning > end ? + ja rpal1 + cmp ecx,65536 + jae rpal1 + mov esi,[RESERVED_PORTS] + test esi,esi ; no reserved areas ? + je rpal2 + cmp esi,255 ; max reserved + jae rpal1 + rpal3: + mov edi,esi + shl edi,4 + add edi,RESERVED_PORTS + cmp ebx,[edi+8] + ja rpal4 + cmp ecx,[edi+4] + jae rpal1 +; jb rpal4 +; jmp rpal1 + rpal4: + + dec esi + jnz rpal3 + jmp rpal2 + rpal1: + popad + mov eax,1 + ret + + rpal2: + popad + + + ; enable port access at port IO map + cli + pushad ; start enable io map + + cmp ecx,65536 ;16384 + jae no_unmask_io ; jge + + mov eax,ebx + + new_port_access: + + pushad + + xor ebp,ebp ; enable - eax = port + call set_io_access_rights + + popad + + inc eax + cmp eax,ecx + jbe new_port_access + + no_unmask_io: + + popad ; end enable io map + sti + + mov edi,[RESERVED_PORTS] + add edi,1 + mov [RESERVED_PORTS],edi + shl edi,4 + add edi,RESERVED_PORTS + mov esi,[TASK_BASE] + mov esi,[esi+TASKDATA.pid] + mov [edi],esi + mov [edi+4],ebx + mov [edi+8],ecx + + xor eax, eax + ret + +free_port_area: + + pushad + + mov esi,[RESERVED_PORTS] ; no reserved areas ? + test esi,esi + je frpal2 + mov edx,[TASK_BASE] + mov edx,[edx+TASKDATA.pid] + frpal3: + mov edi,esi + shl edi,4 + add edi,RESERVED_PORTS + cmp edx,[edi] + jne frpal4 + cmp ebx,[edi+4] + jne frpal4 + cmp ecx,[edi+8] + jne frpal4 + jmp frpal1 + frpal4: + dec esi + jnz frpal3 + frpal2: + popad + mov eax,1 + ret + frpal1: + mov ecx,256 + sub ecx,esi + 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 + + cmp ecx,65536 ;16384 + jge no_mask_io + + mov eax,ebx + + new_port_access_disable: + + pushad + + mov ebp,1 ; disable - eax = port + call set_io_access_rights + + popad + + inc eax + cmp eax,ecx + 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: + push ebp esi ebp + cmp esi, 8 + jnz @f + mov ebp, putimage_get8bpp + mov esi, putimage_init8bpp + 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 + ret + +putimage_init24bpp: + lea eax, [eax*3] +putimage_init8bpp: + ret + +putimage_get24bpp: + mov eax, [esi] + add esi, 3 + ret 4 +putimage_get8bpp: + movzx eax, byte [esi] + push edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + pop edx + inc esi + ret 4 + +putimage_init32bpp: + shl eax, 2 + ret +putimage_get32bpp: + lodsd + 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 + + +_rdtsc: + bt [cpu_caps], CAPS_TSC + jnc ret_rdtsc + rdtsc + ret + ret_rdtsc: + mov edx,0xffffffff + mov eax,0xffffffff + ret + +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 + + + 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: + + mov [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 [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 eax, 4 + jb .audio + jz .eject + cmp eax, 5 + jnz .ret +.load: + call .reserve + call LoadMedium + call .free + ret +.eject: + call .reserve + call clear_CD_cache + call allow_medium_removal + call EjectMedium + call .free + ret +.audio: + call sys_cd_audio + mov [esp+36],eax +.ret: + ret + +.reserve: + call reserve_cd + mov eax, ebx + shr eax, 1 + and eax, 1 + inc eax + mov [ChannelNumber], ax + mov eax, ebx + 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 .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_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+36],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 [screen_workarea.right],eax + mov [screen_workarea.bottom], edx + inc eax + shl eax, 2 ;32 bpp + mov [BytesPerScanLine], eax + push ebx + push esi + push edi + call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + pop edi + pop esi + pop ebx + + popfd + ret + +; --------------- 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 + 56], 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 + 56], 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 + 56], byte 0xfe + or [esp + 56], 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 1 + 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 + +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 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: + mov edx, [ebx+64] + in ax, dx + and ax, 203h + or ax, 3C00h + out dx, ax + mov edx, [ebx+68] + test edx, edx + jz @f + in ax, dx + and ax, 203h + or ax, 3C00h + 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 + +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,$ + diff --git a/kernel/branches/kolibri_pe/kernel32.inc b/kernel/branches/kolibri_pe/kernel32.inc new file mode 100644 index 000000000..66a696219 --- /dev/null +++ b/kernel/branches/kolibri_pe/kernel32.inc @@ -0,0 +1,275 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 ? ;+20 + .fpu_handler dd ? ;+24 + .sse_handler 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 + + db 36 dup(?) ;+92 + + .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" diff --git a/kernel/branches/kolibri_pe/kglobals.inc b/kernel/branches/kolibri_pe/kglobals.inc new file mode 100644 index 000000000..3299a5ebe --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/macros.inc b/kernel/branches/kolibri_pe/macros.inc new file mode 100644 index 000000000..574b4a1e2 --- /dev/null +++ b/kernel/branches/kolibri_pe/macros.inc @@ -0,0 +1,100 @@ + +__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] diff --git a/kernel/branches/kolibri_pe/make.sh b/kernel/branches/kolibri_pe/make.sh new file mode 100755 index 000000000..d49fd1221 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + + diff --git a/kernel/branches/kolibri_pe/makefile b/kernel/branches/kolibri_pe/makefile new file mode 100644 index 000000000..e5f89bc4a --- /dev/null +++ b/kernel/branches/kolibri_pe/makefile @@ -0,0 +1,48 @@ +FASM=fasm +FLAGS=-m 65536 +languages=en|ru|ge|et +drivers_src=sound sis infinity ensoniq ps2mouse uart ati2d vmode +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 diff --git a/kernel/branches/kolibri_pe/memmap.inc b/kernel/branches/kolibri_pe/memmap.inc new file mode 100644 index 000000000..53675c3f0 --- /dev/null +++ b/kernel/branches/kolibri_pe/memmap.inc @@ -0,0 +1,245 @@ +; +; 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 +; +; Runtime: +; +; 0x00000000 -> 0x7FFFFFFF application 2Gb + +; 0x80000000 -> 1FFF 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 +; +; 2000 -> 2FFF free +; +; 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 -> B2FF IDT + +; B300 -> 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 + + diff --git a/kernel/branches/kolibri_pe/network/eth_drv/arp.inc b/kernel/branches/kolibri_pe/network/eth_drv/arp.inc new file mode 100644 index 000000000..dee6457cc --- /dev/null +++ b/kernel/branches/kolibri_pe/network/eth_drv/arp.inc @@ -0,0 +1,558 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ARP.INC ;; +;; ;; +;; Address Resolution Protocol ;; +;; ;; +;; Last revision: 10.11.2006 ;; +;; ;; +;; 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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/3c59x.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/3c59x.inc new file mode 100644 index 000000000..804e462e0 --- /dev/null +++ b/kernel/branches/kolibri_pe/network/eth_drv/drivers/3c59x.inc @@ -0,0 +1,2390 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;; Copyright (c) 2004, Endre Kozma +;; 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 +{ +if defined E3C59X_LINUX + sub reg, [virt_addr] + add reg, [dma_addr] +end if +} + +macro dma_to_virt reg +{ +if defined E3C59X_LINUX + sub reg, [dma_addr] + add reg, [virt_addr] +end if +} + +macro zero_to_virt reg +{ +if defined E3C59X_LINUX + add reg, [virt_addr] +end if +} + +macro virt_to_zero reg +{ +if defined E3C59X_LINUX + sub reg, [virt_addr] +end if +} + +macro zero_to_dma reg +{ +if defined E3C59X_LINUX + add reg, [dma_addr] +end if +} + +macro dma_to_zero reg +{ +if defined E3C59X_LINUX + sub reg, [dma_addr] +end if +} + +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, 2000 +.tx_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .tx_enable + dec ecx + jns .tx_reset_loop + 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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/i8255x.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/i8255x.inc new file mode 100644 index 000000000..3ab4d0628 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/pcnet32.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/pcnet32.inc new file mode 100644 index 000000000..f328e7105 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8029.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8029.inc new file mode 100644 index 000000000..6b66b54ed --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8139.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8139.inc new file mode 100644 index 000000000..e63169f84 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8169.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8169.inc new file mode 100644 index 000000000..5c7ca4b26 --- /dev/null +++ b/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8169.inc @@ -0,0 +1,1210 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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_TxDesc + +; 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,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,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,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,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 + 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 + RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray] + RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray] + 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 + + 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 + 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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/drivers/sis900.inc b/kernel/branches/kolibri_pe/network/eth_drv/drivers/sis900.inc new file mode 100644 index 000000000..8f160e0c7 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/ethernet.inc b/kernel/branches/kolibri_pe/network/eth_drv/ethernet.inc new file mode 100644 index 000000000..b296f2ff7 --- /dev/null +++ b/kernel/branches/kolibri_pe/network/eth_drv/ethernet.inc @@ -0,0 +1,460 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ETHERNET.INC ;; +;; ;; +;; Ethernet network layer for Menuet OS ;; +;; ;; +;; Version 0.4 22 September 2003 ;; +;; ;; +;; 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" + +; 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 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 + +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 +; +;*************************************************************************** +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 + + ; 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 + + 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 diff --git a/kernel/branches/kolibri_pe/network/eth_drv/pci.inc b/kernel/branches/kolibri_pe/network/eth_drv/pci.inc new file mode 100644 index 000000000..5935480c9 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/network/icmp.inc b/kernel/branches/kolibri_pe/network/icmp.inc new file mode 100644 index 000000000..5c0fc9f2f --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/network/ip.inc b/kernel/branches/kolibri_pe/network/ip.inc new file mode 100644 index 000000000..a57e082bc --- /dev/null +++ b/kernel/branches/kolibri_pe/network/ip.inc @@ -0,0 +1,200 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 +} + + +;*************************************************************************** +; 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 + + ; 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], word 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 + + mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!! + jnz .dump ;if CHECKSUM isn't valid then dump packet + + ; 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 + cmp dword[ebx + IP_PACKET.DestinationAddress], 0xffffffff + jne .dump + + @@: + mov al, [ebx + IP_PACKET.VersionAndIHL] + and al, 0x0f ;get IHL(header length) + cmp al, 0x05 ;if IHL!= 5*4(20 bytes) + jnz .dump ;then dump it + + cmp byte[ebx + IP_PACKET.TimeToLive], byte 0 + je .dump ;if TTL==0 then dump it + + mov ax, word[ebx + IP_PACKET.FlagsAndFragmentOffset] + and ax, 0xFFBF ;get flags + cmp ax, 0 ;if some flags was set then we dump this packet + jnz .dump ;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 ;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: + ; No protocol handler available, so + ; silently dump the packet, freeing up the queue buffer + + inc dword [dumped_rx_count] + + mov eax, dword[buffer_number] + call freeBuff + + .exit: + ret +endp + diff --git a/kernel/branches/kolibri_pe/network/queue.inc b/kernel/branches/kolibri_pe/network/queue.inc new file mode 100644 index 000000000..15b458f1a --- /dev/null +++ b/kernel/branches/kolibri_pe/network/queue.inc @@ -0,0 +1,220 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; QUEUE.INC ;; +;; ;; +;; Buffer queue management 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$ + + +;******************************************************************* +; 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 +;*************************************************************************** +freeBuff: + push ebx + push ecx + mov ebx, EMPTY_QUEUE + shl ebx, 1 + add ebx, queues + cli ; Ensure that another process does not interfer + movzx ecx, word [ebx] + mov [ebx], ax + shl eax, 1 + add eax, queueList + mov [eax], 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 +;*************************************************************************** +queue: + 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 +; +;*************************************************************************** +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 + 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 diff --git a/kernel/branches/kolibri_pe/network/socket.inc b/kernel/branches/kolibri_pe/network/socket.inc new file mode 100644 index 000000000..9d197ddf9 --- /dev/null +++ b/kernel/branches/kolibri_pe/network/socket.inc @@ -0,0 +1,934 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; SOCKET.INC ;; +;; ;; +;; Sockets constants, structures and functions ;; +;; ;; +;; Last revision: 11.11.2006 ;; +;; ;; +;; 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 Descriptor + Buffer +; +; 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 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 0| Status ( of this buffer ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 4| Application Process ID | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 8| Local IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 12| Local IP Port | Unused ( set to 0 ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 16| Remote IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 20| Remote IP Port | Unused ( set to 0 ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 24| Rx Data Count INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 28| TCB STATE INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 32| TCB Timer (seconds) INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 36| ISS (Inital Sequence # used by this connection ) INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 40| IRS ( Inital Receive Sequence # ) INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 44| SND.UNA Seq # of unack'ed sent packets INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 48| SND.NXT Next send seq # to use INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 52| SND.WND Send window INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 56| RCV.NXT Next expected receive sequence # INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 60| RCV.WND Receive window INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 64| SEG.LEN Segment length INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 68| SEG.WND Segment window INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 76| RX offset from +; 76| RX Data | +; +-+-+-.......... -+ + + +; so, define struct +struc SOCKET +{ .Status dd ? ;+00 - Status ( of this buffer ) + .PID dd ? ;+04 - Application Process ID + .LocalIP dd ? ;+08 - Local IP Address + .LocalPort dw ? ;+12 - Local Port + .UnusedL dw ? ;+14 - may be removed in future + .RemoteIP dd ? ;+16 - Remote IP Address + .RemotePort dw ? ;+20 - Remote Port + .UnusedR dw ? ;+22 - may be removed in future + .rxDataCount dd ? ;+24 - Rx Data Count + .TCBState dd ? ;+28 - TCB STATE + .TCBTimer dd ? ;+32 - TCB Timer (seconds) + .ISS dd ? ;+36 - Initial Send Sequence + .IRS dd ? ;+40 - Initial Receive Sequence + .SND_UNA dd ? ;+44 - Sequence number of unack'ed sent packets + .SND_NXT dd ? ;+48 - Next send sequence number to use + .SND_WND dd ? ;+52 - Send window + .RCV_NXT dd ? ;+56 - Next receive sequence number to use + .RCV_WND dd ? ;+60 - Receive window + .SEG_LEN dd ? ;+64 - Segment length + .SEG_WND dd ? ;+68 - Segment window + .wndsizeTimer dd ? ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER + .rxData dd ? ;+76 - receive data buffer here +} + +virtual at 0 + SOCKET SOCKET +end virtual + +; simple macro calcing real memory address of SOCKET struct by socket's +macro Index2RealAddr reg +{ + shl reg, 12 + add reg, sockets +} + +;Constants +; current socket statuses +SOCK_EMPTY equ 0 ; socket not in use +SOCK_OPEN equ 1 ; open issued, but no data sent + +; TCP opening modes +SOCKET_PASSIVE equ 0 +SOCKET_ACTIVE equ 1 + +;*************************************************************************** +; Function +; is_localport_unused +; +; Description +; scans through all the active sockets , looking to see if the +; port number specified in bx is in use as a localport number. +; This is useful when you want a to generate a unique local port +; number. +; On return, eax = 1 for free, 0 for in use +; +;*************************************************************************** +is_localport_unused: + mov al, bh + mov ah, bl + mov bx, ax + + mov edx, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + mov eax, 0 ; Assume the return value is 'in use' + +ilu1: + sub edx, SOCKETBUFFSIZE + cmp [edx + sockets + SOCKET.LocalPort], bx + loopnz ilu1 ; Return back if the socket is occupied + + jz ilu_exit + inc eax ; return port not in use + +ilu_exit: + ret + + + +;*************************************************************************** +; Function +; get_free_socket +; +; Description +; +;*************************************************************************** +get_free_socket: + push ecx + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +gfs1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets + SOCKET.Status], dword SOCK_EMPTY + loopnz gfs1 ; Return back if the socket is occupied + mov eax, ecx + pop ecx + jz gfs_exit + mov eax, 0xFFFFFFFF + +gfs_exit: + ret + + +;*************************************************************************** +; Function +; socket_open +; +; Description +; find a free socket +; local port in ebx +; remote port in ecx +; remote ip in edx +; return socket # in eax, -1 if none available +; +;*************************************************************************** +socket_open: + call get_free_socket + + cmp eax, 0xFFFFFFFF + jz so_exit + + ; ax holds the socket number that is free. Get real address + push eax + Index2RealAddr eax + + mov [eax + SOCKET.Status], dword SOCK_OPEN + + xchg bh, bl + mov [eax + SOCKET.LocalPort], bx + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx + + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count + + mov esi, [TASK_BASE] + mov ebx, [esi+TASKDATA.pid] + mov [eax + SOCKET.PID], ebx ; save the process ID + pop eax ; Get the socket number back, so we can return it + +so_exit: + ret + + + +;*************************************************************************** +; Function +; socket_open_tcp +; +; Description +; Opens a TCP socket in PASSIVE or ACTIVE mode +; find a free socket +; local port in ebx ( intel format ) +; remote port in ecx ( intel format ) +; remote ip in edx ( in Internet byte order ) +; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) +; return socket # in eax, -1 if none available +; +;*************************************************************************** +socket_open_tcp: + call get_free_socket + + cmp eax, 0xFFFFFFFF + jz so_exit + + ; ax holds the socket number that is free. Get real address + push eax + Index2RealAddr eax + + mov [sktAddr], eax + mov [eax], dword SOCK_OPEN + + ; TODO - check this works! + mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer. + + xchg bh, bl + mov [eax + SOCKET.LocalPort], bx +; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) +; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) + + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx +; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) +; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) + + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + mov [eax + SOCKET.rxDataCount], dword 0 + + ; Now fill in TCB state + mov ebx, TCB_LISTEN + cmp esi, SOCKET_PASSIVE + jz sot_001 + mov ebx, TCB_SYN_SENT + +sot_001: + mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB + + mov esi, [TASK_BASE] + mov ecx, [esi+TASKDATA.pid] + mov [eax + SOCKET.PID], ecx ; save the process ID + + cmp ebx, TCB_LISTEN + je sot_done + + ; 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 sot_done + + push eax + + mov bl, 0x02 ; SYN + mov ecx, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [sktAddr ] + mov ecx, [ecx + 16] + cmp edx, ecx + jne sot_notlocal + mov eax, IPIN_QUEUE + +sot_notlocal: + ; Send it. + pop ebx + call queue + + mov esi, [sktAddr] + + ; increment SND.NXT in socket + add esi, 48 + call inc_inet_esi + +sot_done: + pop eax ; Get the socket number back, so we can return it + +sot_exit: + ret + + + +;*************************************************************************** +; Function +; socket_close +; +; Description +; socket # in ebx +; returns 0 for ok, -1 for socket not open (fail) +; +;*************************************************************************** +socket_close: + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp ebx, NUM_SOCKETS + jae sc_exit + Index2RealAddr ebx + cmp [ebx + SOCKET.Status], dword SOCK_EMPTY + jz sc_exit + + ; Clear the socket varaibles + xor eax, eax + mov edi, ebx + mov ecx, SOCKETHEADERSIZE + cld + rep stosb + +sc_exit: + ret + + + +;*************************************************************************** +; Function +; socket_close_tcp +; +; Description +; socket # in ebx +; returns 0 for ok, -1 for socket not open (fail) +; +;*************************************************************************** +socket_close_tcp: + ; first, remove any resend entries + pusha + + mov esi, resendQ + mov ecx, 0 + +sct001: + cmp ecx, NUMRESENDENTRIES + je sct003 ; None left + cmp [esi], bl + je sct002 ; found one + inc ecx + add esi, 4 + jmp sct001 + +sct002: + + mov [esi], byte 0xFF + jmp sct001 + +sct003: + popa + + Index2RealAddr ebx + mov [sktAddr], ebx + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp [ebx + SOCKET.Status], dword SOCK_EMPTY + jz sct_exit + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stl_exit + + push eax + + mov bl, 0x11 ; FIN + ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov ebx, [sktAddr] + + ; increament SND.NXT in socket + mov esi, 48 + add esi, ebx + call inc_inet_esi + + + ; Get the socket state + mov eax, [ebx + SOCKET.TCBState] + cmp eax, TCB_LISTEN + je destroyTCB + cmp eax, TCB_SYN_SENT + je destroyTCB + cmp eax, TCB_SYN_RECEIVED + je sct_finwait1 + cmp eax, TCB_ESTABLISHED + je sct_finwait1 + + ; assume CLOSE WAIT + ; Send a fin, then enter last-ack state + mov eax, TCB_LAST_ACK + mov [ebx + SOCKET.TCBState], eax + xor eax, eax + jmp sct_send + +sct_finwait1: + ; Send a fin, then enter finwait2 state + mov eax, TCB_FIN_WAIT_1 + mov [ebx + SOCKET.TCBState], eax + xor eax, eax + +sct_send: + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [sktAddr ] + mov ecx, [ecx + 16] + cmp edx, ecx + jne sct_notlocal + mov eax, IPIN_QUEUE + +sct_notlocal: + ; Send it. + pop ebx + call queue + jmp sct_exit + +destroyTCB: + pop eax + ; Clear the socket varaibles + xor eax, eax + mov edi, ebx + mov ecx, SOCKETHEADERSIZE + cld + rep stosb + +sct_exit: + ret + + + +;*************************************************************************** +; Function +; socket_poll +; +; Description +; socket # in ebx +; returns count in eax. +; +;*************************************************************************** +socket_poll: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.rxDataCount] + + ret + + + +;*************************************************************************** +; Function +; socket_status +; +; Description +; socket # in ebx +; returns TCB state in eax. +; +;*************************************************************************** +socket_status: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.TCBState] + + ret + + + +;*************************************************************************** +; Function +; socket_read +; +; Description +; socket # in ebx +; returns # of bytes remaining in eax, data in bl +; +;*************************************************************************** +socket_read: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes + mov ecx, 1 + test eax, eax + jz sr2 + + dec eax + mov esi, ebx ; esi is address of socket + mov [ebx + SOCKET.rxDataCount], eax ; store new count + ;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte + movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte + add esi, SOCKETHEADERSIZE + mov edi, esi + inc esi + + mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 + cld + rep movsd + xor ecx, ecx + +sr1: + jmp sor_exit + +sr2: + xor bl, bl + +sor_exit: + ret + + +;*************************************************************************** +; Function +; socket_read_packet +; +; Description +; socket # in ebx +; datapointer # in ecx +; buffer size in edx +; returns # of bytes copied in eax +; +;*************************************************************************** +socket_read_packet: + Index2RealAddr ebx ; get real socket address + 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 .copyallbytes + cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data + jge .copyallbytes + + 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 .startcopy ; copy to the application + + mov esi, ebx ; now we're going to copy the remaining bytes to the beginning + add esi, SOCKETHEADERSIZE ; 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 + + ret ; at last, exit + +.copyallbytes: + xor esi, esi + mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) + +.startcopy: + mov edi, ecx ; + ; add edi, std_application_base_address ; get data pointer to buffer in application + + mov esi, ebx ; + add esi, SOCKETHEADERSIZE ; 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 + +.exit: + ret ; exit, or go back to shift remaining bytes if any + + + + +;*************************************************************************** +; Function +; socket_write +; +; Description +; socket in ebx +; # of bytes to write in ecx +; pointer to data in edx +; returns 0 in eax ok, -1 == failed ( invalid socket, or +; could not queue IP packet ) +; +;*************************************************************************** +socket_write: + Index2RealAddr ebx + + mov eax, 0xFFFFFFFF + ; If the socket is invalid, return with an error code + cmp [ebx], dword SOCK_EMPTY + je sw_exit + + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je sw_exit + + ; 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 + 8] + mov [edx + 12], eax ; source IP + mov eax, [ebx + 16] + mov [edx + 16], eax ; Destination IP + + mov al, 0x45 + mov [edx], al ; Version, IHL + xor al, al + mov [edx + 1], al ; Type of service + + pop eax ; Get the UDP data length + push eax + + add eax, 20 + 8 ; add IP header and UDP header lengths + mov [edx + 2], ah + mov [edx + 3], al + xor al, al + mov [edx + 4], al + mov [edx + 5], al + mov al, 0x40 + mov [edx + 6], al + xor al, al + mov [edx + 7], al + mov al, 0x20 + mov [edx + 8], al + mov al, 17 + mov [edx + 9], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 10], ax + + ; Fill in the UDP header ( some data is in the socket descriptor) + mov ax, [ebx + 12] + mov [edx + 20], ax + + mov ax, [ebx + 20] + mov [edx + 20 + 2], ax + + pop eax + push eax + + add eax, 8 + mov [edx + 20 + 4], ah + mov [edx + 20 + 5], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 20 + 6], 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 + 12] + mov [pseudoHeader], eax + mov eax, [edx + 16] + mov [pseudoHeader+4], eax + mov ax, 0x1100 ; 0 + protocol + mov [pseudoHeader+8], ax + add ebx, 8 + mov eax, ebx + mov [pseudoHeader+10], ah + mov [pseudoHeader+11], al + + 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') + cmp ax, 0 + jne sw_001 + mov ax, 0xffff + +sw_001: + mov [edx + 20 + 6], ah + mov [edx + 20 + 7], al + + ; Fill in the IP header checksum + GET_IHL ecx,edx ; get IP-Header length + stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size + + mov [edx + 10], ah + mov [edx + 11], al + + ; 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 + 16] + mov edx, [stack_ip] + cmp edx, ecx + jne sw_notlocal + mov eax, IPIN_QUEUE + +sw_notlocal: + ; Send it. + call queue + + xor eax, eax + +sw_exit: + ret + + + +;*************************************************************************** +; Function +; socket_write_tcp +; +; Description +; socket in ebx +; # of bytes to write in ecx +; pointer to data in edx +; returns 0 in eax ok, -1 == failed ( invalid socket, or +; could not queue IP packet ) +; +;*************************************************************************** +socket_write_tcp: + Index2RealAddr ebx + + mov [sktAddr], ebx + + mov eax, 0xFFFFFFFF + ; If the socket is invalid, return with an error code + cmp [ebx], dword SOCK_EMPTY + je swt_exit + + ; If the sockets window timer is nonzero, do not queue packet + ; TODO - done + cmp [ebx + SOCKET.wndsizeTimer], dword 0 + jne swt_exit + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je swt_exit + + push eax + + mov bl, 0x10 ; ACK + + ; 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 + call buildTCPPacket + 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, [sktAddr ] + mov ecx, [ecx + 16] + cmp edx, ecx + jne swt_notlocal + mov eax, IPIN_QUEUE + +swt_notlocal: + pop ecx + + push ebx ; save ipbuffer number + + call queue + + mov esi, [sktAddr] + + ; increament SND.NXT in socket + ; Amount to increment by is in ecx + add esi, 48 + 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 + +swt003: + cmp ecx, NUMRESENDENTRIES + je swt001 ; None found + cmp [esi], byte 0xFF + je swt002 ; found one + inc ecx + add esi, 4 + jmp swt003 + +swt002: + 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 + + mov eax, [sktAddr] + sub eax, sockets + shr eax, 12 ; get skt # + mov [esi], al + mov [esi + 1], byte TCP_RETRIES + mov [esi + 2], word TCP_TIMEOUT + + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov edi, resendBuffer - IPBUFFSIZE +swt002a: + add edi, IPBUFFSIZE + loop swt002a + + ; 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 + +swt001: + xor eax, eax + +swt_exit: + ret + diff --git a/kernel/branches/kolibri_pe/network/stack.inc b/kernel/branches/kolibri_pe/network/stack.inc new file mode 100644 index 000000000..eefc30457 --- /dev/null +++ b/kernel/branches/kolibri_pe/network/stack.inc @@ -0,0 +1,1021 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; STACK.INC ;; +;; ;; +;; TCP/IP stack for Menuet OS ;; +;; ;; +;; Version 0.7 4th July 2004 ;; +;; ;; +;; 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 76 ; 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 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 + + +; 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 "icmp.inc" +include "tcp.inc" +include "udp.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, 0xFFFFFFFF, NUMRESENDENTRIES + + ; 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 +; +;*************************************************************************** +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 + + ; + ; 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 + +; +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 +; +; modified by [smb] + +; +; 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 +; + +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 + diff --git a/kernel/branches/kolibri_pe/network/tcp.inc b/kernel/branches/kolibri_pe/network/tcp.inc new file mode 100644 index 000000000..a5cb519cd --- /dev/null +++ b/kernel/branches/kolibri_pe/network/tcp.inc @@ -0,0 +1,1302 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; TCP.INC ;; +;; ;; +;; TCP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Version 0.6 4th July 2004 ;; +;; ;; +;; 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_TIME_WAIT equ 10 +TCB_CLOSED equ 11 + +TWOMSL equ 10 ; # of secs to wait before closing socket + +TCP_RETRIES equ 5 ; Number of times to resend a packet +TCP_TIMEOUT equ 10 ; 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 +; +;*************************************************************************** +tcp_tcb_handler: + ; scan through all the sockets, decrementing active timers + + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +tth1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets + 32], dword 0 + jne tth2 + +tth1a: + cmp [eax + sockets + 72], dword 0 + jne tth4 + + loop tth1 + ret + +tth2: + ; decrement it, delete socket if TCB timer = 0 & socket in timewait state + pusha + dec dword [eax + sockets + 32] + cmp [eax + sockets + 32], dword 0 + jne tth3 + + cmp [eax + sockets + 28], dword TCB_TIME_WAIT + jne tth3 + + ; OK, delete socket + mov edi, eax + add edi, sockets + + xor eax, eax + mov ecx, SOCKETHEADERSIZE + cld + rep stosb + +tth3: + popa + + jmp tth1a + + loop tth1 + ret + + ; TODO - prove it works! +tth4: + dec dword [eax + sockets + 72] + loop tth1 + ret + + + + +tth_exit: + ret + + +;*************************************************************************** +; Function +; tcp_tx_handler +; +; Description +; Handles queued TCP data +; This is a kernel function, called by stack_handler +; +;*************************************************************************** +tcp_tx_handler: + ; 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 + +tth001: + cmp ecx, NUMRESENDENTRIES + je tth003 ; None left + cmp [esi], byte 0xFF + jne tth002 ; found one + inc ecx + add esi, 4 + jmp tth001 + +tth002: + ; we have one. decrement it's timer by 1 + dec word [esi+2] + mov ax, [esi+2] + cmp ax, 0 + je tth002a + inc ecx + add esi, 4 + jmp tth001 ; Timer not zero, so move on + +tth002a: + mov bl, 0xff + ; 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] + mov al, [esi+1] + cmp al, 0 + jne tth004 + + ; retries now 0, so delete from queue + xchg [esi], bl +tth004: + + ; resend packet + pusha + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + jne tth004z + + ; TODO - try again in 10ms. + cmp bl, 0xff + jne tth004za + mov [esi], bl + +tth004za: + ; Mark it to expire in 10ms - 1 tick + mov [esi+1], byte 1 + mov [esi+2], word 1 + jmp tth005 + +tth004z: + ; we have a buffer # in ax + + push eax + push ecx + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + ; we have the buffer address in eax + mov edi, eax + pop ecx + ; get resend data address + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov esi, resendBuffer - IPBUFFSIZE +tth004a: + add esi, IPBUFFSIZE + loop tth004a + + ; we have resend buffer location in esi + mov ecx, IPBUFFSIZE + + ; copy data across + cld + rep movsb + + ; queue packet + + + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ edi + 16 ] + cmp edx, ecx + jne tth004b + mov eax, IPIN_QUEUE + +tth004b: + pop ebx + + call queue + + +tth005: + popa + + inc ecx + add esi, 4 + jmp tth001 + +tth003: + ret + + + + +;*************************************************************************** +; 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 +; +;*************************************************************************** +tcp_rx: + ; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS +ss1: + sub eax, SOCKETBUFFSIZE + movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst1 ; different - try next socket + + movzx ebx, word [edx + 20] ; get the source port from the TCP hdr + cmp [eax + sockets + 20], bx ; compare with socket's remote port + jnz nxttst1 ; different - try next socket + + + mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr + cmp [eax + sockets + 16], ebx ; compare with socket's remote IP + jnz nxttst1 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst1: + loop ss1 ; Return back if no match + + ; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +ss2: + sub eax, SOCKETBUFFSIZE + + movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst2 ; different - try next socket + + mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr + cmp [eax + sockets + 16], ebx ; compare with socket's remote IP + jnz nxttst2 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 20], bx ; only match a remote socket of 0 + jnz nxttst2 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst2: + loop ss2 ; Return back if no match + + ; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +ss3: + sub eax, SOCKETBUFFSIZE + + movzx ebx, word [edx + 22] ; get destination port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst3 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 20], bx ; only match a remote socket of 0 + jnz nxttst3 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0 + jnz nxttst3 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst3: + loop ss3 ; Return back if no match + + ; If we got here, we need to reject the packet + inc dword [dumped_rx_count] + jmp tcprx_exit + +tcprx_001: + ; We have a valid socket/TCB, so call the TCB State Machine for that skt. + ; socket is pointed to by [eax + sockets] + ; IP packet is pointed to by [edx] + ; IP buffer number is on stack ( it will be popped at the end) + call tcpStateMachine + +tcprx_exit: + pop eax + call freeBuff + + ret + + + +;*************************************************************************** +; 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 +; +;*************************************************************************** +buildTCPPacket: + 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 + 33], bl ; TCP flags + + mov ebx, [sktAddr] + + ; 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 + 8] + mov [edx + 12], eax ; source IP + mov eax, [ebx + 16] + mov [edx + 16], eax ; Destination IP + + mov al, 0x45 + mov [edx], al ; Version, IHL + xor al, al + mov [edx + 1], al ; Type of service + + pop eax ; Get the TCP data length + push eax + + add eax, 20 + 20 ; add IP header and TCP header lengths + mov [edx + 2], ah + mov [edx + 3], al + xor al, al + mov [edx + 4], al + mov [edx + 5], al + mov al, 0x40 + mov [edx + 6], al + xor al, al + mov [edx + 7], al + mov al, 0x20 + mov [edx + 8], al + mov al, 6 ; TCP protocol + mov [edx + 9], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 10], ax + + ; Fill in the TCP header ( some data is in the socket descriptor) + mov ax, [ebx + 12] + mov [edx + 20], ax ; Local Port + + mov ax, [ebx + 20] + mov [edx + 20 + 2], ax ; desitination Port + + ; Checksum left unfilled + xor ax, ax + mov [edx + 20 + 16], ax + + ; sequence number + mov eax, [ebx + 48] + mov [edx + 20 + 4], eax + + ; ack number + mov eax, [ebx + 56] + mov [edx + 20 + 8], eax + + ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) + ; 768 bytes seems better + mov ax, 0x0003 + mov [edx + 20 + 14], ax + + ; Urgent pointer (0) + mov ax, 0 + mov [edx + 20 + 18], ax + + ; data offset ( 0x50 ) + mov al, 0x50 + mov [edx + 20 + 12], al + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + + cmp ebx, 0 + jz btp_001 + + mov edi, edx + add edi, 40 + cld + rep movsb ; copy the data across + +btp_001: + ; we have edx as IPbuffer ptr. + ; Fill in the TCP checksum + ; First, fill in pseudoheader + mov eax, [edx + 12] + mov [pseudoHeader], eax + mov eax, [edx + 16] + mov [pseudoHeader+4], eax + mov ax, 0x0600 ; 0 + protocol + mov [pseudoHeader+8], ax + add ebx, 20 + mov eax, ebx + mov [pseudoHeader+10], ah + mov [pseudoHeader+11], al + + 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 + + call checksum + + ; store it in the TCP checksum ( in the correct order! ) + mov ax, [checkResult] + + mov [edx + 20 + 16], ah + mov [edx + 20 + 17], al + + ; Fill in the IP header checksum + GET_IHL eax,edx ; get IP-Header length + stdcall checksum_jb,edx,eax ; buf_ptr, buf_size + + mov [edx + 10], ah + mov [edx + 11], al + + ret + + +; Increments the 32 bit value pointed to by esi in internet order +inc_inet_esi: + push eax + add esi, 3 + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + +iie_exit: + pop eax + ret + + +; Increments the 32 bit value pointed to by esi in internet order +; by the value in ecx +add_inet_esi: + push eax + + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + add eax, ecx + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + pop eax + ret + + +iglobal + TCBStateHandler: + dd stateTCB_LISTEN + dd stateTCB_SYN_SENT + dd stateTCB_SYN_RECEIVED + dd stateTCB_ESTABLISHED + dd stateTCB_FIN_WAIT_1 + dd stateTCB_FIN_WAIT_2 + dd stateTCB_CLOSE_WAIT + dd stateTCB_CLOSING + dd stateTCB_LAST_ACK + dd stateTCB_TIME_WAIT + dd 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 [eax + sockets] +; +; The IP buffer will be released by the caller +;*************************************************************************** +tcpStateMachine: + mov ebx, sockets + add ebx, eax + mov [sktAddr], ebx + + ; as a packet has been received, update the TCB timer + mov ecx, TWOMSL + mov [ebx + 32], ecx + + ; If the received packet has an ACK bit set, + ; remove any packets in the resend queue that this + ; received packet acknowledges + pusha + mov cl, [edx + 33] + and cl, 0x10 + cmp cl, 0x10 + jne tsm001 ; No ACK, so no data yet + + + ; get skt number in al + shr eax, 12 + + ; The ack number is in [edx + 28], inet format + ; skt in al + + mov esi, resendQ + mov ecx, 0 + +t001: + cmp ecx, NUMRESENDENTRIES + je t003 ; None left + cmp [esi], al + je t002 ; found one + inc ecx + add esi, 4 + jmp t001 + +t002: ; Can we delete this buffer? + + ; If yes, goto t004. No, goto t001 + ; Get packet data address + + push ecx + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov edi, resendBuffer - IPBUFFSIZE +t002a: + add edi, IPBUFFSIZE + loop t002a + + ; we have dest buffer location in edi. incoming packet in edx. + ; Get this packets sequence number + ; preserve al, ecx, esi, edx + + mov cl, [edi + 24] + shl ecx, 8 + mov cl, [edi + 25] + shl ecx, 8 + mov cl, [edi + 26] + shl ecx, 8 + mov cl, [edi + 27] + movzx ebx, byte [edi + 3] + mov bh, [edi + 2] + sub ebx, 40 + add ecx, ebx ; ecx is now seq# of last byte +1, intel format + + ; get recievd ack #, in intel format + mov bl, [edx + 28] + shl ebx, 8 + mov bl, [edx + 29] + shl ebx, 8 + mov bl, [edx + 30] + shl ebx, 8 + mov bl, [edx + 31] + + 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 t004 ; if rx > old, delete old + inc ecx + add esi, 4 + jmp t001 + + +t004: + dec dword [arp_rx_count] ; ************ TEST ONLY! + + mov [esi], byte 0xFF + inc ecx + add esi, 4 + jmp t001 + +t003: + +tsm001: + popa + + ; Call handler for given TCB state + mov ebx, [eax + sockets+28] + cmp ebx, TCB_LISTEN + jb tsm_exit + cmp ebx, TCB_CLOSED + ja tsm_exit + + dec ebx + call dword [TCBStateHandler+ebx*4] + +tsm_exit: + ret + + + +stateTCB_LISTEN: + ; 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 + mov bl, [edx + 33] + and bl, 0x02 + cmp bl, 0x02 + jnz stl_exit + + ; We have a SYN. update the socket with this IP packets details, + ; And send a response + + mov ebx, [edx + 12] ; IP source address + mov [eax + sockets + 16], ebx + mov bx, [edx + 20] ; IP source port + mov [eax + sockets + 20], bx + mov ebx, [edx + 24] ; IRS + mov [eax + sockets + 40], ebx + mov [eax + sockets + 56], ebx + mov esi, sockets + add esi, eax + add esi, 56 + call inc_inet_esi ; RCV.NXT + mov ebx, [eax + sockets + 36] ; ISS + mov [eax + sockets + 48], ebx ; SND.NXT + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stl_exit + + push eax + mov bl, 0x12 ; SYN + ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stl_notlocal + mov eax, IPIN_QUEUE + +stl_notlocal: + ; Send it. + pop ebx + call queue + + + mov ebx, TCB_SYN_RECEIVED + mov esi, [sktAddr] + mov [esi + 28], ebx + + ; increament SND.NXT in socket + add esi, 48 + call inc_inet_esi + +stl_exit: + ret + + + +stateTCB_SYN_SENT: + ; We are awaiting an ACK to our SYN, with a SYM + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x12 + cmp bl, 0x12 + jnz stss_exit + + mov ebx, TCB_ESTABLISHED + mov esi, [sktAddr] + mov [esi + 28], ebx + + ; Store the recv.nxt field + mov eax, [edx + 24] + + ; Update our recv.nxt field + mov esi, [sktAddr] + add esi, 56 + mov [esi], eax + 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 + je stss_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stss_notlocal + mov eax, IPIN_QUEUE + +stss_notlocal: + ; Send it. + pop ebx + call queue + +stss_exit: + ret + + + +stateTCB_SYN_RECEIVED: + ; In this case, we are expecting an ACK packet + ; For now, if the packet is an ACK, process it, + ; If not, ignore it + + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stsr_exit + + mov ebx, TCB_ESTABLISHED + mov esi, [sktAddr] + mov [esi + 28], ebx + +stsr_exit: + ret + + + +stateTCB_ESTABLISHED: + ; Here we are expecting data, or a request to close + ; OR both... + + ; Did we receive a FIN or RST? + mov bl, [edx + 33] + and bl, 0x05 + cmp bl, 0 + je ste_chkack + + ; It was a fin or reset. + + ; Remove resend entries from the queue - I dont want to send any more data + pusha + + mov ebx, [sktAddr] + sub ebx, sockets + shr ebx, 12 ; get skt # + + mov esi, resendQ + mov ecx, 0 + +ste001: + cmp ecx, NUMRESENDENTRIES + je ste003 ; None left + cmp [esi], bl + je ste002 ; found one + inc ecx + add esi, 4 + jmp ste001 + +ste002: + dec dword [arp_rx_count] ; ************ TEST ONLY! + + mov [esi], byte 0xFF + jmp ste001 + +ste003: + popa + + ; was it a reset? + mov bl, [edx + 33] + and bl, 0x04 + cmp bl, 0x04 + jne ste003a + + mov esi, [sktAddr] + mov ebx, TCB_CLOSED + mov [esi + 28], ebx + jmp ste_exit + +ste003a: + ; Send an ACK to that fin, and enter closewait state + + mov esi, [sktAddr] + mov ebx, TCB_CLOSE_WAIT + mov [esi + 28], ebx + add esi, 56 + mov eax, [esi] ; save original + call inc_inet_esi + ;; jmp ste_ack - NO, there may be data + +ste_chkack: + ; Check that we received an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz ste_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 ch, [edx + 34] + mov cl, [edx + 35] + cmp cx, 1024 + ja ste004 + + mov ecx, [sktAddr] + mov [ecx+72], dword 1 + +ste004: + + ; OK, here is the deal + ; My recv.nct field holds the seq of the expected next rec byte + ; if the recevied sequence number is not equal to this, do not + ; increment the recv.nxt field, do not copy data - just send a + ; repeat ack. + + ; recv.nxt is in dword [edx+24], in inext format + ; recv seq is in [sktAddr]+56, in inet format + ; just do a comparision + mov ecx, [sktAddr] + add ecx, 56 + + cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT + mov ecx, [ecx] + jne stenofin + mov ecx, eax + +stenofin: + cmp ecx, [edx+24] + jne ste_ack + + + ; Read the data bytes, store in socket buffer + xor ecx, ecx + mov ch, [edx + 2] + mov cl, [edx + 3] + sub ecx, 40 ; Discard 40 bytes of header + + cmp ecx, 0 + jnz ste_data ; Read data, if any + + ; If we had received a fin, we need to ACK it. + mov esi, [sktAddr] + mov ebx, [esi + 28] + cmp ebx, TCB_CLOSE_WAIT + jz ste_ack + jnz ste_exit + +ste_data: + push ecx + mov esi, [sktAddr] + + add [esi + 24], ecx ; increment the count of bytes in buffer + + mov eax, [esi + 4] ; get socket owner PID + push eax + + mov eax, [esi + 24] ; get # of bytes already in buffer + + ; point to the location to store the data + add esi, eax + sub esi, ecx + add esi, SOCKETHEADERSIZE + + add edx, 40 ; edx now points to the data + mov edi, esi + mov esi, edx + + cld + rep movsb ; copy the data across + + ; flag an event to the application + pop eax + mov ecx,1 + mov esi,TASK_DATA+TASKDATA.pid + +news: + cmp [esi],eax + je foundPID1 + inc ecx + add esi,0x20 + cmp ecx,[TASK_COUNT] + jbe news + +foundPID1: + shl ecx,8 + or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event + + pop ecx + + ; Update our recv.nxt field + mov esi, [sktAddr] + add esi, 56 + call add_inet_esi + +ste_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 ste_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne ste_notlocal + mov eax, IPIN_QUEUE +ste_notlocal: + + ; Send it. + pop ebx + call queue + +ste_exit: + ret + + + +stateTCB_FIN_WAIT_1: + ; We can either receive an ACK of a fin, or a fin + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stfw1_001 + + ; It was an ACK + mov esi, [sktAddr] + mov ebx, TCB_FIN_WAIT_2 + mov [esi + 28], ebx + jmp stfw1_exit + +stfw1_001: + ; It must be a fin then + mov esi, [sktAddr] + mov ebx, TCB_CLOSING + mov [esi + 28], ebx + add esi, 56 + call inc_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stfw1_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stfw1_notlocal + mov eax, IPIN_QUEUE + +stfw1_notlocal: + ; Send it. + pop ebx + call queue + +stfw1_exit: + ret + + + +stateTCB_FIN_WAIT_2: + mov esi, [sktAddr] + + ; Get data length + xor ecx, ecx + mov ch, [edx+2] + mov cl, [edx+3] + sub ecx, 40 + + mov bl, [edx + 33] + and bl, 0x01 + cmp bl, 0x01 + jne stfw2001 + + ; Change state, as we have a fin + mov ebx, TCB_TIME_WAIT + mov [esi + 28], ebx + + inc ecx ; FIN is part of the sequence space + +stfw2001: + add esi, 56 + call add_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stfw2_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stfw2_notlocal + mov eax, IPIN_QUEUE + +stfw2_notlocal: + ; Send it. + pop ebx + call queue + + ; Only delete the socket if we received the FIN + + mov bl, [edx + 33] + and bl, 0x01 + cmp bl, 0x01 + jne stfw2_exit + +; mov edi, [sktAddr] + + ; delete the socket. Should really wait for 2MSL +; xor eax, eax +; mov ecx,SOCKETHEADERSIZE +; cld +; rep stosb + +stfw2_exit: + ret + + + +stateTCB_CLOSE_WAIT: + ; Intentionally left empty + ; socket_close_tcp handles this + ret + + + +stateTCB_CLOSING: + ; We can either receive an ACK of a fin, or a fin + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stc_exit + + ; It was an ACK + + mov edi, [sktAddr] + + ; delete the socket + xor eax, eax + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +stc_exit: + ret + + + +stateTCB_LAST_ACK: + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stla_exit + + mov edi, [sktAddr] + + ; delete the socket + xor eax, eax + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +stla_exit: + ret + + + +stateTCB_TIME_WAIT: + ret + + + +stateTCB_CLOSED: + ret diff --git a/kernel/branches/kolibri_pe/network/udp.inc b/kernel/branches/kolibri_pe/network/udp.inc new file mode 100644 index 000000000..a6416c37f --- /dev/null +++ b/kernel/branches/kolibri_pe/network/udp.inc @@ -0,0 +1,173 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; UDP.INC ;; +;; ;; +;; UDP 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$ + + +;******************************************************************* +; 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 +; +;*************************************************************************** +udp_rx: + 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 + + movzx ebx, word [edx + 22] ; get the local port from + ; the IP packet's UDP header + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +fs1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value, + ; but the comparision is correct + loopnz fs1 ; Return back if no match + jz fs_done + + ; No match, so exit + jmp udprx_001 + +fs_done: + ; 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 + mov ebx, [eax + sockets + 16] + cmp ebx, 0xffffffff + je udprx_002 + + mov ebx, [edx + 12] ; get the Source address from the IP packet + cmp [eax + sockets + 16], ebx + jne udprx_001 ; Quit if the source IP is not valid + +udprx_002: + ; 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 + movzx ebx, word [edx + 20] ; get the UDP source port + ; ( was 69, now new ) + mov [eax + sockets + 20], bx + + ; 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, byte [edx + 3] ; total length of IP packet. Subtract + mov ch, byte [edx + 2] ; 20 + 8 gives data length + sub ecx, 28 + + mov ebx, eax + add ebx, sockets ; ebx = address of actual socket + + mov eax, [ebx+ 4] ; get socket owner PID + push eax + + mov eax, [ebx + 24] ; get # of bytes already in buffer + add [ebx + 24], ecx ; increment the count of bytes in buffer + + ; point to the location to store the data + add ebx, eax + add ebx, SOCKETHEADERSIZE + + ; ebx = location for first byte, ecx has count, + ; edx points to data + + add edx, 28 ; edx now points to the data + mov edi, ebx + mov esi, edx + + cld + rep movsb ; copy the data across + + ; flag an event to the application + pop eax + mov ecx,1 + mov esi,TASK_DATA+TASKDATA.pid + +newsearch: + cmp [esi],eax + je foundPID + inc ecx + add esi,0x20 + cmp ecx,[TASK_COUNT] + jbe newsearch + +foundPID: + shl ecx,8 + or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event + + mov [check_idle_semaphore],200 + +udprx_001: + pop eax + call freeBuff ; Discard the packet + ret diff --git a/kernel/branches/kolibri_pe/proc32.inc b/kernel/branches/kolibri_pe/proc32.inc new file mode 100644 index 000000000..3f474c02f --- /dev/null +++ b/kernel/branches/kolibri_pe/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, \{ 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: + \\\{ 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 } diff --git a/kernel/branches/kolibri_pe/skin/base.bmp b/kernel/branches/kolibri_pe/skin/base.bmp new file mode 100644 index 0000000000000000000000000000000000000000..185b1f82897ca45a2c27936540eaa58ee8e4db56 GIT binary patch literal 584 zcmZvZF$+Oa7=|CFTQ-9%cE7+6Fj-6_gOVgA8I(a%GDsvpQxb#jVA1D0=XUGfC=?X1i6yUqfBjMY@WvKvkVwxdd+M)gnx8T^ya%8ouv6Odfrdr*}4915DmSVow+& z;xVy0AD;=1sdpy6GfZTG%yAB4iI}VqlQm+pLAHoGh#g|GM@$Zg$q`Xb-q|=KCKu%D N`H$p1Z}Zdj5q^14=R*Jh literal 0 HcmV?d00001 diff --git a/kernel/branches/kolibri_pe/skin/base_1.bmp b/kernel/branches/kolibri_pe/skin/base_1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f53bbeb6f4533da40e2871e94ac4d7dc79e46a97 GIT binary patch literal 584 zcmZ?r^CX;=5h~;Pp_y0_)<_2mGB5xDy&yS5 literal 0 HcmV?d00001 diff --git a/kernel/branches/kolibri_pe/skin/default.asm b/kernel/branches/kolibri_pe/skin/default.asm new file mode 100644 index 000000000..88c6f15f1 --- /dev/null +++ b/kernel/branches/kolibri_pe/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' diff --git a/kernel/branches/kolibri_pe/skin/left.bmp b/kernel/branches/kolibri_pe/skin/left.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bfd97344eb8fa8b748475e1fdac8011645f5a37c GIT binary patch literal 670 zcmZ{b!3qHZ6h$v9HkPun_XR${-pV8kB}pV%C<{r+LL&JCU*lgSvCu4R^t^Y+VrD$k zd8gZ)nOgmn1)r+AqLSa(;14HfSLUeqgD(7$szUYnS)KGtLc8PmzZHidYw%^)6ZbBG7q0;ARJ3qw{D+0+~obC!n{%8!4+@+Zjmu828NK^($?#jFb ztOz7`ZBZsx1d_YHyx_*Nyc^5&&=?@On=4Chtt`8>vILC*lDoaG5-S49-Q7@+6@ldL zZEC)^xfw*FGC*<4{Xp~xOd>PDa(gE}**o#^zKM@f m86df*`=^1?bTkG??%9Fq&klkSDgz|<{LoCS2qcFKF#rHaTS9{X literal 0 HcmV?d00001 diff --git a/kernel/branches/kolibri_pe/skin/me_skin.inc b/kernel/branches/kolibri_pe/skin/me_skin.inc new file mode 100644 index 000000000..365964eb3 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 +} \ No newline at end of file diff --git a/kernel/branches/kolibri_pe/skin/myblue.dtp b/kernel/branches/kolibri_pe/skin/myblue.dtp new file mode 100644 index 0000000000000000000000000000000000000000..9e268cc7a7e358f6da593fac8e74b92da4d39ed3 GIT binary patch literal 40 rcmcap6Tol>ioaaA!0_eE7lwQ5`WQ}>*)V*2_l<#rgMr~%Qy2pPo0k%m literal 0 HcmV?d00001 diff --git a/kernel/branches/kolibri_pe/skin/oper.bmp b/kernel/branches/kolibri_pe/skin/oper.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6011b6d1bdecfb620e2244d0c02ad6332c940d52 GIT binary patch literal 2694 zcmchZu}TC%5JcNd3=GA@SiivV0s}KaP((yHL`*~s1OpL43=ToWpYmH25e(!46KSiv zc6(>%lwBv-p|-B4uWR0pf!xN{WI=qb!`JYv;#tBoC(Ce=ZG8W{$j2M7mHC16x+@fj zSk-pN3piEJ*cNqhKReBjCHHMl1{S&R`vPf?#mUrrgfyLJP435`Lq{X+lq!ZpfNmbV zbP8h;VL`6Fb0;wdR6oZu9owsR5@P_vOwn_$y}`^1A`8{&kxY+UTx0?fMcPEo6upf5 zbs|t4i-IeNDC%DIKG-rv&$-#ve%-2mp9+Md0yIluCmmplUdGjP(X$peyiasuEGQ_lrfr#WFXY~dLJ26XgPt}~TclPYcOnWU++h7x7?&yc zihFN|^!gW#F${*5lc^V_D(<7`lPfE-EoRv1+0Vw3Y{eyXKqnVI Iyzsm32kq!*F8}}l literal 0 HcmV?d00001 diff --git a/kernel/branches/kolibri_pe/skin/oper_1.bmp b/kernel/branches/kolibri_pe/skin/oper_1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d57bd2d161f9f2364bbb199d087b9f28142bef8d GIT binary patch literal 2694 zcmchZy-Nc@5XH|T{43TJT{S$n-mki6~;4UlN^6oJ^JMVtCDa6rs>lx#k7cHxP{`Q*=A-YkuJ^zo@thEjJY|Q*=A-`_U5ADVHg_9rxpS8B$zq)iSS) zBc|wf+{#J1a+=1g>>- 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 ------------------- diff --git a/kernel/branches/kolibri_pe/sys.conf b/kernel/branches/kolibri_pe/sys.conf new file mode 100644 index 000000000..64a0dc295 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/unpacker.inc b/kernel/branches/kolibri_pe/unpacker.inc new file mode 100644 index 000000000..5e70709f9 --- /dev/null +++ b/kernel/branches/kolibri_pe/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 diff --git a/kernel/branches/kolibri_pe/video/arrow.cur b/kernel/branches/kolibri_pe/video/arrow.cur new file mode 100644 index 0000000000000000000000000000000000000000..669962c7220a41eda6f46baec071122db2ec9211 GIT binary patch literal 766 zcmeH_F%E+;3`IW_sbiVC!q~AlAVZ{%xlAS0i5!jN^Z=C@(-#nu!`ihD&-V9^EQFA1 zRqFdzIo`E&rQV 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 [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 + add edx, [LFBAddress] +; 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 [edx], bh + mov [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] +; drawing gradient bars + test eax, 0x00800000 + jz @f + test bh, bh + jz @f + dec bh +@@: +; + 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 [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] +; drawing gradient bars + test eax, 0x80000000 + jz @f + test al, al + jz @f + dec al +@@: +; + dec esi + jnz .new_y + add esp, drbar.stack_data + popad + call VGA_draw_bar + xor eax, eax + mov [EGA_counter],1 + ret + +;voodoodbcplimit: + +; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer + + +; pusha + +; xor edx,edx +; mov eax,ebp +; mov ebx,[Screen_Max_X] ; Screen_X_size +; inc ebx ; +1 +; sub eax,WinMapAddress ; -AddrBuffer +; div ebx ; +; mov ebx,eax ; ebx:=Y +; mov eax,edx ; eax:=X +; call cplimit + +; test ecx,ecx +; jne dbcpl12 +; popa +; clc +; ret +; dbcpl12: +; popa +; stc +; ret + + + + +;dbcplimit: + +; pusha + +; xor edx,edx +; mov ebx,[Screen_Max_X] +; inc ebx +; sub eax,WinMapAddress +; div ebx +; mov ebx,eax +; mov eax,edx +; call cplimit + +; test ecx,ecx +; jne dbcpl1 +; popa +; clc +; ret +; dbcpl1: +; popa +; stc +; ret + + +vesa20_drawbackground_tiled: + call [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, [LFBAddress] +; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + call calculate_edi + xchg edi, ebp +; 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+WinMapAddress], 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 [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 +@@: + add ebp, [LFBAddress] +; 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: + cmp [ebp+WinMapAddress], 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 [edi], ax + shr eax, 16 + mov [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 diff --git a/kernel/branches/kolibri_pe/video/vga.inc b/kernel/branches/kolibri_pe/video/vga.inc new file mode 100644 index 000000000..942f6a41a --- /dev/null +++ b/kernel/branches/kolibri_pe/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 + +uglobal + novesachecksum dd 0x0 + EGA_counter db 0 + VGA_drawing_screen db 0 + VGA_8_pixels: + rb 16 + temp: + .cx dd 0 +endg + +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 + cmp eax,0 + je .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 + cmp eax,0 + je .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 + cmp eax,0 + je .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 + + diff --git a/kernel/branches/kolibri_pe/vmodeint.inc b/kernel/branches/kolibri_pe/vmodeint.inc new file mode 100644 index 000000000..3cb0a1c56 --- /dev/null +++ b/kernel/branches/kolibri_pe/vmodeint.inc @@ -0,0 +1,57 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 + jne .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],eax + mov [esp+24],ebx + mov [esp+32],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 + mov eax, 0 + mov ebx, 0 + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + + .resolution_wasnt_changed: + ret + .no_vmode_drv_access: diff --git a/kernel/branches/kolibri_pe/vmodeld.inc b/kernel/branches/kolibri_pe/vmodeld.inc new file mode 100644 index 000000000..3c5e512a2 --- /dev/null +++ b/kernel/branches/kolibri_pe/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