From 1db510e6a9e889ec78a813b823e7f68406c70ac1 Mon Sep 17 00:00:00 2001 From: trolly Date: Mon, 9 Apr 2007 22:22:25 +0000 Subject: [PATCH] modified kernel from the standard kernel it load the first app (or vrr_m) and cpu from /hd0/1/kolibri/bin the skin is in /hd0/1/kolibri/etc/default.skn the drivers ar loaded from /hd0/1/kolibri/drivers the ramdisk is'nt loaded when you chose to load it from the hard-drive (because it is'nt needed) you will also need to download the modified version of sommes app: launcher vrr_m @panel @menu setup icon jpegview @rb git-svn-id: svn://kolibrios.org@454 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/hd_kolibri/apps/DEFAULT.SKN | Bin 0 -> 10532 bytes .../branches/hd_kolibri/apps/icon/ICONS.DAT | 24 + .../hd_kolibri/apps/icon/build_en.bat | 5 + .../hd_kolibri/apps/icon/build_ge.bat | 5 + .../hd_kolibri/apps/icon/build_ru.bat | 5 + .../hd_kolibri/apps/icon/gif_lite.inc | 328 ++ kernel/branches/hd_kolibri/apps/icon/icon | Bin 0 -> 4830 bytes kernel/branches/hd_kolibri/apps/icon/icon.asm | 1418 ++++++ .../hd_kolibri/apps/icon/iconstrp.gif | Bin 0 -> 13807 bytes kernel/branches/hd_kolibri/apps/icon/lang.inc | 1 + .../branches/hd_kolibri/apps/icon/macros.inc | 269 + .../hd_kolibri/apps/jpegview/build.bat | 3 + .../hd_kolibri/apps/jpegview/filelib.asm | 77 + .../hd_kolibri/apps/jpegview/jpegdat.asm | 22 + .../hd_kolibri/apps/jpegview/jpeglib.asm | 1181 +++++ .../hd_kolibri/apps/jpegview/jpegview | Bin 0 -> 5616 bytes .../hd_kolibri/apps/jpegview/jpegview.asm | 545 ++ .../hd_kolibri/apps/jpegview/jpegview.jpg | Bin 0 -> 19227 bytes .../hd_kolibri/apps/jpegview/lang.inc | 1 + .../hd_kolibri/apps/jpegview/macros.inc | 268 + .../hd_kolibri/apps/jpegview/memlib.asm | 210 + .../hd_kolibri/apps/launcher/AUTORUN.DAT | 11 + .../hd_kolibri/apps/launcher/build.bat | 2 + .../hd_kolibri/apps/launcher/lang.inc | 1 + .../hd_kolibri/apps/launcher/launcher | Bin 0 -> 403 bytes .../hd_kolibri/apps/launcher/launcher.asm | 200 + .../hd_kolibri/apps/launcher/macros.inc | 269 + kernel/branches/hd_kolibri/apps/menu/MENU.DAT | 163 + .../branches/hd_kolibri/apps/menu/build.bat | 2 + kernel/branches/hd_kolibri/apps/menu/lang.inc | 1 + .../branches/hd_kolibri/apps/menu/macros.inc | 269 + kernel/branches/hd_kolibri/apps/menu/menu | Bin 0 -> 1264 bytes kernel/branches/hd_kolibri/apps/menu/menu.asm | 566 +++ .../branches/hd_kolibri/apps/menu/readme.txt | 73 + .../branches/hd_kolibri/apps/menu/readme2.txt | 6 + .../branches/hd_kolibri/apps/panel/@PANEL.ASM | 2089 ++++++++ kernel/branches/hd_kolibri/apps/panel/@panel | Bin 0 -> 5695 bytes .../branches/hd_kolibri/apps/panel/PANEL.DAT | 1 + .../hd_kolibri/apps/panel/build_en.bat | 4 + .../hd_kolibri/apps/panel/build_et.bat | 5 + .../hd_kolibri/apps/panel/build_ru.bat | 4 + .../branches/hd_kolibri/apps/panel/lang.inc | 1 + .../branches/hd_kolibri/apps/panel/macros.inc | 266 + kernel/branches/hd_kolibri/apps/rb/@RB.ASM | 405 ++ kernel/branches/hd_kolibri/apps/rb/@rb | Bin 0 -> 1000 bytes .../branches/hd_kolibri/apps/rb/build_en.bat | 5 + .../branches/hd_kolibri/apps/rb/build_ru.bat | 5 + kernel/branches/hd_kolibri/apps/rb/lang.inc | 1 + kernel/branches/hd_kolibri/apps/rb/macros.inc | 269 + .../branches/hd_kolibri/apps/setup/SETUP.DAT | Bin 0 -> 56 bytes .../branches/hd_kolibri/apps/setup/build.bat | 3 + .../branches/hd_kolibri/apps/setup/lang.inc | 1 + .../branches/hd_kolibri/apps/setup/macros.inc | 269 + .../branches/hd_kolibri/apps/setup/setup.asm | 1804 +++++++ .../branches/hd_kolibri/apps/vrr_m/build.bat | 2 + .../branches/hd_kolibri/apps/vrr_m/macros.inc | 269 + .../branches/hd_kolibri/apps/vrr_m/vrr_m.asm | 123 + .../hd_kolibri/kernel/blkdev/cd_drv.inc | 554 ++ .../hd_kolibri/kernel/blkdev/cdrom.inc | 269 + .../branches/hd_kolibri/kernel/blkdev/fdc.inc | 82 + .../hd_kolibri/kernel/blkdev/flp_drv.inc | 623 +++ .../hd_kolibri/kernel/blkdev/hd_drv.inc | 871 ++++ .../branches/hd_kolibri/kernel/blkdev/rd.inc | 2473 +++++++++ .../hd_kolibri/kernel/blkdev/rdsave.inc | 30 + .../hd_kolibri/kernel/boot/ETFONT.FNT | Bin 0 -> 4096 bytes .../hd_kolibri/kernel/boot/bootcode.inc | 1305 +++++ .../hd_kolibri/kernel/boot/booteng.inc | 94 + .../hd_kolibri/kernel/boot/bootet.inc | 94 + .../hd_kolibri/kernel/boot/bootge.inc | 99 + .../hd_kolibri/kernel/boot/bootru.inc | 95 + .../hd_kolibri/kernel/boot/bootstr.inc | 52 + kernel/branches/hd_kolibri/kernel/boot/et.inc | 7 + .../hd_kolibri/kernel/boot/preboot.inc | 34 + kernel/branches/hd_kolibri/kernel/boot/ru.inc | 93 + .../hd_kolibri/kernel/boot/shutdown.inc | 545 ++ .../hd_kolibri/kernel/bootstrap/allirqs.inc | 0 .../hd_kolibri/kernel/bootstrap/bootlog.inc | 31 + .../hd_kolibri/kernel/bootstrap/bootmsg.inc | 25 + .../hd_kolibri/kernel/bootstrap/bootstrap.inc | 49 + .../hd_kolibri/kernel/bootstrap/clear.inc | 32 + .../kernel/bootstrap/detect/dev_fd.inc | 28 + .../kernel/bootstrap/detect/dev_hdcd.inc | 382 ++ .../kernel/bootstrap/detect/disks.inc | 5 + .../kernel/bootstrap/detect/sear_par.inc | 125 + .../hd_kolibri/kernel/bootstrap/firstapp.inc | 28 + .../hd_kolibri/kernel/bootstrap/graphaddr.inc | 51 + .../hd_kolibri/kernel/bootstrap/graphbase.inc | 7 + .../hd_kolibri/kernel/bootstrap/kbset.inc | 28 + .../hd_kolibri/kernel/bootstrap/loadfont.inc | 30 + .../hd_kolibri/kernel/bootstrap/loadskn.inc | 8 + .../hd_kolibri/kernel/bootstrap/ostask.inc | 63 + .../hd_kolibri/kernel/bootstrap/paging.inc | 53 + .../hd_kolibri/kernel/bootstrap/palette.inc | 16 + .../hd_kolibri/kernel/bootstrap/printmem.inc | 13 + .../hd_kolibri/kernel/bootstrap/rdload.inc | 102 + .../hd_kolibri/kernel/bootstrap/redirirq.inc | 13 + .../hd_kolibri/kernel/bootstrap/resirq.inc | 5 + .../hd_kolibri/kernel/bootstrap/rmode.inc | 37 + .../hd_kolibri/kernel/bootstrap/setbgr.inc | 5 + .../hd_kolibri/kernel/bootstrap/setmouse.inc | 7 + .../hd_kolibri/kernel/bootstrap/setports.inc | 5 + .../hd_kolibri/kernel/bootstrap/switch.inc | 65 + .../hd_kolibri/kernel/bootstrap/sysenter.inc | 43 + .../hd_kolibri/kernel/bootstrap/tasking.inc | 6 + .../hd_kolibri/kernel/bootstrap/timer.inc | 10 + .../hd_kolibri/kernel/bootstrap/tsc.inc | 15 + .../hd_kolibri/kernel/bootstrap/vmodeld.inc | 38 + .../hd_kolibri/kernel/bootstrap/windef.inc | 5 + kernel/branches/hd_kolibri/kernel/build.bat | 114 + .../hd_kolibri/kernel/bus/pci/pci16.inc | 50 + .../hd_kolibri/kernel/bus/pci/pci32.inc | 363 ++ kernel/branches/hd_kolibri/kernel/const.inc | 576 +++ .../branches/hd_kolibri/kernel/core/debug.inc | 507 ++ .../kernel/core/detect/commouse.inc | 143 + .../kernel/core/detect/ps2mouse.inc | 139 + .../branches/hd_kolibri/kernel/core/dll.inc | 1084 ++++ .../hd_kolibri/kernel/core/exports.inc | 117 + .../branches/hd_kolibri/kernel/core/fpu.inc | 283 ++ .../branches/hd_kolibri/kernel/core/heap.inc | 1095 ++++ .../branches/hd_kolibri/kernel/core/idle.inc | 57 + .../hd_kolibri/kernel/core/mainloop.inc | 22 + .../hd_kolibri/kernel/core/malloc.inc | 1001 ++++ .../hd_kolibri/kernel/core/memory.inc | 1662 ++++++ .../branches/hd_kolibri/kernel/core/sched.inc | 217 + .../branches/hd_kolibri/kernel/core/sync.inc | 117 + .../branches/hd_kolibri/kernel/core/sys32.inc | 849 ++++ .../hd_kolibri/kernel/core/syscall.inc | 238 + .../branches/hd_kolibri/kernel/core/sysfn.inc | 4012 +++++++++++++++ .../hd_kolibri/kernel/core/taskman.inc | 1133 +++++ .../hd_kolibri/kernel/core/vmodeint.inc | 55 + .../hd_kolibri/kernel/docs/COPYING.TXT | 347 ++ .../branches/hd_kolibri/kernel/docs/apm.txt | 518 ++ .../hd_kolibri/kernel/docs/memmap.txt | 225 + .../hd_kolibri/kernel/docs/readme.txt | 53 + .../hd_kolibri/kernel/docs/sysfuncr.txt | 4519 +++++++++++++++++ .../hd_kolibri/kernel/docs/sysfuncs.txt | 4473 ++++++++++++++++ .../hd_kolibri/kernel/drivers/ati2d.asm | 1014 ++++ .../hd_kolibri/kernel/drivers/codec.inc | 226 + .../hd_kolibri/kernel/drivers/ensoniq.asm | 1178 +++++ .../hd_kolibri/kernel/drivers/imports.inc | 142 + .../hd_kolibri/kernel/drivers/infinity.asm | 1286 +++++ .../hd_kolibri/kernel/drivers/main.inc | 163 + .../hd_kolibri/kernel/drivers/mix_mmx.inc | 247 + .../hd_kolibri/kernel/drivers/mix_sse2.inc | 145 + .../hd_kolibri/kernel/drivers/mixer.asm | 1102 ++++ .../hd_kolibri/kernel/drivers/proc32.inc | 268 + .../hd_kolibri/kernel/drivers/sceletone.asm | 163 + .../hd_kolibri/kernel/drivers/sis.asm | 1180 +++++ .../hd_kolibri/kernel/drivers/sound.asm | 1419 ++++++ kernel/branches/hd_kolibri/kernel/fdo.inc | 428 ++ .../branches/hd_kolibri/kernel/fs/fat12.inc | 2793 ++++++++++ .../branches/hd_kolibri/kernel/fs/fat32.inc | 3527 +++++++++++++ kernel/branches/hd_kolibri/kernel/fs/fs.inc | 841 +++ .../branches/hd_kolibri/kernel/fs/fs_lfn.inc | 686 +++ .../branches/hd_kolibri/kernel/fs/iso9660.inc | 833 +++ kernel/branches/hd_kolibri/kernel/fs/ntfs.inc | 1798 +++++++ .../hd_kolibri/kernel/fs/part_set.inc | 452 ++ .../branches/hd_kolibri/kernel/gui/button.inc | 674 +++ .../branches/hd_kolibri/kernel/gui/event.inc | 692 +++ .../branches/hd_kolibri/kernel/gui/font.inc | 115 + .../branches/hd_kolibri/kernel/gui/mouse.inc | 248 + .../hd_kolibri/kernel/gui/skincode.inc | 480 ++ .../hd_kolibri/kernel/gui/skindata.inc | 64 + .../branches/hd_kolibri/kernel/gui/window.inc | 1799 +++++++ .../hd_kolibri/kernel/hid/keyboard.inc | 302 ++ .../branches/hd_kolibri/kernel/hid/keymap.inc | 40 + .../branches/hd_kolibri/kernel/hid/m_com1.inc | 138 + .../branches/hd_kolibri/kernel/hid/m_com2.inc | 138 + .../branches/hd_kolibri/kernel/hid/m_ps2.inc | 178 + .../hd_kolibri/kernel/hid/mousedrv.inc | 389 ++ .../hd_kolibri/kernel/hid/set_dtc.inc | 199 + kernel/branches/hd_kolibri/kernel/kernel.asm | 58 + .../branches/hd_kolibri/kernel/kernel16.inc | 51 + .../branches/hd_kolibri/kernel/kernel32.inc | 242 + .../branches/hd_kolibri/kernel/kglobals.inc | 67 + kernel/branches/hd_kolibri/kernel/macros.inc | 97 + kernel/branches/hd_kolibri/kernel/makefile | 16 + .../hd_kolibri/kernel/network/eth_drv/arp.inc | 550 ++ .../kernel/network/eth_drv/drivers/3c59x.inc | 2388 +++++++++ .../kernel/network/eth_drv/drivers/i8255x.inc | 744 +++ .../network/eth_drv/drivers/pcnet32.inc | 818 +++ .../network/eth_drv/drivers/rtl8029.inc | 959 ++++ .../network/eth_drv/drivers/rtl8139.inc | 616 +++ .../network/eth_drv/drivers/rtl8169.inc | 1208 +++++ .../kernel/network/eth_drv/drivers/sis900.inc | 1152 +++++ .../kernel/network/eth_drv/ethernet.inc | 457 ++ .../hd_kolibri/kernel/network/eth_drv/pci.inc | 349 ++ .../hd_kolibri/kernel/network/icmp.inc | 192 + .../branches/hd_kolibri/kernel/network/ip.inc | 198 + .../hd_kolibri/kernel/network/queue.inc | 219 + .../hd_kolibri/kernel/network/socket.inc | 930 ++++ .../hd_kolibri/kernel/network/stack.inc | 1021 ++++ .../hd_kolibri/kernel/network/tcp.inc | 1300 +++++ .../hd_kolibri/kernel/network/udp.inc | 172 + kernel/branches/hd_kolibri/kernel/proc32.inc | 268 + .../branches/hd_kolibri/kernel/skin/Thumbs.db | Bin 0 -> 9216 bytes .../branches/hd_kolibri/kernel/skin/base.bmp | Bin 0 -> 584 bytes .../hd_kolibri/kernel/skin/base_1.bmp | Bin 0 -> 584 bytes .../hd_kolibri/kernel/skin/default.asm | 38 + .../branches/hd_kolibri/kernel/skin/left.bmp | Bin 0 -> 670 bytes .../hd_kolibri/kernel/skin/left_1.bmp | Bin 0 -> 670 bytes .../hd_kolibri/kernel/skin/me_skin.inc | 242 + .../hd_kolibri/kernel/skin/myblue.dtp | Bin 0 -> 40 bytes .../branches/hd_kolibri/kernel/skin/oper.bmp | Bin 0 -> 2694 bytes .../hd_kolibri/kernel/skin/oper_1.bmp | Bin 0 -> 2694 bytes .../hd_kolibri/kernel/sound/playnote.inc | 139 + .../branches/hd_kolibri/kernel/sound/sb16.inc | 354 ++ .../branches/hd_kolibri/kernel/unpacker.inc | 512 ++ kernel/branches/hd_kolibri/kernel/vars1.inc | 19 + kernel/branches/hd_kolibri/kernel/vars2.inc | 99 + .../hd_kolibri/kernel/video/arrow.cur | Bin 0 -> 766 bytes .../hd_kolibri/kernel/video/cursors.inc | 747 +++ .../hd_kolibri/kernel/video/vesa12.inc | 954 ++++ .../hd_kolibri/kernel/video/vesa20.inc | 1204 +++++ .../branches/hd_kolibri/kernel/video/vga.inc | 450 ++ kernel/branches/hd_kolibri/readme.txt | 19 + 216 files changed, 88266 insertions(+) create mode 100644 kernel/branches/hd_kolibri/apps/DEFAULT.SKN create mode 100644 kernel/branches/hd_kolibri/apps/icon/ICONS.DAT create mode 100644 kernel/branches/hd_kolibri/apps/icon/build_en.bat create mode 100644 kernel/branches/hd_kolibri/apps/icon/build_ge.bat create mode 100644 kernel/branches/hd_kolibri/apps/icon/build_ru.bat create mode 100644 kernel/branches/hd_kolibri/apps/icon/gif_lite.inc create mode 100644 kernel/branches/hd_kolibri/apps/icon/icon create mode 100644 kernel/branches/hd_kolibri/apps/icon/icon.asm create mode 100644 kernel/branches/hd_kolibri/apps/icon/iconstrp.gif create mode 100644 kernel/branches/hd_kolibri/apps/icon/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/icon/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/build.bat create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/filelib.asm create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/jpegdat.asm create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/jpeglib.asm create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/jpegview create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/jpegview.asm create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/jpegview.jpg create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/jpegview/memlib.asm create mode 100644 kernel/branches/hd_kolibri/apps/launcher/AUTORUN.DAT create mode 100644 kernel/branches/hd_kolibri/apps/launcher/build.bat create mode 100644 kernel/branches/hd_kolibri/apps/launcher/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/launcher/launcher create mode 100644 kernel/branches/hd_kolibri/apps/launcher/launcher.asm create mode 100644 kernel/branches/hd_kolibri/apps/launcher/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/menu/MENU.DAT create mode 100644 kernel/branches/hd_kolibri/apps/menu/build.bat create mode 100644 kernel/branches/hd_kolibri/apps/menu/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/menu/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/menu/menu create mode 100644 kernel/branches/hd_kolibri/apps/menu/menu.asm create mode 100644 kernel/branches/hd_kolibri/apps/menu/readme.txt create mode 100644 kernel/branches/hd_kolibri/apps/menu/readme2.txt create mode 100644 kernel/branches/hd_kolibri/apps/panel/@PANEL.ASM create mode 100644 kernel/branches/hd_kolibri/apps/panel/@panel create mode 100644 kernel/branches/hd_kolibri/apps/panel/PANEL.DAT create mode 100644 kernel/branches/hd_kolibri/apps/panel/build_en.bat create mode 100644 kernel/branches/hd_kolibri/apps/panel/build_et.bat create mode 100644 kernel/branches/hd_kolibri/apps/panel/build_ru.bat create mode 100644 kernel/branches/hd_kolibri/apps/panel/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/panel/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/rb/@RB.ASM create mode 100644 kernel/branches/hd_kolibri/apps/rb/@rb create mode 100644 kernel/branches/hd_kolibri/apps/rb/build_en.bat create mode 100644 kernel/branches/hd_kolibri/apps/rb/build_ru.bat create mode 100644 kernel/branches/hd_kolibri/apps/rb/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/rb/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/setup/SETUP.DAT create mode 100644 kernel/branches/hd_kolibri/apps/setup/build.bat create mode 100644 kernel/branches/hd_kolibri/apps/setup/lang.inc create mode 100644 kernel/branches/hd_kolibri/apps/setup/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/setup/setup.asm create mode 100644 kernel/branches/hd_kolibri/apps/vrr_m/build.bat create mode 100644 kernel/branches/hd_kolibri/apps/vrr_m/macros.inc create mode 100644 kernel/branches/hd_kolibri/apps/vrr_m/vrr_m.asm create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/cd_drv.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/cdrom.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/fdc.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/flp_drv.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/hd_drv.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/rd.inc create mode 100644 kernel/branches/hd_kolibri/kernel/blkdev/rdsave.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/ETFONT.FNT create mode 100644 kernel/branches/hd_kolibri/kernel/boot/bootcode.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/booteng.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/bootet.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/bootge.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/bootru.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/bootstr.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/et.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/preboot.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/ru.inc create mode 100644 kernel/branches/hd_kolibri/kernel/boot/shutdown.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/allirqs.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/bootlog.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/bootmsg.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/bootstrap.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/clear.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_fd.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_hdcd.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/detect/disks.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/detect/sear_par.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/firstapp.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/graphaddr.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/graphbase.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/kbset.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/loadfont.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/loadskn.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/ostask.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/paging.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/palette.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/printmem.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/rdload.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/redirirq.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/resirq.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/rmode.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/setbgr.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/setmouse.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/setports.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/switch.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/sysenter.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/tasking.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/timer.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/tsc.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/vmodeld.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bootstrap/windef.inc create mode 100644 kernel/branches/hd_kolibri/kernel/build.bat create mode 100644 kernel/branches/hd_kolibri/kernel/bus/pci/pci16.inc create mode 100644 kernel/branches/hd_kolibri/kernel/bus/pci/pci32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/const.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/debug.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/detect/commouse.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/detect/ps2mouse.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/dll.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/exports.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/fpu.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/heap.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/idle.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/mainloop.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/malloc.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/memory.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/sched.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/sync.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/sys32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/syscall.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/sysfn.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/taskman.inc create mode 100644 kernel/branches/hd_kolibri/kernel/core/vmodeint.inc create mode 100644 kernel/branches/hd_kolibri/kernel/docs/COPYING.TXT create mode 100644 kernel/branches/hd_kolibri/kernel/docs/apm.txt create mode 100644 kernel/branches/hd_kolibri/kernel/docs/memmap.txt create mode 100644 kernel/branches/hd_kolibri/kernel/docs/readme.txt create mode 100644 kernel/branches/hd_kolibri/kernel/docs/sysfuncr.txt create mode 100644 kernel/branches/hd_kolibri/kernel/docs/sysfuncs.txt create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/ati2d.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/codec.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/ensoniq.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/imports.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/infinity.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/main.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/mix_mmx.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/mix_sse2.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/mixer.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/proc32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/sceletone.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/sis.asm create mode 100644 kernel/branches/hd_kolibri/kernel/drivers/sound.asm create mode 100644 kernel/branches/hd_kolibri/kernel/fdo.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/fat12.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/fat32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/fs.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/fs_lfn.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/iso9660.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/ntfs.inc create mode 100644 kernel/branches/hd_kolibri/kernel/fs/part_set.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/button.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/event.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/font.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/mouse.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/skincode.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/skindata.inc create mode 100644 kernel/branches/hd_kolibri/kernel/gui/window.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/keyboard.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/keymap.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/m_com1.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/m_com2.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/m_ps2.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/mousedrv.inc create mode 100644 kernel/branches/hd_kolibri/kernel/hid/set_dtc.inc create mode 100644 kernel/branches/hd_kolibri/kernel/kernel.asm create mode 100644 kernel/branches/hd_kolibri/kernel/kernel16.inc create mode 100644 kernel/branches/hd_kolibri/kernel/kernel32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/kglobals.inc create mode 100644 kernel/branches/hd_kolibri/kernel/macros.inc create mode 100644 kernel/branches/hd_kolibri/kernel/makefile create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/arp.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/3c59x.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/i8255x.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/pcnet32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8029.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8139.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8169.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/sis900.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/ethernet.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/eth_drv/pci.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/icmp.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/ip.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/queue.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/socket.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/stack.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/tcp.inc create mode 100644 kernel/branches/hd_kolibri/kernel/network/udp.inc create mode 100644 kernel/branches/hd_kolibri/kernel/proc32.inc create mode 100644 kernel/branches/hd_kolibri/kernel/skin/Thumbs.db create mode 100644 kernel/branches/hd_kolibri/kernel/skin/base.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/base_1.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/default.asm create mode 100644 kernel/branches/hd_kolibri/kernel/skin/left.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/left_1.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/me_skin.inc create mode 100644 kernel/branches/hd_kolibri/kernel/skin/myblue.dtp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/oper.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/skin/oper_1.bmp create mode 100644 kernel/branches/hd_kolibri/kernel/sound/playnote.inc create mode 100644 kernel/branches/hd_kolibri/kernel/sound/sb16.inc create mode 100644 kernel/branches/hd_kolibri/kernel/unpacker.inc create mode 100644 kernel/branches/hd_kolibri/kernel/vars1.inc create mode 100644 kernel/branches/hd_kolibri/kernel/vars2.inc create mode 100644 kernel/branches/hd_kolibri/kernel/video/arrow.cur create mode 100644 kernel/branches/hd_kolibri/kernel/video/cursors.inc create mode 100644 kernel/branches/hd_kolibri/kernel/video/vesa12.inc create mode 100644 kernel/branches/hd_kolibri/kernel/video/vesa20.inc create mode 100644 kernel/branches/hd_kolibri/kernel/video/vga.inc create mode 100644 kernel/branches/hd_kolibri/readme.txt diff --git a/kernel/branches/hd_kolibri/apps/DEFAULT.SKN b/kernel/branches/hd_kolibri/apps/DEFAULT.SKN new file mode 100644 index 0000000000000000000000000000000000000000..5d629d51b9eba7bf4c0762ab8f237c85f52cd4f8 GIT binary patch literal 10532 zcmds*eN@)v8ON!$m;d(1cJ|l)*g4y(m86+6HB7Wr6f_V4Q9%(D5mEtD-a!yWL3vXY z2;Wdd1O!Axc*GYpQxxfx&ZTa)Y{xpCrPV1rv*SL`@8Y?-&+`y%HP-6l;(ET<%YFau z>wf?J0(_=Sf5^?v?U(#V@}J57ulWBde~-953=-;WI_Q9IO-)U1kE7kZ@}~8_JIc%L z!Gi~u-)=K?JGR&V!GlNKe$Jo0#%q1pUf?1ATC87UXvD+lKO@K<=S4$)gg)yR_Fp%* z!p9KMkNLN^(Um^G_o*`8Pd>V%jQZjGx0O-fzx6j|)OWAHrHo1<%BVM9zod-%*2QjR z)IXhnO&RsgvuBi1Uq5|H8MWu+ab?u*PMb37Ia|9j>e==-Wz;imt;(oftu4x^rw$)d zMm=$;Ng0(PR5n#`Vd3-0{`(Zi_mP;8N|$;r-v8pC$_FY-nzrWbOP#+pVtk(e5co=K zmGb_~g(r#=y33RQADEukEC9zkj_Ujdyi%~XwkV?}b>6nf2^$04Va)>YlGksurad9{ z?^e>2PKg{neCU(AA1asUXV+{>t4W<-w(y05z+teN$kGYFU-RM+v46MHHIc4Po9-!q zs^Z)O1!*-Y^C}iiED9bDn~5ZOKe2wsP_Yjn3xkIb9?Nqjk+-j2x!T+F=7sYx0PgNO zd9tmgb^q?VZJTQIQ+BQhDVjfi{fuF7LC|nmu&Y`W{LJQ%5#OFmLPnTOg{CUle2OHZ zJGB7a#{oO?R-0;?uluIpXG-UKD8E{fsqE_2u)zkBh@LS5ZeD&vxhUgh#ekJlp4=2X zqAYBbvStBr^=jBR0RMRR=BFRuSr_nh$!rfPzB76f+tCNN{+b&weDj<>qqrmyJskyH z@9j}8Ok1HCkT})7AjG3${upI55m&EzbAV9 zWBI`&%sM3zJ=X>N`C_+nc}|LAK=zE`o5My|MtCZliMV<->>GfB*?;WrJS@2sE%B2q zx{fwYdFt2E6CTHF)+vefcAb39)_%IJ6$Zez#)F6U?5r&-soI!Ty>>;_syW*hP23zh z8ZHm_gax~*l@ViiE`094!mmV(%?%oP&ekF+AiIt>lSRb1N3r8IpCXC8arTUIL)9+D zfUQ}Hdvg*R(!=*G_2K3To8EOnBg?`)#XcBvd*pLP5ie*W{$rjDAN%O~U=Qq0kJAxh zP=t4E*{m3lpR|1Un)s&Gk^2+;_Qg(wP4DV}krk0%Vjm1yzjB6T@%g=b0+IvAmPL%K zwpwC7Q4+a$qEorDq)0I!KWW*XH3=*9Q1)0-1KW=Hfyv45@9jx|AP#Du*s zdG}kkDJ57UU+rj_I_x(m+L}e(xL|Ts%;W=BW3-?oa{gF{^1fFp6a$!AHS1R$$&G1F zo87d^4>r9e5zp^i?ko1Mm1g@D$4+^=V)3MY%iewO9m3Aq4*PrjF2;LUM&Rh~<43Uk z{q4Wxg^sI@pJtYlM0hK(H8!->)xrR{ac@;^Md_a6yj^*jwHuNe*DS70oK=(H2R9}L z)V=Jl?4&j)&umQ%>X&!K`YiJuIm`18CS$?gZ+zFz+~$h>FfaG`=^o|LQ+T3XZe3rJ z5uY-1Om*CJvy>#FZ#x3a{kAkK(ezftPHRk=)t(iqJg`^80Ef~-s^a~r!DKAh%`n9c zNx_?=rsgl0v@6d4aQbZQNH7-ccr_BBBciWr05cI5yS}yoN}{JVriXUsMk){N)v&<^ zl8D(Du$f3+^77-&jmo7<16r~pPHl=&Ru{n4t6_r;BoTc#7GNe)nw?}jSg*V{Ijkcu z=GBroWpx2uy&5*yKoZfndI9YXbuIh$)^9K0zqP2kICp| zHswSqqhiF>uUEtV2jKhok>RV_Tv+%MT>XDfF<;;X>o+O|<}0OO{ZggCe5(=c^cIBb z^g4m+bT3DBy5OSfw<`tu`AUI)!BU_fu@vZcECu>0OM$sZ3pRI2!A?64s?*X%by@?c zu4D7n-wi)Ah;koUbk`!(_bqzQBGh*rbnDhF)awqqapMN+<;$0^I0*H1gHSITgnHgV z-QC@&XAMFf`YC832oc9jc`|~#sMmmQf8!DFfulJvjlW>bTGs3-Mc4pOW(9xavuq`Cma zQ=3%SZ&?YDM6O=F+S}X9o^|2E1@^Z~mo9a6b+NlA%LiK zov2~~&$1{uIGA5#NJt10LIsOaEn*iVQh@1|0I^6_W`$Z@rj}!)?)!D@cGm+34tRNa(VrSgK^YM_+0UIjC&0`rJ3AYd!$piN z1bT)uWxhoK84*bbFTI2ZJKHrZQlHCD3>_PtAgrJ7mZZc1u==Sws?H zX>+BJ`-A;*VY4+hHda+t(LDCvoSd8$D^{>;kpe{eG)#sSm7Ww8Outb%8#OINI#Ity zVg|6Y;yBl2Ads}s-QC^O(-XTqNFO1Iyk?PHv3Bp?ji%SF)vH%CD5(;SM zQc_Z0wg{I*0%!&m(r@B2fr-UywqG$jHeDeBT8Wgsefu_HtPu|nk4cjzF%~=#%gviN zS&w8&SVBUA1WO{k7_hqQ>+9?4>Htu6b#+BWMR9R42V!n+E-QtnaK1wf4aJ#hLf8d} zan-6-^rR9qlM5#*l4-z3I>tfIKKtzG(W5y->0XJEFe!^=`}XZ@>~b$9S?cE;Vdirp zaH*gJB~qj$!j8>`AQE71zodX&T{MP*nGRy@$X+J_cxgFK?2r>+OzB2qAerPcsc5st zQ-mW}RQiNf%tT`TP!=P54j2pD1^ub@n?plZOk+!>`L^T zlUKvOC0M(5?Z7oiBD93oYI`&b&Os94-BO7@q#w9OD&gW9ECF~KL3OzTCMpM$X~%*p zQtV(=CD^HmQ@oUtM6@yT#$-+{7W+Yi$crVz-5%nF3u!nHG8x2MR8(Yz^a)h4sHCiA z>kAXRR48`Si(On!b&4vHl8EEI-u_Ecta>i+Y+t3NrG(KTj4V@^)xpeRLXw^A$p8ij zBQA0TpsEWm=T?=Ao-f5-?RW6RObE;#sbNPD8SrtWb0v;%c5mBfxzY(5bQdc F{sp`>TRH#$ literal 0 HcmV?d00001 diff --git a/kernel/branches/hd_kolibri/apps/icon/ICONS.DAT b/kernel/branches/hd_kolibri/apps/icon/ICONS.DAT new file mode 100644 index 0000000000..286c84308c --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/icon/ICONS.DAT @@ -0,0 +1,24 @@ +AA-SYSXTREE-004-/hd0/1/kolibri/bin/sysxtree - * +AB-COPY -008-/hd0/1/kolibri/bin/copy2 - * +BB-CALC -006-/hd0/1/kolibri/bin/calc - * +CA-TINYPAD -011-/hd0/1/kolibri/bin/tinypad - * +CB-TINYPAD2-011-/hd0/1/kolibri/tinypad2 - * +JA-VRR -009-/hd0/1/kolibri/bin/vrr - * +II-C4 -005-/hd0/1/kolibri/bin/c4 - * +JI-MINE -017-/hd0/1/kolibri/bin/mine - * +IH-TETRIS -021-/hd0/1/kolibri/bin/tetris - * +JH-MBLOCKS -013-/hd0/1/kolibri/bin/mblocks - * +HI-PONG -026-/hd0/1/kolibri/bin/pong3 - * +GI-15 -000-/hd0/1/kolibri/bin/15 - * +HH-LIFE2 -015-/hd0/1/kolibri/bin/life2 - * +BA-FASM -012-/hd0/1/kolibri/bin/fasm - * +JB-ANIMAGE -018-/hd0/1/kolibri/bin/animage - * +CC-CMD -023-/hd0/1/kolibri/bin/cmd - * +IA-BOARD -022-/hd0/1/kolibri/bin/board - * +BC-KFAR -027-/hd0/1/kolibri/bin/kfar/kfar - * +HA-MTDBG -029-/hd0/1/kolibri/bin/mtdbg - * +AH-PIPES -030-/hd0/1/kolibri/bin/pipes - * +AI-FARA -031-/hd0/1/kolibri/bin/fara - * +BI-ARC-II -014-/hd0/1/kolibri/bin/arcanii - * +BH-XONIX -024-/hd0/1/kolibri/bin/xonix - * +GH-CHECKERS-002-/hd0/1/kolibri/bin/checkers - * diff --git a/kernel/branches/hd_kolibri/apps/icon/build_en.bat b/kernel/branches/hd_kolibri/apps/icon/build_en.bat new file mode 100644 index 0000000000..88c2ba40bb --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/icon/build_en.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix en >lang.inc +@fasm icon.asm icon +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/icon/build_ge.bat b/kernel/branches/hd_kolibri/apps/icon/build_ge.bat new file mode 100644 index 0000000000..f07bb212c4 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/icon/build_ge.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix ge >lang.inc +@fasm icon.asm icon +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/icon/build_ru.bat b/kernel/branches/hd_kolibri/apps/icon/build_ru.bat new file mode 100644 index 0000000000..9099b9cd67 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/icon/build_ru.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix ru >lang.inc +@fasm icon.asm icon +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/icon/gif_lite.inc b/kernel/branches/hd_kolibri/apps/icon/gif_lite.inc new file mode 100644 index 0000000000..4086245a33 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/icon/gif_lite.inc @@ -0,0 +1,328 @@ +; GIF LITE v2.0 by Willow +; Written in pure assembler by Ivushkin Andrey aka Willow +; +; This include file will contain functions to handle GIF image format +; +; Created: August 15, 2004 +; Last changed: September 9, 2004 + +; Change COLOR_ORDER in your program +; if colors are displayed improperly + +if ~ (COLOR_ORDER in ) +; This message may not appear under MenuetOS, so watch... + display 'Please define COLOR_ORDER: MENUETOS or OTHER',13,10 +end if + +; virtual structure, used internally + +struc GIF_list +{ + .NextImg rd 1 + .Left rw 1 + .Top rw 1 + .Width rw 1 + .Height rw 1 +} + +struc GIF_info +{ + .Left rw 1 + .Top rw 1 + .Width rw 1 + .Height rw 1 +} + +_null fix 0x1000 + +; **************************************** +; FUNCTION GetGIFinfo - retrieve Nth image info +; **************************************** +; in: +; esi - pointer to image list header +; ecx - image_index (0...img_count-1) +; edi - pointer to GIF_info structure to be filled + +; out: +; eax - pointer to RAW data, or 0, if error + +GetGIFinfo: + push esi ecx edi + xor eax,eax + jecxz .eloop + .lp: + mov esi,[esi] + test esi,esi + jz .error + loop .lp + .eloop: + add esi,4 + movsd + movsd + mov eax,esi + .error: + pop edi ecx esi + ret + +; **************************************** +; FUNCTION ReadGIF - unpacks GIF image +; **************************************** +; in: +; esi - pointer to GIF file in memory +; edi - pointer to output image list +; eax - pointer to work area (MIN 16 KB!) + +; out: +; eax - 0, all OK; +; eax - 1, invalid signature; +; eax >=8, unsupported image attributes +; +; ecx - number of images + +ReadGIF: + push esi edi + mov [.table_ptr],eax + mov [.cur_info],edi + xor eax,eax + mov [.globalColor],eax + mov [.img_count],eax + inc eax + cmp dword[esi],'GIF8' + jne .er ; signature + mov ecx,[esi+0xa] + inc eax + add esi,0xd + mov edi,esi + bt ecx,7 + jnc .nextblock + mov [.globalColor],esi + call .Gif_skipmap + .nextblock: + cmp byte[edi],0x21 + jne .noextblock + inc edi + cmp byte[edi],0xf9 ; Graphic Control Ext + jne .no_gc + add edi,7 + jmp .nextblock + .no_gc: + cmp byte[edi],0xfe ; Comment Ext + jne .no_comm + inc edi + .block_skip: + movzx eax,byte[edi] + lea edi,[edi+eax+1] + cmp byte[edi],0 + jnz .block_skip + inc edi + jmp .nextblock + .no_comm: + cmp byte[edi],0xff ; Application Ext + jne .nextblock + add edi,13 + jmp .block_skip + .noextblock: + cmp byte[edi],0x2c ; image beginning + jne .er + inc [.img_count] + inc edi + mov esi,[.cur_info] + add esi,4 + xchg esi,edi + movsd + movsd + push edi + movzx ecx,word[esi] + inc esi + bt ecx,7 + jc .uselocal + push [.globalColor] + mov edi,esi + jmp .setPal + .uselocal: + call .Gif_skipmap + push esi + .setPal: + movzx ecx,byte[edi] + inc ecx + mov [.codesize],ecx + dec ecx + pop [.Palette] + lea esi,[edi+1] + mov edi,[.table_ptr] + xor eax,eax + cld + lodsb ; eax - block_count + add eax,esi + mov [.block_ofs],eax + mov [.bit_count],8 + mov eax,1 + shl eax,cl + mov [.CC],eax + inc eax + mov [.EOI],eax + lea ecx,[eax-1] + mov eax, _null shl 16 + .filltable: + stosd + inc eax + loop .filltable + pop edi + mov [.img_start],edi + .reinit: + mov edx,[.EOI] + inc edx + push [.codesize] + pop [.compsize] + call .Gif_get_sym + cmp eax,[.CC] + je .reinit + call .Gif_output + .cycle: + movzx ebx,ax + call .Gif_get_sym + cmp eax,edx + jae .notintable + cmp eax,[.CC] + je .reinit + cmp eax,[.EOI] + je .end + call .Gif_output + .add: + push eax + mov eax,[.table_ptr] + mov [eax+edx*4],ebx + pop eax + cmp edx,0xFFF + jae .cycle + inc edx + bsr ebx,edx + cmp ebx,[.compsize] + jne .noinc + inc [.compsize] + .noinc: + jmp .cycle + .notintable: + push eax + mov eax,ebx + call .Gif_output + push ebx + movzx eax,bx + call .Gif_output + pop ebx eax + jmp .add + .er: + pop edi + jmp .ex + .end: + mov eax,[.cur_info] + mov [eax],edi + mov [.cur_info],edi + add esi,2 + xchg esi,edi + .nxt: + cmp byte[edi],0 + jnz .continue + inc edi + jmp .nxt + .continue: + cmp byte[edi],0x3b + jne .nextblock + xor eax,eax + stosd + mov ecx,[.img_count] + .ex: + pop edi esi + ret + +.Gif_skipmap: +; in: ecx - image descriptor, esi - pointer to colormap +; out: edi - pointer to area after colormap + + and ecx,111b + inc ecx ; color map size + mov ebx,1 + shl ebx,cl + lea ebx,[ebx*2+ebx] + lea edi,[esi+ebx] + ret + +.Gif_get_sym: + mov ecx,[.compsize] + push ecx + xor eax,eax + .shift: + ror byte[esi],1 + rcr eax,1 + dec [.bit_count] + jnz .loop1 + inc esi + cmp esi,[.block_ofs] + jb .noblock + push eax + xor eax,eax + lodsb + test eax,eax + jnz .nextbl + mov eax,[.EOI] + sub esi,2 + add esp,8 + jmp .exx + .nextbl: + add eax,esi + mov [.block_ofs],eax + pop eax + .noblock: + mov [.bit_count],8 + .loop1: + loop .shift + pop ecx + rol eax,cl + .exx: + xor ecx,ecx + ret + +.Gif_output: + push esi eax edx + mov edx,[.table_ptr] + .next: + push word[edx+eax*4] + mov ax,word[edx+eax*4+2] + inc ecx + cmp ax,_null + jnz .next + shl ebx,16 + mov bx,[esp] + .loop2: + pop ax + + lea esi,[eax+eax*2] + add esi,[.Palette] + + if COLOR_ORDER eq MENUETOS + mov esi,[esi] + bswap esi + shr esi,8 + mov [edi],esi + add edi,3 + else + movsw + movsb + end if + + loop .loop2 + pop edx eax esi + ret + + .globalColor rd 1 + .img_count rd 1 + .cur_info rd 1 ; image table pointer + .img_start rd 1 + .codesize rd 1 + .compsize rd 1 + .bit_count rd 1 + .CC rd 1 + .EOI rd 1 + .Palette rd 1 + .block_ofs rd 1 + .table_ptr rd 1 diff --git a/kernel/branches/hd_kolibri/apps/icon/icon b/kernel/branches/hd_kolibri/apps/icon/icon new file mode 100644 index 0000000000000000000000000000000000000000..f5ea87fc418242a06321ecd61568e1fec6fa35bb GIT binary patch literal 4830 zcmbtY4^SIb8h=X?2!XKaA8OTtYp+%6l|oAKifKwh2o&3r6apkLf<2Wx*Sk8>Y|D%~ z4ZdR8*~{sij#FoJMlS8l-PyZ#JP!&vX+kV%tJrF1JS;N~(!08t+NnoRQp=J1z71gi z=#4kGL*Bmkz3=zE@85gxTejM(>+G&VBSQ#zJB1MA9jU~)CSCb`x)6x))NgArhR$oH z`#Zn(rjN(zkow?3@p6l&Ia1#cI07Ki{40cp0(;>V=z_-5v9YqMVm;gG0>M(X&O(Ru z;uPEeS=!DFu^8FpU%-s7^lst4N?++!K|`ZyvCF>F8NpD=_N4irNn?DaM7UBJ8}*eY zgpX-dAN$-_x|;1w0bD|Zi&RR*xGw0kZ|dN|2DUe=0#|6$C6pD!saUF<3f%Q<4{H_m zF9UDY3!2}-%fFkE%&56BG<}G<95@8ssOB|jwP3F?WH~z)cmqb3zyWCen-WKXYwVifvxaTyX4GH)9gglq(Pw9CZB={ zXSd?LWiPrrzDclz>>Ms*-#KT>L2*KALJ=G5bBZJKYrtL0_D1BFpwr}z9dC)P?ndLq z^-1T`p_F}7=rL7gEbc2cv7K+sBofBZo01+~)zTcHpQTxiqqei>{mYvC8*(F(9+%l> z44ujPa3rBe<8gXTJa||sv7^i(cK&Y zlm4fNuW$#SR1-36>9}^{F!*_2b|xVMC5s3-#(=b=#xODfJt)Fp-d?!ALP>bU4nr|wB5K!$;i%S#?jbP8qXED&QSq)kWA0VfrG}hq5_d$ zhoxfsX`B=8ujN;|Au_|3rm$?Fau&b5#rVbZo)eo*~8g)Be*tmz>o&U?m!DGz(PLV z9mE|^PbP*f($l%duPZ9%XyRAH7Sq$Y-b*Dz>Abe5#3+^Xj34oarm4v%LOSM*80m<3ApAa4ySH{o)h?RP zLMj1=4mfDYN(Zf7**^s>e)|YC2@N`3GGps_BH`?aVqS`7OtJyw;+>x9$pf=lcLzjG z&H`&De2};_ejD34bc@~#0dgf!fZho`8m8>E0Gh=1E^Y0IS*@Y- z>Tpa=BY9#DdS{{=a5SFR=2qM(4u;3nbe!$F&@ni_uB3>XZZ$3O>OlDT*Avg+V#;<* z`WUvF+?-Cx$~XiqfO}3Jhd@ubfN#P94XXbzuXhLECXbT7JhGhWPsZ1nz|gN?9wofW zv(0!?%0^{Xi{Ci_Ny_&09)VZou!TmlJmX{ABj1;dYs#%Iatwpdb8fy70{4fc){5iU zo@R!|tWS*U*q&4-0^MYyK#rh2V-Y^ra}4u;@<1fHHEo#$4*aOifQlz~{R^*L#a;Tq`UxDM;@*2Y}>10e|c?9BsQ!b*0I8 zo4|dGl2ygHXvvK5mZVq4iV~}?f@8od@-E=q9yyXSY?1$_l z35I6Tu?HZTVgEtQ)XZYicY^$g^uOO)gtU9y!B@yDq%VfFWE_#U6#4d%ee*P}JGhAe zEd%1sXEaL1*K{betRqZF*7cpB3ZWTfGs9=kvjz76HpyBBcS(ehy#zWzElDMP9Ql&; z=Ryg9;$UhC11y8ENx7hbLD`sASD{`op6ss#OW^2C%D9c8gJArF!EZ=Au=!uYqC!#* za=ySF1pfhV621ZtBs8!8&zM*R&617|s+DA0xvXtF`0SSH?7_EM>zz0NQMnYAYO2c4_hJ_n1zg<^sOZq=NvwN@5vv+t>`pq za3{9q|5$m`c-rpekB10ZPW=1P|Ep5Wcfc7xoF^B@kFQB`ZF!|{2xA5%bnv=fGBc3_84kSQ-@Lo6# zLCbJC#qBs+tw@B9iwq=HiM(1@MB3ruIBfCx{vP*VpYOu{SHS-@i3tM&Tve_u_8%xH z39&kzT(x!U4+AL>r?m$7UG|#VAF|M_VmGkDnp-@aZIiXS(*7MnzJ*xJ%Q?LEZ$NW3 z_N|V3`wbHiV`AG9btn3>knmCW6j%%=1yEvDFE4Oa}myoJQp4`E0-M(Y{&mL#23SYV7v>!otG*f|_!ucIHSoF3xfJHxq6g->26pwUI(i@;WMTu$rp{ zwQMeXIe)L4SHlJlWW(Nsfl^rpG%ye&P+xYOhx8!y_DX&Azgzycs9t0m=5eTO(s`gWRklWJrUv44>!bvq6>F3z6}1SOf0;H6#~} zYXn*T3tVGK+44gGi+y~Prr%);J)S8a1{ghlWv+-;3hVA#D3DEdBIvpsl%CqVM6N^m zHn;Q;k+!P&qDH<54mA0%DNxk>9L!bj&lc>!r-vkH!A7NkkXK{+AG-iHh~{RfDC9eV zfFFKobR~|7QW7UC;JW}{-@x`rSSzU3y^d8vJ@Y}eZzCsY#^cQ~t-qRSUiH=F0pGp& ziCAw88AlIoC~V8xP_kP`Fw!mcIN<5wb4%{kD7 z6hfq))%tg5%6OfbG|E@YzO4|R*+c#)9`eRf<4JKQs<|BkjZf`1dQI0>M6ccV>>7IY zu05;j#TivG&QgU(C8e$eaip2Xi8s@nm`)I{X5uA4c9=1_!B<4sDB0D_3HGoCbNN-s zIZUIeNg!Z~J0&|&m9Nmw4sm{wGOtpvpzo?<87)s4K zAeVuEf?U1Fn@+E;V>`z%J<_0D0N3`dBkSNRW7smJ837E5Kt9kRRfAGN!OaQ9c*{|& zrhMz~Zqr)KWzcP#%tuNf3V?2G{Ax>h%n-~Ycal{RxJ=<5MFy!DC$Ugq;D&^6(CfRg zBz1GgY$y5NJZ#xK&!v 10 + mov ebx,16 + div ebx + imul eax,10 + add eax,edx + + mov ebx,eax + add ebx,icons_reserved + cmp [ebx],byte 'x' + je no_f + mov [ebx],byte 'x' + + mov [cur_btn],edi + xor edx,edx + mov ebx,10 + div ebx + add eax,65 + add edx,65 + mov [icon_default+0],dl + mov [icon_default+1],al + + inc dword [icons] + mov edi,[icons] + dec edi + imul edi,REC_SIZE + add edi,icon_data + + mov [current_icon],edi + + mov esi,icon_default + mov ecx,REC_SIZE + cld + rep movsb + mov esi,[current_icon] + jmp band + no_f: + + call draw_btns;draw_window + + jmp still + + no_add_icon: + + + cmp eax,23 ; user pressed the remove icon button + jne no_remove_icon + + mov eax,4 + mov ebx,24*65536+250+8*14 + mov ecx,0xc0ff0000 + mov edx,rem_text + mov edi,0xffffff + int 0x40 + + mov eax,10 + int 0x40 + cmp eax,3 + jne no_f;ound + mov eax,17 + int 0x40 + shr eax,8 + cmp eax,40 + jb red;no_f;ound + sub eax,40 + + xor edx,edx + mov ebx,16 + div ebx + imul eax,10 + add eax,edx + + mov ebx,eax + add ebx,icons_reserved + cmp [ebx],byte 'x' + jne red + mov [ebx],byte ' ' + + xor edx,edx + mov ebx,10 + div ebx + shl eax,8 + mov al,dl + + add eax,65*256+65 + + mov esi,icon_data + mov edi,REC_SIZE + imul edi,[icons] + add edi,icon_data + news: + cmp word [esi],ax + je foundi + add esi,REC_SIZE + cmp esi,edi + jb news + jmp red + + foundi: + + mov ecx,edi + sub ecx,esi + + mov edi,esi + add esi,REC_SIZE + + cld + rep movsb + + dec [icons] + + mov eax,icon_data + mov [current_icon],eax + movzx ebx,word[eax] + sub bx,'AA' + shl bl,4 + shr ebx,4 + add ebx,40 + mov [cur_btn],ebx + + jmp red + + no_remove_icon: + + cmp eax,40 ; user pressed button for icon position + jb no_on_screen_button + mov edi,eax + sub eax,40 + mov edx,eax + shl eax,4 + and edx,0xf + mov dh,ah + add edx,65*256+65 + + mov esi,icon_data + mov ecx,[icons] + cld + findl1: + cmp dx,[esi] + je foundl1 + add esi,REC_SIZE + loop findl1 + jmp still + + foundl1: + + mov [current_icon],esi + mov [cur_btn],edi + band: + add esi,12 + call atoi + and eax,0xfffff8 + mov [cur_band],eax + call draw_btns + + jmp still + + no_on_screen_button: + + + jmp still + + +current_icon dd icon_data + + +print_strings: + + pusha + + mov eax,13 ; clear text area + mov ebx,100*65536+180 + mov ecx,(278+12)*65536+40 + mov edx,0xffffff + int 0x40 + + xor edi,edi + mov eax,4 ; icon text + mov ebx,100*65536+278+14 + mov ecx,3 + .ll: + push ecx + mov ecx,0x000000 + mov edx,[current_icon] + add edx,[positions+edi*4] + movzx esi,byte[str_lens+edi] + inc edi + int 0x40 + add ebx,14 + pop ecx + loop .ll + + popa + ret + +iconlst db ICONS_DAT,0 + +load_icon_list: + + mov edi,icons_reserved ; clear reserved area + mov eax,32 + mov ecx,10*9 + cld + rep stosb + + mov ecx,[icons] ; set used icons to reserved area + mov esi,icon_data + ldl1: + movzx ebx,byte [esi+1] + sub ebx,65 + imul ebx,10 + movzx eax,byte [esi] + add ebx,eax + sub ebx,65 + add ebx,icons_reserved + mov [ebx],byte 'x' + add esi,REC_SIZE + loop ldl1 + ret + +lst_path: + mov ecx,30 + mov edi,finfo.path + rep movsb + ret + +load_ic: + mov ebx,finfo + mov dword[ebx+12],48*REC_SIZE + mov dword[ebx+16],icon_data + mov esi,iconlst + call lst_path + mcall 70 + lea eax,[ebx+10] + xor edx,edx + mov ebx,REC_SIZE + div ebx + mov [icons],eax + ret + + +positions dd 3,16,47 +str_lens db 8,30,30 + +read_string: + pusha + sub eax,11 + movzx ecx,byte[str_lens+eax] + mov [cur_str],ecx + mov eax,[positions+eax*4] + + mov edi,[current_icon] + add edi,eax + mov [addr],edi + + add edi,ecx + + .l1: + dec edi + cmp byte[edi],' ' + jne .found + mov byte[edi],'_' + loop .l1 + dec edi + .found: + inc edi + push edi + call print_strings + + pop edi + f11: + mov eax,10 + int 0x40 + cmp eax,2 + jz fbu + jmp rs_done + fbu: + mov eax,2 + int 0x40 + shr eax,8 + cmp eax,13 + je rs_done + cmp eax,8 + jnz nobsl + cmp edi,[addr] + jz f11 + dec edi + mov [edi],byte '_' + call print_strings + jmp f11 + nobsl: + cmp eax,31 + jbe f11 + mov [edi],al + call print_strings + + inc edi + mov esi,[addr] + add esi,[cur_str] + cmp esi,edi + jnz f11 + + rs_done: + + mov ecx,[addr] + add ecx,[cur_str] + sub ecx,edi + mov eax,32 + cld + rep stosb + call print_strings + popa + ret + + key: ; key + mov al,2 ; just read it and ignore + int 0x40 + jmp still + +; ********************************************* +; ******* WINDOW DEFINITIONS AND DRAW ******** +; ********************************************* + + +draw_window: + + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,1 ; 1, start of draw + int 0x40 + + ; DRAW WINDOW + xor eax,eax + mov ebx,210*65536+300 + mov ecx,30*65536+390-14 + mov edx,0x13ffffff + mov edi,header ; WINDOW LABEL + int 0x40 + + mov eax,13 ; WINDOW AREA + mov ebx,20*65536+260 + mov ecx,35*65536+200 + mov edx,0x3366cc + int 0x40 + + mov eax,38 ; VERTICAL LINE ON WINDOW AREA + mov ebx,150*65536+150 + mov ecx,35*65536+235 + mov edx,0xffffff + int 0x40 + + mov eax,38 ; HOROZONTAL LINE ON WINDOW AREA + mov ebx,20*65536+280 + mov ecx,135*65536+135 + mov edx,0xffffff + int 0x40 + + mov eax,8 ; TEXT ENTER BUTTONS + mov ebx,20*65536+72 + mov ecx,(275+1+14)*65536+13-2 + mov edx,11 + mov esi,[bcolor] + int 0x40 + inc edx + add ecx,14*65536 + int 0x40 + inc edx + add ecx,14*65536 + int 0x40 + +; mov eax,8 ; APPLY AND SAVE CHANGES BUTTON + mov ebx,20*65536+259 + mov ecx,(329+2)*65536+15-4 + mov edx,21 + mov esi,[bcolor] + int 0x40 + +; mov eax,8 ; ADD ICON BUTTON + mov ebx,20*65536+129-2 + add ecx,14*65536 + inc edx + int 0x40 + +; mov eax,8 ; REMOVE ICON BUTTON + add ebx,(130+2)*65536 + inc edx + int 0x40 + + mcall ,<20-14,8>,<260-23,32>,30+1 shl 30 ; IMAGE BUTTON + inc edx + add ebx,(36*7+26) shl 16 + mcall + add edx,1+1 shl 29 + mov ebx,(33-19) shl 16+(34*8) + mcall + mcall 4,<23-15,273-24>,0,arrows,1 + add ebx,(36*7+27)shl 16 + add edx,2 + mcall + dec edx + mcall ,<120,250> + lea edx,[ebx+8 shl 16] + mov ecx,[icon_count] + mcall 47,0x30000,,,0 + +;; + mov eax,4 + mov ebx,24*65536+250+14+14+14 + mov ecx,0xffffff + mov edx,text + mov esi,47 + newline: + mov ecx,[edx] + add edx,4 + int 0x40 + add ebx,14 + add edx,47 + cmp [edx],byte 'x' + jne newline +draw_btns: +;; + mov eax,0 ; DRAW BUTTONS ON WINDOW AREA + mov ebx,20*65536+25 + mov ecx,35*65536+19 + mov edi,icon_table + mov edx,40 + newbline: + + cmp [edi],byte 'x' + jne no_button + + mov esi,0x5577cc + cmp [edi+90],byte 'x' + jne nores + mov esi,0xcc5555 + cmp edx,[cur_btn] + jne nores + mov esi,0xe7e05a + nores: + + push eax + mov eax,8 + int 0x40 + pop eax + + no_button: + + add ebx,26*65536 + + inc edi + inc edx + + inc al + cmp al,9 + jbe newbline + mov al,0 + + add edx,6 + + ror ebx,16 + mov bx,20 + ror ebx,16 + add ecx,20*65536 + + inc ah + cmp ah,8;9 + jbe newbline + call print_strings + call draw_icon + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,2 ; 2, end of draw + int 0x40 + + ret + +draw_icon: + mcall 13,<33-20,34*8+2>,<260-24,37+15-2>,0xffffff + mov esi,[current_icon] + add esi,12 + call atoi + push eax + cmp eax,[cur_band] + jb .nou + sub eax,[cur_band] + cmp eax,7 + ja .nou + imul eax,34 shl 16 + lea ebx,[eax+(33-19) shl 16] + mov bx,34 + mcall 13,,<236+35,3>,0xff0000 + mov eax,[esp] + .nou: + mov eax,[cur_band] + and eax,0xfffffff8 + push eax + imul eax,ICON_SIZE + lea ebx,[strip_file+12+eax] + mov ecx,8 + mov edx,(33-18) shl 16+238 + .nxt: + push ecx + mcall 7,,<32,32> + pop ecx + add ebx,ICON_SIZE + add edx,34 shl 16 + loop .nxt + + mcall 4,<45,280-2>,0,rep_text,rep_text_len-rep_text + lea edx,[ebx+(8*5)shl 16] + pop ecx + mcall 47,0x30000,,,0xff + add ecx,7 + add edx,(3*8+4)shl 16 + mcall + mov ecx,[icon_count] + add edx,(5*8+4)shl 16 + mcall + pop ecx + add edx,(10*8+4)shl 16 + mcall ,,,,0xff0000 + ret + +; DATA AREA + + +bcolor dd 0x335599 + +icon_table: + + times 4 db 'xxxx xxxx' + times 2 db ' ' + times 1 db ' ' + times 2 db 'xxxx xxxx' +; times 1 db ' ' + +icons_reserved: + times 9 db ' ' + +if lang eq ru + text: + db 255,255,255,0, ' ’…Š‘’ ' + db 255,255,255,0, ' Žƒ€ŒŒ€ ' + db 255,255,255,0, ' €€Œ…’› ' + db 255,255,255,0, ' ˆŒ…ˆ’œ ' + db 255,255,255,0, ' „Ž€‚ˆ’œ “„€‹ˆ’œ ' + db 0,0,0,0, '€†Œˆ’… € Ž‡ˆ–ˆž ˆŠŽŠˆ „‹Ÿ …„€Š’ˆŽ‚€ˆŸ ' + db 'x' ; <- END MARKER, DONT DELETE +add_text db '€†Œˆ’… € Ž‡ˆ–ˆž …ˆ‘Ž‹œ‡“…ŒŽ‰ ˆŠŽŠˆ ',0 + +rem_text db '€†Œˆ’… € Ž‡ˆ–ˆž ˆ‘Ž‹œ‡“…ŒŽ‰ ˆŠŽŠˆ ',0 +header db 'Œ„­„¤¦„ą ØŖ®­®Ŗ',0 + +else if lang eq ge + text: + db 255,255,255,0, ' TITLE ' + db 255,255,255,0, ' APP NAME ' + db 255,255,255,0, ' PARAMETER ' + db 255,255,255,0, ' ANWENDEN ' + db 255,255,255,0, ' HINZUFUEGEN ENTFERNEN ' + db 0,0,0,0, 'AUF BUTTON KLICKEN, UM ICON ZU EDITIEREN ' + db 'x' ; <- END MARKER, DONT DELETE +add_text db 'AUF UNBENUTZTE ICONPOSITION KLICKEN ',0 + +rem_text db 'ICON ANKLICKEN; DAS GELOESCHT WERDEN SOLL',0 +header db 'Icon Manager',0 + +else + text: + db 255,255,255,0, ' TITLE ' + db 255,255,255,0, ' APP NAME ' + db 255,255,255,0, ' PARAMETERS ' + db 255,255,255,0, ' APPLY CHANGES ' + db 255,255,255,0, ' ADD ICON REMOVE ICON ' + db 0,0,0,0, 'CLICK BUTTON ON ICON POSITION FOR EDIT ' + db 'x' ; <- END MARKER, DONT DELETE +add_text db 'CLICK ON A NOT USED POSITION ',0 + +rem_text db 'CLICK ICON POSITION; YOU WANT TO DELETE',0 +header db 'Icon Manager',0 + +end if + +arrows db '' +iconname: + db ICON_APP,0 + +icon_default: + db 'AA-SYSXTREE-000-/RD/1/SYSXTREE ' + db '- *' + db 13,10 + +rep_text: +if lang eq ru + db '‡€—Šˆ - ˆ‡ , ‚›€ #' +else + db 'ICONS - OF , SELECTED' +end if + +rep_text_len: + +;////////////////////////// +get_bg_info: + mov eax,39 + mov ebx,4 + int 0x40 + mov [bgrdrawtype],eax + + mov eax,39 ; get background size + mov ebx,1 + int 0x40 + mov [bgrxy],eax + + mov ebx,eax + shr eax,16 + and ebx,0xffff + mov [bgrx],eax + mov [bgry],ebx + ret + +calc_icon_pos: + movzx eax,byte [ebp-20] ; x position + sub eax,'A' ;eax - number of letter + cmp eax,4 + jg no_left + shl eax,6 ;imul eax,64 + add eax,16 + movzx ebx,[warea.left] + add eax,ebx + jmp x_done + no_left: + sub eax,9 + sal eax,6 ;imul eax,64 + sub eax,16+52-1 + movzx ebx,[warea.right] + add eax,ebx + x_done: +; mov [xpos],eax + mov [ebp-12],eax + + movzx eax,byte [ebp-20+1] ; y position + sub eax,'A' ; eax - number of letter + cmp eax,4 + jg no_up + shl eax,6 ;imul eax,80 + add eax,16 + movzx ebx,[warea.top] + add eax,ebx + jmp y_done + no_up: + sub eax,9 + shl eax,6 ;imul eax,80 + sub eax,16-1 + movzx ebx,[warea.bottom] + add eax,ebx + y_done: +; mov [ypos],eax + mov [ebp-8],eax + ret + +;START2: +load_icon_list2: + call get_bg_info + + mcall 48,5 + mov [warea.by_x],eax + mov [warea.by_y],ebx + + mov eax,14 + int 0x40 + add eax,0x00010001 + mov [scrxy],eax + +apply_changes2: + + mov edi,[icons] + mov esi,icon_data + mov ebp,0x5000 ; threads stack starting point + + start_new: + mov eax,[esi] + mov [ebp-20],eax + call calc_icon_pos + + mov eax,51 + mov ebx,1 + mov ecx,thread +; mov edx,[thread_stack] + mov edx,ebp +; sub edx,4 +; mov [edx],esi + mov dword[ebp-4],esi + int 0x40 +; add [thread_stack],0x100 + add ebp,0x100 + + mov eax,5 + mov ebx,1 +wait_thread_start: ;wait until thread draw itself first time + cmp [create_thread_event],bl + jz wait_thread_end + int 0x40 + jmp wait_thread_start +wait_thread_end: + dec [create_thread_event] ;reset event + + + add esi,REC_SIZE + dec edi + jnz start_new + close: + or eax,-1 + int 0x40 + +thread: +; pop ebp ;ebp - address of our icon + sub esp,12 + mov ebp,esp + sub esp,16 + call draw_window2 + mov [create_thread_event],1 + mov eax,40 + mov ebx,010101b + int 0x40 + +still2: + + mov eax,10 + int 0x40 + + cmp eax,1 + je red2 + cmp eax,3 + je button2 + cmp eax,5 + jne still2 + + call get_bg_info + mov eax,5 + mov ebx,1 + call draw_icon2 + + jmp still2 + + red2: + mcall 14 + add eax,0x00010001 + mov [scrxy],eax + mcall 48,5 + mov [warea.by_x],eax + mov [warea.by_y],ebx + add ebp,+12 + call calc_icon_pos + add ebp,-12 + mcall 9,I_END,-1 + mov eax,[I_END+process_information.x_start] + cmp eax,[ebp+0] + jne @f + mov eax,[I_END+process_information.y_start] + cmp eax,[ebp+4] + je .lp1 + @@: call get_bg_info + mcall 67,[ebp+0],[ebp+4],51,51 + + .lp1: call draw_window2 + jmp still2 + + key2: + mov al,2 + int 0x40 + + jmp still2 + + button2: + mov al,17 + int 0x40 + + + mov esi,[ebp+8] + mov ebx,1 + mov edi,finfo.path + call fill_paths + inc ebx + mov edi,param_str + mov dword[finfo_start+8],edi + call fill_paths + cmp byte[edi],0 + jne .no0 + and dword[finfo_start+8],0 + .no0: +; lea ebx,[ebp+19] + mov ebx,finfo_start + mov eax,70 + int 0x40 +; dph eax +; cmp eax,1024 +; jae still2 + jmp still2 + +fill_paths: + push esi edi +; dps '>' + movzx ecx,byte[str_lens+ebx] + add esi,[positions+ebx*4] + push esi +; mov edx,esi + add esi,ecx + + .l1: + dec esi + cmp byte[esi],' ' + jnz .found + loop .l1 + pop esi + jmp .noms + .found: + lea ecx,[esi+1] + pop esi + sub ecx,esi + rep movsb + .noms: + and byte[edi],0 +; call debug_outstr +; dps <'<',13,10> + pop edi esi + ret + +atoi: + push esi + xor eax,eax + xor ebx,ebx + .nxt: + lodsb + cmp al,'0' + jb .done + cmp al,'9' + ja .done + sub eax,'0' + imul ebx,10 + add ebx,eax + jmp .nxt + .done: + pop esi + mov eax,ebx + ret + +itoa: +; mov esi,[current_icon] + add esi,2 + mov ebx,10 + mov ecx,3 + .l0: + xor edx,edx + div ebx + add dl,'0' + mov [esi],dl + dec esi + loop .l0 +; and byte[esi],0 + ret + +draw_picture: + mov [image],0x3000 + mov edi,[ebp+8] + lea esi,[edi+12] + call atoi + cmp eax,[icon_count] + ja toponly.ex + imul eax,(32*3*32) + lea edi,[eax+strip_file+12] + xor ebx,ebx + xor ecx,ecx + mov esi,edi;strip_file+12+(32*3*32)*2 + + mov [pixpos],0 + newb: + push ebx + push ecx + + cmp ebx,10 + jb yesbpix + cmp ebx,42 + jge yesbpix + cmp ecx,31;2 + jg yesbpix + + push esi + mov esi,edi + add esi,[pixpos] + +no_correction_pixpos: + add [pixpos],3 + mov eax,[esi] + and eax,0xffffff + + pop esi + + cmp eax,0 + je yesbpix + cmp eax,0xfffcff ;f5f5f5 + je yesbpix + jmp nobpix + + yesbpix: + + stretch: + cmp [bgrdrawtype],dword 2 + jne nostretch +; mov eax,[ypos] + mov eax,[ebp+4] + add eax,ecx + imul eax,[bgry] + cdq + movzx ebx,word [scrxy] + div ebx + imul eax,[bgrx] + push eax +; mov eax,[xpos] + mov eax,[ebp+0] + add eax,[esp+8] + imul eax,[bgrx] + cdq + movzx ebx,word [scrxy+2] + div ebx + add eax,[esp] + add esp,4 + + jmp notiled + + nostretch: + + cmp [bgrdrawtype],dword 1 + jne notiled +; mov eax,[ypos] + mov eax,[ebp+4] + add eax,ecx + cdq + movzx ebx,word [bgrxy] + div ebx + mov eax,edx + imul eax,[bgrx] + push eax +; mov eax,[xpos] + mov eax,[ebp+0] + add eax,[esp+8] + movzx ebx,word [bgrxy+2] + cdq + div ebx + mov eax,edx + add eax,[esp] + add esp,4 + + notiled: + + lea ecx,[eax+eax*2] + mov eax,39 + mov ebx,2 + int 0x40 + + nobpix: + + pop ecx + pop ebx + + mov edx,eax + mov eax,[image] + mov [eax],edx + mov [eax],dl + inc eax + ror edx,8 + mov [eax],dl + inc eax + ror edx,8 + mov [eax],dl + inc eax + mov [image],eax + inc ebx + mov eax,[yw] + inc eax + cmp ebx,eax + jnz newb + xor ebx,ebx + + inc ecx + + mov eax,[ya] + add [pixpos],eax + + cmp [top],1 + jne notop + cmp ecx,38 + je toponly + + notop: + + cmp ecx,52 + jnz newb + + toponly: + + mov eax,7 + mov ebx,0x3000 + mov ecx,52 shl 16 + 52 + xor edx,edx + int 0x40 + .ex: + mov [load_pic],0 + ret + +draw_text: + + mov esi,[ebp+8] + add esi,3 + push edi + mov edi,header + mov ecx,8 + cld + rep movsb + pop edi + mov eax,header + news2: + cmp [eax],byte 33 + jb founde + inc eax + cmp eax,header+8;11 + jb news2 + founde: + sub eax,header + mov [tl],eax + + mov eax,[tl] + lea eax,[eax+eax*2] ; eax *= char_width/2 + shl eax,16 + + mov ebx,27*65536+40 + sub ebx,eax + + mov eax,4 + xor ecx,ecx ; black shade of text + mov edx,header + mov esi,[tl] + add ebx,1 shl 16 ;*65536+1 + int 0x40 + inc ebx + int 0x40 + add ebx,1 shl 16 + int 0x40 + inc ebx + int 0x40 + sub ebx,1 shl 16 + int 0x40 + dec ebx + sub ebx,1 shl 16 + int 0x40 + sub ebx,1 shl 16 + dec ebx + int 0x40 + dec ebx + add ebx,1 shl 16 + int 0x40 + inc ebx + mov ecx,0xffffff + + int 0x40 + mov [draw_pic],0 + ret + +; ********************************************* +; ******* WINDOW DEFINITIONS AND DRAW ******** +; ********************************************* + + +draw_window2: + + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,1 ; 1, start of draw + int 0x40 + + ; DRAW WINDOW + xor eax,eax ; function 0 : define and draw window +; mov ebx,[xpos-2] + mov ebx,[ebp+0-2] +; mov ecx,[ypos-2] + mov ecx,[ebp+4-2] + add ebx,[yw] ; [x start] *65536 + [x size] + add ecx,51 ; [y start] *65536 + [y size] + mov edx,0x01000000 ; color of work area RRGGBB,8->color gl + int 0x40 + + mov eax,8 ; button + mov ebx,51 + mov ecx,50 + mov edx,0x40000001 + int 0x40 + + mov eax,5 + mov ebx,1 +draw_icon2: + xchg [load_pic],bl + test bl,bl + je draw_icon_end + int 0x40 + jmp draw_icon2 +draw_icon_end: + + mov eax,5 + mov ebx,1 +draw_icon_2: + xchg [draw_pic],bl + test bl,bl + je draw_icon_end_2 + int 0x40 + jmp draw_icon_2 +draw_icon_end_2: + + mov eax,9 + mov ebx,process_table + mov ecx,-1 + int 0x40 + + call draw_picture + call draw_text + + mov eax,12 + mov ebx,2 + int 0x40 + + ret + +tl dd 8 +yw dd 51 +ya dd 0 +cur_btn dd 40 + +;xpos dd 15 +;ypos dd 185 +draw_pic db 0 +load_pic db 0 +create_thread_event db 0 + + +image dd 0x3000 +;thread_stack dd 0x5000 + +;icons dd 0 + + +I_Param: + + icon_data = I_END+0x1400 + process_table = I_END+0x2400 + +;I_END: + +bgrx dd ? +bgry dd ? +param_str rb 31 + +;////////////////////////// + +bgrxy dd ? +warea: + .by_x: + .right dw ? + .left dw ? + .by_y: + .bottom dw ? + .top dw ? +scrxy dd ? +bgrdrawtype dd ? + +pixpos dd ? +top dd ? +icons dd ? +addr dd ? +cur_str dd ? +cur_band dd ? +sel_icon1 rd 1 +icon_count rd 1 +gif_file rb GIF_SIZE +strip_file rb RAW_SIZE +;I_Param: + +; icon_data = I_END+256 + +I_END: diff --git a/kernel/branches/hd_kolibri/apps/icon/iconstrp.gif b/kernel/branches/hd_kolibri/apps/icon/iconstrp.gif new file mode 100644 index 0000000000000000000000000000000000000000..77b0386e5fe10e27586ab955127b92c2cd8f0de0 GIT binary patch literal 13807 zcmWmK_aoGg9|!RF?K88pJ1d(rvmLTal5Da^K8QF>`+2yi#vdhfM3fVjJ zd_UjUfAIX_`OD+^(l^voQg%WC0CYJN`0tQWNH`%J+TBGBeudD1CwC{;wsk`Xp%H}e z6a$+5Ki?w=P-gAxui`t3!B7^a`=t?gc=$Q>v@_B8aq{~FTNj(w4l45UX?_0n6iPDj z{;i&lZ@qe%eC`87AL5snmj^p44TLV`f4i;ekyzr!vK(Uwdk7^KPKFfx+S*$)(9^%} z?6>>}4lOI|>NrsGc<-jiU=M}a8%oPZnD35$j4D~aZt80nO)4mU|G9*!r}k6wx8q88 zVQR|lRARv2$!~Wgh3$(Dg@vvbjvc!ZOSxF+xARTs{vL*d!_TraE$`k`-VI{EUy%9c7&+*5_3mfCc}m*oFs!b2B%$^oBP0Ec z2wm-c@Bg53a%wW|L|#Qj#qOAmi-+gr?8MaIou|81^`@!2IpTAu{Nm!|vv-frz-QsA zw9vn6PMtr_+Tt#b{5#(D2Rx@9u*q zY_tKHrVAlP@}Yz9An1KJNjr+`c3TK675bjy8K80m4$sTz`#)KdE@idOo+2nu2#_C3Nx^^y}AWwXW5adV|0Z;T6xg_@B=Fl3FY? zS5h4e?^g~MD2VXH^^kQ zFYL#npTOV+0xQ3K`zeNw2{SqVBSjM6Ofnm3^_~rJ|SYehDhS9y?pV;EGP+&iJ`% zoy+$(JMh8bqltGmsb)~S*J2~3k$L>Qy$WxKKH`L=mXLQ)+#YEoCws!dk{VtjGN)?M z(w~g#GPG>NqnQ$H(q4a^NnS;N`PQeH!&sUTdd;Oh`ZD-ZHtEo!v#Ulb^82qf%Qph2 zkzbzr@2&Q$_2u6zKKwMWtZztJg}Q!3yZ-)G<8W1qTli^sK9{ORsNCDIlS8?j?0ft2 zlrzeRhI05aLK3z9@z#NN3(q zqQQK`m25IBMy!-%_dr9f2hH5fIRo6w(v%@dh#UcSlg0R`SBl#*`0tKxVdnxA&R z7D`|;5i5G1_Q?n(Ptl`pb}y#NtX*LeFUr--CB+`RNFrfx*0uF99Xxc-U;@BV4h$)EgaM$-Y%E+Q>5n13~Ds#y_Dv)I)u`1r`bS8nLpZr`LlsY*aWT9lzz{enB-wFcy7 zz)zK}uIisk%g^L{G>7V|e;jFe?T?tz*awcNX@-^e-Xrt{4lzEo|1xs>ZA0KP;8k{yZK?cF@CG? zU(%E94C5IZxdzSbCo3eKA(h@QgoO0g^8Z$sy_zhAhnBVcZa(5_j{$}-O`Vm z^@|^yN|kp0KKfmIw)`S7WaU$o!}G(xPiMB+E~`$ANCmzVxVKpNjSN>Y^?O0gg$f(A zP}`93LEX9VYh5j@XLBYq)OkpKgI1=QzXb7SrWB1_8fHg44LaP3y*0O$GoK+sffjPr z#4qNue;$IOE~2H1-63*1|BVc8HKVujz+cVgkHkoT(9XFL)a;DWqElM*t%L1S8jLY! zP&m8uHi#=59j)rGP(_FqkSincuXsQ2E;M~{MT?tMi{oonO)Z*oaI)qpoyXQRtoo$ z%s0au^2t?6LS%Q(L3;9`mlBvS{r4^O2uPMwN9v$Lx@kOndP;EIh5u<{MX_l=I8R<32 z-!HKl8`wE)SEi{8Ag=XTtDNVB=hAsmeN6t6{O8eqx@NqX#gZ(`4=t3@HU)-|Xts$_ zXx0shG8@L@H}L#*nQmK~Q?8@SOFjG*V6 z)bYi95vcXzg}1^LZ=}|ajBNP1oK9bgxUBoV3nDj5BJ5^gZXidb!Jd5#_uf~m9l6^o zKWpl+XHrueN|utVJe{NmfpjrMpYX>(Q~=9S^GF1Qtu`-D_YVlkNb!~BU7w!*+0uB_ zCmHmZVMgZ}nf(fzOf;^UmS%XYSrOmneJ($*MpkOY`0nu0gP`<+0z5;_;Fvw26s~X3 zsX^~gdMoiqXP8JA>e$BAKIe+i|H`h*yAwn>_D>>}TZtAnN&|kdbUsIZ^A&Vm_%q;;|6+ z&cYRx90;Yb}%_RO#Y9U zO1~9Whg|i^`+Z<40{0kU@ew9~8t+?z2fj z87iO6F(e*&7Vf6KH?L=5A5iKe*~}T zi@5Q|B>7B(j3F3uVu$qU>&&#$P?8YceBTMOHCuBp>|xV4{8$l6fP2^*~2JSeHM z|MxDcZsT9$;R4OQW2=jXy|2%MmIT69jipuh!zg7z<74N`b<5|yJ{Ro6b@i)}?&sfW ze(wyv{k>f+eZHdk`?zoN;%a11(-2ahL|?FW0kC5Mc6)BDBRm8vk}sNJhMoF}r9Z+> zB#A;pB&W1x0#LZvRxIlgn0p+@dxVoF0hf!gOxn0fFd&V^l3DQrN;o zz)#@us5An%2wvU_PZ#py+7CR32Z6yVeDWuO(<9tSBwWD&Q3V1fcEfKIU))IpOo`!R z{1GMw5w;!?cS9lsyRcOL1f+H(!a34$1#eswZZ#fZx)OPhJ<6*nBA_e6Y&_D%01--# zx<4NI$Rqr*M-+Y~!k3*GZWTp|GKdJVihR;Vd=?V<{3wcnJvwOxYbAnB6Tvzm!&5Ii zoQ=IWxg3+P6!Xq1=H$JvwyaIjQt1u=ex4D0Nr&kK&9wV!p@ggAzh866Jd(g zo{yE5jSEG`HYz#Dwz77R<4#*+sS15-M&f=N2&V1CD(>-zl2Ahi@dHHZju2EGIlhh< zXUrcr*%jMQW)gBv=n#po9*=`+C$tL1Z4eV0juKWx5^pUfbc%3pjVFv4cs3$|Q&}a8 z7Qq9LxD&F7Erv8)lt9oC6xro(Fo=I*5exk*%oH78zY@z(EUUBoG6Nq^W&Ki%Iaa4N zj`^5Wjf`(6CrSLJ#HeZ~_97FZvI=$;FPW)GWwO3EwBv>h(0{(f9(g3DRq(bP#n8Nr zi*=4M;gH3U`KcHPiuqVpaCm60h^66csx&6+P_)%w7W==bJKtY(%Dm=$iFN({+B!Yu z9#ss|EX6!JW&Tf!5r3+TRZ4cSZSeOL{|Biw(WzqO)Mp%Np4Rpezfz;3ZKI1(_|UZY zU%s*5(-!Why*iG4U7VK6k?t3op7uR8;ct5SgY=B_^t`|6nW3n}?bWJvc|u{u2Gz_e*MboBWH<~OJ|CR&Rb{A846ONsJE-K*F~vOrrA@)S;;8s)$iGB zhB?XG*((pS=Z}>R9^@qK<(w2}okeHo-^s}w(wN-NIi|{47R{lK$sx(*F`XzusI$+1 zX}o%yU0RjPET(+fCYQlTWACpD@`ENHXAaf2`YYz#e5}%yS~}5_T=5UNED!S~C-UXq z{w<_SN{$51P4i{;c1auunSrH$kbYx6FR1B9YqxmbkK_4c>#Toc)Nqnl!pmFUaIPv3U zcJRklVMqm{r~4CkGJ<@90O}wuwIWPCuP;xQS5NTq7?)%U;V}$gR*a{>T4^mmMN2rN z@@{1%i*4l#z!@!WCu?ipt*nJ1!LQY!WP7Y>wh=Udvqr`zu#6PVM{yLU`nqkk`e~KV zTW_PDQpL(DlRCgO1Frw5OdMNw(p@GeE=>Oq;@0!oev%K?143k!Po0QUp|oshoT;#1 z%#0a~%S*)2!c|URo@W4>jy3HmH6r=qzPVsVmYTkY-;Z|f0b0Njuo$cK>AuPUgxh` zo!9f3oB?a*s=HeW=3@Zc`Uc96Gm6(HA%c(Li20)YDR9+8E>b8G)t}ppA|jAxle( zpKTM5llW3zxAqDU^r$u28X6gMM!KM-&)TXv#agM4agaQdcgM!(awmWdg z8re3PIac^@gX{*W0(#rbO9Z_$}F3la_x=+Bj zr(&&^wh$T=!l}ILsshBk9`UErXA*hUEVmCg}^ zQm+KRBr^jI;dcMplUe^}t(UXpD);3N`6slQ55N2r@1vLfDtU^KBLOP_ z;^{VIJhP9F^tEuUmpiwXF`$y=5c#Vf(s5chS%NB#C09SKTp>ZahX=?Rb@aPvB9~UI zZGD-E=99F$4s~A6Qk|kv<>2L0Zu*w<<+UB#O8=eas z#&}_^;-ze-`Kho&H+e?E#1f-(zN(kLqFTdV%ER9A!|vy!?)EIZ+9U2+BWeCa`aI)C zbYlh$V|MnVgoY9O=`q~&nC=c=Wc;}5r{Sdh@!V~)3RmRe(;H+vRU%E(bVC;EJj(;<}G zWLB6mC+j_b#bjQ_WItC>IoY$0^HJMwyH3JwmF4Cd?Ft<{9_EXttELnRmS!OS3 zH!gWmmP9Cjo|Mj0o=VMgQ$pM|_#VyxhNdfqXuc%EvVZm>-eEc1dxc0*ikVqRo|z9n zjy7>xH4K8Ii|4nN9Yu5j_N^6xf?{DVj-&~4PzSLr2Hc;p-Bqq3KrM+h9yq2l4 zCMC55l)m3NUu#f@w`#1no2=VpjdWzMcYCi}eS*zzuiIePdo(s$6GrAqKn8F%!a9aw@|t<-@oWJ>O;qBV8>88PR1V^!3fDj*m7L~QPxi=|#^#w6 zT=-&r9=*wt17Mmq*Pm}dwsu7m_s8h>I0yEBdT#}p9vI!*H@a#mPxM8EYzv!^f z^WwnZ(%z~6!A0Z2JTKfs^PgAZ&S}yirGIl?3ii32*67lEWo)}6ep9lEHcXnHmvj`< zbQD*1G>>hc&&}%B*zPeswjo_g%Q=2ib_^ao{+SCSHNi3l_iVRs2RYK-`QaagLOL=W zzx}=WQ4ERCg;n1={r3FS`V*{Oa8s=50FtxOhumSX+;#M4<}BN8y!h8Ku_*eBhW+jbv9sQb^(3?1NsYrR7yF)?@ej@ZP2M^jnOV2H_?K03xM#A{RytChcs@?w zF!*%;%f${V@sxaN`=sgO?Dqxb);a*f%wq5`I^OGPrgPenbKEMf?2OnpHC8^O8wM5m z9lq?0k(2C|Z}kZ%9UDRGUBT{TsDgL>xc_WVnykA9_k%mj{n1LH)bG-VmW&frZ)USh z>=qfk72gxQX}B*sT%`YKwcYSwxuxVkVBh~c@~}VmniKVFY8kI@pXIVD!&GIY2Fb=w z-S&oGHfQSHbSpo9R76iyJb%yGII)*E-r>mQqdtz=b?tsFd9U=@%{{mNtTH;vgqp#= z$Iqm)+uB(w2Y*Ly+BF5KBM;SvifX1C<4*!&*^*1YdNZHhTfchwv_P4{21P4gVruXdN!r1VcKoNjG&JUu)=dltOk zH8%M|x^AO(fxi9(;NDWEAO*d64|$&rs*KFP-Tr*C0xA0f9hgk4g~&h$mB$MON~0lk zB|ZS1vT>pg_@)};b=K*g1XU&~HO7uDH?^CMmzR5P>)#C7-_gIox03+=Fu|QJ?!N*U z!=ac=lP(BiP|ygxlAiSa5`o*SM^dOxMukDE-t2}H7p6=L@jHB|1+#3h6V2T9u4dJTwp$^TtYeBvAf#;E09w&AR{?ntOND21cU2d)Mja>#;y2ab(oS{nLoKi)5RDY!^WC zj1b}+|A1p9`M%}!6M5xPi4$B9=DFr}d>`!BuKbPOBVBzg7oL)~z~jLMfWqD0_&Fxn zHy#ymBFJCA;2x6=gD3fx23=Agb7J_N1kDZH6R6@^#z0rebCJ>ag3<*XaYyL|oYycI z=eOZp*{Ga*ZZFAilv~fWFU1R~E@Ry=GX}7S>5i@OK6f0BQ>C*hKhmsKmkPe}XDo-c z#0QwVY5%#GZSf^HaM|ms6RT%RO*$mmZQ_CY)h?@5)~OJjM?}@=n@7=Kt&i92Es$iK z`xGhtVcpPD?Sn5b{8T-0?+#Kn>z1c&HVT(Lo?h-4hzLz-zNCaDTz0_PEf?IGncR4K zj0=i$CyUl`Wa(d-#y#Bq^L69lPpuZ*J=yHBd23UX_dx|ie!1zFxi#uHsJJm45z39e z7>uTy zKlF`kdh?X8Kl@~N@}f0~Z|2Xp<-@!(J>X-D;@NrGlYg!EG${F_SQ*Sb*70=a-`SYP z2J1EriI^co{Uw%4aDec0h!?!$PTS8Ij$0ejp?;Ox%ED_JPGz23i^?NY4G%^t(B{FK zNQuvqO&^{iofyQ6+P0n0vYf+Cr`dIx^OmG*Yut6 z%i@M1E+K7PW`j}e9$Iv( zcEXZ(FtE-YJi-T~LwkZ5P;Zva>8sYFu5Teu}btS&n@3 zHu3onagVq0rDd7d71MPs8~Q6#;R^3LDV$?wM1hL-agnOD?e6|k=9B@z(=HZ6?Tq%O zo%a0n=uUa~IFmLzfmVo`<*6yx_B?mDX(Y@+k;ZaKF{gYHCR4I4YYZLx>Ll4Jh-B=0 zjBa_2fC-CUy?w)&MT>6Cz7TC#F&%NnlHBH1h`!%q_8-czZ;9YTM{*<2mMnQIQGz!R$7~M=#}Vck+jwh7m@%`TaF{yI=7kP%ID~qU8z_Lwv^1PGDnR|gk-9zq>V(W_6p>_6X&ikfbTAmolJfr5WnwTw5ih{fu%gSA-pit~pU2$ip{M#}kdz>w zFKYjQ`<@LrNpb(3aNh$O&6A0PI=P}+5A3T+9trHUh=7tXLUr# z7$)ym_(W;|d8L(!LF!fH3*~u+9J0RH<{#oDXzmga+R0Jrr{bHtpvSJQi=kkhh}?XF z@7uoL;Z1THuKzx^SS9n&Ho6mYTNQ5$Xp0)6r zS{@dkW86L^Yuz^O$ui&bkm`HW>kPtO4DYfD?&Po~q`UgsA1S|7P3}G45I7Iq=OkuP zV~x8=b<3~Rw`s`XNEuW2`!(;eB$;=9p!xZ_%+}eGd*fE|mGgrN&F4#}=Nw|B6Si64 zY~o+oQumb?XE}3EixDr*o4z%!Ow%KhUAPw(E;J?j2y zA;YR$k5!4$ue2r2mFPU1Yyh1IOp9oo`tDODCT^t&QXGK6+F{$2u49>zX!uhdrEt8( zHeNk0LTMiln`D!2ZWH(YqP+-JD$yy%;qAI2*=NyS9=KT#f&&ANl?!Z1CRm7ERazt% zRby$$bTbScULGJg15%Gn(2S!M0bmy6<%}p@!{iP{51iLFlo7z*E`r=leq#Z^EXUCr z#CB`JPMbIo;1RAG!eKfHpwVC_!A_5N9c;dxdR-A(+F0QgxBx?>7czlu5ciy2&+rVv zL&o|@zySBk5bqLm5S| zj3nK#as#h4T}?Fj5eE2vq$}VHzm=vtBchj+-0>_t>X9eb&Jik*i}OqFEbxTzpuyKs zMsKfoJGo*V9E}Xk!(Vt1UZBI@$92E0h9-F8=sbXexK1P*oNyNPoZIL-7OaOcOz?!< zLxWT8y4e`QE6<`{Y#U@G(@JBo8bv*`+fWVwQAKO`z9j0?S(H&YKFAa6g8{0;;fC+N zzmxA_8;qh`=%QIM5&#U`w17vZk+Elbk=LP=+t6VFbVcrINjicqs*oI*vf9L>Bxq(1)q@6*8hYHRDg>Zk?-SF(z_BsMS zH~@6P9H!p-AhAH#O##zz*xhgr0HA*aJF!E5H;ACVIjH^arU(*&Im>`6;i%Pd40J!t zkys0l2p@y%ipg<43_qBUBEf@fhT16#?|yK8{=xOBF6rkFp3m6Fv$uKF5mzLO|5Oop z05GZI%}2x9*C@hA!?X}k9bSZDrs4s&8<$ovt>jLFfz4&b?-IBH5WN+i{&gJBAP?cWXQ0lF4)iX4u3Nsh#A)I0Qf_Ou7x1d zzvG@B4V&8I4Z;w7D_~yqU0PJ6xlrWYupudOR3eU`2fJ$k1F<*XF9Nf^@`^oY@NsJpA7o&p<=0a2%kTiffJ3Ar>^UF8O@=3us z{v2vP8{vk9Ff{{JGlk@OMJB}}a7Yc>70VEXyVuW0Ea+?%0Fa%PrV`d#?422t5<#BT(p-1=!E0gn zBwIUVeI1>KVBly~bZWTO{`;{W8R5j`~E$PTzQ1_;@;g0%ed-Xnb52C$Lf&H~Q`^moPX&8?FsSy0Ryai7a_?8zsdvN4^%wsBk)+=+v0KX=pqP}V`IwiosHZS=z{dR{D%A9 zV`zq~S7A>+|K?M2bT^*mwsQOzuS_LS(I7XABBEI*9bktuXyHDXXo6TXp7x8=#X`A05iWN`0bGl49=-^f z5Ga2F+yWCBQsks!g*zQ_pg#pET45!Mz;eD(Y77up28gI4K|c+5{^0j*YtVl=uY`n) zk(>jIz@kLBd^T7v2qB7zL>GZ2-5izSSZNAKhJhf~1!iSmpeDjuNdz={!2?M^AI)7N z(UONO*Qe2jHOF%rau zp5UfPK>J2HCPc!TU4pyt;~Q@4@lmXiORzL&Kg!iVup*oS>b`>og6ucrJws%5gt@1H z?dV+{D1e*+;gW9@wZ{@NBn8_!-8Km*1T9^{xXY2ifeaAkBAi4KC`vD?1n*A2tvfnN z_-`5xc8u^yfmm2UWX2H|ju8@8Sh_*6kj5#VE|6roYj6=x%<8}C-(AKOk>WS#KC^#N8x1R+XsO1x^E zMWQ8I{O7&|FG@6=yh4`-qVG$oRwS;eJ3>ll=@#&9dY)3b-&@^0-Hq4V4hcts>vS3G zbUJkO1W(Pubr<5TZr*imb2>_!g=b&FdcU`)JB^n>*Lt6#SIg+l)<(}CS2uoA*2hX6 zJC@d`yf=n4W`B-)#g?phmpaZZZOlux&z8=P7cR_|deIwioGExuKieGA^ByjQE_H4$ zD0HydehTvIguiz9oJVCefCo#|9M{-INbcBh=23c=g7k6B*FW% zaqFmXb7INoY;^Ou&~tw@Z)s^`Ut=2*L{0CpjkrgJxR?grSeneLrE1##-RDbF<~up< zduhv8{oI%Fk{|WAZKf-J%wxVR?mNuEJFGAK=o9@IzHNg9F}+ngTmydKshthg=_@bL z&5`fey|7TU|NY`PZCT2$fP0G2*bx7{U1-`M)DaLX+x>0;On%;#l)ftNj+JiO<@W*T zMf}l-$D+Rlq&4?MQvDS!b|n(8UMuszo%>kjn!ntO$FhmE%I3t*VKuyg}>t7SoU zsc{-PzCl}p8WdSJRL#Hpp}~K{;3r{hO%4apaj*&il71^o18^pZ>`Hn};jXZXsUCTP zLKsZVSgod{CqXZy{iAb2ViGUo2SD^UkAyyPBwWajOA30Bj$WnNNBSHkUM}Bb4$WQ* z!8aWpw$^6TM8CeM1Z55i7 zVR;gH1)~JC2lCY>G@TR#hkh6UsR@PTkDYk#gjT+nZE8ER`8ODzNvSwnhnhAVbJ^nxayp0}ZiFw&sWS zg0ACW3JT4M8V9)!;_Fj6IdtGk27v20d~J+L1q2`swP^|z*%wrD|Q_(~LIXE5$>BBh^1T5Y2I8H^htKDYV% ze40c8e#HMlz4%>3HKv`F0ImC07S&Yc8^ zrQUkikE@2MR}r1<9wfJ(7->4^>t8DtuV*U0+LZ9v=Nrtu;l!C`Z3b9?@+%+yq15ia z(8oDdq}SZx~cdwPs(|S_z-+^8H6rOQm4j}gmX;g6O6a>N}`Z8Z)=QffWA@}gdv zM%hKnTcrJt;P6h5E70wDF+E`At8h-($+2+u;|XPtH#nvz9(n$w(fQDLmDLsM zK+Xxlw~01S{zeCj)xrw1R8+zXZons2s7=!*Rv3!4e-tx*`m!pL&Gb$M%2G99^YK&e zhldY8B=ARxeX4q6BVJKY&$V9C2;P41DV~XIz3N9c^~1MK`7z?vzcijcDjUfT{Z!HU zQ*5*JqnT>)`;@E3pWfzsce@t+wc&h_i8p&A)!=IqBa(l*YwVG0j8sEYT3}qy(Ai#M z_2@RwlwEW?qp{jf8+9r_Qzu81xlzVtpF1%ks90{#M#iL2~8#=C*Ih_VXfysztPEZp!s?L#F+e<^)L?(K+*mfIbnfKC@ve zgYfDR#YgA2hvz&6x_{a02Lys|Z>fD5^b*Lb9yU)+ikdWwZ@3A5kRcf}b$eM$aUvoo zj4a}EYw^o0LH}H)>xt&s?YaA!jdYOv`i*_Ri8-GR7CbT<;ujJZ!pOhExDvjM_V}5c z%%;&~e_b(q>OdaF(NJzLmAN|{4u8BtU-OG60)p8pfNULX&dd*hd;qd!J%8ABBZ|E8N zpX$g?Ur^-U?~5DXurM1b(Aq1T3o|{QMC;N=DLVGNNMiFTo%ciDfZVB*(U!kn+t2^1 z<}GlCv@-cKM4U47Q3;L9fTYU*GgAbF$x(-GDb86V&Z-SCjo@RdAnK{{GrcNm7m}@r zHhIR+@>Z#x)wCkU;$1#Vlm~(a^EP&VR!^aoUC(b^E5`N)!2J`6uUygMa+EHJKm2!3Pv^Go?$FC-H!a^w1L((A@*At~!(W4Ei1V+O9fN!kCpVeKIIrZRI${G&C@ zg(4dr1S~5Oe%*Amkx44$zAsuF((Ur3irTpZ&dmOx#~Pi-nOZL_=0&CNDD^Y`iG+yu zwO{)D)RlSkVIq8&y9cAps`D6i`Lz?%f9R?(MLR)VG!!NVp3YQ}O5X8nPAPxCy(^Gy z6)-Q`mfqp>@J{CKxCbikDkcFF$p8~^%&r)Rs*ZxicHul6V?e@^hE%iIM^zad>afSqCQtP zfY||tNF=vqrKX79mE2W?Yx^wwHxW?K>Gs&d)oZkONS~a`7;w(=pLy;Oqb%!e#x}Yw zpa6QEby#dfpM^kX4AB!B=88Ihb3mrxeYe~pT)&GB0h;uc>%s=Mu`VP9`Yfw*M(mq0 zaj28>BO>-$#TzO|2||fVxu>KN){&~brV4;JM`XlCI0FmRDuXzr+bm6;Hn|G#=t*l* zABmo_s2q&=$cRUWqxSjedyr9n?oa2DC49v@9by6QrZ7!k5c4Gmc*Lt`E{vJ%9hPDK zspiAU zMB-JRZ$knl$OF%V9_J!x?_Z0({6qV`e2(b($|8RhYX+-C-n0Y}*)H%S)?2@C9=8ptU8-8bb(Lxzl184#{@R-WF?^%!jWY;0^ z41q;04A%C;+BKF$9V$WJjm_-SPtUIg__+X)q7q8ni9`sxiw+*v^mW8CO$#bwvJx$x zIafOk`M|pA7FK6@nUPq+X1cZ%zov@hO~pD0X!wN+2g8^94?112ezjm1 + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/jpegview/build.bat b/kernel/branches/hd_kolibri/apps/jpegview/build.bat new file mode 100644 index 0000000000..1048ba3e05 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/jpegview/build.bat @@ -0,0 +1,3 @@ +echo lang fix en >lang.inc +fasm jpegview.asm jpegview + diff --git a/kernel/branches/hd_kolibri/apps/jpegview/filelib.asm b/kernel/branches/hd_kolibri/apps/jpegview/filelib.asm new file mode 100644 index 0000000000..622eb13b7b --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/jpegview/filelib.asm @@ -0,0 +1,77 @@ +file_handler: + .operation=0 + .position=4 + .reserved=8 + .n_bytes=12 + .bufer=16 + .name=20 + .st_size=20+1024 + +open: ;esi=name_string + ;retorna eax + pushad + mov ecx,file_handler.st_size + call mallocz + mov [esp+28],edi + push edi + mov ecx,1024 + add edi,file_handler.name + call movedata + pop edi +; test if file exists + lea ebx,[edi+file_handler.operation] + mov byte[ebx],5 + mov dword[ebx+16],fileattr + mov eax,70 + int 0x40 + cmp eax,2 + jz .virtual + test eax,eax + jnz close.b +@@: + clc + popad + ret +.virtual: + mov byte [fileattr], 0x10 + jmp @b + +close: + pushad + .b: + mov edi,[esp+28] + call free + popad + xor eax,eax + ret + + +read: ;(f,bufer,nbytes) eax,edi,ecx ncr + ;retorna bytes leidos en ecx + pushad + lea ebx, [eax+file_handler.operation] + mov byte [ebx], 0 + mov [ebx+12], ecx + mov [ebx+16], edi + mov eax, 70 + int 0x40 + cmp ebx, -1 + sbb ebx, -1 + mov eax, [esp+28] + add [eax+file_handler.position], ebx + mov [esp+24], ebx + popad + ret + +ftell: mov edx,[eax+file_handler.position] + ret +lseek: ;eax=file edx=pos + mov [eax+file_handler.position],edx + ret +skip: ;eax=file edx=bytes to skip + add [eax+file_handler.position],edx + ret + + + + diff --git a/kernel/branches/hd_kolibri/apps/jpegview/jpegdat.asm b/kernel/branches/hd_kolibri/apps/jpegview/jpegdat.asm new file mode 100644 index 0000000000..d06f21010f --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/jpegview/jpegdat.asm @@ -0,0 +1,22 @@ +modes: +dd mcu100,color100,8,8 ;monocromo +dd mcu111,color111,8,8 +dd mcu211,color211,16,8 +dd mcu411,color411,16,16 + +zigzag: +db 0,0, 4+1,0, 32,1, 64,1, 36,2, 8+1,0, 12+1,0, 40,4 +db 68,2, 96,1, 128,1, 100,2, 72,4, 44,8, 16+1,0, 20+1,0 +db 48,16, 76,8, 104,4, 132,2, 160,1, 192,1, 164,2, 136,4 +db 108,8, 80,16, 52,32, 24+1,0, 28+1,0, 56,64, 84,32, 112,16 +db 140,8, 168,4, 196,2, 224,1, 228,2, 200,4, 172,8, 144,16 +db 116,32, 88,64, 60,128, 92,128, 120,64, 148,32, 176,16, 204,8 +db 232,4, 236,8, 208,16, 180,32, 152,64, 124,128, 156,128, 184,64 +db 212,32, 240,16, 244,32, 216,64, 188,128, 220,128, 248,64, 252,128 + +k: +dd 1.41421,1.84776,1.08239,-2.6131 +k2: +dd 0.3535534,0.49039264,0.46193953,0.415734806 +dd 0.3535534,0.277785116,0.191341716,0.0975451609 + diff --git a/kernel/branches/hd_kolibri/apps/jpegview/jpeglib.asm b/kernel/branches/hd_kolibri/apps/jpegview/jpeglib.asm new file mode 100644 index 0000000000..fdcabc5865 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/jpegview/jpeglib.asm @@ -0,0 +1,1181 @@ +;405 412 586 +; +; +bufer_size=1024*16+2 +fichero=4 +mcu_ptr=8 +color_ptr=12 +estado=16 +color_c=17 +nbits=color_c +idct=20 +tmp_bits=24 +actable=28 +matriz_limit=32 +sourcebits=36 +sourcebits_index=40 +sourcebits_limit=44 +qt_ptrs=48 +ht_dc_ptrs=64 +ht_ac_ptrs=80 +matrices=96 +tmp_bufer=100 +x_org=104 +y_org=108 +x_mcu=112 +y_mcu=116 +x_size=120 +y_size=124 +x_org2=128 +y_org2=132 +x_mcu2=136 +y_mcu2=140 +x_size2=144 +y_size2=148 +q_ptr=152 +dc=164 +position=204 +draw_ptr=208 +struct_size=212 + +jpeg_info: ;fichero en eax + ;retorna ebp + xor ebp,ebp + pushad + mov ebp,esp + mov ecx,6 + sub esp,ecx + mov edi,esp + call read + pop dx + cmp dx,0d8ffh + je .l1 + mov esp,ebp + popad + ret + .l1: push eax + mov ecx,struct_size + call mallocz + mov [edi],ebp + mov ebp,edi + pop dword [ebp+fichero] + pop ax + pop cx + jmp .l3 + .l2: mov ebx,[ebp+tmp_bufer] + add ebx,[ebx-4] + mov cx,[ebx-2] + mov ax,[ebx-4] + .l3: push .l2 + xchg cl,ch + add cx,2 + cmp ch,3 + jnc .l4 + cmp al,0ffh + jne eoi + cmp ah,0dbh + je dqt + cmp ah,0c4h + je dht + cmp ah,0c0h + je sof0 + cmp ah,0dah + je sos + cmp ah,0c2h + je eoi + cmp ah,0c9h + je eoi + cmp ah,0d9h + je eoi + .l4: lea edx,[ecx-4] + xor ecx,ecx + mov eax,[ebp+fichero] + call skip + mov ecx,4 + call READ + cmp ecx,[edi-4] + jne eoi + ret + +eoi: + mov esp,[ebp] +; do not close file - this will be done by caller + and dword [ebp+fichero], 0 + call jpeg_close + popad + xor ebp,ebp + ret + +jpeg_close: + test ebp,ebp + jz .l2 + pushad + mov eax,[ebp+fichero] + call close + mov edi,[ebp+sourcebits] + call free + lea esi,[ebp+qt_ptrs] + mov ecx,14 + .l1: mov edi,[esi] + add esi,4 + call free + loop .l1 + mov edi,ebp + call free + popad + .l2: ret + +dqt: call READ + mov esi,edi + lea eax,[edi+ecx] + push eax + .l1: xor eax,eax + lodsb + cmp al,4 + jnc eoi + lea ebx,[ebp+qt_ptrs+eax*4] + test dword [ebx],-1 + jnz eoi + mov ecx,64 + xor eax,eax + sub esp,128 + mov edi,esp + .l2: lodsb + stosw + loop .l2 + mov ecx,256 + call malloc + mov [ebx],edi + mov eax,esi + mov esi,esp + pushad + mov ebp,zigzag + fninit + mov cl,64 + xor eax,eax + .l3: fild word[esi] + mov al,[ebp] + and al,-2 + add ebp,2 + add esi,2 + mov ebx,eax + and ebx,28 + fmul dword [ebx+k2] + mov ebx,eax + shr ebx,3 + and ebx,4+8+16 + fmul dword [ebx+k2] + fstp dword [edi+eax] + dec cl + jnz .l3 + popad + mov esi,eax + add esp,128 + mov eax,[esp] + sub eax,esi + jc eoi + cmp eax,4 + ja .l1 + jne eoi + pop eax + ret + +sof0: call READ + cmp byte [edi],8 + jne eoi ;precision + mov ax,[edi+1] + xchg al,ah + mov [ebp+y_size],ax + mov ax,[edi+3] + xchg al,ah + mov [ebp+x_size],ax + mov al,[edi+5] ;ncomponentes + mov cl,al + mov [ebp+color_c],al + mov edx,modes + dec al + jz .l1 + dec al + dec al + jnz eoi + mov al,[edi+10] + mov ah,[edi+13] + cmp ax,1111h + jne eoi + mov al,[edi+7] + add edx,16 + cmp al,11h + je .l1 + add edx,16 + cmp al,21h + je .l1 + add edx,16 + cmp al,22h + jne eoi + .l1: lea ebx,[ebp+q_ptr] + lea esi,[ebp+qt_ptrs] + mov [ebp+mcu_ptr],edx + .l2: movzx eax,byte [edi+8] + add edi,3 + cmp al,4 + jnc eoi + lea eax,[eax*4+esi] + mov [ebx],eax + add ebx,16 + dec cl + jnz .l2 + ret + +READ: mov eax,[ebp+fichero] + mov edi,[ebp+tmp_bufer] + movzx ecx,cx + call mresize + mov [ebp+tmp_bufer],edi + jmp read + +dht: call READ + mov esi,edi + lea eax,[edi+ecx] + push eax + .l1: lodsb + mov edi,esi + mov ebx,3+16 + and bl,al + cmp bl,al + jne eoi + shr bl,2 + and al,3 + or bl,al + lea ebx,[ebp+ht_dc_ptrs+ebx*4] + test dword [ebx],-1 + jnz eoi + mov cl,15 + mov al,[edi] + .l2: inc edi ;calcular numero de codigos + add al,[edi] + jc eoi + dec cl + jnz .l2 + movzx ecx,al + lea ecx,[ecx*4+2] + call malloc + mov [ebx],edi + call arbol_hf + mov eax,[esp] + sub eax,ebx + jc eoi + mov esi,ebx + cmp eax,4 + ja .l1 + jne eoi + pop eax + ret + +arbol_hf: ;esi=ht edi=memoria para el arbol + ;retorna en ebx el final de ht + ;codigos: bits 0-3=nbits del siguiente numero + ; bits 4-7=numero de zeros + ; bits 8-14=longitud de este codigo o error si =127 + ; bit 15=codigo/puntero + push ebp + lea ebx,[edi-2] + add ebx,[ebx-2] + mov word [ebx],-1 ;codigo de error si encontrado + push ebx + push esi + lea ebx,[esi+16] + mov ebp,esp + xor ecx,ecx + push edi + push ecx + add edi,2 + mov dx,1 + add dh,[esi] + jz .l3 + jmp .l2 + .l1: push edi + push ecx + add edi,2 + .l2: inc cl + cmp cl,dl + jc .l1 + mov al,[ebx] + inc ebx + mov ah,128 ;marca de codigo + or ah,dl + cmp edi,[ebp+4] + jnc .l5 + stosw + cmp esp,ebp + jnc .l5 + pop ecx + pop esi + lea eax,[edi-2] + sub eax,esi + mov [esi],ax + dec dh + jnz .l2 ;ncodigos + mov esi,[ebp] + .l3: inc esi + inc dl + cmp dl,17 + jnc .l4 + add dh,[esi] + jz .l3 + mov [ebp],esi + jmp .l2 + .l4: lea esp,[ebp+8] + pop ebp + ret + .l5: mov ebp,[ebp+8] + jmp eoi + +sos: sub ecx,4 ;a continuacion vienen los datos de la imagen + call READ + mov eax,[ebp+fichero] + call ftell + mov [ebp+position],edx + mov esi,edi + lea edi,[ebp+q_ptr] + lodsb ;numero de componentes + sub [ebp+color_c],al + jnz eoi + mov dh,al + .l1: mov ebx,[edi] + mov eax,[ebx] + stosd + lodsw + mov cl,ah + and eax,0f00h + and ecx,0f0h + shr eax,6 + shr ecx,2 + lea ebx,[ebp+ht_ac_ptrs+eax] + mov eax,[ebx] + lea ebx,[ebp+ht_dc_ptrs+ecx] + mov ecx,[ebx] + test eax,eax + jz eoi + test ecx,ecx + jz eoi + stosd + mov eax,ecx + stosd + add edi,4 + dec dh + jnz .l1 + mov edx,[ebp+mcu_ptr] + cmp edx,modes + jne .l2 + lea esi,[ebp+q_ptr] + lea edi,[ebp+q_ptr+32] + movsd + movsd + movsd + .l2: + mov esi,edx + push dword [esi] + pop dword [ebp+mcu_ptr] + push dword [esi+4] + pop dword[ebp+color_ptr] + push dword [esi+12] + pop dword [ebp+y_mcu] + push dword [esi+8] + pop dword [ebp+x_mcu] + mov ecx,64*18 + call malloc + mov [ebp+matrices],edi + mov ecx,bufer_size + call malloc + mov [ebp+sourcebits],edi + mov esp,[ebp] + mov [esp+8],ebp + popad + ret + +jpeg_display: + test ebp,ebp + jnz .inicio + ret + .inicio: + pushad + mov [ebp],esp + mov eax,[ebp+fichero] + mov edx,[ebp+position] + call lseek + mov edi,[ebp+sourcebits] + add edi,bufer_size + mov [ebp+sourcebits_index],edi + sub edi,2 + mov [ebp+sourcebits_limit],edi + mov edi,[ebp+matrices] + mov [ebp+matriz_limit],edi + xor eax,eax + mov [esp+8],eax + mov [ebp+estado],eax + mov [ebp+tmp_bits],eax + mov [ebp+dc],eax + mov [ebp+dc+16],eax + mov [ebp+dc+32],eax + + mov eax,[ebp+y_mcu] + mov ecx,[ebp+y_org] + sub ecx,eax + mov [ebp+y_org2],ecx + mov [ebp+y_mcu2],eax + push dword [ebp+y_size] + pop dword [ebp+y_size2] + .l3: push dword [ebp+x_org] + pop dword [ebp+x_org2] + push dword [ebp+x_mcu] + pop dword [ebp+x_mcu2] + push dword [ebp+x_size] + pop dword [ebp+x_size2] + mov eax,[ebp+y_mcu2] + add [ebp+y_org2],eax + sub [ebp+y_size2],eax + jnc .l4 + add eax,[ebp+y_size2] + jnz .cont + mov [esp+8],ebp + popad + ret + .cont: + mov dword [ebp+y_size2],0 + mov [ebp+y_mcu2],eax + .l4: + mov eax,[ebp+x_mcu2] + sub [ebp+x_size2],eax + jnc .l5 + add eax,[ebp+x_size2] + jz .l3 + mov dword [ebp+x_size2],0 + mov [ebp+x_mcu2],eax + call dword [ebp+mcu_ptr] + mov eax,[ebp+x_mcu] + mov ecx,[ebp+x_mcu2] + mov edx,[ebp+y_mcu2] + call recortar + jmp .l6 + .l5: + call dword [ebp+mcu_ptr] + mov ecx,[ebp+x_mcu2] + mov edx,[ebp+y_mcu2] + .l6: + mov eax,[ebp+x_org2] + mov ebx,[ebp+y_org2] + call dword [ebp+draw_ptr] + add [ebp+x_org2],ecx + mov ax,[ebp+estado] + test al,15 + jz .l4 + cmp ah,8 + jnc .l4 + xor edx,edx + mov [ebp+tmp_bits],edx + mov [ebp+dc],edx + mov [ebp+dc+16],edx + mov [ebp+dc+32],edx + add dword [ebp+sourcebits_index],2 + and word [ebp+estado],0c0h + test al,32 + jz .l4 + jmp .l3 + +color100: + push edi + .l1: lodsw + mov dl,ah + mov ah,al + stosw + mov ah,dl + stosb + mov al,dl + stosb + stosw + dec cl + jnz .l1 + pop edi + ret + +color111: + push edi + .l1: lodsw + mov bx,[esi+62] + mov dx,[esi+126] + xchg ah,bh + xchg ah,dl + xchg ah,bl + stosw + mov ax,bx + stosw + mov ax,dx + stosw + dec cl + jnz .l1 + pop edi + mov ecx,64*3 + jmp ybr_bgr + +color411: + push ebp + push edi + lea ebp,[esi+ecx*8] + .l1: push ecx + mov ax,[esi] + mov cx,[ebp] + mov dx,[ebp+64] + add ebp,2 + xchg ch,dl + mov bx,ax + mov ah,cl + mov bl,ch + mov [edi],ax + mov [edi+2],bx + mov [edi+4],cx + mov ax,[esi+8] + mov bh,ah + mov ah,cl + mov [edi+48],ax + mov [edi+48+2],bx + mov [edi+48+4],cx + mov ax,[esi+2] + mov bx,ax + mov ah,dl + mov bl,dh + mov [edi+6],ax + mov [edi+2+6],bx + mov [edi+4+6],dx + mov ax,[esi+8+2] + mov bh,ah + mov ah,dl + mov [edi+48+6],ax + mov [edi+48+2+6],bx + mov [edi+48+4+6],dx + pop ecx + add edi,12 + dec ecx + add esi,4 + test cl,1 + jnz .l1 + add esi,64-8 + test cl,2 + jnz .l1 + sub esi,128-16 + add edi,48 + test cl,15 + jnz .l1 + add esi,64 + test cl,cl + jnz .l1 + pop edi + pop ebp + mov ecx,64*4*3 + jmp ybr_bgr + +color211: + push ebp + push edi + lea ebp,[esi+ecx*4] + .l1: push ecx + mov ax,[esi] + mov cx,[ebp] + mov dx,[ebp+64] + add ebp,2 + xchg ch,dl + mov bx,ax + mov ah,cl + mov bl,ch + mov [edi],ax + mov [edi+2],bx + mov [edi+4],cx + mov ax,[esi+2] + mov bx,ax + mov ah,dl + mov bl,dh + mov [edi+6],ax + mov [edi+2+6],bx + mov [edi+4+6],dx + pop ecx + add edi,12 + dec cl + add esi,4 + test cl,1 + jnz .l1 + add esi,64-8 + test cl,2 + jnz .l1 + sub esi,128-8 + test cl,cl + jnz .l1 + pop edi + pop ebp + mov ecx,64*3*2 + jmp ybr_bgr + + +mcu411: lea ebx,[ebp+q_ptr] + call hufdecode + lea ebx,[ebp+q_ptr] + call hufdecode +mcu211: lea ebx,[ebp+q_ptr] + call hufdecode +mcu111: lea ebx,[ebp+q_ptr] + call hufdecode + lea ebx,[ebp+q_ptr+16] + call hufdecode +mcu100: lea ebx,[ebp+q_ptr+32] + call hufdecode + mov esi,[ebp+matrices] + mov dword [ebp+matriz_limit],esi + mov ecx,32 + lea edi,[esi+64*6] + jmp dword [ebp+color_ptr] + +cargar_bits: ;edx=bits,cl=nbits, + ;bp=data struct + ;cr: cl,edx,eax,si + ;ncr bx,bp,di,ch + + mov esi,[ebp+sourcebits_index] + cmp esi,[ebp+sourcebits_limit] + jnc .l6 + movzx eax,byte [esi] + inc esi + add cl,8 + cmp al,-1 + je .l2 + mov ah,al + lodsb + add cl,8 + cmp al,-1 + je .l2 + .l1: ror eax,cl + or edx,eax + mov [ebp+sourcebits_index],esi + ret + .l2: lodsb + test al,al + jnz .l3 + mov al,-1 + call .l1 + cmp cl,16 + jc cargar_bits + ret + .l3: sub esi,2 + sub cl,8 + sub al,0d0h + cmp al,8 + jc .l4 + sub al,9 + mov al,63 + jz .l4 + mov al,127 + .l4: inc al + or [ebp+estado],al + movzx eax,ah + jmp .l1 + .l5: mov [ebp+sourcebits_limit],edi + mov word [edi],0d9ffh + popad + jmp cargar_bits + .l6: ;read file + pushad + mov ecx,bufer_size-2 + mov edx,[ebp+sourcebits_limit] + mov edi,[ebp+sourcebits] + mov ax,[edx] + sub edx,edi + stosw + sub esi,edx + mov [ebp+sourcebits_index],esi + cmp edx,ecx + jne .l5 + mov eax,[ebp+fichero] + call read + lea ecx,[edi+ecx-2] + mov [ebp+sourcebits_limit],ecx + popad + jmp cargar_bits + + +hufdecode: ;si->dctable [bp+20]->actable di->outbufer edx->bits cl->bits en edx + + + ;[bp+24]->sourcebits + ;[bp+22]=outbufer+128 + ;[bx] q ptr para aa&n + ;[bx+2] a ptr + ;[bx+4] d ptr + ;[bx+8] dc componente + fninit + push dword [ebx] + mov cl,[ebp+nbits] + mov edx,[ebp+tmp_bits] + cmp cl,16 + jnc .l1 + call cargar_bits + .l1: mov eax,[ebx+4] + mov esi,[ebx+8] + mov [ebp+actable],eax + movzx eax,word [esi] + add esi,2 + .l2: add edx,edx + jnc .l3 + add esi,eax + .l3: lodsw + test ax,ax + jns .l2 + ;codigo encontrado + and ax,7f0fh + mov edi,[ebp+matriz_limit] ;arrays + sub cl,ah + jns .l4 + fldz + .error: + xor ecx,ecx + or byte [ebp+estado],32 + jmp .l12 + .l4: cmp cl,al + jnc .l5 + push eax + call cargar_bits + pop eax + .l5: sub cl,al + mov ch,cl + mov cl,al + mov eax,edx + shl edx,cl + sar eax,17 + xor ax,8000h + xor cl,15 + sar ax,cl + mov cl,ch + mov ch,2 + add ax,8000h ;incrementar si negativo + adc ax,8000h + add [ebx+12],ax + fild word [ebx+12] + push ecx + mov ecx,64 + xor eax,eax + add [ebp+matriz_limit],ecx + rep stosd + pop ecx + sub edi,64*4 + mov ebx,[esp] + fmul dword [ebx] + .l6: cmp cl,16 + jnc .l7 + call cargar_bits + .l7: mov esi,[ebp+actable] + movzx eax,word[esi] + add esi,2 + .l8: add edx,edx + jnc .l9 + add esi,eax + .l9: lodsw + test ax,ax + jns .l8 + ;codigo encontrado + and ah,127 + xor ebx,ebx + sub cl,ah + js .error + or bl,al + jz .l12 + and al,0f0h + shr al,3 + add ch,al + js .error + and bl,0fh + jz .l11 + cmp cl,bl + jnc .l10 + call cargar_bits + .l10: sub cl,bl + xchg bl,cl + mov eax,edx + shl edx,cl + sar eax,17 + xor cl,15 + xor ax,8000h + sar ax,cl + add ax,8000h ;incrementar si negativo + adc ax,8000h + mov cl,bl + mov bl,ch + mov [ebp+tmp_bits],ax + mov ax,[ebx+zigzag] + mov ebx,[esp] + fild word [ebp+tmp_bits] + or [ebp+idct],ax + and eax,11111100b + fmul dword [ebx+eax] + fstp dword [edi+eax] + .l11: add ch,2 + jns .l6 + .l12: mov [ebp+nbits],cl + mov [ebp+tmp_bits],edx + xor ebx,ebx + add esp,4 + xchg ebx,[ebp+idct] + cmp ch,2 + je idctf1 + fstp dword [edi] + test bh,0feh + jnz idctf3 +idctf2a: test bh,1 + mov esi,edi + jz .l1 + test bl,1 + jnz idctf3 + push idctf2b + jmp idctf3b + .l1: call idctf3a + mov cl,4 + call limit + mov eax,[edi-8] + mov edx,[edi-4] + mov cl,7 + .l2: mov [edi],eax + mov [edi+4],edx + add edi,8 + dec cl + jnz .l2 + ret + +idctf1: fistp word[edi+64] + mov ax,128 + add ax,[edi+64] + jz .l2 + test ah,ah + jz .l1 + mov al,-1 + js .l2 + .l1: mov ah,al + stosw + stosw + mov eax,[edi-4] + mov ecx,15 + rep stosd + .l2: ret + +idctf3: mov bl,8 + mov esi,edi + .l1: rcr bh,1 + jc .l3 + mov eax,[esi] + test eax,eax + jz .l4 + mov cl,7 + .l2: add esi,32 + mov [esi],eax + dec cl + jnz .l2 + sub esi,32*7-4 + dec bl + jnz .l1 + jmp .l5 + .l3: call idctf3b + .l4: add esi,4 + dec bl + jnz .l1 + .l5: mov esi,edi + mov cl,8 + .l6: call idctf3a + add esi,32 + add edi,16 + dec cl + jnz .l6 + sub edi,128 + mov esi,edi + mov cl,32 +limit: mov dx,[esi] + mov bx,[esi+2] + add esi,4 + add dx,128 + add bx,128 + test dh,dh + mov ax,dx + jz .l1 + mov al,0 + js .l1 + mov al,-1 + .l1: test bh,bh + mov ah,bl + jz .l2 + mov ah,0 + js .l2 + mov ah,-1 + .l2: stosw + dec cl + jnz limit + ret + +idctf2b: + mov dl,8 + .l1: fld dword[esi] + add esi,32 + mov ax,128 + fistp word [edi] + add ax,[edi] + test ah,ah + jz .l2 + mov al,0 + js .l2 + mov al,-1 + .l2: mov ah,al + stosw + stosw + stosw + stosw + dec dl + jnz .l1 + ret + +idctf3a: ;si(d float),di(w int) ncr +fld dword[esi+1*4] ;f1 ;t21=f1+f7 +fld st0 +fld dword[esi+7*4] ;f7 +fadd st2,st0 +fsubp st1,st0 ;t22=f1-f7 +fld dword[esi+5*4] +fld st0 ;f5 ;t23=f5+f3 +fld dword[esi+3*4] ;f3 +fadd st2,st0 +fsubp st1,st0 ;t20=f5-f3 +fld st0 +fadd st0,st3 ;t25=(t20+t22)*k2 +fmul dword[k+4] ;k2 ;t25,t20,t23,t22,t21 +fld st4 ;t7=t21+t23 +fadd st0,st3 ;t7,t25,t20,t23,t22,t21 +fld dword[k+12] ;k4 ;t6=k4*t20+t25-t7 +fmulp st3,st0 +fsub st2,st0 +fld st1 +faddp st3,st0 ;t7,t25,t6,t23,t22,t21 +fld st5 ;t5=(t21-t23)*k1-t6 +fsub st0,st4 +fmul dword[k] ;k1 +fsub st0,st3 +fstp st6 ;t7,t25,t6,t23,t22,t5 +fstp st3 ;t25,t6,t7,t22,t5 +fxch st3 +fmul dword[k+8] ;k3 ;t4=k3*t22-t25+t5 +fadd st0,st4 ;t22*k3+t5,t6,t7,t25,t5 +fsubrp st3,st0 ;t6,t7,t4,t5 +fld dword[esi] ;f0 ;t10=f0+f4 +fst st5 ;f0,t4,t5,t6,t7,f0 +fld dword[esi+4*4] ;f4 +fsub st6,st0 ;t11=f0-f4 +faddp st1,st0 +fld st0 ;t10,t10,t6,t7,t4,t5,t11 +fld dword[esi+2*4] ;f2 ;t13=f2+f6 +fadd dword[esi+6*4] ;f6 ;t13,t10,t10,t6,t7,t4,t5,t11 +fadd st2,st0 ;t13,t10,t0,t6,t7,t4,t5,t11 ;t0=t10+t13 +fsubp st1,st0 ;t3,t0,t6,t7,t4,t5,t11 ;t3=t10-t13 +fld st0 ;p3=t3-t4 +fsub st0,st5 +fistp word [edi+3*2] ;p3 +fadd st0,st4 ;p4=t3+t4 +fld dword[esi+2*4] ;f2 +fstp st5 +fistp word [edi+4*2] ;p4 ;t0,t6,t7,f2,t5,t11 +fld st0 ;p0=t0+t7 +fsub st0,st3 +fistp word [edi+7*2] ;p7 +fadd st0,st2 ;p7=t0-t7 +fistp word [edi] ;p0 ;t6,t7,f2,t5,t11 +fld st2 ;f2 ;f2,t6,t7,f2,t5,t11 ;t12=(f2-f6)*k1-t13 +fld dword[esi+6*4] ;f6 +fadd st4,st0 ;f6,f2,t6,t7,t13,t5,t11 +fsubp st1,st0 +fmul dword[k] ;k1 +fsub st0,st3 +fst st3 ;t12,t6,t7,t12,t5,t11 +fadd st0,st5 ;t1=t11+t12 +fst st2 ;t1,t6,t1,t12,t5,t11 +fadd st0,st1 ;p1=t1+t6 +fistp word [edi+2] ;p1 ;t6,t1,t12,t5,t11 +fsubp st1,st0 ;p6=t1-t6 +fistp word [edi+6*2] ;p6 ;t12,t5,t11 +fsubp st2,st0 ;t2=t11-t12 ;t5,t2 +fld st0 +fadd st0,st2 ;p2=t2+t5 +fistp word [edi+2*2] ;p2 +fsubp st1,st0 ;p5=t2-t5 ;t5,t2 +fistp word [edi+5*2] +ret ;p5 + + + + +idctf3b: ;si ncr +fld dword[esi+1*32] +fld st0 ;f1 ;t21=f1+f7 +fld dword[esi+7*32] +fadd st2,st0 ;f7 +fsubp st1,st0 ;t22=f1-f7 +fld dword[esi+5*32] +fld st0 ;f5 ;t23=f5+f3 +fld dword[esi+3*32] ;f3 +fadd st2,st0 +fsubp st1,st0 +fld st0 ;t20=f5-f3 +fadd st0,st3 ;t25=(t20+t22)*k2 +fmul dword[k+4] ;k2 ;t25,t20,t23,t22,t21 +fld st4 ;t7=t21+t23 +fadd st0,st3 ;t7,t25,t20,t23,t22,t21 +fld dword[k+12] ;k4 ;t6=k4*t20+t25-t7 +fmulp st3,st0 +fsub st2,st0 +fld st1 +faddp st3,st0 ;t7,t25,t6,t23,t22,t21 +fld st5 ;t5=(t21-t23)*k1-t6 +fsub st0,st4 +fmul dword[k] ;k1 +fsub st0,st3 +fstp st6 ;t7,t25,t6,t23,t22,t5 +fstp st3 +fxch st3 ;t25,t6,t7,t22,t5 +fmul dword[k+8] ;k3 ;t4=k3*t22-t25+t5 +fadd st0,st4 ;t22*k3+t5,t6,t7,t25,t5 +fsubrp st3,st0 ;t6,t7,t4,t5 +fld dword[esi] ;f0 ;t10=f0+f4 +fst st5 ;f0,t4,t5,t6,t7,f0 +fld dword[esi+4*32] ;f4 +fsub st6,st0 ;t11=f0-f4 +faddp st1,st0 +fld st0 ;t10,t10,t6,t7,t4,t5,t11 +fld dword[esi+2*32] ;f2 ;t13=f2+f6 +fadd dword[esi+6*32] ;f6 ;t13,t10,t10,t6,t7,t4,t5,t11 +fadd st2,st0 ;t13,t10,t0,t6,t7,t4,t5,t11 ;t0=t10+t13 +fsubp st1,st0 ;t3,t0,t6,t7,t4,t5,t11 ;t3=t10-t13 +fld st0 ;p3=t3-t4 +fsub st0,st5 +fstp dword[esi+3*32] ;p3 +fadd st0,st4 ;p4=t3+t4 +fld dword[esi+2*32] ;f2 +fstp st5 +fstp dword[esi+4*32] ;p4 ;t0,t6,t7,f2,t5,t11 +fld st0 +fsub st0,st3 ;p0=t0+t7 +fstp dword[esi+7*32] ;p7 +fadd st0,st2 ;p7=t0-t7 +fstp dword[esi] ;p0 ;t6,t7,f2,t5,t11 +fld st2 ;f2 ;f2,t6,t7,f2,t5,t11 ;t12=(f2-f6)*k1-t13 +fld dword[esi+6*32] ;f6 +fadd st4,st0 ;f6,f2,t6,t7,t13,t5,t11 +fsubp st1,st0 +fmul dword[k] ;k1 +fsub st0,st3 +fst st3 ;t12,t6,t7,t12,t5,t11 +fadd st0,st5 ;t1=t11+t12 +fst st2 ;t1,t6,t1,t12,t5,t11 +fadd st0,st1 ;p1=t1+t6 +fstp dword[esi+1*32] ;p1 ;t6,t1,t12,t5,t11 +fsubp st1,st0 ;p6=t1-t6 +fstp dword[esi+6*32] ;p6 ;t12,t5,t11 +fsubp st2,st0 +fld st0 ;t2=t11-t12 ;t5,t2 +fadd st0,st2 ;p2=t2+t5 +fstp dword[esi+2*32] ;p2 +fsubp st1,st0 ;p5=t2-t5 ;t5,t2 +fstp dword[esi+5*32] +ret ;p5 + +ybr_bgr: ;edi=bmp ecx=n_BYTES + ;retorna edi+=ecx + pushad + mov esi,edi + add edi,ecx + push edi + mov edi,[colortabla] + .l1: lodsw + movzx ebx,ah + movzx ebp,al + movzx eax,al + movzx ecx,byte[esi] + lea ebx,[ebx*4+edi+1024] + lea ecx,[ecx*4+edi] + add eax,[ebx] ;cb ;solo se usan 16 bits + mov edx,[ebx+2] ;pero el codigo de 32 bits es mas rapido + mov ebx,[ecx] ;cr + add eax,[ecx+2] + add ebx,ebp ;b + add edx,ebp ;r + test ah,ah + jz .l2 + mov al,0 + js .l2 + mov al,-1 + .l2: test dh,dh + jz .l3 + mov dl,0 + js .l3 + mov dl,-1 + .l3: test bh,bh + mov dh,al + jz .l4 + mov bl,0 + js .l4 + mov bl,-1 + .l4: mov [esi-2],dx + mov [esi],bl + inc esi + cmp esi,[esp] + jc .l1 + pop edi + popad + ret + +recortar: ;edi=bufer eax=ancho en pixels (ecx,edx)tama¤o deseado + pushad + dec edx + jz .l2 + lea ebx,[ecx*3] + lea eax,[eax*3] + lea esi,[edi+eax] + add edi,ebx + sub eax,ebx + .l1: mov ecx,ebx + call movedata + add esi,eax + dec edx + jnz .l1 + .l2: popad + ret + +;R = Y + 1.402 *(Cr-128) +;G = Y - 0.34414*(Cb-128) - 0.71414*(Cr-128) +;B = Y + 1.772 *(Cb-128) + +colortabla: dd 0 + +colorprecalc: ;prepara la tabla para convertir ycb a rgb + mov ecx,1024*2 + call malloc + mov [colortabla],edi + fninit + fld dword [.k+4] + fld dword [.k] + mov dl,0 + call .l1 + fld dword [.k+12] + fld dword[.k+8] + .l1: mov cx,-128 + .l2: mov [edi],ecx + inc ecx + fild word[edi] + fld st0 + fmul st0,st2 + fistp word[edi] + fmul st0,st2 + fistp word[edi+2] + add edi,4 + inc dl + jnz .l2 + ret + + .k: dd 1.402,-0.71414,-0.34414,+1.772 diff --git a/kernel/branches/hd_kolibri/apps/jpegview/jpegview b/kernel/branches/hd_kolibri/apps/jpegview/jpegview new file mode 100644 index 0000000000000000000000000000000000000000..b08e34fc48c041f78ebcc8aa85cf7e741571bc0c GIT binary patch literal 5616 zcmds4eRLF6manf)S1?U=FhQIF>Gd>{uqf%_Lo)el37v?F0VE_bNIGXp$+phQCRNDH zlCff?LqBTTs58uZ=8OyuIENvT4T_O43f-yDorov`YBzxdh|y}pmxc)e+OEB?5=Zuo z=ggk7|81XBukO9?zI%W7zWZ*yUg~%A+LLh(IonQe5L_U{M~W1yk%E z2DDN^L5kB{;~{K54ho&HSc;RPN$%E4dJ}Zp2+!Jz;oUGC!U24I&u5Zllu172@{Yg`Lj+CqpJ-MbshL5ql$fKV}b??oXi z>^%m;dYp^CWQdY0ck~u2OE)T|n~pkx^Dvbjs$z_!D{+)4?**`hK749~M)Q9QBxrO0 zb%YE))k7o8%Xlt*8y34ZJ{6#M{0>NL$5g3U@IoaWt0>0Gqt4f`0n&sgUc;KC3D4>l zY(VU;Ry|qe9=fsvZ=EOOae$G6@f~&Yavn}IA=>${2~#hUK;UH0Ci(qq34X^Pf#!GY zgmK8>NiP2jPM_QZ`=k`!JvOTp-ZQ446wcyzU?WQ5ef$n=M47f7FIT1+Qj1|rvEUg; zKuKpN6GX%N;C=3)XFvp~*m6&HB|oOY%dwfkb5=Q+qReMO(?en0OgZ}@`Z9kk6??tZhFbFn} z)nO$*PZpdJ96*CQq7wx7juEUJ%V-Ef9YCGnG{bg%SE}4tss1N;h|M(v8uzUxWc{aq zpRWT@>Ueu@Nq(=MOE`KC7;)!9a;jB1Zx4VV#A$LKJ|u*YW(2^s8-Yu?6Xyu@`B62* zOeD1TU>=A$5ZI*=(-Z(`6$W?U^$++Ab!8f6yuBi+hG;TWm_mjNtxjA8MUdpz@TBf! zRjs=l1LBPioZQUo!@IR)2xu(5b729XXx1vAOL;Gf z6SNwT#5RG#_jxKE&-W1MJP}L4@ppHmLGHERf-c%*pIX*I04s;njMY{C=^@$#fN@|3 zVCaK_*&7foqt$9?EZ(83ZUt6qH^4--BLH1*N{A-V!zt)LtYd3#>T<8HEVfT2%NexV zKBZb!mN6=VhlFRDBak^NpQT^Q?EYoS@JJJ0c-D{NM zxb|yEXIXZzmO{Z*+9F`8G)N_3DBW~dDbK{0%7byo@f8O!81yL`euE5UCu*;uuQRV_ zcFQpa(K&^2(UN^aNJjnGLy$a-hQRYRW;)o@g{#>|#M|jLaT>#sgG^2>Bhu&>462GF z4yyCIv(`yom&3IDWn4ZNN8Op%H=A%&+2IW{{m(M!o6SbZ*G{23P#NPdi)UU#`4D2} z6;u=_Lz&;8$?Bm9hL><0SGa3Ynv=r}U9bpp_G39@uDwnEA`X}@3ttS~=G8?rZNcVM z$MNf`x?_I!;0|v?U-%bI`ZVE`~4XD~2X2 zPpqXY#RT>$byTZ92-!K}!0TuDd^17ax`4y2sSAm6@Khr9(VL8E=GIjTV3}s6`BajP!e#`lo~>=VF(RM8A|e^ z3g5MVc4O5QpsLi{wMPM=U(E7MtWfgh5ToS-fBq`Etj!0aTGeKODU|Rt92943E>pM1 zzuKF1jmG;U{?X&Ca0D7INMIa&*~+(^zu5upiO`+}<0uDRL0`Dv%YcOS4(xS00{ux_ zT!cL#AEx9Gg;aT9YDC$OldlGcpj5}X=u~r}M?6uDLJeKmu)^3guW--L1&8t|!)+FU z;JkJi;Y8rhEfuhwHw}1RDJGk`c;wmy6m3u&w-lRvL7yx2fChac(Jd@UbSJtw?;r%X zrFg=YCoOzlYAWab#Nf?xr!_ZKn1o;dB;1BycXQqjnDf8-3V4D%p;DG>FJ__Uav4tE zhNqY&M9ZobKo6>rS*3n0_fC(-#~}svYh$A~;hr%F=*E)RimrKXue7NPRnF^%)qx?( zPP3|i^{dXYq;g(dGkdu$=3>gsJ)a8pLXe+0WeoT=nh_$_dO#gR#T;Ku_CQ=vo)y zw75|X+|3xp0I$`63LKG!FkXP_Gvvz@s-LaYyHUN(5kQOWEOJ?qYYOu2BtXHt<O4 zR9u3x^y$nX@;4eXT&B9XsoDD*gIL$>l?-Biv)5-38=Ji^0-<=ZCh5hiG7aUryJ+Jr zCXK-i8yrl7Kdh@51~QG+bq?Bi3$KQa_n4O9pp;cy>lHtym92Q4b`Y+3t^inDco$8l6T1#R64aCV+SXsGbDb0+1~P*-tCvaLN*Bfg?dud`S*190^h) zk}s{7!&xIij`RKkqLD++#vac543Je%bP#ZTi=~YteBpnG@Q2V~&xxLK*Zap^x5<|_ zHui{r20s$?)L1J64ajIi+9}A)IQh}{B;JH^X@^1Xf>GOJkobUTJ77>mHxg|gTZR81 zwyM{pC}KvAIJ>T#YfmbYf^4oXO!9TLj#2E1?&MA+W~i-j*Rr(f+64$)x^As~UzIOW zQjDE_ESIfiXD7E62vpm1i2&=ea_wD1-EdC$uvw2*4{djM5Ki!03J1r|D^%tUz9sWh zu$le77{%S4nf)eruem>04;GR?JZ5ii&Zi!xU^hisswpbs8x-eL0UZzch)#VvM-%(!>9XoM8 zIGW1OCnV`>jz2N#i@ig|=g&EMGtO<4SXHR8UkPY5ahUVrXruv7cxYi1;`lYJ&WJWe$6;UyfCONC2f-J` zD9Qg5!Q*l3i&t;t)kz2B720V^A^N#QWkYHCn_( z1JR3+T6W9<56F?kdWeXRqB;Rjs-o67KX*UE*h){&{Ay zAO5ODwFBSiIvILMyjraS2BL#tq4HxOLDWDWJJ!y#k1q1Dn zbi_T-Z-yki-#;CmDhgjaI>ng!uJBgDxsMkdx@&IR!NFta3$TNS*4I3_;a_W>wPoGs zm`^pCt)7*_#p@rVI!TSok}JwL goto handler + je boot_set_background + + mov edi, name_string ; clear string with file name + mov al, 0 + mov ecx, 100 + rep stosb + + mov ecx, 100 ; calculate length of parameter string + mov edi, PARAMS + repne scasb + sub edi, PARAMS + mov ecx, edi + + mov esi, PARAMS ; copy parameters to file name + mov edi, name_string + cld + rep movsb + + jmp START.l1 ; return to beggining of the progra + +;****************************************************************************** + + + +boot_set_background: + + mov ecx,memsize-fin-stack_size ; size + mov edi,fin ; pointer + call add_mem ; mark memory from fin to 0x100000-1024 as free + call colorprecalc ; calculate colors + mov esi,name_string + call open + test eax,eax + jz close_program + call jpeg_info + mov dword [jpeg_st],ebp + call set_as_bgr2 ; set wallpaper + jmp close_program ; close the program right now + +;****************************************************************************** +;****************************************************************************** + +set_as_bgr2: + mov ebp,dword[jpeg_st] + test ebp,ebp + jz .end + + mov dword [ebp+draw_ptr],put_chunk_to_bgr + call jpeg_display + mov eax, 15 + mov ebx, 1 + mov ecx, [ebp + x_size] + mov edx, [ebp + y_size] + int 0x40 + + ; Stretch the image to fit + mov eax, 15 + mov ebx, 4 + mov ecx, 2 + int 0x40 + + mov eax, 15 + mov ebx, 3 + int 0x40 + + + .end: + ret + +;****************************************************************************** + +put_chunk_to_bgr: + pushad + + mov [x_pointer], edi + mov esi, ecx + imul esi, 3 + mov [x_numofbytes], esi + mov ecx, [ebp + x_size] + imul ecx, ebx + add ecx, eax + imul ecx, 3 + mov [x_offset], ecx + mov [x_counter], edx + mov eax, [ebp + x_size] + imul eax, 3 + mov [x_numofb2], eax + .new_string: + mov eax, 15 + mov ebx, 5 + mov ecx, [x_pointer] + mov edx, [x_offset] + mov esi, [x_numofbytes] + int 0x40 + mov eax, [x_numofbytes] + add [x_pointer], eax + mov eax, [x_numofb2] + add [x_offset], eax + dec [x_counter] + jnz .new_string + + popad + ret + +;****************************************************************************** + + + +; ********************************************* +; ******* WINDOW DEFINITIONS AND DRAW ******** +; ********************************************* + + +draw_window: + + mov eax,48 + mov ebx,3 + mov ecx,sc + mov edx,sizeof.system_colors + int 0x40 + + mov eax,12 + mov ebx,1 + int 0x40 + + ; Draw the window to the appropriate size - it may have + ; been resized by the user + cmp [winxs], 0 + jne dw_001 + + ; Give the screen some inital defaults + mov [winxs], 400 + mov [winys], 300 + mov ax, 100 + mov [winxo], ax + mov [winyo], ax + jmp dw_002 + +dw_001: + mov eax, 9 + mov ebx, memsize - 1024 + mov ecx, -1 + int 0x40 + mov eax, [ebx + 34] + mov [winxo], ax + mov eax, [ebx + 38] + mov [winyo], ax + mov eax, [ebx + 42] + mov [winxs], ax + mov eax, [ebx + 46] + mov [winys], ax + +dw_002: + mov ebx, dword [winxo-2] + mov bx, [winxs] + mov ecx, dword [winyo-2] + mov cx, [winys] + + xor eax,eax ; DRAW WINDOW + mov edx,[sc.work] + or edx,0x33000000 + mov edi,header ; WINDOW LABEL + int 0x40 + + + mov eax,8 ; BUTTON 2: slideshow + mov ebx,57 + mov cx, [winys] + sub cx, 39 + shl ecx, 16 + add ecx, 12 + mov esi, [sc.work_button] + mov edx,2 + int 0x40 + + mov eax,4 ; Button text + movzx ebx, word [winys] + add ebx, 3 shl 16 - 36 + mov ecx,[sc.work_button_text] + mov edx,setname + mov esi,setnamelen-setname + int 0x40 + + + mov eax,8 ; BUTTON 3: set as background + mov bx, [winxs] + sub bx, 65 + shl ebx, 16 + mov bx,55 + mov cx, [winys] + sub cx, 39 + shl ecx, 16 + add ecx, 12 + mov esi, [sc.work_button] + mov edx,3 + int 0x40 + + mov eax,4 ; Button text + movzx ebx, word [winxs] + sub ebx, 63 + shl ebx,16 + mov bx, word [winys] + sub bx,36 + mov ecx,[sc.work_button_text] + mov edx,setbgr + mov esi,setbgrlen-setbgr + int 0x40 + call print_strings + call load_image + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,2 ; 2, end of draw + int 0x40 + + ret + + + + ; Read in the image file name. +read_string: + movzx edi,byte[name_string.cursor] + add edi,name_string + mov eax,2 + int 0x40 ; Get the key value + shr eax,8 + cmp eax,13 ; Return key ends input + je .rs_done + cmp eax,8 + jnz .nobsl + cmp edi,name_string + je .exit + dec edi + mov [edi],byte 0;'_' + dec byte[name_string.cursor] + jmp print_strings +.exit: ret +.nobsl: + cmp eax,31 + jbe .exit + cmp eax,97 + jb .keyok + sub eax,32 +.keyok: + mov ah,0 + stosw + cmp edi,name_string.end + jnc print_strings + inc byte[name_string.cursor] + jmp print_strings +.rs_done: + call print_strings + mov esi,name_string + call open + test eax,eax + jz .exit + call jpeg_info + test ebp,ebp + jz close + xchg [jpeg_st],ebp + call jpeg_close + +load_image: + + mov eax,13 ; clear picture area + movzx ebx, word [winxs] + add ebx, 1 shl 16 -10 + movzx ecx, word [winys] + sub ecx, 40 + add ecx, 1 shl 16 + + mov edx,[sc.work] + int 0x40 + mov ebp,[jpeg_st] + test ebp,ebp + jz .exit + mov dword [ebp+draw_ptr],put_image + jmp jpeg_display + .exit: ret + +print_strings: + pusha + mov eax,13 ; clear text area + movzx ebx, word [winxs] + add ebx, 59 shl 16 -125 + mov cx, [winys] + sub cx, 39 + shl ecx, 16 + add ecx, 12 + mov edx,0xffffff + int 0x40 + + mov eax,4 ; + movzx ebx, word [winys] + add ebx, 61 shl 16 - 37 + mov ecx,0x000000 + mov edx,name_string + mov esi,60 + int 0x40 + popa + ret + +slideshow: + cmp [file_dir], 0 + jnz .exit + cmp [jpeg_st], 0 + jz .exit + mov esi, name_string + movzx ecx, byte [name_string.cursor] +.l1: + cmp byte [esi+ecx], '/' + jz .l2 + loop .l1 +.exit: + ret +.l2: + mov byte [esi+ecx], 0 + call open + mov byte [esi+ecx], '/' + test eax, eax + jz .exit + test byte [fileattr], 0x10 + jz .exit + mov [file_dir], eax + inc ecx + mov [name_string.cursor], cl +display_next: + mov ebx, [file_dir] + test ebx, ebx + jnz @f + ret +@@: + mov byte [ebx], 1 + mov byte [ebx+12], 1 + mov dword [ebx+16], dirinfo + mov eax, 70 + int 0x40 + mov eax, [file_dir] + inc dword [eax+4] + cmp ebx, 1 + jz @f + mov eax, [file_dir] + and [file_dir], 0 + jmp close +@@: + movzx edi, byte [name_string.cursor] + add edi, name_string + lea esi, [dirinfo+32+40] +@@: + lodsb + stosb + test al, al + jnz @b + mov ecx, name_string.end + sub ecx, edi + rep stosb + call print_strings + mov esi,name_string + call open + test eax,eax + jz display_next + call jpeg_info + test ebp,ebp + jnz .l6 + call close + jmp display_next + .l6: + mov dword[ebp+draw_ptr],put_image + push ebp + xchg [jpeg_st],ebp + call jpeg_close + pop ebp + jmp jpeg_display + + +include 'filelib.asm' +include 'memlib.asm' +include 'jpeglib.asm' + + +; DATA AREA + +wcolor dd 0x000000 +header db appname,version,0 +setname db 'SLIDESHOW' +setnamelen: + +setbgr db ' BGR ' +setbgrlen: + +x_pointer dd 0 +x_offset dd 0 +x_numofbytes dd 0 +x_numofb2 dd 0 +x_counter dd 0 +winxo dw 0 +winyo dw 0 +winxs dw 0 +winys dw 0 +jpeg_st dd 0 +file_dir dd 0 +name_string: db '/HD0/1/KOLIBRI/ETC/jpegview.jpg',0 +rb 256 + .end: + .cursor: db 19 + .cursor2: db 0 + +align 4 + +rgb16: db 0,4,8,13,17,21,25,29,34,38,42,46,50,55,59,63 +rgb4: db 0,21,42,63 + +include 'jpegdat.asm' + +align 4 + +iniciomemoria: + dd -(iniciomemoria+4),-(iniciomemoria+4),(iniciomemoria+4),.l1,0 +.l1 dd 0 + +fin: +I_END: +sc system_colors +fileattr: rb 40 +dirinfo: rb 32+304 diff --git a/kernel/branches/hd_kolibri/apps/jpegview/jpegview.jpg b/kernel/branches/hd_kolibri/apps/jpegview/jpegview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b93c5476c6b0da5b08cd82d5ed1332689c3dffea GIT binary patch literal 19227 zcmbTddsvcL|NnafB8taGN-R93k3t92Wb#O&Jt?4gfO=}2raUwXev3rP1C9ooHA93N zmWG5hg6KTsR5MnZS!5|$nFNlRr%X*lJY->(S^e(WdtbkOUHh-SH(vfF7qZs6*Jr&y z@Aqqc?f*Io*i$0OkpKh&0Z8Bv@O2Q_0a%!uBh29z2n52?(gJCXvazErFTev=0VgAKrK^7X^x@vh!Mgutz#KK}Tv|9l9<($dn}${KBBgWl?n zao_s?`Sn!|tg?WNLU}OAdH}i#0$T<7dLM8F00 zM6Pi}JFWefmp2x-0srl`fWV;O9sk}L8AT#f=(~3RXV2d65>pTUn3m39W^j%k%g)Ko z;})MNIeF^mUj%2x73a=ZR$Y+%TB}gjsp=bk`}41+Yu9fyx7=*McfX@k^PuaYPT%`? z-?RSb124zMCtgiXy*5lQynSa{e82SJmA^sT` z1eyc>!d98V-TlnJ2~R*IvmMrNnU=LC;sKX7XBI9|1q-v zcLOW>|24AzJ+S|KTmyhL3<545Y!wg&j0Nz?Q(Vj!l*OKwZl4as+_PJ`i8foMnKlrq zX|>yUSs2A~N-p2wJM{-{kT}gGFF&oxNJ1xQ)1-c{akr*)yx;RBW~A5njjWZaEWT87)1E0=j=^X4B60D?Zj+T~VXHsg-wo*>R$I`Fa3hh#WUi9G&YY z;$fuJ0r8Or)v*a(5!Si01U;Hoi9pRrVj1?3?kx|oNdLZz*Q-uW(26M}X9j`*2e3~9 zJJ5vJA-ow}NxSsC95IV%^s>*Xe|*{?j(krr$2RZHAykYNJr3cM-=&`KK)WWIulrKR z;|x^3f>zg1l0umHL$GUZX|-$(os`ITX;Gq`{XWpSi*lD>I$9wfsJbumU#7pwr;Vmc zX;63ZSKyiQb4Dz|#>-9)Jq^Eawj59F3Z=aX);YY!LZGteszY_>SudXO9v3idb`H)` zy%9>>W*IYZzK?%$+!z_xS5Yp4dnY_Y@%B0Nrts`tnsjl0Fay2IsQgo+^@fb zj439iWQEWsMU1<6Ud*S2a={O`Z_(_r=&By>HZD!aA(~qlNzwE_cOnq=a&y+A@&SJS zyd;uKgXCw|C2^4lHtAO1on~4`z`Y2D=i4hz=+G~!Xlo7~RXrun`R8z9pY(4+-jT1k z^!~oq@ea~*vU0sR)6^)0t*d`NPj1$d39ljj3B3ZU!B`_#ScE*~VIeuEm3f?U9Z&fH#Y!|= z*OPIeN>ovcP@?ewk1J!Uxw_QerB zgv(i`M055t)L643untCAR08jnUCt$51q`4o^dN2ZqE`{o7&#xyKtn`Q+B*{2L$2&W z@%(2=$48WdvZi*`8@ZXAn3RdjUZ(TaQ&9d;saQ*!&B!~40Me>&eFZE!Hp2U>ZMn2n zqPmKCLL3UHy(&-5b-gF?jSCkPF3jNkTiXCHzrP!DO1@y8HoZqxlw}6% z4rZgQa6+59vG}6LVz;BN7v0PAuSE&LM*v6|sM?z&1t+ug+fR^4U?Z|pw-Njd;$um2`TmKpn-^ z095K5Mb|QN+r+Zgcck_4ctqh)uNn5&STR4maz3 zNbKk_g`dKuU9xM*vzJ$_O^|GIbh^=Noxlsxi~PFkq%a--XH4l$f6Bp>AVtukV!X{w z8_-~+V6rELb`)lUfoO8R8@dpw=B{P9<#d}#(*H) z$TQT11C$uE2lIlsie=q7M4Oj>K#|NJL{)X5J+Ao>jS};JdHF{-rwJ!{P{5g~Sf)37 zG_GSnL$9sNm$1jmBs&~bi4iZ(_z)O@O7@v9Q?1B!Ynh&D<1TujF!qTLqt}-?<}TJM z(WpC{52bj&jMOo6xLDMkfXlClJP+Dx*qv9A+f_yiWH}yE-tQ3IybOsPTB=2EU-Vrk zUGx+jkSl$P<%)OY(9OQq4$*&}d6ExVls9NLmnwlk`2MCmK``>j!;o|%>3bc2Z<+rp zorK)u#eYzXHWG^)F_NtW+)sCfY5ZTV$V`V_6ZcK^iFyJ49+!$%=2q-b2pz(nVGKr9 z6*g7>HNfko)(N?~m#wrJ0u{n;0iHI4B~p+}j7o%OxmGQymB@@3?2=+A1YC8vCV>KU z`%v+7p>+EdeROFf)c=L5Ei8lIwNh_m@yJE3`?1tHBd+ZDqQS~Ri-eB*<_qck_@Gdo ze*sgm);w%uKRwztkp)aMcS4f0Mouj#T}*V#uyE3*FgIj`T4v+Vip;~;isT9Ge%o;#+p^ZO8wMp~kjV(cqDoAb zzE|M=5k|6@R?_oR{BGiuWK&2vl+f*C`CjFk9NDK#YS!MatHdls3y&$@0k50x#SawV zkjv8egQ>k^k~};gGPsC8MQHxD5_K|wiD=t`Z{;br$V?~Q!GARyg}CPPf(t}w+Sc)B z!_~_=)_a9tX2{wI8;om4&C3Q5>~` zY=Yrb4R?n_@_eLUbn!eT3*kva_p}SsE`BJ)vv=~Y2?CwJ0vlMCwM@;om&!(WhIsVS zBWSbe$*L;lLW~cmBkYwkcC5+<(*KFRawYg0+WV5yB46uhzac@UrWe&4quU%us{RQ0 zp8_m4UveOTu%_%PAr@=1gMnfl_zLXCmuN!u(Wy$9YuD?r;Qj1JcI~yBdaak^*SNl2 zQmSWTobat+`FFP20?vODSAX+U0rQtX3Ac2!&RqS&@iv&#MEph}OiM4i!KE=qLbPj7 zgO$@xh0n}GWy>QLjpT0U;Br%K?iWKHjOSIEA!_P=%w?0J{+q_T>h%gHYU<1;z+rsd znejHj-zN^=q7vR1P7M9CZ~;6%Sfh-uKq&3pZbMfcD`>QE7efA4@ovR{ET1J=;%AC` zwVNX+xM>y8eA>cSU|I$5sh9f%9BISz?1mdc{{jnpzTQe`jJ{IyrOjs)j=ytBL5Mo6 z;l@3z+BaGD&2WA5UUp_MJ$kB7y579zFBlJ(5%Q~@bh)=Urw|tnpT^xzFdRrs8Aku1kRv{6$3|td3z-UIIRh+Te1^bIpN=wHkaAdPdZH ziam!5(H$%%Wjm_k84na)9WYsw^$$&l@y*V^)Ur`UV@b;i8gBMiAR%(slHA81)^|pB z@?w)q#n86^{%o+$T(!#BjjFomsXI1LVUtTK04q-}T#^fE_RMWtzXGu9jN#XSQq$(+ zxX>75*2%DnmeON>{t*1%Y+vx8FGz^=_>%IE}WRw6wA^W?@m; z{UN3;Cl<-rNWAZy8HbufWI(xkHS|J&!}i`*P>$kT%;@&*bwZ?gu+ev%fQ3Xk;{uZ6 z_uzHFyadQ(%Yt=tX|pi^m)^420cZ{_9x7mN-@OD@a-RY?)WOq)l1_%Ox3@<##-5WmG+gTw-M-}{224OK(#sV`<8|X$P0XH zWFTw-JkWNVy|p1Zz*fLX+!C`VDb?9<(%l%&k^Jy{Hj-bje``XucFo4Z2)L2&=85}G zvwQF*J;V(^2tp<+)33;Vem48DVT9zIr@9KeO$|6M@7QQNlSvG=dvX%6Jx&q&W8P7M zjIm?A%tNjfYnkZ;QU|$Le_eP~*|NvY*#8AT!+!RrVcRFYt>d+gwqx02MV57yb#va= zU{_|wRR$8(?9gq8U>cWQ{K7TSUqBtH<6GTuei!*RBt;UZ zbnjXQOQBV1rj_k}Ra_8(ia#g+cJ24V zlxhu^9i#{qRa9vo`U_}HsUwO@5d2zS#uyLS8R%f7j-#s9gIh6*O}=Z0nG|YaS0e|g zBTbh6x-#=HAe$8!@!#uflK$uTU5}mtLw#G}$ATZTw7q95S?gq8yt{OGl z1Q9j0j|bro6Q<++b(M#qE%vZbK~CV<#p}X&M|-@AsA}>wCo)hDx0{LUs|@ARiQaPMU1w4qq)99l6A!smKoN~0Y?B-gER9t%rW3_X zf}u4?ULIZl+Mj&3cUF#!u}d_E#Brk4+nWw6*G17wGt9ibl`h{AGKj=awPA@?E*CVq zizRHcT+FB)ckAsbLkD_(M07Dv4hu4rC4Cw>K1DL)cN)2hCQ^@$%(@rl=5#e;%?@rG`H&qaJvx)OF} z-j_>r?jGVt{zqK;75D)_-<_-kWX#r|6)(iv8l`*bh7j=FB~6yq{6u4Q%`qT3?=hdT zo~0QfS#0V@wvjUGepu6@*ub4a%{KPav#;lUW?%!I|B6DW-qt$JP<{0MTG)4XbaInG z%y8*t5l$91?e&T30rz{m!t?m5m4;Jhqcrr1oLRE;*yP05{saR9}kZ~ zOkrpfH5sLx_u~d~5my4e*X7bQ+&h$7N5vwVKh3x4?W3_K)5 zq!7;&O=~d@{I2(^!>oxdM#>XEA%Hu+r5O>!F*p#{}NzOE!8_TJ6)0~)a8_FY`8JIm(l%J$_v z#3?^?M3NSJbVAusLgtnEEJk2xDxS~jnyhrAp-cSle#X8fPS&&zmU5YH3&bCO-sAEW zpd|OOOO+%-=_~4wq1wBCHL=)b-7J9tlfkJc1B!LR6j}IO)Jt;dp@ih2*ouSk#6?Ar zNdY_6C#<0`V7D0)N9CzEbp^QApN-*%L>2IoQ~`^ugb@r}P+s{N!`*QA! z+r`i-VI#E@B8Ixr`cU9?E-j0JYVJu)@_H&`j9*bD**;&^xi$js-l&n=O$*m6>kY(x zN%R@q-Kd`=+4>it3Zp`sSulBryXVsuj?r{U`W`KZgFWw$doF+Llq#YIG|036_3l*i zM}3a?g)4>FGD~rMfogvcQ;4q>3%~4ogDPOmtL0{c9}@I!TgFLfZoK=}0&Gy|QB}G& zMUt}?h_UNDGja4YlRZzIx(2iNBQUxM%>G5t#4%^s|7|9v3%CNyyC%hp*_dw~lV-co z?`v}!v0-%LwRQR-{Yl1DbB7r?3!3y^-73uoU2@e=wWz$LEDe5cGyFlQwRo0dFKdPh zXEAKj!LUSt_H*#X7m1OXApj0}{=LdV?K&dg<}obe>0Xw43krQhkSt(Hp5tKEkI}s~ zw~NaNQVtLp=ACnZNd+s{3-;N?Xdk@@d@tXFa?>PItCnf3fk4Fw6_SP<1gD;ixNIQB zj~7$MuPEE5xAm}?A2bQ!9?#w=@KK`U?UhVI!$(3TwCoe8$j=PGw*-#TSZc7N0(SHy z2Dr*qc3=(X?r>_J;(yd(WR|K=w0OTuQOU8hWlg%zJ~y(9Ss3xFeW8L%AJ3o82%dfXHVK4N$1>9aepVrC80ZrD|KG^+Y% z#iMMzd?E`6Tre|rDU9H`oAby>%FNfHhmMz%XXEagY5`lO?Kt;o2Tqd#2LjB6DN^FE zJcn%TgE^*Mn-|>e>d_L{T-`xiVt1hTjj2e#L?`Q^xL914<~p;msf0KGkq%M2m<}&a zO7@N`z2Z2;y?FzO3}&G(q|PxxFCk8tP`3A5Qi8^+dHL_=iDrxVQ9-bF^GTB->TyQ+ z3@&@>Hm>AByX|Df;h7-SEU1%wAfw=MdQgYS!GoqyyvLN7XmP;VoM}F}xY}2kB7}_a z_X&N1^;fW-NT&Cd70}62Jka1vuJ(S}by zHWzSdNqD!o}NR}T3sDqqkwptQ0VjQBIz^1@=Lvhcy-iK@}s!-`D%hNYRO>9B< z*}T4 zYvrJkTysdv{t6i7oL-4p$mAT`bcxtAyh2^an`Qg!rr^Q6;jgkljs5qnmMuN!NqYu_RBHg>_c#%|=Y)kmX%Lis9Lg=u{HAroFoPGj2Gq zPKQqQkn9lM!#A(s`q8t*2iIkF70{sWkUJ>7W&wb0dv78PA!+d{yxB|tho5+3%bhrqzXH`Ej!K z*tl@elH3t>0bHUBtzhTRYh%3lJiv(HN}uvV__M^0kz% z$3?h^Npaw7e^c$I;RPb^x6)e-v#$Vhlq<>V5V1e#Zyp1?%e$Yc%H-sQX=g$u( zi?#{aW$ShIlFwL;~MffJDHfg?_e1$L8U1-ba>?|5P z>^&el^#{{3?R~9^E+M+7J;4RoerA%o*G2V}-D460QHM1@X~Sojkvm}y;1MmQ%{g0i zxW_Z>tADONhW1dpA4wqI_oRVMMid4alXC8)m)*-K52cyzGt-*IiG+uIq^0m2P*vTV zy$z%vwY+1>(W9sfp#A38X#MZbf`;a)zKb20_j0oi^pesdjvl!?*GL4MW@G!K_RD&^ zr>@j)9@4IHZi#9$2Yvk`2>Ik0Rm)fv#Ph8N4;lnOehrtI#YF;{2k3$y)H!uL(!^M0 z(xM!e&GZvkPQ5~!lP5@Wbu8bD6=&nDIuJq}gTtn%a+`QIFC( zH4FludM#r3TG~oC$#(neZl4)hZXM)?Gc^Qu%?%8G3XcL!w^k)o&M?ew#4^zlkZ!?@3)uQ?} z{qnbAmD9|Y-C#?^*+*>bJPc2E|<#s_-Zj?Z}+a7r*1-e)|2`q|`SMRH$i|pE@huGI8rJWAxFG zzLS2S@J0=te~%hPWDxNEUZ?ns1s)J^*)FCZqX5n{({g*$@4ll)(F(=zG>$k-N-1or z^1ckcc*8lU)=0DnM0farOR&?631J)*RkX5u!2(04G7g5g(O86Lg%dtiV!nmmrG$aP z#+JZT_Jk9^NfpWIv43w@jYv>3P6u}PJn?t)9ePwT+YsvkEz9S`B&%mQ6#t==vKsn_ zcz>{zF&4YGz^=K|xROBUJUKCw$^Jm&3{>F2cH1iD;@RP=w{u#dub*NNQ7DU$lzn`iB*z65{PzDHsrA;<&S?^3WW!jq0O`}>f7JECvv|%T*Uj`~h@oZ89e|hm)}*9I1gtPE!Qxdc*|Dy#w7t^JRLkr^p}dIr zR6>2|u}R@K1T3I-HYm;pvyIUYK-X7xYf%BInG+QlEZyF9hZwrOf_k{->$;4(3V@ku zml%_(1k6%L#7@Qzck~pV8>UJizT++Dm|pmn)6rqHV*jeq`aT!t?qaUWNg zgw);-HleEHxVZ=J87UEqL3rfE_v~&T!qwPKi13(U*{}T5!hAhBNQ1hxS9fBu&TnhJ zwT>5e4K&-~2nn3s3>$hn$d7JcRQSXVqk!fI6S|+|T-~9RyfB^;8JtpOffj2}D_q@) zu}WkcnE5|WSNaS%mA=sz9^w#f$HX~uB~ZZJ3Ak;qt90rAXA*908Npk`e)f+In(x4R z$`DhOJ)b(OPFVZ%yFF;)P6V{-z+u3B{Kj|`s`W2we}UhkJhgbX_DK)Aj$g{PM41=2 zEY_6^Aew8~Ha~hdbObyeT*{L-%pFI@-|oLu;d>T5E-%YfKm7*o-!6k% zd1YS?aw`?zBj({+InN~fL0Jxc5MkxQ3`Dh(3G7(Q8`47j-kb>d=E2qLdFHr)6mih6 z?T$g)O{t=a%v^l4sm{F_B`v^_(Gzr%cUcByZ5)B=Z;Z1NHJx%Amq5qa2GX8)s%?k^ z4<$L-3O}}}jR7uVE%4JY!z1h^(fUcq!KXZKjhcRafofEvtSvlL6SxqQav&W>bH_LATbl{IW!_I> zYx>TWWNil~1vEkf;B2sN%|--DmMW$xPY`OIR1(uT0rH+ zL(Y4=`pk?F_m%l2?mI7scLpD;oetX&i}>jil6y52-T__r7wBhawVh;sIgrKp7)3<1 zL7TPCH)VwSfz$J*x{z|c3G|>FI$&3Q=40XB7mTE~;54bdOC0KcWY#d&vh>z*NL&&k z7N=Yweuk-HahAY@RI=l|Vt@^1Yn(`ZKfNfQ-oC7LM9Xc5^w*~bE|vw>I^UI7|Lg$+ z37bY=zn%~JPCIkH-&RX?-KePP_utw;?UbDD9EGw$?$sUfZVbo_OSJ3b_tS4Ylk8{( zowIxs=)owoFpjJk^jn5>mGOk_75C1+&cs5V?>3P3$^58Rq8DcZt=~xy2c5ZZnGxmS zD6I67c;{0dP`<6Le4$GbGB_Z+T0bGx?zMGXl=wytJB&Qde1bkjOu1msYML6Yk(ar#Nss?3VTMZML z?#Y^3c}w_XM)DcUI|IVyr~Lke8z^3jfU2fv7BDP(zD-Lx@2&K*G}1P#%@uO>t7jrS zdMLT2eTtV+P{~2`#1|BDmKR?uh~F6nk{WhKs@t7J=zU?-AIu9uYNhLz{mkbGB@n=v zkBY6BRp@{a>1Ujf6~3%{XHwn`J4!3L`?2&D@el8Zaj^wd+?fX^)Y$8`4PI4Z@bO<; z3bD`Pkka?1TuSQc!vEJ2l)3WkA9gaozd<2B)<`8~Q9TjNPw}?w4|JLjC9Ca2-N%cSjgWPX*!cYTwHB7FrrU{M@Uyp@!*<_VqRfPMUJR6I(9IIpno8;V8hrLlV zY%Q{I##H-gbFbEME+E%A2!F}yZLaF~j9-hf7zpulzgcpyem~J1?zB0w1MJf5Xq*1R z=zGU6;}z-hZg={SHsn%A@8KA7g}4$9zA=eMG!69?HO z^Wb-poLQpHb8+9rYf<4uBf0dzL;lbELirG_wI{15u? zzHh)E(Ll?5LtXN|b>hf2#NLwlB8WEbmv}WGKl7l;{(F^cV)BlfX`Eg7ryW_h60Y(- z-lSQ}35Fe0jgb0-w#6={Q(hO(bp%)s2ggHMGq`PFFo#4WL~du<0QgcOuGULo1v;(A zR_d?JA;FFt4DN9!9F6MQf8{2ICsS0zGhRrJ1N?9yf^&7i8roMI_laCDT-H+lB z|5$%d#I>VS_TxuaI)7z4m!h-*1=A@v*z>qUC789R{wJpaI%`;_jY>A*XMDFbh5*^B z!wJtCy;)eR)1BswWm*cqJZ8rYuq$8nR=|RwzCrAeB>7meqj|OB4|MC_BZKMOCB+(7 zsYx*?s}t75;_Uw55D{@Vu|1(R?R@cUoLUnTZ_RpYQdwWlU>-xfniOy1E)bCifp^q@ zm3kayE$e`4a`nUHF+T4_aN8)~?b@ojN0LHEjIP7rK;2j40RtUKr324H_O$s1U= zXupk1Xq`MKUK8k+TztD^3^(XeKsBeY!rBGb)U4qG``%IZgiaRO>BJ>+v%AZ*i@y;J z)+NmyXqP5yOE3_L4O?r6I_1SLUL|5SyHc`ocKgiX>{v9;f0{b4VPxHV?TELUIwA7 zB^$Mrex=2jPzHA!3YrB?RvW6i2mh*Y7?%}d%RuYey2ixYi&0~Ni+Hf-B6=fKQ>0y6 z`lOkGiA?mTUTf;?2U=cnpzB4%X5bwL^%QnKr&YPoum2)|>>TV|gT^u<1fa zLRA(s(yu2mhyeF_x)SwP9&tni&<+Q61%enO8g=iPu!d_+_<_yCro$RmHmv`hE2aIG z!ut~nf)8`dOIr)5F%CJDbMdz5aYM|$uGK}HV%qQfmhHG@e_r~yGjgvCByO@bt9MT| z;=4M5vC_+l5xb6;0Qd=$90s7qJYAQmb^i+-t6BCRK$`<0Fu{UGm$<+r^+X zm|g4!%((G3zE@Xp;p0%gXfvpew-^62aKGz3=!v&ftQwcV zD+v~37jKvsfoG=GP=a2>@aVhHsuvK+;JKN6U%*TWM9tnhD2ZJ`0z1C^jqVv%{d_mb ztLR}(B7*(jRZp1r0T2pus`?afJ`LM1|K1sQ>uQ%O6`Xpa7k?koFBZ@e_kRRAR8Z84 zQfeEfbhVovb5lhA(@ZXSP%=!lvK2wDnQ5$yXBT!6l8JfWfkOt(lfK6fpCWLGkQ63# z$`}XV_0teNy0|^%v~a&;1FG|1H!}%T_Z?ChH4q6ferRd~xv;%kVw)bbCUngjR!=w; zG_w0w8mu7tMp#6N#;fvpa<}h68JDh3cp)*nKiGOXF}{`I3FhUH@{wv$E_fJp2Z-CX zzEAW$i9dY0DS(cjpU^E(+HHz4?8Um(7@gSA(+0Up)ILrVqhGV>SR2_33UZl4%2|(a z-WjretgLLqR^=J@xge-+QRIPY zJ(SNYc#S?K>s^gkfQfh4C~Q$~_5{1RRY^$c*~A>&o#)J0{S+;flpQV=lcHTSl8rrh z^YO>69})zt$8U!utgOO#&TL%#hmSojz2^7GchxHm)0|!!udO7oe1N}gT|vD!C|=f= zU7rh%ciSQgrUy%Vi?&ZG(XQ=SXKnXI@H|kL`NFYi{EVnZ31LHvpX8}nmVH%m$)vzn z_4e;7F-Pn2{(Ve!i@(n$O5uoD{O$Q%7mgOfBD_^`HUEAw}&qjgY7 zXOIesNZz(8JjvW9%=5i+RfBP7(dP$w8JYWRD<;=*X@x1Lt%I{`o!<-zW4l>S{`0TAe-LzYDM61)_BKKaW&YFLVI#QZ8%gog^Egd~PJA24Rk=AQJYt zijtZtALC&%&EdY+L-gd0^TY`bDI3V4l^~?L(RjF9vwc*CZ?JT2_Lts1kI-XsvyI(m z@1c?%E-FDL5bx*rK}%E`NU_0M_#X%^G44(2lL|09i$3_%ul0}P5g})MMiJ23y98#g zGXvPvugRdcOcwQ4rJ6uX1*UY{Gz0^*S+=*g3K>`{2IU+JD#HD)3G8IX5*QCcAwNOJ_5o6+*3MQ*) z<$#6Sab0T;>hNOFd)3UimL9#~GsEgV1oV;8cP;C!nxx1Cv~wQbcDVC=o}FA(0&u$B z@#zA94RB(-LyyXRotf(i?2|D9_)f1AIj38fdA ze*gG#r@z@E%1=IFQuc@FgvaghEzTeDJm!Ny7z!~s9}aF)AS+0o+{*4!-1UZ5rgKOK z2i3|XlXKG+FG(TDsYn;62E;cKiC!aFxPa^qY!`@B_28}36a55qFwIaY0Us*vu94bv z8Fi|BmU#crlpy>Wi0S1TVjs9B5)-YanE?>;Sq7}H{P7(Zhy(#M z{M5Tv&&1JE(S|S;o-;HxQ1v@5?3cP%t)>PPOX=YZ;xD_+KxgGfLL?YM`b3$R*=_(9 z>n>~)VIfue6RDwkyM#+ZUQ((t&VGFU9VOEix5MR>5?V-%5LM{KTKW~sv2rP7o>=zc z=2m9tVU97 z;z~us46}Q3#jwaUg^2y}2sAQG3{8Hmvxc6-&ZQj?Jhi6oDM(Q=a6=cj@n?(UH~kaSZg z&~;{qUe!C7q%#8(*H~L$b4e+^iL>%QCg%$FVb!RSy^BgDVn1^on0&;ocJeeS@A=Ks z;kyrT5m$i-E*J$XQv3|mDFg8jFXD6X_ct`jzF$?|uK%)o3E!EWTCC&kS*7R)U<-Au&CeudSPu!c`O}???ytSH z=5Yro7CrkBO83J})u)fjlSs}uAZ@~=+Q9Epl?;QJ2kcsi+c8BNjNcuZl|Ol!Hx+U- z6W4~F?>nOk!V4n67A2DthislI1~0%!Z5fa(L~K(LZ!4D*`!at*XMcE}6qQVFE;kSl zNkPE#GxHMJYXWOqQ_DD15(}<+Eh9X7OqU9dHpz)u1r0lVeD5vP8cDn2q1%WLLg|QD=4gtT zk=m1J?pqU1AuQ7$F6c`WnE>c&IIA%t92quJT{HqB7^vk>I{T{B*|^>E>`CeO&Vh9s zMHD>qun3us3je*{Bxvi;=Sn+$& zOa%1p-|K=1!L+Me*Ajj6lxziz@LK)FrO72SnD$#ac-Tbs;8m|MYn?u-C$y+^@5T@d z<|9nO(`j6L=uyM$j?BEeBLuj6>1Gikk?HzNt%t61pv-0kDW3sP+Pnt>`i@VY2{?k#E4d7a0#t(mV)JWX1vI`gLx&ehsn+b%!m{TSo%dor1+0Ml zc>KB>$7+wbRHPnu3IY>ELu7#=j(`iqO!6?c%=@-2^{2ndRoMpNE#*(RNGQL{7~9EZ z&yzB5n}8Enjk;=KR*;IfcYL+?Ilcrs5eiiRMk%dca@9|-&`m~hE=oC7er zfE%x(_H$y=)doq*m2_vu3kg;6uCHuC4Qec2Pf)Gr8^kyXGLD~BFAy!83h^ZcxR?3* z_h$*%)epEwjTCcR@(S)#J|wEL6U6t|wN!E1b*av{;Sd^M_CapW?+#(?k4vl z29w`)jne&%#9EMYmOE|loq=?%82m*|2g|#`TbTKFPbBu&AX_=H-Wc1aV(kxdc2r@7 zoU0}6&)3@@f=Tt{)M?O@>Z|lz1c`Mxkm*PDW-O}ChHzr;hHBL;vXSD;%$@`x+hE$2 z`(fY%otPdD@(( zufJfDd*!Kwwie2%8z>~0b9n=~dkLHJ;#vS)Cs}D(CcFEJ0bYo|xqCYr%v! zjsJ5&L*6VYP*qq|b;1l5KBYpXf|na3i7qCfsJwZel4qcH2H~y$$;W_W^KlrH!UM!w zpl6vY-Ys=S%=?f&(5&v(N$Y`$ci@GsQQ8|sn^~!q29qGo%&j}pjc*Q(U*odBYVTxi zkh06A7fe!R@Bn5{*g497%ViZ92-xl+VsjOng14Z?!ZsYS((&vXzpd64J;xvJhLOU1 z5^;AU2@Sck#JTmNJk`l0b)w(OBIsn_{RS8(TG-=o>LOmM1 z_%IK`Xb3!z#dX2Gz#75ET6d8bM<~F-`F|ExYK`2%av}_UNeWh7U)uf>V zH}MXPb3jcu`UQ2Wm`~X&AvSG2F?A;~*C2_Ac*E7fH+Q=^iuL?h^!{JPfha|BOoW33 zj7^a=qCy=`ik*Xdj|6pN$Cd79Hu5DfPInk6C%_8X4DUmDWmH}b0la2cTiM-^^c zT2$#U5zb%qEB{OnH}vsB_{X*q=yv~sGSj*ngs@=08>+?-t< z3Yu?{m$fmK7j7P1l<)W%1VK|Y^0CTfjQAty%XI+$Y22r3rEyUXBIF3wHSac`nar>a zI9}2*)Ww2^Y?sHay6=ZFLFSQQTl%3yldR4Pg4 zTI-)CkPA|rQQB-O1y zX~&CFu75v$iM33R4c-j6gXm=yeze&bK7I}G0*s`*FkJ;^(YVr};B>glJzQT>#&WU4VW56k9Ki`5DXu5L~}rF6IWrz0+nds1`e9=Q3;N#IpmB+#WgG7ghi z4&@qRJTP0PNcoa5>?rN9=erI#Z}eE*kH1Xucm0_BeAjfI;*oMY;@G>aV$>z*+eik4PoA*rR6=$gd|U9^8zx8#(c5So zy#>rgFUkGVR+5E>cOxYExykiR0A>m=2i*opAI}jC5&V}#xO?7nrJX$ULRJ&N>S-fQS-rDE{`w``kq9XCz2Z$N|tyd11>>3u_BK8@V}WK#H=BOJx5DdaS;G6s8Bd4$l)ihT@Q6u9Se(OH+N-kL(dJT?KD@6YyL3 zrxzCyPGeP6Y$|aEA)Vw)7liaTe&U#(!2NK*2UylYqIy#*(cmS~{8SXAROwZ)(>-+s z?{}6pCLwAtbmAOWeR+ojn0apw+k_@M=1JfxNd ze(ZNYx7%Vh7=71+`sX~u{|coCTKGW64_?$42c7=+Qgu%lr-o|NFepPc|V2faKBLfdJLCU_JDu1Z)6 zjGTkEnUZPTD9P*TOe`P-_2!o#ecnwOEHHSck&cvrUESK04c^oR&)(}#;d)R5M0ob4 zErIRpNx$(lZO_ccfE&1zh3P>9>S#IWxdN3^fsFx)#Y!+b^`mwMDXoAwpj(eEOf=k| zr7rLVFtA{O%`~^QFD*vV^rSHW%_vV!Y1kvLPfA?pbfK}0%y2(iiI}j!7!(aFib{{W%X-s!2j}ZR1$uR*9G{wkwij^66oWYC zm&?Z>&@+yB6b6D3o|LBwJ?U7CU{gYpdFFr+o!HMF)bI~#a6#UhP7f3c;m~u|lOBeX zc26|n)`9FduN1p6(wxK(N?^}WXbX$q-kMus^`M^AZ09ttF#{Il)B1JkLBjoMg!<9} zOK$p7Z09+}9VtO1&@pmP7{I082LMu*&lJ+2bn8HbVb3(v(u0xKlznLo6-hkwrxpXX z1ojl6arK}@oa3I<7yj?(O#z#pl<=W>6+~<^X=9U53I}d!Nfgpape`vpdQ&n6ev@`=7KXw&ykMQ&Pkvw#V2XvjBcXP z4FvAs3PK3$`A}H)=|BnP;N^~KclM)pdYVEr(trZJ$>Naz0J1+CFhS>C&6Ff|BkbC5{anK;)Wtw^~BD=Q*IELHq?KIO3Epezfis^U3s}R~o9sdQ-r` zd1Li-6tpm8wNj!A*sW%SX zpIT|;V;CNkflpcilBnZ7X-bZxtwtor2BaS_$v6}eN0uiYX-kD2a%g7b3Mw+VIiP3{ zCviN|WRu5AU8MU{xKZsu#)TuLFCN*XIU|Zph4(ZJb}`8`g|`e-a7n2E0CU!X2(g~I z{3+Xl{b{WJl-%co)_~knbL~L?049K>{VBr$b3h0djD;LfNj!>9y?7nX03w3N-lV2> zz~E3b^b}ZQf&=xV?$BS3X`_>qNCuusped;cQaR#~XYiuIaR3yhc*Q9h_NFrtKr4+o z27pMQ62_$p0Li31hJnUSAsOHdQOR#=U*-Ji0Kt{%`O@wHbJmCFIcrT|;8=9&XHT6j_T(X^hF1;p4oq*aQ1||UJjoHW@DRyU*Nw^N3eP{tT z9;D!U((hFmQAQY_K}&^RM_K?)rG`&RcHo>;eqqlPyLWW!=|EUkU}>D5l%Wo3`+yh& znq%0HZaUM0WbsDAew6+YW{|EYmPpB_5x0OT#zM!6Q5ijYQx?Q|EP8WKR3oiPwNP2VqSO z=}s9VAFTt}2&Eq90+a6a=9dJV^`;=tW#WJZ9Q3CG0Oy)OCO)=nYuraoF{ymES;0cJMf$1lzZ*Az*l=&gyQ^IqyIK z9<+TaLC4?e=|dd<0EGh(5%~JjV3XHA^Z-xNoIYN2_)`Gd0LSyB$?4jc?{m_SpTdv} zg#$h5j9VO@DGPpdObUig;f16kgREOSgb1xVPAquooTbA_+O5bjha!p4?D9 zi1Kr^Q-b9G09u#J1ZVW5BWTS5a0|3k3w5K+;}p9A8K7RIcqgSeDeq4TMI$&P1FZwN zyMhWs^O|5ooOLwfc68;vXbTE{PQR5koHr+fNEnmqX?B6n@p{lPHWA7EsY~_E9Ev{o zN&s#@KT2P^dFxBJZ%(uUlkZ4(0mVw>T!TQ zs&@<6k6;}sgq-8GJ + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & (arg2 eqtype 0) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + rb (1024-52) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/jpegview/memlib.asm b/kernel/branches/hd_kolibri/apps/jpegview/memlib.asm new file mode 100644 index 0000000000..65bbc7a480 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/jpegview/memlib.asm @@ -0,0 +1,210 @@ + +movedata: + push eax + xor eax,eax + sub eax,edi + and eax,3 + xchg ecx,eax + sub eax,ecx + jle .l1 + rep movsb + mov ecx,eax + shr ecx,2 + rep movsd + and eax,3 + .l1: add ecx,eax + rep movsb + pop eax + ret + +mallocz: + call malloc + pushad + add ecx,3 + xor eax,eax + shr ecx,2 + rep stosd + popad + ret + + mresize1: popad + xor edi,edi + stc + mresize2: ret +mresize: ; puntero en di ncr retorna nuevo puntero en di + test edi,edi + jz malloc + cmp ecx,[edi-4] + je mresize2 + call free +malloc: + mov edi,ecx + jecxz mresize2 + pushad + mov esi,iniciomemoria+4 + lea ebx,[ecx+3] + and ebx,-4 ;redondeo a 4 + .l1: mov edi,esi + add esi,[esi] + jc mresize1 + lodsd + cmp eax,ebx + jc .l1 + cmp esi,[iniciomemoria+8] + jc .l2 + jne mresize1 + lea edx,[ebx+esi+4] + cmp edx,[iniciomemoria+12] + jnc mresize1 + mov [iniciomemoria+8],edx + .l2: pop dword [esi-4] + push esi + sub eax,ebx + je .l3 + sub eax,4 + mov [esi+ebx],eax + jz .l3 + ;fragmentar + add ebx,4 + add [edi],ebx + mov eax,[esi] + sub eax,ebx + mov [esi+ebx],eax + popad + ret + .l3: lodsd + add eax,4 + add [edi],eax + popad + ret + +realloc: test edi,edi + jz malloc + jecxz free + pushad + pop esi + mov eax,[edi-4] + call malloc + push edi + cmp ecx,eax + jc .l1 + mov ecx,eax + .l1: push esi + call movedata + pop edi + call free + popad + .l2: ret +free: ;puntero en di + ;no se comprueban los punteros + ;retorna di=0 , ncr + test edi,edi + jz realloc.l2 + pushad + pop edi + mov ebp,[edi-4] + dec ebp + and ebp,-4 ;redondeo a 4,dx=dx-4 + xor edx,edx + push edx + mov edx,iniciomemoria+4 + mov esi,edx + ;buscar puntero libre anterior + .l1: mov ebx,esi + lodsd + add esi,eax + cmp esi,edi + jc .l1 + ;enlazar + mov ecx,esi + sub ecx,edi + sub eax,ecx + sub ecx,4 + mov [ebx],eax + ;fusionar con el anterior + cmp eax,[ebx-4] + jne .l2 + cmp ebx,edx + je .l2 ;no fusionar con el primero + mov edi,ebx + add eax,4 + add ecx,eax + add ebp,eax + .l2: mov ebx,ebp ;fusionar con bloques de tama¤o 0 + .l3: add ebx,4 + test dword [edi+ebx],-1 + jz .l3 + cmp ebx,ecx + jne .l4 + ;fusionar con el siguiente + add ebx,[esi-4] + add ecx,[esi] + add ebx,4 + add ecx,4 + cmp esi,[edx+4] + jne .l4 + mov [edx+4],edi + .l4: mov [edi-4],ebx + mov [edi],ecx + popad + ret + +add_mem: ;edi,ecx ;el ultimo bloque libre debe ser >8 bytes para poder fragmentarlo + cmp ecx,64 + jc .l1 + add ecx,edi + add edi,3 + and edi,-4 + and ecx,-4 + mov eax,ecx + sub ecx,edi ;redondeo + xchg eax,[iniciomemoria+12] + cmp edi,eax + jna .l1 + lea esi,[edi+4] + mov edx,esi + xchg esi,[iniciomemoria+8] + neg edx + mov [edi],edx + mov [edi+4],edx + lea edx,[edi-4] + sub edi,esi + mov [esi],edi + sub eax,4 + sub eax,esi + mov [esi-4],eax + add esi,eax + sub edx,esi + mov [esi],edx + .l1: ret + +check_mem: ;busqueda de errores en la memoria + ;retorna edx nbloques o 0 si error,ecx memoria libre + ;ncr: ebp,ebx,eax + mov edi,iniciomemoria + mov esi,edi + xor edx,edx + mov ecx,[edi] + neg ecx ;el primer bloque no cuenta + .l1: add ecx,[edi] + add edi,4 + add edi,[edi] + .l2: inc edx + add esi,[esi] + jc .l4 + add esi,7 + jc .l3 + and esi,-4 + cmp esi,edi + jc .l2 + je .l1 + jmp .l4 + .l3: test edi,edi + jnz .l4 + add ecx,[iniciomemoria+12] + ret + .l4: xor edx,edx + stc + ret + + diff --git a/kernel/branches/hd_kolibri/apps/launcher/AUTORUN.DAT b/kernel/branches/hd_kolibri/apps/launcher/AUTORUN.DAT new file mode 100644 index 0000000000..4e475ccf87 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/launcher/AUTORUN.DAT @@ -0,0 +1,11 @@ +7 # <- Number of programs in the list + +# Program Parameters Delay +/HD0/1/KOLIBRI/BIN/SETUP BOOT 99 # System setup +/HD0/1/KOLIBRI/BIN/JPEGVIEW BOOT 99 # Background image +/HD0/1/KOLIBRI/BIN/@RB 30 # Desktop right-click menu +/HD0/1/KOLIBRI/BIN/@SS 30 # Screensaver +/HD0/1/KOLIBRI/BIN/@TRACKER 30 # tracker +/HD0/1/KOLIBRI/BIN/@TASKBAR 30 # taskbar +/HD0/1/KOLIBRI/BIN/@DOCK 30 # dock +### Total: 2.6 seconds ### diff --git a/kernel/branches/hd_kolibri/apps/launcher/build.bat b/kernel/branches/hd_kolibri/apps/launcher/build.bat new file mode 100644 index 0000000000..f3f5033341 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/launcher/build.bat @@ -0,0 +1,2 @@ +echo lang fix en >lang.inc +fasm launcher.asm launcher diff --git a/kernel/branches/hd_kolibri/apps/launcher/lang.inc b/kernel/branches/hd_kolibri/apps/launcher/lang.inc new file mode 100644 index 0000000000..0b78d13aff --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/launcher/lang.inc @@ -0,0 +1 @@ +lang fix en diff --git a/kernel/branches/hd_kolibri/apps/launcher/launcher b/kernel/branches/hd_kolibri/apps/launcher/launcher new file mode 100644 index 0000000000000000000000000000000000000000..324963b2f91130f2c77d5d79f4a626bed06f9ea5 GIT binary patch literal 403 zcmeZu^$T?kF)(CgU|>)I;>jRJ0~7-(5XcgW$l{Ma>yYIZvD*hIf7ane4^Vh9FB1d9 zi;F9l z98Soxi3FQsaNzSQ5F2F9=T(V^6JGcNb$6S30Qrr_1c7F(u~8`DT=kz7B=Y)G;^E-1 z7g}ga3=bIIUZZ1R!&%PPD>J)SCIYJZb?1$^=)(zy2hhwb<$x;q473ncj<*CZ*9^9j z$!(2|atVtKZz=1G3;+NBPdp5?92F=qFn}DY@8M#gZ>aC>@8jtdZj-87{b5~)dcb>3;+OheQbmP literal 0 HcmV?d00001 diff --git a/kernel/branches/hd_kolibri/apps/launcher/launcher.asm b/kernel/branches/hd_kolibri/apps/launcher/launcher.asm new file mode 100644 index 0000000000..0e5d135fac --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/launcher/launcher.asm @@ -0,0 +1,200 @@ +; +; LAUNCHER - €‚’Ž‡€“‘Š Žƒ€ŒŒ +; Š®¤ Æą®£ą ¬¬ė į®¢į„¬ ­„ ®ÆāØ¬Ø§Øą®¢ ­, ­® ®ē„­ģ Æą®įā ¤«ļ Æ®­Ø¬ ­Øļ. +; ā®ā « ć­ē„ą £ąć§Øā Ø­ä®ą¬ ęØī ® Æą®£ą ¬¬ å ¤«ļ § ÆćįŖ  ا ä ©«  +; AUTORUN.DAT. ”®ą¬ ā ®ē„­ģ Æą®įā Ø ¢ Ŗ®¬¬„­ā ąØļå ­„ ­ć¦¤ „āįļ. +; +; Š®¬ÆØ«Øąć©ā„ į Æ®¬®éģī FASM 1.52 Ø ¢ėč„ +; +include "MACROS.INC" + + use32 + org 0x0 + db 'MENUET01' ; 8 byte id + dd 0x01 ; header version + dd START ; start of code + dd I_END ; size of image + dd 0x8000 ; memory for app + dd 0x8000 ; esp + dd 0x0 , 0x0 ; I_Param , I_Icon + +;include "DEBUG.INC" + +START: ; start of execution + +; mov eax, 5 +; mov ebx, 10 +; int 0x40 + + mcall 18,15 + + mov eax, 70 ; load AUTORUN.DAT + mov ebx, autorun_dat_info + int 0x40 + + call get_number + mov [number_of_files], eax +;dps "NUMBER OF FILES: " +;dpd eax +;dps <13,10> + call next_line + + start_program: +;dps <"STARTING A PROGRAM",13,10> + call clear_strings + mov edi, program + call get_string + mov edi, parameters + call get_string + call get_number + call run_program + call next_line + dec [number_of_files] + jnz start_program + + exit: + or eax, -1 + int 0x40 + + + run_program: ; time to delay in eax + push eax + mcall 70, start_info + pop ebx + + mov eax, 5 + int 0x40 + ret + + + clear_strings: ; clears buffers + pushad + + mov ecx, 60 + mov edi, program + xor al, al ;mov al, ' ' + rep stosb + + mov ecx, 60 + mov edi, parameters + rep stosb + + popad + ret + + + get_string: ; pointer to destination buffer in edi + pushad + call skip_spaces + mov esi, [position] +;dpd esi +;dps <13,10> + add esi, file_data + .start: + lodsb + cmp al, ' ' + je .finish + stosb + inc [position] + jmp .start + .finish: + popad + ret + + + get_number: + push ebx esi + call skip_spaces + mov esi, [position] + add esi, file_data + xor eax, eax + xor ebx, ebx + .start: + lodsb + sub al, '0' + cmp al, 9 + ja .finish + lea ebx,[ebx*4+ebx] + lea ebx,[ebx*2+eax] + inc [position] + jmp .start + .finish: + mov eax, ebx + pop esi ebx + ret + + + skip_spaces: + pushad + xor eax, eax + mov esi, [position] + add esi, file_data + .start: + lodsb + cmp al, ' ' + jne .finish + inc [position] + jmp .start + .finish: +;dps "NOW AL = " +;mov [tmp],al +;mov edx, tmp +;call debug_outstr +;dps <13,10> + popad + ret + + + next_line: + pushad + mov esi, [position] + add esi, file_data + .start: + lodsb + cmp al, 13 + je .finish + inc [position] + jmp .start + .finish: + add [position], 2 + inc esi + lodsb + cmp al, '#' + je .skipline + cmp al, 13 + jne .donotskip + .skipline: + call next_line + .donotskip: + popad + ret + + + +; DATA: + position dd 0 ; position in file + + autorun_dat_info: ; AUTORUN.DAT + .mode dd 0 ; read file + .start_block dd 0 ; block to read + dd 0 + .blocks dd 16*512 ; 16*512 bytes max + .address dd file_data + db "/HD0/1/KOLIBRI/ETC/AUTORUN.DAT",0 + + start_info: + .mode dd 7 + dd 0 + .params dd parameters + dd 0 + dd 0 + .path: ;       + +I_END: + + program rb 61 ; 60 + [0] char + parameters rb 61 + + number_of_files dd ? + + file_data rb 16*512 diff --git a/kernel/branches/hd_kolibri/apps/launcher/macros.inc b/kernel/branches/hd_kolibri/apps/launcher/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/launcher/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/menu/MENU.DAT b/kernel/branches/hd_kolibri/apps/menu/MENU.DAT new file mode 100644 index 0000000000..b8b4fbaa18 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/MENU.DAT @@ -0,0 +1,163 @@ +#0 **** MAIN **** +GAMES > /@6 +DEMOS > /@1 +GRAPHICS > /@12 +SOUND AND MUSIC > /@11 +DEVELOPMENT > /@2 +SYSTEM > /@4 +NETWORK > /@3 +OTHER > /@5 +HELP /HD0/1/KOLIBRI/BIN/docpak +RUN APPLICATION /HD0/1/KOLIBRI/BIN/run +SHUTDOWN /HD0/1/KOLIBRI/BIN/end +#1 **** DEMOS **** +FIRE /HD0/1/KOLIBRI/BIN/fire +FIRE2 /HD0/1/KOLIBRI/BIN/fire2 +CIRCLE /HD0/1/KOLIBRI/BIN/circle +TRANSPARENCY /HD0/1/KOLIBRI/BIN/transp +FRACTAL /HD0/1/KOLIBRI/BIN/tinyfrac +COLOR DEMO /HD0/1/KOLIBRI/BIN/colorref +EYES /HD0/1/KOLIBRI/BIN/eyes +TUBE /HD0/1/KOLIBRI/BIN/tube +PLASMA /HD0/1/KOLIBRI/BIN/plasma +MOVEBACK /HD0/1/KOLIBRI/BIN/movback +LIFE /HD0/1/KOLIBRI/BIN/life2 +SDLFIRE /HD0/1/KOLIBRI/BIN/sdlfire +TRANTEST /HD0/1/KOLIBRI/BIN/trantest +3D > /@15 +#2 **** PROGRAMMING **** +ARCHIVER MHC /HD0/1/KOLIBRI/BIN/mhc +PACKER MTAPPACK /HD0/1/KOLIBRI/BIN/mtappack +TINYPAD /HD0/1/KOLIBRI/BIN/tinypad +TINYPAD2 /HD0/1/KOLIBRI/BIN/tinypad2 +FLAT ASSEMBLER /HD0/1/KOLIBRI/BIN/fasm +HEX-EDITOR /HD0/1/KOLIBRI/BIN/heed +ASCII-CODES /HD0/1/KOLIBRI/BIN/keyascii +SCAN-CODES /HD0/1/KOLIBRI/BIN/scancode +HEX2DEC2BIN /HD0/1/KOLIBRI/BIN/h2d2b +CALCULATOR /HD0/1/KOLIBRI/BIN/calc +DEBUG BOARD /HD0/1/KOLIBRI/BIN/board +DEBUGGER /HD0/1/KOLIBRI/BIN/mtdbg +EXAMPLES > /@7 +#3 **** NET **** +CONFIGURATION /HD0/1/KOLIBRI/BIN/stackcfg +NET STATUS /HD0/1/KOLIBRI/BIN/ethstat +ARP STATUS /HD0/1/KOLIBRI/BIN/arpstat +DNS RESOLVER /HD0/1/KOLIBRI/BIN/dnsr +DHCP (ONLY TEST) /HD0/1/KOLIBRI/BIN/dhcp +AUTODHCP /HD0/1/KOLIBRI/BIN/autodhcp +TERMINAL /HD0/1/KOLIBRI/BIN/terminal +LOCAL CLUSTER /HD0/1/KOLIBRI/BIN/local +REMOTE CLUSTER /HD0/1/KOLIBRI/BIN/remote +SERVERS > /@9 +CLIENTS > /@10 +#4 **** SYSTEM **** +PROTECTION TEST /HD0/1/KOLIBRI/BIN/test +DEBUG BOARD /HD0/1/KOLIBRI/BIN/board +READ HDD /HD0/1/KOLIBRI/BIN/hdread +ADJUSTMENT > /@8 +SYSTEM SENSORS > /@14 +WORK WITH FILES > /@13 +#5 **** MISC **** +SCREEN MAGNIFIER /HD0/1/KOLIBRI/BIN/magnify +ANALOGUE CLOCK /HD0/1/KOLIBRI/BIN/aclock +BINARY CLOCK /HD0/1/KOLIBRI/BIN/bcdclk +TIMER /HD0/1/KOLIBRI/BIN/timer +SCRSHOOT /HD0/1/KOLIBRI/BIN/scrshoot +CALENDAR /HD0/1/KOLIBRI/BIN/calendar +BGI FONT DEMO /HD0/1/KOLIBRI/BIN/bgitest +RTF READER /HD0/1/KOLIBRI/BIN/rtfread +@RCHER /HD0/1/KOLIBRI/BIN/@rcher +#6 **** GAMES **** +TETRIS /HD0/1/KOLIBRI/BIN/tetris +C4 /HD0/1/KOLIBRI/BIN/c4 +15 /HD0/1/KOLIBRI/BIN/15 +MINE /HD0/1/KOLIBRI/BIN/mine +PONG /HD0/1/KOLIBRI/BIN/pong +MEMORY BLOCKS /HD0/1/KOLIBRI/BIN/mblocks +NEW PONG /HD0/1/KOLIBRI/BIN/pong3 +PHENIX /HD0/1/KOLIBRI/BIN/phenix +FREECELL /HD0/1/KOLIBRI/BIN/freecell +ARCANII /HD0/1/KOLIBRI/BIN/arcanii +CLICKOMANIA /HD0/1/KOLIBRI/BIN/click +RED SQUARE /HD0/1/KOLIBRI/BIN/rsquare +PIPES /HD0/1/KOLIBRI/BIN/pipes +XONIX /HD0/1/KOLIBRI/BIN/xonix +PHARAOH TOMB /HD0/1/KOLIBRI/BIN/fara +SQ_GAME /HD0/1/KOLIBRI/BIN/sq_game +CHECKERS /HD0/1/KOLIBRI/BIN/checkers +QUAKE HD0_1 /HD0/1/MENUETOS/sdlquake +DOOM HD0_1 /HD0/1/MENUETOS/doom/mdoom +SOKOBAN HD0_1 /HD0/1/KOLIBRI/BIN/soko +#7 **** EXAMPLES **** +THREADS /HD0/1/KOLIBRI/BIN/thread +IPC /HD0/1/KOLIBRI/BIN/ipc +COLOR SLIDER /HD0/1/KOLIBRI/BIN/cslide +CONSOLE EXAMPLE /HD0/1/KOLIBRI/BIN/testcon2 +#8 **** SETUP **** +DEVICES SETUP /HD0/1/KOLIBRI/BIN/setup +BACKGROUND SETUP /HD0/1/KOLIBRI/BIN/pic4 +MEVIEW /HD0/1/KOLIBRI/BIN/mv +JPEGVIEW /HD0/1/KOLIBRI/BIN/jpegview +COLORS & SKIN SETUP /HD0/1/KOLIBRI/BIN/desktop +PANEL SETUP /HD0/1/KOLIBRI/BIN/spanel +ICONS SETUP /HD0/1/KOLIBRI/BIN/icon +VRR /HD0/1/KOLIBRI/BIN/vrr +#9 **** SERVERS **** +SMTPS /HD0/1/KOLIBRI/BIN/smtps +HTTPS /HD0/1/KOLIBRI/BIN/https +MP3S /HD0/1/KOLIBRI/BIN/mp3s +FTPS /HD0/1/KOLIBRI/BIN/ftps +NETSENDS /HD0/1/KOLIBRI/BIN/netsends +RCC-SERVER /HD0/1/KOLIBRI/BIN/rccs +#10 **** CLIENTS **** +TFTP CLIENT /HD0/1/KOLIBRI/BIN/tftpc +INTERNET-CHESS /HD0/1/KOLIBRI/BIN/chess +SIMPLY BROWSER /HD0/1/KOLIBRI/BIN/httpc +NNTP-NEWSGROUPS /HD0/1/KOLIBRI/BIN/nntpc +TELNET /HD0/1/KOLIBRI/BIN/telnet +POP - MAIL /HD0/1/KOLIBRI/BIN/popc +TFTP AUDIO STREAM /HD0/1/KOLIBRI/BIN/tftpa +IRC CLIENT /HD0/1/KOLIBRI/BIN/airc +YAHOO MESSENG.(DEMO) /HD0/1/KOLIBRI/BIN/ym +NETSENDC /HD0/1/KOLIBRI/BIN/netsendc +TESTFTP1 /HD0/1/KOLIBRI/BIN/testftp1 +RCC-CLIENT /HD0/1/KOLIBRI/BIN/rccc +JMAIL /rd/1/network/jmail +#11 **** AUDIO **** +SB AUDIO PLAYER /HD0/1/KOLIBRI/BIN/sb +MIDAMP /HD0/1/KOLIBRI/BIN/midamp +CD PLAYER /HD0/1/KOLIBRI/BIN/cdp +VOLUME /HD0/1/KOLIBRI/BIN/mixer +TEST MIDI /HD0/1/KOLIBRI/BIN/midiplay +#12 **** GRAPHICS **** +ICON EDITOR (BMP) /HD0/1/KOLIBRI/BIN/iconedit +JPEG VIEWER /HD0/1/KOLIBRI/BIN/jpegview +BMP VIEWER /HD0/1/KOLIBRI/BIN/mv +GIFVIEW /HD0/1/KOLIBRI/BIN/gifview +ANIMAGE /HD0/1/KOLIBRI/BIN/animage +#13 **** €Ž’€ ‘ ”€‰‹€Œˆ **** +CMD CONSOLE /HD0/1/KOLIBRI/BIN/cmd +SYSXTREE /HD0/1/KOLIBRI/BIN/sysxtree +KFAR /HD0/1/KOLIBRI/BIN/kfar +COPY FILE /HD0/1/KOLIBRI/BIN/copy2 +SAVE RD IMAGE /HD0/1/KOLIBRI/BIN/rdsave +#14 +PROCESSES (CPU) /HD0/1/KOLIBRI/BIN/cpu +PCI DEVICES /HD0/1/KOLIBRI/BIN/pcidev +TEST GRAPHICS SPEED /HD0/1/KOLIBRI/BIN/mgb +CPUID /HD0/1/KOLIBRI/BIN/cpuid +GHOST MONITOR /HD0/1/KOLIBRI/BIN/gmon +K. BUS DISCONNECTED /HD0/1/KOLIBRI/BIN/kbd +#15 +SCREENSAVER /HD0/1/KOLIBRI/BIN/crownscr +3D-CUBE /HD0/1/KOLIBRI/BIN/3dcube2 +3D-LABYRINTH /HD0/1/KOLIBRI/BIN/free3d04 +3D-TEXTURED CUBE /HD0/1/KOLIBRI/BIN/3dtcub10 +3DSHEART /HD0/1/KOLIBRI/BIN/3dsheart +VIEW3DS /HD0/1/KOLIBRI/BIN/view3ds +CUBELINE /HD0/1/KOLIBRI/BIN/cubeline +3D-TEXTURED CUBE 2 /HD0/1/KOLIBRI/BIN/cubetext +GEARS /HD0/1/KOLIBRI/BIN/gears +FLATWAV /HD0/1/KOLIBRI/BIN/flatwav +## diff --git a/kernel/branches/hd_kolibri/apps/menu/build.bat b/kernel/branches/hd_kolibri/apps/menu/build.bat new file mode 100644 index 0000000000..eb536046f8 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/build.bat @@ -0,0 +1,2 @@ +echo lang fix en >lang.inc +fasm menu.asm menu diff --git a/kernel/branches/hd_kolibri/apps/menu/lang.inc b/kernel/branches/hd_kolibri/apps/menu/lang.inc new file mode 100644 index 0000000000..0b78d13aff --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/lang.inc @@ -0,0 +1 @@ +lang fix en diff --git a/kernel/branches/hd_kolibri/apps/menu/macros.inc b/kernel/branches/hd_kolibri/apps/menu/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/menu/menu b/kernel/branches/hd_kolibri/apps/menu/menu new file mode 100644 index 0000000000000000000000000000000000000000..c0a7ed27f233d98915fe16e27c4a0a7170daf7b8 GIT binary patch literal 1264 zcmb7E-EZ4e6u(LBW{DG=X>BSofvOF(lx-wYLFz(7Tz5_AKH8}&#I#ZaFP`MS6?>I< zA(m@oJA*#~Z43!*lTZPv)tJQM8Koa!gbG51NT|>kM?s9OL&+eEIX6Lj*c(UkJ)ie? z@A;i8pB8!_9l2s2lWBH^iKtc7a3;9~KXoyM$~-0Zo6&B`*L_ z?R!0SA9V34?45p;Pi*NAj#A5khZsoQS4fAX`)uv5{)+Q9rE$ zr>OR^a|EkPHe+OoLi01J&p1zM=Yy?DidL@zh?b?Qmq8brpGpV+%VnvdEJeR-K)9Tx zJXN`!4@o5CYX=I=gS2|ab=~R*5Eu3X3wkS8OdAj?E~cHW~RfvI#zx z>QTVWSHEq!ZuXpm-w>x(#6Ps{&LCS~4{a~*Br|@oqGkMiaf0M!^F2hbd}sbf$hR?F zync#=gwL2GqPz4;=?WeSy;7MHB3yl!A24U2!Ur8}z;PNIFjzukDUA)5SwE6f3-}^C z9wY_U$c_zj=ve(g#vqrdjNbSgYKpx$Z8OygU`lwF6TC28wIt=ih8mkO*Ta13B3ewD zPB^h8L}u%I3`~+ZvAy^l&@c8Fd8+V^A4wF9NXrME>wxME!a`qf^HE)Y=(^4!9QeEw zScQO+YI7x$)vMTBceSh^2Glr?n>QW8$|XvPis8!+#}`7wCl>w3;`5b&$Ey9Fw}fEl zYWN!SR)k)i^bMHiuVIflPOs)kb2rT2yoeH|FW^j%{v$kHKUlD<-JF%!a-IgCP3DM& zzrZtcRBO|rAY|l%V8OJIH6`rh00eWsIlmDBbj9o~zSsk|Yuz5oQBt>D4u``?-h`Td z8z|XoZO;E3k*#h-;7udNzCto2cCobvTSx|^d*jlbVyGYX3j`B%$W?9_N{Y +; +; Compile with FASM for Menuet +;****************************************************************************** + include "lang.inc" + include "macros.inc" + + BTN_HEIGHT = 22 + TXT_Y = (BTN_HEIGHT)/2-5 + + use32 + org 0x0 + db 'MENUET01' ; 8 byte id + dd 0x01 ; header version + dd START ; start of code + dd I_END ; size of image + dd 0x20000 ; memory for app + dd 0x20000-1 ; esp + dd 0x0 , 0x0 ; I_Param , I_Icon +;****************************************************************************** +;include "DEBUG.INC" ; debug macros +START: ; start of execution + + mov eax, 48 ; load system colors + mov ebx, 3 + mov ecx, sc + mov edx, sizeof.system_colors + int 0x40 + + mov eax, 70 ; load MENU.DAT + mov ebx, fileinfo + int 0x40 + test eax, eax ; error ? + jz @f + cmp eax,6 + jnz close + @@: + test ebx, ebx ; length = 0 ? + jz close + mov ecx, ebx + mov edi, mem_end + newsearch: + mov al, '#' + cld + repne scasb + test ecx, ecx ; if not found + jz close + call get_number + test ebx, ebx + jnz .number + cmp al, '#' + je search_end + .number: + shl ebx, 4 + add ebx, menu_data ; pointer to process table + mov [ebx], edi + inc [processes] + jmp newsearch + search_end: + mov [end_pointer], edi + mov ebx, [processes] + dec ebx + shl ebx, 4 + add ebx, menu_data + newprocess: + xor edx, edx + mov ecx, edi + sub ecx, [ebx] + mov al, 10 + newsearch1: + std + repne scasb + test ecx, ecx + je endprocess + cmp [edi], byte 13 + jne newsearch1 + inc edx + jmp newsearch1 + endprocess: + mov esi, ebx + add esi, 4 + dec edx + mov [esi], dl + cmp ebx, menu_data + jbe search_end1 + sub ebx, 16 + jmp newprocess + search_end1: + mov eax, 14 + int 0x40 + sub ax, 20 + mov [menu_data + y_end], ax + mov [menu_data + x_start], 5 + mov al, [menu_data + rows] + mov [menu_data + cur_sel], al ; clear selection + mov [menu_data + prev_sel], al + + mov [buffer], 0 + thread: + mov eax, [buffer] ; identifier + shl eax, 4 + add eax, menu_data + mov edi, eax + + mov eax, 40 ; set event mask + mov ebx, 100111b ; mouse + button + key + redraw + int 0x40 + + call draw_window + +still: + mov eax, 23 ; wait here for event + mov ebx, 5 + int 0x40 + + test [close_now], 1 ; is close flag set? + jnz close + + cmp eax, 1 ; redraw request ? + je red + cmp eax, 2 ; key pressed ? + je key + cmp eax, 3 ; button in buffer ? + je button + cmp eax, 6 ; mouse event ? + je mouse + + cmp edi, menu_data + je still ; if main process-ignored + + movzx ebx, [edi + parent] ; parent id + shl ebx, 4 + add ebx, menu_data ; ebx = base of parent info + call backconvert ; get my id in al + cmp al, [ebx + child] ; if I'm not child of my parent, I shall die :) + jne close + + jmp still + + + red: ; redraw + call draw_window + jmp still + + + key: +; mov eax, 2 + int 0x40 + + mov al, [edi + rows] ; number of buttons + + cmp ah, 178 ; KEY_UP + jne .noup + + mov ah, [edi+cur_sel] + mov [edi+prev_sel], ah + dec byte [edi+cur_sel] + jnz redrawbut + mov [edi+cur_sel], al + jmp redrawbut + + + .noup: + cmp ah, 177 ; KEY_DOWN + jne .nodn + + mov ah, [edi + cur_sel] + mov [edi + prev_sel], ah + inc [edi + cur_sel] + cmp [edi + cur_sel], al + jna redrawbut + mov [edi + cur_sel], 1 + jmp redrawbut + + .nodn: + cmp ah, 13 ; ENTER + jne .noenter + mov ah, [edi + cur_sel] + jmp button1 + + .noenter: + cmp ah, 27 ; ESC + jne still + jmp close + +; include "DEBUG.INC" + + button: ; BUTTON HANDLER + mov eax, 17 ; get id + int 0x40 + + button1: + mov esi, edi + push edi + mov edi, [edi + pointer] + +; print "hello" + mov al, [esi + cur_sel] + mov [esi + prev_sel], al + mov [esi + cur_sel], ah + pushad + mov edi, esi +; dph eax + call draw_only_needed_buttons + popad + + ; look for the next line times; = button_id + push eax + .next_string: + call searchstartstring + dec ah + jnz .next_string + pop eax + + mov ecx, 40 + mov al, '/' + cld + repne scasb + test ecx, ecx ; if '/' not found + je searchexit + + cmp [edi], byte '@' ; check for submenu + je runthread + + dec edi + push edi ; pointer to start of filename + call searchstartstring ; search for next string + sub edi, 2 ; to last byte of string + + mov ecx, edi + pop esi + sub ecx, esi + inc ecx ; length of filename + mov edi, fileinfo_start.name + rep movsb ; copy string + mov byte [edi], 0 ; store terminator + mov eax, 70 ; start program + mov ebx, fileinfo_start + int 0x40 +; mcall 5,100 + or [close_now], 1 ; set close flag + pop edi + mov [mousemask], 0 + jmp close + + searchexit: + pop edi + jmp still + + + runthread: + inc edi + + push eax + call get_number ; get number of this process + pop eax + + test ebx, ebx ; returned zero - main menu or not number + jz searchexit + + mov al, bl + + mov ebx, [processes] + dec bl + cmp al, bl + ja searchexit ; such process doesnt exist + cmp al, [esi + child] + je searchexit ; such process already exists + + mov [esi + child], al ; this is my child + mov cx, [esi + x_start] + add cx, 141 ; new x_start in cx + movzx edx, al + shl edx, 4 + add edx, menu_data ; edx points to child's base address + mov [edx + x_start], cx ; xstart for new thread + mov cx, [esi + y_end] ; y_end in cx + mov bl, [esi + rows] ; number of buttons in bl + sub bl, ah ; number of btn from bottom + movzx eax, al + mov [buffer], eax ; thread id in buffer + movzx ebx, bl + push edx + mov eax, BTN_HEIGHT + mul ebx + sub cx, ax ; new y_end for new thread + pop edx + mov [edx + y_end], cx ; store y_end + mov edi, esi + call backconvert ; get number of this process (al) + mov [edx + parent], al ; store number of parent process + mov al, [edx + rows] + mov [edx + cur_sel], al ; clear current selected element + mov [edx + prev_sel], al ; clear previous selected element + mov [edx + child], 0 + + cmp [thread_stack], 0x1e000 + jne thread_stack_not_full + mov [thread_stack], 0xE000 + +thread_stack_not_full: + add [thread_stack], 0x2000 ; start new thread + mov eax, 51 + mov ebx, 1 + mov ecx, thread + mov edx, [thread_stack] + int 0x40 + + jmp searchexit + + + mouse: ; MOUSE EVENT HANDLER + mov eax, 37 + mov ebx, 2 + int 0x40 + test eax, eax ; check buttons state + jnz click + mov eax, 37 + mov ebx, 1 + int 0x40 + ror eax, 16 ; eax = [ Y | X ] relative to window + cmp ax, 140 ; pointer in window? + ja noinwindow +;  in window  + + shr eax, 16 ; eax = [ 0 | Y ] + xor edx, edx + mov ebx, BTN_HEIGHT + div ebx + inc eax ; number of "button" in eax + movzx ebx, [edi + rows] ; total strings in ebx + cmp eax, ebx + ja noinwindow + cmp [edi + cur_sel], al + je noredrawbut + mov bl, [edi + cur_sel] + + ;;;;;; + cmp [edi + child], 0 + jne noredrawbut + ;;;;;; + + mov [edi + cur_sel], al + mov [edi + prev_sel], bl + redrawbut: + call draw_only_needed_buttons + noredrawbut: + call backconvert + bts [mousemask], eax + jmp still + noinwindow: + call backconvert + btr [mousemask], eax + jmp still + click: + cmp [mousemask], 0 ; not in a window (i.e. menu) + je close + jmp still + + + close: + or eax, -1 ; close this thread + mov [edi + child], al ; my child is not mine + int 0x40 + + + backconvert: ; convert from pointer to process id + mov eax, edi + sub eax, menu_data + shr eax, 4 + ret + + +;================================== +; get_number +; load number from [edi] to ebx +;================================== + get_number: + push edi + + xor eax, eax + xor ebx, ebx + + .get_next_char: + mov al, [edi] + inc edi + cmp al, '0' + jb .finish + cmp al, '9' + ja .finish + sub al, '0' + imul ebx, 10 + add ebx, eax + jmp .get_next_char + + .finish: + pop edi + ret + + +; ********************************************* +; ******* WINDOW DEFINITIONS AND DRAW ******** +; ********************************************* + + +draw_window: + + mov eax, 12 ; function 12:tell os about windowdraw + mov ebx, 1 ; 1, start of draw + int 0x40 + + movzx ebx, [edi + rows] + imul eax, ebx, BTN_HEIGHT ; eax = height of window + movzx ecx, [edi + y_end] + sub ecx, eax ; ecx = Y_START + shl ecx, 16 + add ecx, eax ; ecx = [ Y_START | Y_SIZE ] + dec ecx + movzx ebx, [edi + x_start] + shl ebx, 16 + mov bx, 140 ; ebx = [ X_START | X_SIZE ] + xor eax, eax ; function 0 : define and draw window + mov edx, 0x01000000 ; color of work area RRGGBB,8->color gl + mov esi, edx ; unmovable window + int 0x40 + + call draw_all_buttons + + mov eax,12 + mov ebx,2 + int 0x40 + + ret + + + draw_all_buttons: + xor edx, edx + .new_button: + call draw_one_button + inc edx + cmp dl, [edi + rows] + jb .new_button + + ret + + + draw_only_needed_buttons: + xor edx, edx + mov dl, [edi + cur_sel] + dec dl + call draw_one_button + mov dl, [edi + prev_sel] + dec dl + call draw_one_button + ret + + + draw_one_button: + ; receives number of button in dl + push edx;ad + + mov eax, 8 + mov ebx, 140 + movzx ecx, dl + imul ecx, BTN_HEIGHT + shl ecx, 16 + add ecx, BTN_HEIGHT-1 +; edx = button identifier + mov esi, [sc.work] + inc dl + cmp [edi + cur_sel], dl + jne .nohighlight + add esi, 0x101010 + .nohighlight: + or edx, 0x20000000 + int 0x40 + movzx edx, dl + + dec dl + imul ebx, edx, BTN_HEIGHT + add ebx, (4 shl 16) + TXT_Y + + movzx ecx, dl + inc ecx + mov edx, [edi + pointer] + .findline: + cmp byte [edx], 13 + je .linefound + inc edx + jmp .findline + .linefound: + inc edx + cmp byte [edx], 10 + jne .findline + dec ecx + jnz .findline + + mov ecx, [sc.work_text] + mov eax, 4 + mov esi, 21 + int 0x40 + + pop edx;ad + ret + + + searchstartstring: + mov ecx, 40 + mov al, 13 + cld + repne scasb + cmp byte [edi], 10 + jne searchstartstring + ret + + +;*** DATA AREA **************************************************************** + +thread_stack dd 0xE000 +processes dd 0 + +fileinfo: + .subfunction dd 0 ; 0=READ + .start dd 0 ; start byte + .size_high dd 0 ; rezerved + .size dd 0x10000-mem_end ; blocks to read + .return dd mem_end ; return data pointer + .name: + db '/HD0/1/KOLIBRI/ETC/MENU.DAT',0 ; ASCIIZ dir & filename + +fileinfo_start: + .subfunction dd 7 ; 7=START APPLICATION + .flags dd 0 ; flags + .params dd 0x0 ; nop + .rezerved dd 0x0 ; nop + .rezerved_1 dd 0x0 ; nop + .name: + times 50 db ' ' + +I_END: + +close_now dd ? ; close all processes immediately +end_pointer dd ? +buffer dd ? +mousemask dd ? ; mask for mouse pointer location + +sc system_colors + +menu_data: + rb 0x4000 ;x10000 + +virtual at 0 ; PROCESSES TABLE (located at menu_data) + pointer dd ? ; +0 pointer in file + rows db ? ; +4 numer of strings + x_start dw ? ; +5 x start + y_end dw ? ; +7 y end + child db ? ; +9 id of child menu + parent db ? ; +10 id of parent menu + cur_sel db ? ; +11 current selection + prev_sel db ? ; +12 previous selection + rb 16-$+1 ; [16 bytes per element] +end virtual + +mem_end: diff --git a/kernel/branches/hd_kolibri/apps/menu/readme.txt b/kernel/branches/hd_kolibri/apps/menu/readme.txt new file mode 100644 index 0000000000..7e7c093e4a --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/readme.txt @@ -0,0 +1,73 @@ +English text is below +ĶĪĀĪÅ ĆĖĄĀĶĪÅ ĢÅĶŽ. +Āķčģąķčå: äė’ źīššåźņķīé šąįīņū šåźīģåķäóåņń’ MENUET ķå ķčęå 0.76 +č öāåņķīé ģīķčņīš (ķą ģīķīõšīģķīģ ļīäńāåņźą ķå āčäķą) + +Īņėč÷č’ īņ Āčėėčķīćī ģåķž: +1.Źīķōčćóščšóåģīńņü. Ļóķźņū źąź īńķīāķīćī, ņąź č äīļīėķčņåėüķūõ +ģåķžųåź ēąäąžņń’ ōąéėīģ MENU.DAT. +Żņī ļīēāīė’åņ: +-äīįąāė’ņü/óįčšąņü ėžįūå ļóķźņū ā ģåķž. Ļšīćšąģģą ńąģą ąķąėčēčšóåņ +čēģåķåķč’ č ščńóåņ īźķī ń źķīļźąģč ļī źīėč÷åńņāó ļóķźņīā.Ā äąėüķåéųåģ +čģõī żņī ļīēāīėčņ źīķōčćóščšīāąņü ģåķž ķå ņīėüźī āšó÷ķóž, ķī č ļšīć- +šąģģķī. Ķčźąźīćī āģåųąņåėüńņāą ā źīä, ÷ņī ļīēāīė’åņ źīķōčćóščņü ģåķž +č ļšīńņūģ ļīėüēīāąņåė’ģ. +-ļåšåāīäčņü ģåķž ķą ėžįūå ’ēūźč, ķå ėąē’ ā źīä. +-ļīńźīėüźó ēąļóńź ļščėīęåķčé ÷åšåē 58-ž ōóķźöčž, ļščėīęåķč’ ģīćóņ ķąõīäčņü- +ń’ ķå ņīėüźī ķą šąģäčńźå. +2.Āåłčöą, ńīāńåģ ķå čķņåšåńķą’ äė’ ļīėüēīāąņåėåé, ķī āīēģīęķī +ļšåäńņąāė’žłą’ čķņåšåń äė’ ļšīćšąģģčńņīā. Ļščėīęåķčå ģķīćīļīņī÷ķīå, ķī āńå +ļīņīźč ēąļóńźąžņń’ ķą īäķīģ č ņīģ ęå źīäå. Żņī ļīēāīėčėī ēąģåķčņü čńļīė- +ķ’åģūå ōąéėū MENU, SELECT1, SELECT2 č ņ.ä. īäķčģ-åäčķńņāåķķūģ MENU +č ńčėüķī ńżźīķīģčņü ģåńņī ķą äčńźå. +3.Ńąģīóķč÷ņīęąåģīńņü ģåķž ļšč źėčźå ēą åćī ļšåäåėąģč č ļšč ēąļóńźå ļščėīęåķč’ +4.Źķīļźč, ļīäńāå÷čāąåģūå ļšč ķąāåäåķčč ķą ķčõ ģūųüž (ķą ģīķīõšīģķīģ ģīķčņīšå +ļīäńāåņźą ķå āčäķą). +5.Ļīääåšęźą źėąāčąņóšū. Źķīļźč Āāåšõ, Āķčē, Enter č Esc. +Ā īįłåģ, ļīńņąšąėń’ ļščįėčēčņüń’ ź āčķäīāńźīé ģåķžųźå. + +Ēąģå÷ąķč’ ļī ńčķņąźńčńó ōąéėą MENU.DAT: +Šąēģåš ōąéėą MENU.DAT-ķå įīėåå 2Ź +Ģåķž #0-āńåćäą ćėąāķīå. +Źīėč÷åńņāī ģåķž-ķå įīėåå 10 - īņ #0 äī #9 +Ā źąęäīé ńņšīźå ėčįī ļóņü ķą čńļīėķ’åģūé ōąéė, ėčįī ńńūėźą ķą äī÷åšķåå +ģåķž, ķąļščģåš /@5 +Ģąšźåš źīķöą ## īį’ēąņåėåķ (āķčģąķčå! TINYPAD įūāąåņ åćī īįšåēąåņ) +Ļīä ņåźńņ ķą ģåķžųķūõ źķīļźąõ īņāīä’ņń’ ļåšāūå 20 ļīēčöčé źąęäīé ńņšīźč +Źąęäą’ ńņšīźą īņäåė’åņń’ ENTERīģ, ņ.å. äīėęķū ļščńóņńņāīāąņü ēķąźč ļåšå- +āīäą ńņšīźč 0x0d,0x0a + +Ļšīćą Ī×ÅĶÜ ńūšą’, ļīżņīģó ļšīńüįą ķå óäčāė’ņüń’, åńėč ÷ņī-ķčņü ķå įóäåņ +šąįīņąņü. Ń ōąéėīģ MENU.DAT ļšīńüįą īįšąłąņüń’ ī÷åķü īńņīšīęķī. TINYPAD +čķīćäą åćī źąėå÷čņ. Īńīįåķķī ģąšźåš źīķöą ōąéėą! +Čńļīėķ’åģūé ōąéė ī÷åķü šåźīģåķäóåņń’ ķąēāąņü MENU. (ļšč źīģļčė’öčč) +Ņīćäą īķ įóäåņ āūēūāąņüń’ čē ļąķåėč źąź č ļīėīęåķī. +Āńå ēąģå÷ąķč’ č ļšåäėīęåķč’ ń óäīāīėüńņāčåģ ļščķčģąžņń’ ķą lisovin@26.ru +Ļščąņņą÷åķķūå ōąéėū ńėåäóåņ āūńūėąņü ķą mutny@rambler.ru +Ń óāąęåķčåģ, +Ģčõąčė Ėčńīāčķ + +NEW MAIN MENU +Requirements: MENUET 0.76, color monitor +WHAT'S NEW? +1.Self-configuring menu. All the configurational data is in MENU.DAT +You may add/remove menu positions, translate menu to any language, +run menu applications from HDD without source code change. +2.Multi-thread application. There're two files only: MENU and MENU.DAT +instead of MENU, SELECT1, SELECT2, SELECT3 etc. +3.Self-closing when running application or clicking out of menu. +4.Button highlight +5.Keyboard support (keys Up, Dn, Enter, Esc.) +So, it's just like Windows menu ;) +NOTES ON MENU.DAT: +Size of MENU.DAT should be not more than 2K +Number of menus-not more than 10 (from #0 to #9). #0 is always main menu +## is an end file marker - always required. +First 20 positions of any string reserved for button text +Any string contains file path or link to submenu, for example /@4. +You may edit MENU.DAT by any text editor, but be careful when using +TINYPAD (sometimes it cuts end marker). +It is recommended to compile MMENU.ASM as MENU. So, you can run it from +standard panel. +All the comments and bugreports send to lisovin@26.ru +Michail Lisovin. \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/menu/readme2.txt b/kernel/branches/hd_kolibri/apps/menu/readme2.txt new file mode 100644 index 0000000000..288b9b5267 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/menu/readme2.txt @@ -0,0 +1,6 @@ +Changes: +11.07.06 - Mario79, application used function 70. +Earlier changes were made: +Ivan Poddubny, Mario79 and Halyavin + + diff --git a/kernel/branches/hd_kolibri/apps/panel/@PANEL.ASM b/kernel/branches/hd_kolibri/apps/panel/@PANEL.ASM new file mode 100644 index 0000000000..dfc2257d0a --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/panel/@PANEL.ASM @@ -0,0 +1,2089 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MENUBAR for KolibriOS - Compile with fasm ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +use32 + org 0x0 + db 'MENUET01' ; 8 byte id + dd 0x01 ; header version + dd START ; program start + dd I_END ; program image size + dd 0xA000 ; reguired amount of memory - 10 Kb + dd 0xA000 ; esp + dd 0x0,0x0 ; param, icon + +include 'lang.inc' +include 'macros.inc' + +width dd 305 +buttons dd 1 ; 0 no frames ; 1 frames +soften_up dd 1 ; 0 no ; 1 yes +soften_down dd 0 ; 0 no ; 1 yes +minimize_left dd 1 +minimize_right dd 1 +icons_position dd 95 +menu_enable dd 1 +setup_enable dd 0 +graph_text dd 1 +soften_middle dd 1 ; 0 no ; 1 yes +icons dd 1 ; 0 defaults ; 1 activate + +PANEL_HEIGHT = 18 + +handle_key: + + mcall 18, 7 + mov [active_process],eax + + mcall 2 + cmp al, 2 + jnz begin_1.ret + mov ebx, exec_fileinfo + shr eax, 8 + cmp al, 15 + jz alt_tab_pressed + cmp al, 88 + jz start_end_application + cmp al, 91 + jz start_menu_application + cmp al, 92 + jz start_menu_application + cmp al, 62 + jz kill_active_application + cmp al, 71 + jz page_list_next + cmp al, 72 + jz page_list_prev + cmp [current_alt_tab_app], -1 + jz @f + test ah, 0x30 + jz alt_tab_released +@@: +; this is hotkey Ctrl+Shift ;or LShift+RShift + mov ebx, setup_exec +; test ah, 001100b +; jz change_sys_lang +change_key_lang: + mov dword [ebx+8], chlang + mcall 70 + call chlang_music +; mcall 5, 25 +begin_1: + mov ecx,[active_process] + mcall 18, 3 + mcall 5, 25 +.ret: + ret + +;change_sys_lang: +; mov dword [ebx+8], syslang +; mcall 70 +; call syslang_music +;; mcall 5, 25 +; jmp begin_1 + + start_end_application: + mov dword [ebx+21], end_name + mcall 70 + mcall 5 ,50 + jmp begin_1.ret + + kill_active_application: + mcall 18, 7 + mov ecx,eax +; mcall 9, area9 +; mov eax,area9 +; mov ecx,[eax+4] + mcall 18, 2 + jmp begin_1.ret + + start_menu_application: + mov [draw_window_1], 1 + mov dword [ebx+21], menu_name + mcall 70 + call menu_music + mcall 5,50 + jmp begin_1.ret + +page_list_next: + cmp [page_list],15 + je @f + inc [page_list] + mov [draw_window_1],1 + @@: + jmp begin_1.ret + +page_list_prev: + cmp [page_list],0 + je @f + dec [page_list] + mov [draw_window_1],1 + @@: + jmp begin_1.ret + +alt_tab_pressed: +; handle Alt+Tab and Alt+Shift+Tab + mov ebp, eax + cmp [current_alt_tab_app], -1 + jnz has_alt_tab_app +; § Æ®«­ļ„¬ ā ”«Øęć ÆąØ«®¦„­Ø©, Æ®¤«„¦ éØå Æ„ą„Ŗ«īē„­Øī + xor edx, edx + mov ebx, 0x8000 + mov ecx, 1 + mov eax, 9 +.fill: + inc ecx + int 0x40 + call need_window_tab + jz @f + cmp edx, 256 + jz @f + mov [alt_tab_list+edx*8], ecx + movzx esi, word [ebx+4] + mov [alt_tab_list+edx*8+4], esi + inc edx +@@: + cmp ecx, eax + mov eax, 9 + jb .fill + mov [alt_tab_list_size], edx + cmp edx, 2 + jb begin_1.ret + mcall 66,4,0,0 ; «®¢Ø¬ ¬®¬„­ā ®āÆćįŖ ­Øļ ¢į„å ćÆą ¢«ļīéØå Ŗ« ¢Øč + test eax, eax + jnz begin_1.ret + xor edx, edx + mov eax, [alt_tab_list+4] + xor ecx, ecx + inc ecx +.findmax: + cmp [alt_tab_list+ecx*8+4], eax + jb @f + mov edx, ecx + mov eax, [alt_tab_list+ecx*8+4] +@@: + inc ecx + cmp ecx, [alt_tab_list_size] + jb .findmax + mov [current_alt_tab_app], edx +has_alt_tab_app: + mov eax, [current_alt_tab_app] + mov edx, [alt_tab_list+eax*8+4] ; slot + xor ecx, ecx + or eax, -1 + test ebp, 300h + jz .notshift + or esi, -1 +.loop1: + cmp [alt_tab_list+ecx*8+4], edx + jbe @f + cmp [alt_tab_list+ecx*8+4], esi + jae @f + mov eax, ecx + mov esi, [alt_tab_list+ecx*8+4] +@@: + inc ecx + cmp ecx, [alt_tab_list_size] + jb .loop1 + cmp eax, -1 + jnz .found + xor edx, edx + xor ecx, ecx + jmp .loop1 +.notshift: + xor esi, esi +.loop2: + cmp [alt_tab_list+ecx*8+4], edx + jae @f + cmp [alt_tab_list+ecx*8+4], esi + jbe @f + mov eax, ecx + mov esi, [alt_tab_list+ecx*8+4] +@@: + inc ecx + cmp ecx, [alt_tab_list_size] + jb .loop2 + cmp eax, -1 + jnz .found + or edx, -1 + xor ecx, ecx + jmp .loop2 +.found: + mov [current_alt_tab_app], eax + push eax + xor edx, edx + div [max_applications] + mov [page_list], eax + mov [draw_window_1], 1 + mov edi, app_list + push edi + mov ecx, 20 + or eax, -1 + rep stosd + pop edi + pop ecx + sub ecx, edx +@@: + cmp ecx, [alt_tab_list_size] + jae redraw_window_tabs + mov eax, [alt_tab_list+ecx*8] + stosd + inc ecx + jmp @b + +alt_tab_released: + mcall 66,5,0,0 ; 榄 Æ®©¬ «Ø, 墠āØā :) + or eax, -1 + xchg eax, [current_alt_tab_app] + mov ecx, [alt_tab_list+eax*8] + mov eax, 18 + mov ebx, 3 + int 0x40 + jmp redraw_window_tabs + +active_process dd 0 + +calendar_music: + mcall 55, eax, , , calendarmusic + ret +setup_music: + mcall 55,eax, , ,setupmusic + ret +sysmeter_music: + mcall 55,eax, , ,sysmetermusic + ret +button_music: + mcall 55,eax, , ,buttonmusic + ret +;syslang_music: +; mcall 55, eax, , , syslangmusic +; ret +chlang_music: + mcall 55, eax, , , chlangmusic + ret +menu_music: + mcall 55,eax, , ,menumusic + ret + +chlangmusic: db 0x82,0x60,0x83,0x65,0x82,0x60,0 + +;syslangmusic: db 0x82,0x65,0x83,0x70,0x82,0x65,0 + +menumusic: db 0x82,0x50,0x84,0x48,0x82,0x50,0x84,0x53,0x82,0x51,0 + +activatemusic: db 0x83,0x30,0x85,0x60,0 + +buttonmusic: db 0x85,0x25,0x85,0x40,0 + +sysmetermusic: db 0x85,0x35,0x85,0x45,0 + +setupmusic: db 0x85,0x40,0x85,0x50,0 + +calendarmusic: db 0x85,0x37,0x85,0x48,0 + +; .exit: mcall -1 + + +START: + mcall 66,4,0,2 ; LShift+RShift + mcall 66, , ,11h ; Ctrl+Shift + mcall 66,,88,110h ; Alt+Ctrl+F12 + mcall 66,,91,100h ; Alt+LWin + mcall 66,,92 ; Alt+RWin + mcall 66,,62 ; Alt+F4 + mcall 66,,71 ; Alt+Home + mcall 66,,72 ; Alt+Up + mcall 66,,15 ; Alt+Tab + mcall 66,,,101h ; Alt+Shift+Tab + mcall 18, 8, 1 + test eax, eax + jne @f + mcall 18, 8, 2 + @@: + mov eax, 70 + mov ebx, dat_fileinfo + int 0x40 + + mov edi,width + mov esi,I_END + xor eax,eax + new_number: + cmp [esi],byte ';' + je number_ready + imul eax,10 + movzx ebx,byte [esi] + sub ebx,'0' + add eax,ebx + inc esi + jmp new_number + number_ready: + stosd + xor eax,eax + inc esi + cmp [esi],byte 'x' + jne new_number + + mcall 14 + mov [screen_size],eax + + mcall 48,5 + mov ecx,eax + lea edx,[ebx-PANEL_HEIGHT-1] + mcall 48,6 + + call set_variables + +start_after_minimize: + + call draw_window + call draw_info + call draw_running_applications + + mov eax, 23 + mov ebx, 30 + int 0x40 + +still: +; mcall 13,<390,70>,<3,11>,0xffffff +; mov ecx,[button_presssed_alt] +; mcall 47,0x80100,ecx ,400 shl 16+5,0 + + call draw_info + call draw_running_applications + + mov eax, 23 + mov ebx, 20 + int 0x40 + + cmp eax,1 ; redraw ? + jz red + cmp eax,3 ; button ? + jz button + call handle_key + jmp still + + red: ; redraw window + + mcall 14 + movzx ecx,ax + mov edx,eax + shr edx,16 + cmp [screen_size.height],ax + jne @f + rol eax,16 + cmp [screen_size.width],ax + je .lp1 + rol eax,16 + @@: mov [screen_size],eax + sub ecx,PANEL_HEIGHT + mcall 67,0,,,PANEL_HEIGHT + + .lp1: + call draw_window + call draw_info + jmp still + + button: ; button + mov eax,17 + int 0x40 + + cmp ah,50 + jb no_activate + cmp ah,70 + jg no_activate + + movzx ecx,byte ah + sub ecx,52 + shl ecx,2 + + mov eax,18 + mov ebx,3 + mov ecx,[app_list+ecx] + int 0x40 +; cmp [music_type],0 +; je still + mcall 55,eax, , ,activatemusic + jmp still + no_activate: + + + cmp ah,101 ; minimize to left + je left_button + + cmp ah,102 ; minimize to right + je right_button + + cmp ah,byte 1 ; start/terminate menu + jnz noselect + call menu_handler +; cmp [music_type],0 +; je still + call menu_music + jmp still + noselect: + + mov ebx, exec_fileinfo + cmp ah,byte 2 ; start calendar + jnz noid15 ;noclock + mov dword [ebx+21], calendar_name + mov eax, 70 + int 0x40 + call calendar_music + jmp still + + noid15: + cmp ah,16 + jne noid16 + mov ebx, setup_exec + mov dword [ebx+8], chlang + mov eax, 70 + int 0x40 + call chlang_music + mcall 5, 25 + jmp still + + noid16: +; cmp ah,17 +; jne noid17 +; mov ebx, setup_exec +; mov dword [ebx+8], syslang +; mov eax, 70 +; int 0x40 +; call syslang_music +; mcall 5, 25 +; jmp still +; +; noid17: + cmp ah,18 + jne noid18 + mov dword [ebx+21], sysmeter_name + mov eax, 70 + int 0x40 + call sysmeter_music + jmp still + + noid18: + cmp ah,19 + jne noid19 +; inc [music_type] +; and [music_type],1 + mcall 18,8,2 +; mcall 18,8 +; mov [sound_flag],al + +; mcall 15,4,2 + mcall 15,3 + jmp red + + noid19: + cmp ah,20 ; start system setup + jnz noid20 + mov ebx, setup_exec + and dword [ebx+8], 0 + mov eax, 70 + int 0x40 + call setup_music + jmp still + + noid20: + cmp ah,21 + jnz noid21 + cmp [page_list],15 + je @f + inc [page_list] + jmp red + @@: + jmp still + + noid21: + cmp ah,22 + jnz noid22 + cmp [page_list],0 + je @f + dec [page_list] + jmp red + @@: + jmp still + + noid22: + + jmp still + + + +draw_running_applications: + + pusha + + cmp [icons],1 + jne dr_ret + + call calculate_applications + + cmp edi,[running_applications] + jne noret + popa + ret + noret: + +; cmp edi,[running_applications] +; jge no_application_decrease + call draw_window +; no_application_decrease: + + mov [running_applications],edi + + call redraw_window_tabs + + dr_ret: + + popa + + ret + +need_window_tab: +; in: ebx->process info +; out: ZF set <=> do not draw + cmp byte [ebx+10], '@' + jz .nodraw +; \begin{diamond}[29.03.2007] +; do not draw undefined (zero-sized) windows + cmp dword [ebx+42], 0 + jnz @f + cmp dword [ebx+46], 0 + jz .nodraw +@@: +; \end{diamond}[29.03.2007] + cmp dword [ebx+10], 'ICON' + jnz @f + cmp [ebx+42], dword 51 + jnz @f + cmp [ebx+46], dword 51 + jz .nodraw +@@: + cmp [ebx+10], dword ' ' +.nodraw: + ret + +redraw_window_tabs: + xor edi, edi + mov [contrast], 0 +.loop: + mov ecx, [app_list+edi*4] + cmp ecx, -1 + jz .done + + push ecx + mov eax, 9 + mov ebx, 0x8000 + int 0x40 + + mov eax, 13 + imul ebx, edi, 6*10*10000h + add ebx, 6*10*10000h + 7*10000h + 54 + mov ecx, 3*10000h + 14 + xor edx, edx + int 0x40 + sub ebx, 10000h + 53 + mov ecx, 4*10000h + 12 + int 0x40 + sub ebx, 10000h + mov ecx, 5*10000h + 10 + int 0x40 + add ebx, 56*10000h + mov ecx, 4*10000h + 12 + int 0x40 + add ebx, 10000h + mov ecx, 5*10000h + 10 + int 0x40 + + mov edx, 0x88FF + xor [contrast], 1 + jz @f + mov dh, 0x55 +@@: + pop ecx + mov esi, [current_alt_tab_app] + cmp esi, -1 + jz @f + cmp ecx, [alt_tab_list+esi*8] + jnz @f +; xor edx, 0xFFFFFF + mov edx, 0xFF8000 +@@: + sub ebx, 55*10000h - 53 + mov ecx, 4*10000h + 12 + int 0x40 + sub ebx, 10000h + 53 + mov ecx, 5*10000h + 10 + int 0x40 + add ebx, 55*10000h + int 0x40 + + mov eax, 4 + sub ebx, 51*10000h - 6 + mov ecx, 0xffffff ;[wcolor] + mov edx, 0x8000+10 + mov esi, 11 + int 0x40 + + inc edi + cmp edi, [max_applications] + jb .loop +.done: + ret + +calculate_applications: + + mov eax,[max_applications] + mul [page_list] + test eax,eax + je @f + inc eax + @@: + mov [draw_start_position],eax + + mov edi,app_list + mov ecx,20 + mov eax,-1 + cld + rep stosd + + mov edi,0 + mov ecx,2 + + cnewpr: + + mov eax,9 + mov ebx,0x8000 + int 0x40 + + call need_window_tab + jz cnorpl + sub [draw_start_position], 1 + jg cnorpl + + mov [app_list+edi*4],ecx + + inc edi + + cnorpl: + inc ecx + + cmp eax,ecx + jge cnewpr + + ret + + +draw_application_buttons: + + pusha + + cmp [icons],1 + jne da_ret + + mov eax,14 + int 0x40 + + shr eax,16 + + cmp eax,639 + jne now1 + mov [max_applications],7 ;6 + now1: + cmp eax,799 + jne now2 + mov [max_applications],9 ;10 ;8 + now2: + cmp eax,1023 + jne now3 + mov [max_applications],12 ;13 ;8 + now3: + cmp eax,1279 + jne now4 + mov [max_applications],17 ;18 ;8 + now4: + mov edi,1 + + nb: + + mov eax,8 + mov ebx,edi + shl ebx,16 + imul ebx,6*10 ;13 + add ebx,15*65536+10*6-1 ;13 + mov ecx,1*65536+17 + mov edx,edi + add edx,51 + cmp [buttons],1 + je bufr + or edx,0x60000000 + bufr: + mov esi,[wcolor] + sub ebx,11 shl 16 + int 0x40 + + inc edi + cmp edi,[max_applications] + jbe nb + + da_ret: + + popa + + ret + + +menu_handler: + mov eax, 70 + mov ebx, exec_fileinfo + mov dword [ebx+21], menu_name + int 0x40 + ret + +draw_small_right: + + pusha + + mov eax,12 + mov ebx,1 + int 0x40 + + mov eax,0 + mov edx,[wcolor] + mov esi,edx + mov edi,edx + or edx, 0x01000000 + int 0x40 + + mov eax,8 + mov ebx,0*65536+9 + mov ecx,0*65536 + mov cx,[b_size_y] + mov edx,1 + mov esi,[wcolor] + int 0x40 + + mov eax,4 + mov ebx,2*65536+16 + cmp [graph_text],1 + jne nos3 + mov ebx,2*65536+7 + nos3: + mov ecx,[wcolor] + add ecx,0x303030 + mov edx,hidetext + mov esi,1 + int 0x40 + + mov eax,12 + mov ebx,2 + int 0x40 + + popa + + ret + + + +draw_small_left: + + pusha + + mov eax,12 + mov ebx,1 + int 0x40 + + mov eax,0 + mov edx,[wcolor] + mov esi,edx + mov edi,edx + or edx, 0x01000000 + int 0x40 + + cmp [graph_text],1 + je nos4 + + mov eax,8 + mov ebx,0*65536+9 + mov ecx,0*65536+18-6 + mov edx,2 + mov esi,[wcolor] + int 0x40 + + mov eax,4 + mov ebx,2*65536+4 + mov ecx,[wcolor] + add ecx,0x303030 + mov edx,hidetext+2 + mov esi,1 + int 0x40 + + nos4: + + mov eax,8 + mov ebx,0*65536+9 + mov ecx,13*65536+25 + cmp [graph_text],1 + jne nos6 + mov ecx,0*65536 + mov cx,word [b_size_y] + nos6: + mov edx,1 + mov esi,[wcolor] + int 0x40 + + mov eax,4 + mov ebx,3*65536+22 + cmp [graph_text],1 + jne nos7 + mov ebx,3*65536+7 + nos7: + mov ecx,[wcolor] + add ecx,0x303030 + mov edx,hidetext+1 + mov esi,1 + int 0x40 + + mov eax,12 + mov ebx,2 + int 0x40 + + popa + ret + + +;------------------------------------------------- + +right_button: + + call button_music + + mov [small_draw],dword draw_small_right + + mcall 14 + shr eax, 16 + mov ebx, eax + mov ecx, -1 + mov edx, 9 + sub ebx, edx + mov esi, -1 + mcall 67 + + call draw_small_right + + jmp small_wait + +;------------------------------------------------- + +left_button: + + call button_music + + mov [small_draw],dword draw_small_left + + mov ebx, 0 + mov edx, 9 + mov ecx, -1 + mov esi, -1 + mcall 67 + + call draw_small_left + +;------------------------------------------------- + + small_wait: + + mov eax, 10 + int 0x40 + + cmp eax,1 + jne no_win + call [small_draw] + jmp small_wait + no_win: + cmp eax,2 + jne no_key + call handle_key + jmp small_wait +no_key: + + mov eax,17 + int 0x40 + + cmp ah,1 + jne no_full + + mov eax, 14 ; get screen max x & max y + int 0x40 + mov edx, eax + shr edx, 16 + xor ebx, ebx + mov ecx, -1 + mov esi, -1 + mcall 67 ; x0 y0 xs ys + + call button_music + + jmp still + + + no_full: + + call menu_handler + + jmp small_wait + + + +set_variables: + + pusha + + mov [b_size_y],dword 38 + cmp [graph_text],1 + jne noy2 + mov [b_size_y],dword 18 + noy2: + + mov [button_frames],0x0 + cmp [buttons],0 + jne no_frames + mov [button_frames],0x40000000 + no_frames: + + + mov eax,48 ; 3d button look + mov ebx,1 + mov ecx,1 + int 0x40 + + mov eax,0x40404040 ; dividers for processes + mov edi,pros + mov ecx,10 + cld + rep stosd + + popa + ret + + + +; eax = number (1 or 2) +; ebx = language id +draw_flag: + pusha + +; cmp [graph_text],0 +; je mini_flag + +; eax = 2 BIG +; eax = 1 small + + mov edx,ebx + + mov ebx,[maxx] + and eax,1 + imul eax,17 ;17 + sub ebx,eax + sub ebx,76 ;79 ;28 + + pushad +; dec ebx + sub ebx,2 + shl ebx, 16 + add ebx, 15 ;25 + mov ecx, 4*65536+13 + mov edx,0 + mov eax,13 + int 0x40 + add ebx,1 shl 16 + sub ebx,2 + mov ecx, 5 shl 16+11 + cmp [type_lang],1 + je label_1 + mov edx,0xff ;[wcolor] + jmp label_2 +label_1: + mov edx,0x7700 +label_2: + mov eax, 13 + int 0x40 + popad + + shl ebx,16 + add ebx,7 ;24 + + mov ecx,[bte] ; color + + dec edx + shl edx,1 + add edx,flag_text + mov esi,2 + mov eax,4 + int 0x40 + + mov ebx,[maxx] + sub ebx,48 + shl ebx,16 + mov bx,34 + mov ecx,3 shl 16+14 + xor edx,edx + mov eax,13 + int 0x40 + add ebx,1 shl 16 + sub ebx,2 + mov ecx,4 shl 16+12 + mov edx,0x66cc + int 0x40 + + popa + ret + +;mini_flag: +; popa +; ret + + + + +; *************************************************** +; ********* WINDOW DEFINITIONS AND DRAW ************* +; *************************************************** + + +draw_window: + + pusha + + mov [running_applications],-1 + mov [checks],-1 + + mov eax, 12 ; tell os about redraw + mov ebx, 1 + int 0x40 + + mov eax, 48 + mov ebx, 3 + mov ecx, system_colours + mov edx, 10*4 + int 0x40 + + mov eax, [system_colours+4*6] + sub eax, 0x101010 + mov [wcolor], eax + + mov eax,14 ; get screen max x & max y + int 0x40 + + cmp [width],0 + je no_def_width + and eax,0xffff + mov ebx,[width] + shl ebx,16 + add eax,ebx + no_def_width: + + mov ebx,eax + mov [screenxy],ebx + shr ebx,16 + sub ax,38 + shl eax,16 + mov ecx,eax + add ecx,0*65536+38 + cmp [graph_text],1 + jne no_text_1 + mov cx,PANEL_HEIGHT + add ecx,20*65536 + no_text_1: + mov eax, 0 ; DEFINE AND DRAW WINDOW + mov edx, [wcolor] + or edx, 0x01000000 ; do not draw the window + mov esi, [wcolor] + or esi, 0x01000000 ; unmovable window + mov edi, [wcolor] + int 0x40 + + movzx ebx,word [screenxy+2] + mov ecx,0*65536+0 + mov edx,[wcolor] + add edx,0x161616 + newline: + sub edx,0x040404 + mov eax,38 + cmp [soften_up],1 + jne no_su + and edx,0x00FFFFFF + int 0x40 + no_su: + + pusha + cmp [soften_down],1 + jne no_sd + sub edx,0x141414 + mov edi,[b_size_y] + shl edi,16 + add edi,[b_size_y] + add ecx,edi + sub ecx,3*65536+3 + and edx,0x00FFFFFF + int 0x40 + no_sd: + popa + + add ecx,1*65536+1 + cmp cx,5 + jb newline + + cmp [soften_middle],1 + jne no_sm + + movzx ebx,word [screenxy+2] + mov ecx,5*65536+5 + mov esi,stripe + mov edx,[wcolor] + newline3: + add edx,[esi] + add esi,4 + + mov eax,38 + and edx,0x00FFFFFF + int 0x40 + add ecx,1*65536+1 + cmp cx,15 + jb newline3 + + no_sm: + + cmp [minimize_left],1 + jne no_mleft + mov eax,8 ; ABS LEFT + mov ebx,0 *65536+9 + mov ecx,1 *65536 + add ecx,[b_size_y] + dec ecx + mov edx,101 + add edx,[button_frames] + mov esi,[wcolor] + int 0x40 + mov eax,4 ; HIDE TEXT + mov ebx,2*65536+17 + cmp [graph_text],1 + jne no_y1 + mov bx,7 + no_y1: + mov ecx,[wcolor] + add ecx,0x303030 + mov edx,hidetext + mov esi,1 + int 0x40 + no_mleft: + + movzx eax,word [screenxy+2] + mov [maxx],eax + + cmp [minimize_right],1 + jne no_mright + mov eax,[maxx] + sub eax,77 + shl eax,16 + mov ebx,eax + add ebx,67 + mov eax,8 ; ABS RIGHT + mov ecx,1 *65536 + add ecx,[b_size_y] + dec ecx + add ebx,68*65536 + mov bx,9 + mov edx,102 + add edx,[button_frames] + mov esi,[wcolor] + int 0x40 + mov edx,hidetext+1 + mov eax,4 + mov ebx,[maxx] + sub ebx,6 + shl ebx,16 + mov bx,17 + cmp [graph_text],1 + jne no_y2 + mov bx,7 + no_y2: + mov ecx,[wcolor] + add ecx,0x303030 + mov esi,1 + int 0x40 + no_mright: + + call draw_menuet_icon + + call draw_program_icons + + mov [ptime],0 + call draw_info + + call draw_application_buttons + +; mov ecx,[button_presssed_alt] +; mcall 47,0x80100,ecx ,400 shl 16+5,0 + + mov eax,12 + mov ebx,2 + int 0x40 + + popa + ret + + + +draw_menuet_icon: + + pusha + + cmp [menu_enable],1 + jne no_menu + + + mov eax, 8 ; M BUTTON + mov ebx, 10*65536 + 47 + cmp [minimize_left], 0 + jne @f + sub ebx, 10*65536 + @@: + mov ecx, 1*65536 + add ecx, [b_size_y] + dec ecx + mov edx, 0x20000001 + add edx, [button_frames] + mov esi, [wcolor] + int 0x40 + + cmp [graph_text], 1 + jne no_mtext + + push ebx + mov eax,13 + mov ebx,12 shl 16+44 ;51 + mov ecx,1 shl 16+17 + xor edx,edx + int 0x40 +; mov ebx,63 shl 16+1 + mov ebx,56 shl 16+1 + mov ecx,2 shl 16+15 + int 0x40 + mov ebx,57 shl 16+1 + mov ecx,4 shl 16+11 + int 0x40 + mov ebx,58 shl 16+1 + mov ecx,6 shl 16+7 + int 0x40 +; mov ebx,66 shl 16+1 +; mov ecx,9 shl 16+1 +; int 0x40 + mov ebx,13 shl 16+43 ;50 + mov ecx,2 shl 16+15 + mov edx,0x7700 + int 0x40 +; mov ebx,62 shl 16+1 +; mov ecx,3 shl 16+14 +; int 0x40 + mov ebx,56 shl 16+1 + mov ecx,4 shl 16+11 + int 0x40 + mov ebx,57 shl 16+1 + mov ecx,6 shl 16+7 + int 0x40 + pop ebx + + mov eax, 4 + mov bx, 7 + add ebx, 8*65536 + mov ecx, 0x10ffffff + mov edx, m_text + mov esi, 4 + int 0x40 + + popa + ret + + no_mtext: + + + + mov eax,[wcolor] + mov [m_icon+4],eax + +; load & display menuet.bmp + mov eax, 70 + mov ebx, m_bmp_fileinfo + int 0x40 + + mov eax,40 + mov ebx,0 + mov edi,image+53 + + new_m_pix: + +; movzx ecx,byte [edi] +; shr ecx,5 + + cmp byte [edi], 10 + jb nopix + cmp byte [edi+1], 10 + jb nopix + cmp byte [edi+2], 10 + jb nopix + + pusha + cmp [minimize_left],0 + jne no_m_s2 + sub ebx,10 + no_m_s2: +; mov edx,[ecx*4+m_icon] + mov edx,[edi+1] + + mov ecx,eax + mov eax,1 + add ebx,12 + int 0x40 + popa + + nopix: + + add edi,3 + add ebx,1 + cmp ebx,40 + jnz new_m_pix + + mov ebx,0 + dec eax + jnz new_m_pix + + no_menu: + + popa + ret + + +draw_program_icons: + + pusha + + cmp [icons],0 + jne dp_ret + + mov edi,1 + push edi + + new_icon_file: + + pusha + mov edx,[esp+32] + add edx,10 + push edx + mov esi,[wcolor] + mov ecx,1*65536 + add ecx,[b_size_y] + dec ecx + mov eax,edi + dec eax + imul eax,40 + mov ebx,eax + add ebx,[icons_position] + shl ebx,16 + mov bx,39 + pop edx + add edx,[button_frames] + or edx, 0x20000000 + mov eax,8 + int 0x40 + popa + + mov ecx,[esp] + add ecx,48 + mov [iconf+6],cl + + mov eax, 70 + mov ebx, iconf_fileinfo + int 0x40 + + mov eax,0 + mov ebx,32 + mov edi,image+51+32*33*3 + + np2: ; new pixel of file + + mov edx,[edi] + and edx,0xffffff + + cmp eax,3 ; Y draw limits + jb nopix2 + cmp eax,36 + jg nopix2 + cmp ebx,38 ; X draw limits + jg nopix2 + cmp ebx,2 + jb nopix2 + + cmp edx,0 + jz nopix2 + + cmp [graph_text],1 + jne no_icon_text + + pusha + + mov ebx,[esp+32] + dec ebx + imul ebx,40 + add ebx,8 + add ebx,[icons_position] + shl ebx,16 + mov bx,7 + + mov eax,4 + mov ecx,0xffffff + mov edx,[esp+32] + dec edx + imul edx,4 + add edx,mi_text + mov esi,4 + int 0x40 + + popa + + jmp nopix2 + + no_icon_text: + + mov esi,[esp] + pusha + push edx + mov ecx,eax + add ecx,2 + mov eax,esi + dec eax + imul eax,40 + add ebx,eax + add ebx,3 + add ebx,[icons_position] + pop edx + mov eax,1 + int 0x40 + popa + + nopix2: + + sub edi,3 + dec ebx + jnz np2 + + mov ebx,32 + add eax,1 + cmp eax,32 + jnz np2 + + add dword [esp],1 + mov edi,[esp] + cmp dword [esp],4 + jbe new_icon_file + add esp,4 + + mov eax,4 + mov ebx,40 + imul ebx,3 + add ebx,[icons_position] + add ebx,10 + shl ebx,16 + mov bx,23 + mov ecx,[wcolor] + mov edx,gpl + mov esi,3 + int 0x40 + + dp_ret: + + popa + ret + + + +draw_info: ; draw cpu usage, time, date + + pusha + + cmp [setup_enable],1 + jne no_setup + + cmp [minimize_right],0 + jne no_m_r + add [maxx],10 + + no_m_r: + + mov eax,3 + int 0x40 + cmp eax,[ptime] + jz _ret + mov [ptime],eax + + call draw_cpu_usage + + mov eax,[maxx] ; blink sec + sub eax,33 + shl eax,16 + mov ebx,eax + add ebx,9 + mov eax,3 + int 0x40 + cmp [graph_text],1 + jne no_y4 + sub bx,2 + no_y4: + mov ecx,eax + shr ecx,16 + and ecx,1 + mov edx,[bte] + sub edx,[wcolor] + imul ecx,edx + add ecx,[wcolor] + mov edx,sec + mov eax,4 + mov esi,1 + int 0x40 + + +; mov eax,26 ; check for change in time or country +; mov ebx,5 +; int 0x40 +; mov edx,eax + mov eax,26 + mov ebx,2 + mov ecx,9 + int 0x40 +; add edx,eax + mov edx,eax + mov eax,3 + int 0x40 + and eax,0xffff + add edx,eax + cmp edx,[checks] + je _ret + mov [checks],edx + + mov ebx,[maxx] + sub ebx,48 ;;94 ;;74 + shl ebx,16 + add ebx,33 ;;84 ;;64 + + mov eax,8 ; time/date button + mov ecx,3 *65536 + add ecx,[b_size_y] +; dec ecx + sub cx,5 + mov edx,2+0x20000000 + mov esi,[wcolor] + int 0x40 + pusha + mov eax,13 + add ebx,10*65536-16 + add ecx,5*65536-8 + mov edx,[wcolor] + int 0x40 + popa + and edx,0xffff + add edx,[button_frames] + int 0x40 + + mov eax,8 + mov ebx,[maxx] + sub ebx,77 ;80 + shl ebx,16 + add ebx,12 + mov ecx,5 shl 16+10 + mov edx,16+0x20000000 ;button 16 + mov esi,[wcolor] + int 0x40 + sub ebx,17 shl 16 + inc edx ;button 17 +; int 0x40 + add ebx,33 shl 16 + mov bx,8 + inc edx ;button 18 + int 0x40 + sub ebx,30 shl 16 + mov bx,10 + inc edx ;button 19 + int 0x40 + sub ebx,14 shl 16 + inc edx ;button 20 + int 0x40 + sub ebx,12 shl 16 + mov bx,8 + mov ecx,6 shl 16+10 + inc edx ;button 21 + int 0x40 + sub ebx,18 shl 16 + inc edx ;button 22 + int 0x40 + + ; flags + +; mov eax,26 +; mov ebx,5 +; int 0x40 +; mov ebx,eax +; +; mov eax,1 +; mov [type_lang],al +; call draw_flag + + mov eax,26 + mov ebx,2 + mov ecx,9 + int 0x40 + mov ebx,eax + + mov eax,2 + mov [type_lang],al + call draw_flag + + mcall 18,8,1 + mov [sound_flag],al + + mov ebx,[maxx] + sub ebx,92 ;109 ;112 ;28 + shl ebx,16 + mov bx,12 + mov ecx, 4*65536+13 + mov edx,0 + mov eax,13 + int 0x40 + add ebx,1 shl 16 + sub bx,2 + mov ecx,5 shl 16+11 + mov edx,0xcc + int 0x40 + add ebx,1 shl 16 + mov bx,5 + mov ecx,8 shl 16+5 + mov edx,0xdddd00 + int 0x40 + add ebx,5 shl 16 + mov bx,1 + mov ecx,7 shl 16+7 + int 0x40 + add ebx,1 shl 16 + mov ecx,6 shl 16+9 + int 0x40 + add ebx,1 shl 16 + mov ecx,5 shl 16+11 + int 0x40 + +; cmp [music_type],0 +; jne dalshe + cmp [sound_flag],0 + je dalshe + + sub ebx,8 shl 16 + ror ebx,16 + mov cx,bx + rol ebx,16 + mov bx,cx + add bx,8 + mov ecx,5 shl 16+15 + mov edx,0xff0000 + mov eax,38 + int 0x40 + add ebx,1 shl 16 + inc bx + int 0x40 + rol ecx,16 + int 0x40 + sub ebx,1 shl 16 + dec bx + int 0x40 + +dalshe: + + mov ebx,[maxx] + sub ebx,106;123 + shl ebx,16 + mov bx,12 + mov ecx, 4*65536+13 + mov edx,0 + mov eax,13 + int 0x40 + add ebx,1 shl 16 + sub bx,2 + mov ecx,5 shl 16+11 + mov edx,0xffcc00 + int 0x40 + mov eax,4 + mov ebx,[maxx] + sub ebx,104;121 + shl ebx,16 + mov bx,7 + mov ecx,0x10000000 + mov edx,file_sys + mov esi,1 + int 0x40 + add ebx,1 shl 16 + int 0x40 + + mov edx,0 + mov eax,13 + mov ebx,[maxx] + sub ebx,117;134 + shl ebx,16 + mov bx,9 + mov ecx,6 shl 16+11 + int 0x40 + sub ebx,18 shl 16 + int 0x40 + add ebx,19 shl 16 + sub bx,2 + mov ecx,7 shl 16+9 + mov edx,0xffffff + int 0x40 + sub ebx,18 shl 16 + int 0x40 + + mov eax,4 + mov edx,page_a1 + mov ebx,[maxx] + sub ebx,133;150 + shl ebx,16 + mov bx,8 + mov esi,4 + int 0x40 + add ebx,1 shl 16 + int 0x40 + + mov eax,47 + mov ebx,0x10100 + mov ecx,[page_list] + mov edx,[maxx] + sub edx,124;141 + shl edx,16 + mov dx,7 + mov esi,0xffffff + int 0x40 + +; sub ebx,14 shl 16 +; mov bx,7 +; mov edx,turn_text +; mov esi,1 + +; mov ecx,0x60a060 ;[wcolor] +; add ecx,0x303030 +; mov eax,4 +; int 0x40 +; add ebx,1 shl 16 +; int 0x40 +; add ebx,1 shl 16 +; int 0x40 +; add ebx,1 shl 16 +; int 0x40 + +; add ebx,1 shl 16 +; mov ecx,0x60a060 ;[wcolor] +; int 0x40 +; add ebx,1 shl 16 +; int 0x40 +; add ebx,1 shl 16 +; sub ecx,0x303030 +; int 0x40 + +; sub ebx,6 shl 16 +; mov bx,1 +; mov ecx,2 shl 16+15 +; mov edx,0x60a060 ;[wcolor] +; add edx,0x303030 +; mov eax,13 +; int 0x40 +; add ebx,1 shl 16 +; mov bx,1 +; mov edx,0x60a060 ;[wcolor] +; int 0x40 +; add ebx,1 shl 16 +; mov bx,1 +; sub edx,0x303030 +; int 0x40 +; add ebx,1 shl 16 +; mov edx,[wcolor] +; int 0x40 + + mov eax,3 ; get time + int 0x40 + + movzx ebx,al + shr eax,8 + movzx ecx,al + shr eax,8 + movzx edx,al + + ; ebx ecx edx h m s + + push ebx + push ecx + + mov eax,[maxx] + sub eax,32 + shl eax,16 + mov ebx,eax + add ebx,9 + + mov ecx,[bte] + + cmp [graph_text],1 + jne no_y3 + sub bx,2 + mov ecx,0xffffff + no_y3: + + + mov edx,[esp] ; __:_X + and edx,15 + mov eax,4 + add ebx,10*65536 + add edx,text + mov esi,1 + int 0x40 + + pop edx ; __:X_ + shr edx,4 + and edx,15 + mov eax,4 + sub ebx,6*65536 + add edx,text + mov esi,1 + int 0x40 + + mov edx,[esp] ; _X:__ + and edx,15 + mov eax,4 + sub ebx,11*65536 + add edx,text + mov esi,1 + int 0x40 + + pop edx ; X_:__ + shr edx,4 + and edx,15 + mov eax,4 + sub ebx,6*65536 + add edx,text + mov esi,1 + int 0x40 + + call draw_cpu_usage + + _ret: + + cmp [minimize_right],0 + jne no_m_r2 + sub [maxx],10 + no_m_r2: + + no_setup: + + popa + ret + + + +draw_cpu_usage: + + pushad + + mov [ysi],30 + cmp [graph_text],1 + jne @f + mov [ysi],12 + @@: + + + mov eax,18 ; TSC / SEC + mov ebx,5 + int 0x40 + shr eax,20 + push eax + mov eax,18 ; IDLE / SEC + mov ebx,4 + int 0x40 + shr eax,20 + xor edx,edx + imul eax,[ysi] + + cdq + pop ebx + inc ebx + div ebx + cmp eax,[ysi] + jng no_bug + mov eax,[ysi] +no_bug: + push eax + + mov eax,13 + mov ebx,[maxx] + sub ebx,60 + shl ebx,16 + add ebx,8 + mov ecx,5 shl 16 + add ecx,[ysi] + mov edx,0xdd2222 + int 0x40 + + pop eax + mov ecx,5 shl 16 + add ecx,eax + mov eax,13 + mov edx,0x44aa44 + int 0x40 + + popad + ret + +; DATA + +stripe: + dd -0x010101 + dd -0x010101 + dd -0x020202 + dd -0x010101 + dd -0x000000 + + dd 0x000000 + dd 0x010101 + dd 0x020202 + dd 0x010101 + dd 0x010101 + +m_icon: + dd 0x0 + dd 0x808080 + dd 0x000000 + dd 0x000000 + dd 0xffffff + + +lsz m_text,\ + ru, "Œ…ž",\ + en, "MENU",\ + et, "MENÜÜ" + +mi_text db 'WAVETETRBGRDGPL ' + +flag_text db 'EnFiGeRuFrEt' + +type_lang db 0 +;music_type db 1 +sound_flag db 0 +button_frames dd 0x0 + +checks dd -1 +hidetext db 0x11,0x10,0x1e + +turn_text db '><' +gpl db 'GPL' + +chlang db 'LANG',0 +;syslang db 'SLAN',0 + +contrast db 0 + +running_applications dd 0x100 +max_applications dd 11 + +current_alt_tab_app dd -1 + +page_list dd 0 +draw_start_position dd 0 +draw_window_1 db 0 + +b_size_y: dd 0x0 +ysi dd 0 +small_draw dd 0x0 + +ptime dd 0x0 +maxx dd 0x0 +text db '0123456789' +page_a1 db '< >' +bte dd 0xccddee + +wcolor dd 0x506070 + +sec db ': ' +pros db ' ' + db ' ' + +screenxy dd 0x0 +stcount dd 0x0 + +setup_exec: + dd 7 + dd 0 +.cmdline dd ? + dd 0 + dd 0 + db '/HD0/1/KOLIBRi/BIN/' +file_sys db 'SETUP',0 + +exec_fileinfo: + dd 7 + dd 0 + dd 0 + dd 0 + dd 0 + db 0 +.name dd ? + +end_name db '/HD0/1/KOLIBRi/BIN/END',0 +menu_name db '/HD0/1/KOLIBRi/BIN/@MENU',0 +calendar_name db '/HD0/1/KOLIBRi/BIN/CALENDAR',0 +sysmeter_name db '/HD0/1/KOLIBRi/BIN/GMON',0 + +dat_fileinfo: + dd 0 + dd 0 + dd 0 + dd 1024 + dd I_END + db '/HD0/1/KOLIBRi/ETC/PANEL.DAT',0 + +m_bmp_fileinfo: + dd 0 + dd 0 + dd 0 + dd 8192 + dd image + db '/HD0/1/KOLIBRi/USR/ICONS/MENUET.BMP',0 + +iconf_fileinfo: + dd 0 + dd 0 + dd 0 + dd 8192 + dd image + db '/HD0/1/KOLIBRi/USR/ICONS/' +iconf db 'MBAR_IX.BMP',0 + +I_END: + +screen_size: + .height dw ? + .width dw ? + +area9 rb 100 +system_colours rd 10 +app_list rd 50 +alt_tab_list rd 256*2 +alt_tab_list_size dd ? +tictable: + rd 256 +image: diff --git a/kernel/branches/hd_kolibri/apps/panel/@panel b/kernel/branches/hd_kolibri/apps/panel/@panel new file mode 100644 index 0000000000000000000000000000000000000000..e11753a4fae8deb8a8462fbbbb9aecac3bff9e42 GIT binary patch literal 5695 zcmcgwYiwK99Y5EP#CDusCnPD1wR0gYDUT*@1EC}icHU`|kR~a064W}ddg5kGU1kH* z9mint z65dYW<<4jd#!@sh(B8rc^M23@AlR!BWS#<#0@bs!yB8Q@urzO`iAs<=s_ZlDm+JPj zkL2@t&@-vQ7fT;sg(;w-viO^RaZbNj(Jx-pFJ9FzPAQ8izkGPg&!!H`N2U(5ss8CM z{067?F}W`4XVI-u4~yOzZD&zWw4X&AqFqdC@kypp*XxpD1ct++OdWm0Ne5?2o1?=? za@(bW*@qAT;Y)|b=`k~7;Y$H=x`t1LkeJCD!MXNwKA&|1i|0o8k|9)u z_)R-Nd;#LO1h-xFW{S1Fl7X_TOL@zErl3x1KY<(c>+1ymBsTvLK4=l>I#i zT^G7u??_R}vg|7ySP{CO>mfg6Q4?}IQ9jOrm7yE7Bq>pnBs&E_c7#K#G$;#}D5;YD zCPAC%)qs~@cK0J;1Tp#~44C-|UXAW{q*}-@md?asyBJ@(@(8gL<~BgsbKQ7(`v5T##zdFWOnj-1DSQ$%f zU`FOT9mz3fgEBM`BB4L>A*tR&4*xdGJh0t zX-?+%LpyM80Oz|3^y{M5xi>(HWYQ~H%qm!d>Qs`9Bb6M~RP7x0c^lniTXE{QaLriy znueaEsFx~+U!h8O>7y69XV$H++B`U{vv;{>Z>wtWV54GdIKvsNUAKGiW`&Au9^80^ zy(cX(`>Q0n)4TiRkDf}e2hPvP4^&E08Han)fY7lmn&}uwWaj<`l1|&O(nemlfg*wp z(>g{OHeC5m$pVXMUTtI|OO(MivCrg%U9!6dI6|-}@&-nK{LUXj5}B|BmhM#S_vqYM znu;NHKef4_5BMcJicIUW$2A|XB&yh%*q=BT0Y0+$BrB?FAYOVuK(5m*3TN)USqC#9 z?z%{D$UIw&RlJnTP1V)avE)vo__zbOcBQqAeYG%^RdA;wRk9DGH|XV=u9i?=kihj! z+`vi;3R%BQ>ndb|UTfo(TJI|GENGosUCZYe%?AN_4Bpec8cWNs=OydN_CLyR=25Cq zrC&mT=BhKv0{#Wyql8;WfLg%%7+8`G_~;HHOTLmA=iZms458x8o=?ExyjtRg&=xL? zHw)K_p2q=*$o}-xd_J?CWd6>-XeJMBgEO?lA>L@K99xU#TQQ?Y2^1cC>Xrwc4FSMg z=PMpOb5p>TY{SSRcr5mp_@)3h~P4iUXvgIIzdSl<>wlX>q*taUkq@`+Q{K>m<)`5Cvh`qYBH_0V^#VVCMIq3$?n?;Ib?~Pr~0?-@yqTyzOyy5T2WEK;%;(d z>K_gxp9r5u(6Wt8Lm!Kz1S;n8r{;+lWOolI-KEM*nBj}#OV{CSJh_ck@(B}!YQzOv zapHpPuIIFUO8zCF6f^R?@0Jda7%M4W^yyfpOMg=U`G4)~7hg8h>1TKlx$ov8jy%U# znO?GMT28k@q+T9%pf+?7E0Y3ONlsFNB2=_MDdK@rR*3p9Xu?ZS=4Qyvw4$9ZnjZuM zdNL7I<;?hwVK8q48G&7h28MqG2kQVWA?WDd{y$0?m1)ZL}Eq@gSmh_I74h z>a^?hvIh+pja7u<_$$`;W?ub6%awBAdbQcWOg!^g*Q(} z(!z~{3nSVj1>ejXTu(*+B#J&NaSc*^Zs|tG!uQ%HZV68cwuvp_NrP?TMx4B!tP(QH zIa~aI5KFn{J#yL(R`Q~;RlZmgI^|mF3Y|d0DYqjgM%_3)8q)!Pe5l$fFW3f@_|O|D zw$?R1UlU6kH#LDfch)UT^(jvoC#(!1aeK9#sykY`n=%y&8!=K-lANP+x1zblH!3lU z%k;#f@>=!ecjb%QCciCTG)#O;{)`15)Xd)Ck3UfD+&jKfBd0Aosl^mE{E9)!?ioLA ziY(X*=E~g^udntGP?8&BACk%f;?k(lkH8dUhYyT<#pw5trBDjR+bKo^RCP?%@uq6I zsoEqy@ezu#{F(`pq?*z36_s92+xWpZswt9eAh|~FCK$6#jW~3CnI{Mf70YJI5SwI# zZ5nyViqjWxN0_1L&HNKHHHEgQDP-lSnh{I^6yjJam37GP3h_!RwYTvCAing5kvHjN zm~=4tln(th^-E_#!ptx#S@Gc{EO3^*G71Zgl~h{A=|d15<8v(osZ`79ElLWbGVziT zkhA6_^2@1J3_p?~lKwDnMcG`#*)idePv7#(2V=YR{ z*@7}*;S226Vqw!38?=d?qkvD5wo^_MIx7FXOT)d-Q@hG+Ktt78AeP2|1`6a~=(oCW z%;&cQT~qWC?p&n#7rG&Nfw#lt5`3)n$iS?bp)gxmlAS%P?wX+^uGz)79%^U_E3XHX z-hfb3#b=+J1hZf>*}%e5ryPOUpHpePPX!R}C>v&QWqE2W8lM0zcd3*EOVFTE>|O7& zKlm>+XG_$S5GmSmzt4$^8M2%?l9ebdJcblKk+O6hP;eu;CxFAzt#kq^Z=^)IddBO} zwO}AC4xLnbp9Y1vWUyf3NbVOJAAIYXkT;qzsTSW?f`GiD@2+?yB~4`YNy0ww2qcTy zafL6BWbxQL_}51~c9Or}8r-L*kW)(`469H19hkON5hHh)?Mc@uz1o#za1R^(cpmO2H?T)r=*rK?kKu%>U`e|-b z=C0G?OC0B!(bi8s>MwXj&NXqDSQs@ZcoDH@EG1?E@1R!+5;<+4e$_q7gK60_>hmaw zvDCi7NS5Mg9TQv#8UNL^z0d~Nj-~ULQ3vt6{5d|!F+xfH2ym6bV1UPPWxjdw=^-`_Mp3=RjL$e~+{MI~@;q9v%pFOtc3TWMJmY9Gjb)0PgYjb+SRc z0Rqnw1>?)#b*`Pe>hHX(;qKi{PG|G`XP4L!e?Pm&`Tuw{t%|jYZmjKUtE+X@?!B+4 zyJeuewxzqTcCdYDe?R|Z)Zwj9uR+n?*T$}~O;)|ueyg_!6yAYr!8&{IBa`YLbSV16 z>MH*2L#?&_-oEyp9c|tr9X6&;#-7G)<0^vvg9Ejl1K$3w?$*It(yV=GM@w)2|4!QC L9XQnOlang.inc +@fasm @panel.asm @panel +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/panel/build_et.bat b/kernel/branches/hd_kolibri/apps/panel/build_et.bat new file mode 100644 index 0000000000..7e6b1cdd5e --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/panel/build_et.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix et >lang.inc +@fasm @panel.asm @panel +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/panel/build_ru.bat b/kernel/branches/hd_kolibri/apps/panel/build_ru.bat new file mode 100644 index 0000000000..b3c5a994ce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/panel/build_ru.bat @@ -0,0 +1,4 @@ +@erase lang.inc +@echo lang fix ru >lang.inc +@fasm @panel.asm @panel +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/panel/lang.inc b/kernel/branches/hd_kolibri/apps/panel/lang.inc new file mode 100644 index 0000000000..0b78d13aff --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/panel/lang.inc @@ -0,0 +1 @@ +lang fix en diff --git a/kernel/branches/hd_kolibri/apps/panel/macros.inc b/kernel/branches/hd_kolibri/apps/panel/macros.inc new file mode 100644 index 0000000000..5824e42816 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/panel/macros.inc @@ -0,0 +1,266 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & (arg2 eqtype 0) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + rb (1024-52) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/rb/@RB.ASM b/kernel/branches/hd_kolibri/apps/rb/@RB.ASM new file mode 100644 index 0000000000..74a2732a10 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/rb/@RB.ASM @@ -0,0 +1,405 @@ +; +; DESKTOP CONTEXT MENU +; written by Ivan Poddubny +; +; €¢ā®ą - ˆ¢ ­ ®¤¤ć”­ė© +; e-mail: ivan-yar@bk.ru +; +; Compile with flat assembler +; +include 'lang.inc' +include 'macros.inc' + +meos_app_start +code + + mov eax,40 ; ćįā ­®¢Ø¬ ¬ įŖć į®”ėāØ© + mov ebx,100000b ; ­ į Ø­ā„ą„įć„ā ā®«ģŖ® ¬ėčģ + int 0x40 + +still: ; £« ¢­ė© ęØŖ« ®į­®¢­®£® Æą®ę„įį  + + mov eax,10 ; ¦¤ń¬ į®”ėāØļ + int 0x40 + + mov eax,37 ; Ŗ ŖØ„ ­ ¦ āė ŖÆ®ÆŖØ? + mov ebx,2 + int 0x40 + + cmp eax,2 ; „į«Ø ­„ Æą ¢ ļ, ¢®§¢ą ā + jne still + +;---Æ®„å «Ø!--- + +; mov eax,37 ; ķā® ¤«ļ ®ā« ¤ŖØ - „į«Ø ¬ėčģ ¢ ā®ēŖ„ (0;0), § Ŗą®„¬įļ +; xor ebx,ebx +; int 0x40 +; test eax,eax ; Ŗćąį®ą ¢ ā®ēŖ„ (0;0), ā.„. eax = 0 +; je exit + + + mov eax,9 ; Æ®«ćēج ēØį«® Æą®ę„įį®¢ ¢ įØįā„¬„ + mov ebx,procinfo + xor ecx,ecx + int 0x40 + + inc eax ; ā„Æ„ąģ ¢ eax į®¤„ą¦Øāįļ ēØį«® Æą®ę„įį®¢ + 1 + mov [processes],eax + mov ecx,1 + + new_process: + pushad + mov eax,9 ; Æ®«ćēج Ø­ä®ą¬ ęØī ® Æą®ę„įį„; ­®¬„ą - ¢ ecx + mov ebx,procinfo + int 0x40 + mov eax,37 ; Ŗ®®ą¤Ø­ āė Ŗćąį®ą  + xor ebx,ebx + int 0x40 + mov ebx,eax ; eax = cursor_x + shr eax,16 ; ebx = cursor_y + and ebx,0xffff + mov [curx1],eax ; curx1 = cursor_x + mov [cury1],ebx ; cury1 = cursor_y +; \begin{diamond}[18.09.2006] +; ignore minimized windows + test [procinfo.wnd_state], 2 + jnz ne_goden +; \end{diamond}[18.09.2006] + mov eax,[procinfo.x_start] ; eax = wnd_x_start + mov ebx,[procinfo.y_start] ; ebx = wnd_y_start + + mov ecx,[procinfo.x_size] + add ecx,eax ; ecx = wnd_x_end + mov edx,[procinfo.y_size] + add edx,ebx ; ecx = wnd_y_end + + cmp eax,[curx1] ; wnd_x_start > cursor_x => Ŗćąį®ą «„¢„„ ®Ŗ­  + jg ne_goden + cmp ecx,[curx1] ; wnd_x_end < cursor_x => Ŗćąį®ą Æą ¢„„ ®Ŗ­  + jl ne_goden + cmp ebx,[cury1] ; wnd_y_start > cursor_y => Ŗćąį®ą ¢ėč„ ®Ŗ­  + jg ne_goden + cmp edx,[cury1] ; wnd_y_end < cursor_y => Ŗćąį®ą ­Ø¦„ ®Ŗ­  + jl ne_goden + +goden: ; Ŗ«ØŖ ”ė« ¢­ćāąØ Ŗ Ŗ®£®-ā® ®Ŗ­ , Æ®ķā®¬ć ­Øē„£® ­„ ¤„« „¬ + popad + jmp still + +ne_goden: ; Ŗ«ØŖ ”ė« į­ ąć¦Ø ą įį¬ āąØ¢ „¬®£® ®Ŗ­ , Æ®ķā®¬ć + popad + inc ecx + cmp ecx,[processes] + jl new_process ; «Ø”® į¬®ąØ¬ į«„¤ćīé„„ ®Ŗ­®, «Ø”® § ÆćįŖ „¬ ¬„­ī + + +@@: ; Æ®¤®¦¤ń¬, Æ®Ŗ  Æ®«ģ§®¢ ā„«ģ ­„ ®āÆćįāØ« Æą ¢ćī Ŗ­®ÆŖć ¬ėčØ + mov eax,37 + mov ebx,2 ; äć­ŖęØļ 37-2: + int 0x40 ; ­ ¦ āė «Ø Ŗ­®ÆŖØ ¬ėčØ? + cmp eax,ebx ; „į«Ø ®āÆćįāØ«, (eax != 2) + jnz @f ; ؤń¬ ¢ ­ ē «® £« ¢­®£® ęØŖ«  + + mov eax,5 ; Ø­ ē„ + mov ebx,2 ; Æ®¤®¦¤ń¬ 2 ¬į + int 0x40 + + jmp @b ; Ø Æą®¢„ąØ¬ ¬ėčģ ®Æļāģ +@@: + +; „į«Ø 榄 ”ė«® ®āŖąėā® ¬„­ī, ­ć¦­® Æ®¤®¦¤ āģ, Æ®Ŗ  ®­® § Ŗą®„āįļ: +@@: + cmp [menu_opened],0 + je @f + mov eax,5 + mov ebx,3 ; ¦¤ń¬ 3 ¬į + int 0x40 + jmp @b +@@: + + mov eax,51 ;   ā„Æ„ąģ ¬®¦­® į¬„«® § ÆćįŖ āģ Æą®ę„įį (Æ®ā®Ŗ) ¬„­ī + mov ebx,1 ; į®§¤ ń¬ Æ®ā®Ŗ (thread) + mov ecx,start_wnd ; ā®ēŖ  ¢å®¤  Æ®ā®Ŗ  + mov edx,stack_wnd ; ¢„ąčØ­  įāķŖ  ¤«ļ Æ®ā®Ŗ  + int 0x40 + + jmp still + + + +exit_menu: ; „į«Ø ¢ė室ج ا ¬„­ī, ­ ¤® § ÆØį āģ ¢ [menu_opened] 0 + mov [menu_opened],0 +exit: ; įī¤  ¬ė ؤń¬, Ŗ®£¤  ¢ė室ج ا ®į­®¢­®£® Æą®ę„įį  + or eax,-1 ; eax = -1 + int 0x40 + + + + +; §¤„įģ įā ąāć„ā Æą®ę„įį ¬„­ī +start_wnd: + mov [menu_opened],1 + mov eax,40 ; ćįā ­®¢Ø¬ ¬ įŖć ¦„« „¬ėå į®”ėāØ© ¤«ļ ķā®£® Æą®ę„įį  + mov ebx,100101b ; ¬„­ī + Ŗ­®ÆŖØ + Æ„ą„ąØį®¢Ŗ  + int 0x40 + +red: + call draw_window + +still2: ; £« ¢­ė© ęØŖ« Æą®ę„įį  ¬„­ī + + mov eax,10 ; ¦¤ń¬ į®”ėāØļ + int 0x40 + + cmp eax,1 ; Æ„ą„ąØį®¢Ŗ ? + je red + cmp eax,3 ; Ŗ­®ÆŖ ? + je button + cmp eax,6 ; ¬ėčģ? + je mouse + + jmp still2 ; ¢„ą­ń¬įļ ¢ ­ ē «® £« ¢­®£® ęØŖ«  + + +; Ž€Ž’—ˆŠ Œ›˜ˆ +mouse: ; Ŗ®£¤  Æ®«ģ§®¢ ā„«ģ ­ ¦¬ńā Ŗ­®ÆŖć ¬ėčØ, § Ŗą®„¬įļ + mov eax,37 + mov ebx,2 ; Ŗ ŖØ„ Ŗ­®ÆŖØ ­ ¦ āė? + int 0x40 + test eax,eax ; ­ØŖ ŖØ„? - ā®£¤  Æą„Ŗą į­®! ¢„ą­ń¬įļ ¢ £« ­ė© ęØŖ« + jz still2 + jmp exit_menu ;   „į«Ø ¢įń-ā ŖØ ­ ¦ āė - § Ŗą®„¬ ®Ŗ­® + + +; €†€’€ ŠŽŠ€ +button: + mov eax,17 ; Æ®«ćēØāģ ؤ„­āØäØŖ ā®ą ­ ¦ ā®© Ŗ­®ÆŖØ + int 0x40 + + sub ah,10 ; įą ¢­Ø¢ „¬ į 10 + jl nofuncbtns ; „į«Ø ¬„­ģč„ - § Ŗąė¢ „¬ ¬„­ī + + movzx ebx,ah ; Æ®«ćēØ«Ø ­®¬„ą Æą®£ą ¬¬ė ¢ įÆØįŖ„ ¢ ebx + mov esi, [startapps + ebx*4] + mov edi, start_info.path + cld + @@: + lodsb + stosb + test al, al + jnz @b + mcall 70, start_info + +; mov eax,5 ; Æ®¤®¦¤ń¬, Æ®Ŗ  Æą®£ą ¬¬  § ÆćįāØāģįļ +; mov ebx,1 ;   ā® „ń ®Ŗ­® ­„ ”椄ā ®āąØį®¢ ­® (” £ ¢ ļ¤ą„???) +; int 0x40 ; ą įŖ®¬¬„­āØąć©ā„ ķāØ įāą®ŖØ, „į«Ø ć ¢ į Æą®”«„¬ė + ; į ®āąØį®¢Ŗ®© + +nofuncbtns: ; § Ŗąė¢ „¬ ¬„­ī + jmp exit_menu + + + +_BTNS_ = 7 ; Ŗ®«Øē„įā¢® Ŗ­®Æ®Ŗ ("Æć­Ŗā®¢ ¬„­ī") + +if lang eq ru + font = 0x00000000 + string_length = 20 ; ¤«Ø­  įāą®ŖØ + wnd_x_size = 133 ; čØąØ­  ®Ŗ­  + header_pos = 36 shl 16 + 7 +else + font = 0x10000000 + string_length = 12 ; ¤«Ø­  įāą®ŖØ + wnd_x_size = 105 ; čØąØ­  ®Ŗ­  + header_pos = 23 shl 16 + 7 +end if + +;******************************* +;******** ˆ‘“…Œ ŽŠŽ ******** +;******************************* + +draw_window: + + mov eax,12 ; ­ ēØ­ „¬ "ąØį®¢ āģ" + mov ebx,1 + int 0x40 + + mov eax,[curx1] ; ā„ŖćéØ„ Ŗ®®ą¤Ø­ āė Ŗćąį®ą  + mov [curx],eax ; § ÆØ脬 ¢ Ŗ®®ą¤Ø­ āė ®Ŗ­  + mov eax,[cury1] + mov [cury],eax + +; ā„Æ„ąģ ”椄¬ įēØā āģ Ŗ®®ą¤Ø­ āė ®Ŗ­ , ēā®”ė ®­® §  Ŗą © ķŖą ­  ­„ ¢ė«„§«® + mov eax,14 ; Æ®«ćēج ą §¬„ą ķŖą ­  + int 0x40 + mov ebx,eax + shr eax,16 ; ¢ eax - x_screen + and ebx,0xffff ; ¢ ebx - y_screen + add eax,-wnd_x_size ; eax = [x_screen - čØąØ­  ®Ŗ­ ] + add ebx,-_BTNS_*15-21 ; ebx = [y_screen - ¢ėį®ā  ®Ŗ­ ] + + cmp eax,[curx] + jg .okx ; „į«Ø ®Ŗ­® į«ØčŖ®¬ ”«Ø§Ŗ® Ŗ Æą ¢®¬ć Ŗą ī, + add [curx],-wnd_x_size ; į¤¢Ø­„¬ „£® ¢«„¢® ­  100 + .okx: + + cmp ebx, [cury] + jg .oky ; Æ® ¢„ąāØŖ «Ø ā®ē­® ā Ŗ¦„ + add [cury], -_BTNS_*15-21 + .oky: + + mov eax, 48 ; Æ®«ćēØāģ įØįā„¬­ė„ ę¢„ā  + mov ebx, 3 + mov ecx, sc ;  ¤ą„į įāąćŖāćąė + mov edx, sizeof.system_colors ; Ø „„ ą §¬„ą + int 0x40 + + xor eax, eax ; äć­ŖęØļ 0 - į®§¤ āģ ®Ŗ­® + mov ebx, [curx] ; ebx = [Ŗ®®ą¤Ø­ ā  Æ® x] shl 16 + [čØąØ­ ] + shl ebx, 16 + add ebx, wnd_x_size + mov ecx, [cury] ; ecx = [Ŗ®®ą¤Ø­ ā  Æ® y] shl 16 + [¢ėį®ā ] + shl ecx, 16 + add ecx, _BTNS_*15+21 + mov edx, [sc.work] ; ę¢„ā ą ”®ē„© ®”« įāØ + mov esi, [sc.grab] ; ę¢„ā § £®«®¢Ŗ  + or esi, 0x81000000 + mov edi, [sc.frame] ; ę¢„ā ą ¬ŖØ + int 0x40 + + mov eax, 4 ; § £®«®¢®Ŗ + mov ebx, header_pos ; [x] shl 16 + [y] + mov ecx, [sc.grab_text]; čąØäā Ø ę¢„ā (į„ąė©) + or ecx, 0x10000000 +; add ecx, -0x333333 + push ecx + push ecx + xor edx,edx +.dec_color: + sub byte [esp+edx], 0x33 + jae @f + mov byte [esp+edx], 0 +@@: + inc edx + jnp .dec_color + pop ecx + mov edx, header ;  ¤ą„į § £®«®¢Ŗ  + mov esi, header.size ; ¤«Ø­  § £®«®¢Ŗ  ("M E N U") + int 0x40 + pop ecx + add ebx, 1 shl 16 ; į¤¢Ø­„¬ ¢Æą ¢® ­  1 + int 0x40 + + mov ebx, 1*65536+wnd_x_size-2 ; ­ ēØ­ „¬ ¤„« āģ Ŗ­®ÆŖØ + mov ecx, 20*65536+15 + mov edx, 10 or 0x40000000 ; ”Øā 30 ćįā ­®¢«„­ => Ŗ­®ÆŖ  ­„ ąØįć„āįļ + + mov edi,_BTNS_ ; Ŗ®«Øē„įā¢® Ŗ­®Æ®Ŗ (įēńāēØŖ) + + newbtn: ; ­ ē «® ęØŖ«  + mov eax,8 ; į®§¤ ń¬ Ŗ­®ÆŖć + int 0x40 + + ; ÆØ脬 ā„Ŗįā ­  Ŗ­®ÆŖ„ + pushad ; įÆ į „¬ ą„£Øįāąė + shr ecx, 16 + and ebx, 0xffff0000 + add ebx, ecx ; ebx = [x] shl 16 + [y]; + add ebx, 10*65536+4 ; ebx += į¬„é„­Ø„ ®ā­®įØā„«ģ­® Ŗą ļ Ŗ­®ÆŖØ; + mov ecx, [sc.work_text] ; čąØäā Ø ę¢„ā + or ecx, font + add edx, -10 ; edx = ­®¬„ą Ŗ­®ÆŖØ; + imul edx, string_length ; edx *= ¤«Ø­  įāą®ŖØ; + add edx, text ; edx += text; ā„Æ„ąģ ¢ edx  ¤ą„į įāą®ŖØ + mov esi, string_length ; ¢ esi - ¤«Ø­  įāą®ŖØ + mov eax, 4 ; äć­ŖęØļ 4 - ¢ė¢®¤ ā„Ŗįā  + int 0x40 + popad + + inc edx ; ­®¬„ą Ŗ­®ÆŖØ++; + add ecx,15*65536 ; ć¢„«Øēج į¬„é„­Ø„ Æ® y + dec edi ; 欄­ģčج įēńāēØŖ + jnz newbtn ; „į«Ø ­„ ­®«ģ, Æ®¢ā®ąØ¬ ¢įń „éń ą § + + mov eax,12 ; § Ŗ®­ēØ«Ø "ąØį®¢ āģ" + mov ebx,2 + int 0x40 + +ret ; ¢®§¢ą ā + + + +; „€›… Žƒ€ŒŒ› +DATA + + macro strtbl name, [string] + { + common + label name dword + forward + local str + dd str + forward + str db string + } + + strtbl startapps ,\ + <"/HD0/1/KOLIBRI/BIN/PIC4",0> ,\ + <"/HD0/1/KOLIBRI/BIN/SKINSEL",0> ,\ + <"/HD0/1/KOLIBRI/BIN/DESKTOP",0> ,\ + <"/HD0/1/KOLIBRI/BIN/ICON",0> ,\ + <"/HD0/1/KOLIBRI/BIN/SETUP",0> ,\ + <"/HD0/1/KOLIBRI/BIN/VRR",0> ,\ + <"/HD0/1/KOLIBRI/BIN/CPU",0> + + sz header, "KolibriOS" + + lsz text,\ + en, 'Background ',\ + en, 'Change skin ',\ + en, 'Desktop ',\ + en, 'Icon manager',\ + en, 'Device setup',\ + en, 'VRR ',\ + en, 'Processes ',\ + \ + ru, 'ƒ„­„ą ā®ą ®”®„¢ ',\ + ru, '‘¬„­  įŖØ­  ',\ + ru, ' įāą®©Ŗ  ®Ŗ®­ ',\ + ru, '“Æą ¢«„­Ø„ ØŖ®­Ŗ ¬Ø ',\ + ru, ' įāą®©Ŗ  ćįāą®©įā¢ ',\ + ru, ' įāą®©Ŗ  ¬®­Øā®ą  ',\ + ru, 'ą®ę„įįė ' + +start_info: + .mode dd 7 + dd 0 + .params dd 0 + dd 0 + dd 0 + db 0 + dd start_info.path + +; …ˆˆ–ˆ€‹ˆ‡ˆŽ‚€›… „€›… +UDATA + processes dd ? ; Ŗ®«Øē„įā¢® Æą®ę„įį®¢ ¢ įØįā„¬„ + curx1 dd ? ; Ŗ®®ą¤Ø­ āė Ŗćąį®ą  + cury1 dd ? + curx dd ? ; Ŗ®®ą¤Ø­ āė ®Ŗ­  ¬„­ī + cury dd ? + + menu_opened db ? ; ®āŖąėā® ¬„­ī Ø«Ø ­„ā? (1-¤ , 0-­„ā) + +align 4 +start_info.path rb 256 + + sc system_colors ; įØįā„¬­ė„ ę¢„ā  + procinfo process_information ; Ø­ä®ą¬ ęØļ ® Æą®ę„įį„ + + rb 1024 ; įāķŖ ¤«ļ ®Ŗ­  ¬„­ī - 墠āØā Ø 1 Š” + align 32 + stack_wnd: + + +MEOS_APP_END +; ŠŽ…– Žƒ€ŒŒ› \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/rb/@rb b/kernel/branches/hd_kolibri/apps/rb/@rb new file mode 100644 index 0000000000000000000000000000000000000000..e8fb6ffe866daca5cac2f958945b43337be70793 GIT binary patch literal 1000 zcmZuvO=uHA6n^H( z>!Iw$TTdQJPKsxtjcC$fvB)a)Bvu9KrERJxN(oX}-)yM}X5hUyGw*xfyq~$|4~_VT zdsrO+oI}|*0C0{&!K1cFH&2*xg(DUoRToe6c#xXKc zQd>Ob)*@#*+z!f6JQm+cs;U|va9io)#rdP`F1;^Ui0LrX#_nwY0eV5yt_+xb<16Xq z*-h{A8LWGSvjQmGjuV;IOd3*ptt#B%UPr6%!kFy{QfMuZnmX}^)HH|=sd-G)H+GL+ zeNYuYH=dId*rwS%OOfe(_EGM8^jHt@5{v)`PoKplo3v`r}7SgDSq!oW%r&2lH$Va0+!h?sAX<5##AVv@iQ^>FRsfy&X2_c^s^0+tSu>N28_x=DZ6)!IU literal 0 HcmV?d00001 diff --git a/kernel/branches/hd_kolibri/apps/rb/build_en.bat b/kernel/branches/hd_kolibri/apps/rb/build_en.bat new file mode 100644 index 0000000000..239a8cd406 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/rb/build_en.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix en >lang.inc +@fasm @rb.asm @rb +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/rb/build_ru.bat b/kernel/branches/hd_kolibri/apps/rb/build_ru.bat new file mode 100644 index 0000000000..81244df8f0 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/rb/build_ru.bat @@ -0,0 +1,5 @@ +@erase lang.inc +@echo lang fix ru >lang.inc +@fasm @rb.asm @rb +@erase lang.inc +@pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/rb/lang.inc b/kernel/branches/hd_kolibri/apps/rb/lang.inc new file mode 100644 index 0000000000..0b78d13aff --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/rb/lang.inc @@ -0,0 +1 @@ +lang fix en diff --git a/kernel/branches/hd_kolibri/apps/rb/macros.inc b/kernel/branches/hd_kolibri/apps/rb/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/rb/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/setup/SETUP.DAT b/kernel/branches/hd_kolibri/apps/setup/SETUP.DAT new file mode 100644 index 0000000000000000000000000000000000000000..cadc7edd93f9252563df8db2994dbb8020b74f0a GIT binary patch literal 56 lcmZQ!U|>*SW?*0e(M${sj6fQM4OkIum>7r#DrMjTVgMFW0G9v& literal 0 HcmV?d00001 diff --git a/kernel/branches/hd_kolibri/apps/setup/build.bat b/kernel/branches/hd_kolibri/apps/setup/build.bat new file mode 100644 index 0000000000..2944a3f1c7 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/setup/build.bat @@ -0,0 +1,3 @@ +echo lang fix en > lang.inc +fasm setup.asm setup +pause \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/setup/lang.inc b/kernel/branches/hd_kolibri/apps/setup/lang.inc new file mode 100644 index 0000000000..0b78d13aff --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/setup/lang.inc @@ -0,0 +1 @@ +lang fix en diff --git a/kernel/branches/hd_kolibri/apps/setup/macros.inc b/kernel/branches/hd_kolibri/apps/setup/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/setup/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/setup/setup.asm b/kernel/branches/hd_kolibri/apps/setup/setup.asm new file mode 100644 index 0000000000..4f3a703d1e --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/setup/setup.asm @@ -0,0 +1,1804 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; DEVICE SETUP ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Authors: Ville - original version +; A. Ivushkin - autostart (w launcher) +; M. Lisovin - added many feauters (apply all, save all, set time...) +; I. Poddubny - fixed russian keymap +;14/08/06 Mario79 - added regulation of mouse features + +;****************************************************************************** + use32 + org 0x0 + db 'MENUET01' ; 8 byte identifier + dd 0x01 ; header version + dd START ; pointer to program start + dd I_END ; size of image + dd 0x4000 ; reguired amount of memory + dd 0x4000 ; stack pointer (esp) + dd I_PARAM,0 ; parameters, reserved +; include 'lang.inc' + include 'macros.inc' +;****************************************************************************** + +LLL equ (56+3) +BBB equ 25 + +;****************************************************************************** +apply_all: + + call _midibase ;1 + call _sound_dma ;10 + call _pci_acc ;12 + call _sb16 ;4 + call _wssp ;6 + call _syslang ;5 + call _keyboard ;2 + call _mouse_speed + call _mouse_delay + call get_disk_info + cmp [cd],0 + jne no_cd + call _cdbase ;3 + no_cd: + cmp [hd],0 + jne no_hd + call _lba_read ;11 + call _hdbase ;7 + call _f32p ;8 + no_hd: +ret +;------------------------------------------------------------------------------- +get_disk_info: + mov [hd],1 + mov [cd],1 + mov [hdbase],0 + mov [cdbase],0 + mcall 18,11,1,table_area + + ide_0: + mov al,[table_area+1] + shr al,6 + cmp al,0 + je ide_1 + cmp al,01b + jnz ide_0_cd + mov [hdbase],1 + mov [hd],0 + jmp ide_1 + + ide_0_cd: + cmp al,10b + jnz ide_1 + mov [cdbase],1 + mov [cd],0 + cmp [hd],0 + je all_device + + ide_1: + mov al,[table_area+1] + shl al,2 + shr al,6 + cmp al,0 + je ide_2 + cmp al,01b + jnz ide_1_cd + cmp [hd],0 + je ide_11 + mov [hdbase],2 + mov [hd],0 + ide_11: + cmp [cd],0 + je all_device + jmp ide_2 + + ide_1_cd: + cmp al,10b + jnz ide_2 + cmp [cd],0 + je ide_11_cd + mov [cdbase],2 + mov [cd],0 + ide_11_cd: + cmp [hd],0 + je all_device + + ide_2: + mov al,[table_area+1] + shl al,4 + shr al,6 + cmp al,0 + je ide_3 + cmp al,01b + jnz ide_2_cd + cmp [hd],0 + je ide_21 + mov [hdbase],3 + mov [hd],0 + ide_21: + cmp [cd],0 + je all_device + jmp ide_3 + + ide_2_cd: + cmp al,10b + jnz ide_3 + cmp [cd],0 + je ide_21_cd + mov [cdbase],3 + mov [cd],0 + ide_21_cd: + cmp [hd],0 + je all_device + + ide_3: + mov al,[table_area+1] + shl al,6 + shr al,6 + cmp al,0 + je not_device + cmp al,01b + jnz ide_3_cd + cmp [hd],0 + je ide_31 + mov [hdbase],4 + mov [hd],0 + ide_31: + cmp [cd],0 + jmp all_device + + ide_3_cd: + cmp al,10b + jnz not_device + cmp [cd],0 + je all_device + mov [cdbase],4 + mov [cd],0 + + all_device: + not_device: + ret + +hd db 0 +cd db 0 +;****************************************************************************** +apply_all_and_exit: + mcall 70,read_fileinfo + call apply_all + + jmp close + +;****************************************************************************** +set_language_and_exit: + mov eax,26 + mov ebx,2 + mov ecx,9 + int 0x40 +; cmp eax,5 +; jne @f +; xor eax,eax +;@@: mov [keyboard],eax + cmp eax,1 + je russian + xor eax,eax +set_lang_now: + mov [keyboard],eax + call _keyboard + jmp close +russian: + mov eax,3 + jmp set_lang_now + +set_syslanguage_and_exit: + mov eax,26 + mov ebx,5 +; mov ecx,9 + int 0x40 + cmp eax,6 + jne temp ;@f + xor eax,eax +;@@: inc eax +temp: inc eax + mov [syslang],eax + call _syslang + jmp close + +get_setup_values: + mcall 26,1 + mov [midibase],eax + mcall 26,2,9 + dec eax + mov [keyboard],eax + mcall 26,3 + mov [cdbase],eax + mcall 26,4 + mov [sb16],eax + mcall 26,5 + mov [syslang],eax + mcall 26,6 + cmp eax,0x530 + jne s_wss_2 + mov eax,1 + jmp get_other +s_wss_2: + cmp eax,0x608 + jne s_wss_3 + mov eax,2 + jmp get_other +s_wss_3: + cmp eax,0xe80 + jne s_wss_4 + mov eax,3 + jmp get_other +s_wss_4: + mov eax,4 +get_other: + mov [wss],eax + mcall 26,7 + mov [hdbase],eax + mcall 26,8 + mov [f32p],eax + mcall 26,10 + mov [sound_dma],eax + mcall 26,11 + mov [lba_read],eax + mcall 26,12 + mov [pci_acc],eax + mcall 18,19,0 + mov [mouse_speed],eax + mcall 18,19,2 + mov [mouse_delay],eax + ret + +;****************************************************************************** + +START: + cmp [I_PARAM], 'SLAN' + je set_syslanguage_and_exit + + cmp [I_PARAM], 'LANG' + je set_language_and_exit + + cmp [I_PARAM], 'BOOT' + je apply_all_and_exit + + call get_setup_values + call loadtxt +red: + call draw_window + +still: + + cmp word [blinkpar],0 + jne blinker + mov eax,29 ;get system date + int 0x40 + cmp eax,[date] + je gettime + mov [date],eax + gettime: + mov eax,3 ;get system time + int 0x40 + cmp ax,[time] + je sysevent + mov [time],ax + call drawtime + + sysevent: + mov eax,23 + mov ebx,8 ; wait here for event with timeout + int 0x40 + + cmp eax,1 + jz red + cmp eax,2 + jz key + cmp eax,3 + jz button + + jmp still + + blinker: + cmp byte [count],6 + jb noblink + btc dword [blinkpar],16 + mov byte [count],0 + call drawtime + noblink: + inc byte [count] + jmp sysevent + +incdectime: + cmp byte [blinkpar],0 + je still + mov esi,time + mov bl,0x23 ;border + cmp byte [blinkpar],1 + je hours + mov bl,0x59 ;minutes + inc esi + hours: + mov al,byte [esi] + cmp ah,112 + je dectime + cmp al,bl + je noinctime + inc al + daa + jmp incdectime1 + noinctime: + xor al,al + incdectime1: + mov byte [esi],al + jmp still + dectime: + cmp al,0 + je nodectime + dec al + das + jmp incdectime1 + nodectime: + mov al,bl + jmp incdectime1 + +incdecdate: + cmp byte [blinkpar+1],0 + je still + mov esi,date + mov bl,0 ;border of years + cmp byte [blinkpar+1],1 + jne days + mov bl,0x12 ;months + inc esi + days: + cmp byte [blinkpar+1],2 + jne nodays + mov bl,0x31 + add esi,2 + nodays: + mov al,byte [esi] + cmp ah,122 + je decdate + cmp al,bl + je noincdate + inc al ;add al,1 + daa + jmp incdecdate1 + noincdate: + mov al,1 + incdecdate1: + mov byte [esi],al + jmp still + decdate: + cmp al,1 + je nodecdate + dec al + das + jmp incdecdate1 + nodecdate: + mov al,bl + jmp incdecdate1 + + + key: + ;mov eax,2 + int 0x40 + cmp ah,27 + jne still + mov dword [blinkpar],0 + call drawtime + jmp still + + button: + + mov eax,17 + int 0x40 + + cmp ah,112 + je incdectime + cmp ah,113 + je incdectime + cmp ah,122 + je incdecdate + cmp ah,123 + je incdecdate + cmp ah,111 + jne noseltime + mov al, [blinkpar] + cmp al,2 + jae seltime + inc al + jmp seltime1 + seltime: + xor al,al + seltime1: + mov [blinkpar],al + call drawtime + jmp still +noseltime: + cmp ah,121 + jne noseldate + mov al,byte [blinkpar+1] + cmp al,3 + jae seldate + inc al + jmp seldate1 + seldate: + xor al,al + seldate1: + mov [blinkpar+1],al + call drawtime + jmp still +noseldate: + cmp ah,99 + jne nosaveall + mcall 70,save_fileinfo + call settime + mov dword [blinkpar],0 + call drawtime + jmp still +nosaveall: + cmp ah,100 + jne no_apply_all + call apply_all + jmp still +no_apply_all: + + cmp ah,1 ; CLOSE APPLICATION + jne no_close +close: + or eax,-1 + int 0x40 + no_close: + + cmp ah,11 ; SET MIDI BASE + jnz nosetbase1 + call _midibase + nosetbase1: + cmp ah,12 + jnz nomm + sub [midibase],2 + call draw_infotext + nomm: + cmp ah,13 + jnz nomp + add [midibase],2 + call draw_infotext + nomp: + + + cmp ah,4 ; SET KEYBOARD + jnz nokm + mov eax,[keyboard] + test eax,eax + je downuplbl + dec eax + jmp nodownup + downuplbl: + mov eax,5 + nodownup: + mov [keyboard],eax + call draw_infotext + nokm: + cmp ah,5 + jnz nokp + mov eax,[keyboard] + cmp eax,5 + je updownlbl + inc eax + jmp noupdown + updownlbl: + xor eax,eax + noupdown: + mov [keyboard],eax + call draw_infotext + nokp: + + + cmp ah,22 ; SET CD BASE + jnz nocm + mov eax,[cdbase] + sub eax,2 + and eax,3 + inc eax + mov [cdbase],eax + call draw_infotext + nocm: + cmp ah,23 + jnz nocp + mov eax,[cdbase] + and eax,3 + inc eax + mov [cdbase],eax + call draw_infotext + nocp: + cmp ah,21 + jnz nocs + call _cdbase + nocs: + + cmp ah,62 ; SET HD BASE + jnz hnocm + mov eax,[hdbase] + sub eax,2 + and eax,3 + inc eax + mov [hdbase],eax + call draw_infotext + hnocm: + cmp ah,63 + jnz hnocp + mov eax,[hdbase] + and eax,3 + inc eax + mov [hdbase],eax + call draw_infotext + hnocp: + cmp ah,61 + jnz hnocs + call _hdbase + hnocs: + + cmp ah,82 ; SET SOUND DMA + jne no_sdma_d + mov eax,[sound_dma] + dec eax + sdmal: + and eax,3 + mov [sound_dma],eax + call draw_infotext + jmp still + no_sdma_d: + cmp ah,83 + jne no_sdma_i + mov eax,[sound_dma] + inc eax + jmp sdmal + no_sdma_i: + cmp ah,81 + jne no_set_sound_dma + call _sound_dma + jmp still + no_set_sound_dma: + + cmp ah,92 ; SET LBA READ + jne no_lba_d + slbal: + btc [lba_read],0 + call draw_infotext + jmp still + no_lba_d: + cmp ah,93 + jne no_lba_i + jmp slbal + no_lba_i: + cmp ah,91 + jne no_set_lba_read + call _lba_read + jmp still + no_set_lba_read: + + + cmp ah,102 ; SET PCI ACCESS + jne no_pci_d + pcip: + btc [pci_acc],0 + call draw_infotext + jmp still + no_pci_d: + cmp ah,103 + jne no_pci_i + jmp pcip + no_pci_i: + cmp ah,101 + jne no_set_pci_acc + call _pci_acc + jmp still + no_set_pci_acc: + + + set_partition: + cmp ah,72 ; SET FAT32 PARTITION + jnz .nominus + mov eax,[f32p] + sub eax,2 +; and eax,15 ; 3 - four partitions, 7 - eight p., 15 - sixteen, etc. + cmp eax,15 + jb @f + mov eax,14 +@@: + inc eax + mov [f32p],eax + call draw_infotext + .nominus: + cmp ah,73 + jnz .noplus + mov eax,[f32p] +; and eax,15 ; 3 - four partitions, 7 - eight p., 15 - sixteen, etc. + cmp eax,15 + jb @f + mov eax,0 +@@: + inc eax + mov [f32p],eax + call draw_infotext + .noplus: + cmp ah,71 + jnz .noapply + call _f32p + .noapply: + + cmp ah,32 ; SET SOUND BLASTER 16 BASE + jnz nosbm + sub [sb16],2 + call draw_infotext + nosbm: + cmp ah,33 + jnz nosbp + add [sb16],2 + call draw_infotext + nosbp: + cmp ah,31 + jnz nosbs + call _sb16 + nosbs: + + cmp ah,52 ; SET WINDOWS SOUND SYSTEM BASE + jnz nowssm + mov eax,[wss] + sub eax,2 + and eax,3 + inc eax + mov [wss],eax + call draw_infotext + nowssm: + cmp ah,53 + jnz nowssp + mov eax,[wss] + and eax,3 + inc eax + mov [wss],eax + call draw_infotext + nowssp: + cmp ah,51 + jnz nowsss + call _wssp + nowsss: + + cmp ah,42 ; SET SYSTEM LANGUAGE BASE + jnz nosysm + mov eax,[syslang] + dec eax + jz still + mov [syslang],eax + call draw_infotext + nosysm: + cmp ah,43 + jnz nosysp + mov eax,[syslang] + cmp eax,6 + je nosysp + inc eax + mov [syslang],eax + call draw_infotext + nosysp: + cmp ah,41 + jnz nosyss + call _syslang + call cleantxt + call loadtxt + call draw_window + call drawtime + nosyss: + cmp ah,132 ; SET MOUSE SPEED + jnz .nominus + mov eax,[mouse_speed] + sub eax,2 + cmp eax,9 + jb @f + mov eax,8 +@@: + inc eax + mov [mouse_speed],eax + call draw_infotext + .nominus: + cmp ah,133 + jnz .noplus + mov eax,[mouse_speed] + cmp eax,9 + jb @f + mov eax,0 +@@: + inc eax + mov [mouse_speed],eax + call draw_infotext + .noplus: + cmp ah,131 + jnz .noapply + call _mouse_speed + .noapply: + mousedelay: + cmp ah,142 ; SET MOUSE DELAY + jnz .nominus + mov eax,[mouse_delay] + sub eax,2 + cmp eax,0xfff + jb @f + mov eax,0xffe +@@: + inc eax + mov [mouse_delay],eax + call draw_infotext + .nominus: + cmp ah,143 + jnz .noplus + mov eax,[mouse_delay] + cmp eax,0xfff + jb @f + mov eax,0 +@@: + inc eax + mov [mouse_delay],eax + call draw_infotext + .noplus: + cmp ah,141 + jnz .noapply + call _mouse_delay + .noapply: + + cmp ah,3 ; SET KEYMAP + jne still + call _keyboard + jmp still + + _keyboard: + cmp [keyboard],0 + jnz nosetkeyle + mov eax,21 ; english + mov ebx,2 + mov ecx,1 + mov edx,en_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,en_keymap_shift + int 0x40 + mov eax,21 + mov ecx,9 + mov edx,1 + int 0x40 + call alt_gen + nosetkeyle: + cmp [keyboard],1 + jnz nosetkeylfi + mov eax,21 ; finnish + mov ebx,2 + mov ecx,1 + mov edx,fi_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,fi_keymap_shift + int 0x40 + mov eax,21 + mov ecx,9 + mov edx,2 + int 0x40 + call alt_gen + nosetkeylfi: + cmp [keyboard],2 + jnz nosetkeylge + mov eax,21 ; german + mov ebx,2 + mov ecx,1 + mov edx,ge_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,ge_keymap_shift + int 0x40 + mov eax,21 + mov ecx,9 + mov edx,3 + int 0x40 + call alt_gen + nosetkeylge: + cmp [keyboard],3 + jnz nosetkeylru + mov eax,21 ; russian + mov ebx,2 + mov ecx,1 + mov edx,ru_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,ru_keymap_shift + int 0x40 + call alt_gen + mov eax,21 + mov ecx,9 + mov edx,4 + int 0x40 + nosetkeylru: + cmp [keyboard],4 ;french + jnz nosetkeylfr + mov eax,21 + mov ebx,2 + mov ecx,1 + mov edx,fr_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,fr_keymap_shift + int 0x40 + mov eax,21 + inc ecx + mov edx,fr_keymap_alt_gr + int 0x40 + mov eax,21 + mov ecx,9 + mov edx,5 + int 0x40 + nosetkeylfr: + cmp [keyboard],5 + jnz nosetkeylet + mov eax,21 ; estonian + mov ebx,2 + mov ecx,1 + mov edx,et_keymap + int 0x40 + mov eax,21 + inc ecx + mov edx,et_keymap_shift + int 0x40 + mov eax,21 + mov ecx,9 + mov edx,6 + int 0x40 + call alt_gen + nosetkeylet: + ret + + alt_gen: + mov eax,21 + mov ecx,3 + mov edx,alt_general + int 0x40 + ret + + + +draw_buttons: + + pusha + + shl ecx,16 + add ecx,12 + mov ebx,(350-50)*65536+46+BBB + + mov eax,8 + int 0x40 + + mov ebx,(350-79)*65536+9 + inc edx + int 0x40 + + mov ebx,(350-67)*65536+9 + inc edx + int 0x40 + + popa + ret + + + +; ******************************************** +; ******* WINDOW DEFINITIONS AND DRAW ******* +; ******************************************** + + +draw_window: + + pusha + + mov eax,12 + mov ebx,1 + int 0x40 + + xor eax,eax ; DRAW WINDOW + mov ebx,40*65536+355+BBB + mov ecx,40*65536+320 + mov edx,0x83111199 +; mov esi,0x805588dd +; mov edi,0x005588dd + int 0x40 + + mov eax,4 + mov ebx,8*65536+8 + mov ecx,0x10ffffff + mov edx,labelt + cmp [syslang],4 + je ruslabel + add edx,20 + ruslabel: + mov esi,19 ;26 + int 0x40 + +; mov eax,8 ; CLOSE BUTTON +; mov ebx,(355+BBB-19)*65536+12 +; mov ecx,5*65536+12 +; mov edx,1 +; mov esi,0x005588dd +; int 0x40 + + mov eax,8 ; APPLY ALL + mov ebx,(350-79)*65536+100 + mov ecx,282*65536+12 + mov edx,100 + mov esi,0x005588dd + int 0x40 + add ecx,16*65536 ; SAVE ALL + dec edx + int 0x40 + + mov esi,0x5580c0 + + mov edx,11 + mov ecx,43 + call draw_buttons + + mov edx,41 + mov ecx,43+8*8 + call draw_buttons + + mov edx,21 + mov ecx,43+4*8 + call draw_buttons + + mov edx,31 + mov ecx,43+2*8 + call draw_buttons + + mov edx,3 + mov ecx,43+10*8 + call draw_buttons + + mov edx,51 + mov ecx,43+12*8 + call draw_buttons + + mov edx,61 + mov ecx,43+6*8 + call draw_buttons + + mov edx,91 + mov ecx,43+18*8 + call draw_buttons + + mov edx,71 + mov ecx,43+14*8 + call draw_buttons + + mov edx,81 + mov ecx,43+16*8 + call draw_buttons + + mov edx,101 + mov ecx,43+20*8 + call draw_buttons + + mov edx,111 + mov ecx,43+22*8 ; 22 + call draw_buttons + + mov edx,121 + mov ecx,43+24*8 ; 24 + call draw_buttons + + mov edx,131 + mov ecx,43+26*8 ; 26 + call draw_buttons + + mov edx,141 + mov ecx,43+28*8 ; 26 + call draw_buttons + + call draw_infotext + + mov eax,12 + mov ebx,2 + int 0x40 + + popa + ret + + + +draw_infotext: + + pusha + + mov eax,[keyboard] ; KEYBOARD + test eax,eax + jnz noen + mov [text00+LLL*10+28],dword 'ENGL' + mov [text00+LLL*10+32],dword 'ISH ' + noen: + cmp eax,1 + jnz nofi + mov [text00+LLL*10+28],dword 'FINN' + mov [text00+LLL*10+32],dword 'ISH ' + nofi: + cmp eax,2 + jnz noge + mov [text00+LLL*10+28],dword 'GERM' + mov [text00+LLL*10+32],dword 'AN ' + noge: + cmp eax,3 + jnz nogr + mov [text00+LLL*10+28],dword 'RUSS' + mov [text00+LLL*10+32],dword 'IAN ' + nogr: + cmp eax,4 + jnz nofr + mov [text00+LLL*10+28],dword 'FREN' + mov [text00+LLL*10+32],dword 'CH ' + nofr: + cmp eax,5 + jnz noet + mov [text00+LLL*10+28],dword 'ESTO' + mov [text00+LLL*10+32],dword 'NIAN' + noet: + + mov eax,[syslang] ; SYSTEM LANGUAGE + dec eax + test eax,eax + jnz noen5 + mov [text00+LLL*8+28],dword 'ENGL' + mov [text00+LLL*8+32],dword 'ISH ' + noen5: + cmp eax,1 + jnz nofi5 + mov [text00+LLL*8+28],dword 'FINN' + mov [text00+LLL*8+32],dword 'ISH ' + nofi5: + cmp eax,2 + jnz noge5 + mov [text00+LLL*8+28],dword 'GERM' + mov [text00+LLL*8+32],dword 'AN ' + noge5: + cmp eax,3 + jnz nogr5 + mov [text00+LLL*8+28],dword 'RUSS' + mov [text00+LLL*8+32],dword 'IAN ' + nogr5: + cmp eax,4 + jne nofr5 + mov [text00+LLL*8+28],dword 'FREN' + mov [text00+LLL*8+32],dword 'CH ' + nofr5: + cmp eax,5 + jne noet5 + mov [text00+LLL*8+28],dword 'ESTO' + mov [text00+LLL*8+32],dword 'NIAN' + noet5: + + mov eax,[midibase] + mov esi,text00+LLL*0+32 + call hexconvert ; MIDI BASE + + + mov eax,[sb16] ; SB16 BASE + mov esi,text00+LLL*2+32 + call hexconvert + + + mov eax,[wss] ; WSS BASE + cmp eax,1 + jnz nowss1 + mov [wssp],dword 0x530 + nowss1: + cmp eax,2 + jnz nowss2 + mov [wssp],dword 0x608 + nowss2: + cmp eax,3 + jnz nowss3 + mov [wssp],dword 0xe80 + nowss3: + cmp eax,4 + jnz nowss4 + mov [wssp],dword 0xf40 + nowss4: + + mov eax,[wssp] + mov esi,text00+LLL*12+32 + call hexconvert + + mov eax,[cdbase] ; CD BASE + cmp eax,1 + jnz noe1 + mov [text00+LLL*4+28],dword 'PRI.' + mov [text00+LLL*4+32],dword 'MAST' + mov [text00+LLL*4+36],dword 'ER ' + noe1: + cmp eax,2 + jnz nof1 + mov [text00+LLL*4+28],dword 'PRI.' + mov [text00+LLL*4+32],dword 'SLAV' + mov [text00+LLL*4+36],dword 'E ' + nof1: + cmp eax,3 + jnz nog1 + mov [text00+LLL*4+28],dword 'SEC.' + mov [text00+LLL*4+32],dword 'MAST' + mov [text00+LLL*4+36],dword 'ER ' + nog1: + cmp eax,4 + jnz nog2 + mov [text00+LLL*4+28],dword 'SEC.' + mov [text00+LLL*4+32],dword 'SLAV' + mov [text00+LLL*4+36],dword 'E ' + nog2: + + + mov eax,[hdbase] ; HD BASE + cmp eax,1 + jnz hnoe1 + mov [text00+LLL*6+28],dword 'PRI.' + mov [text00+LLL*6+32],dword 'MAST' + mov [text00+LLL*6+36],dword 'ER ' + hnoe1: + cmp eax,2 + jnz hnof1 + mov [text00+LLL*6+28],dword 'PRI.' + mov [text00+LLL*6+32],dword 'SLAV' + mov [text00+LLL*6+36],dword 'E ' + hnof1: + cmp eax,3 + jnz hnog1 + mov [text00+LLL*6+28],dword 'SEC.' + mov [text00+LLL*6+32],dword 'MAST' + mov [text00+LLL*6+36],dword 'ER ' + hnog1: + cmp eax,4 + jnz hnog2 + mov [text00+LLL*6+28],dword 'SEC.' + mov [text00+LLL*6+32],dword 'SLAV' + mov [text00+LLL*6+36],dword 'E ' + hnog2: + + + mov eax,[f32p] ; FAT32 PARTITION + add al,48 + mov [text00+LLL*14+28],al + + mov eax,[sound_dma] ; SOUND DMA + add eax,48 + mov [text00+LLL*16+28],al + + mov eax,[lba_read] + call onoff ; LBA READ + mov [text00+LLL*18+28],ebx + + mov eax,[pci_acc] + call onoff ; PCI ACCESS + mov [text00+LLL*20+28],ebx + + mov eax,[mouse_speed] ; MOUSE SPEED + add al,48 + mov [text00+LLL*26+28],al + + mov eax,[mouse_delay] + mov esi,text00+LLL*28+32 + call hexconvert ; MOUSE DELAY + + mov eax,13 + mov ebx,175*65536+85 + mov ecx,40*65536+245 + mov edx,0x80111199-19 + int 0x40 + + mov edx,text00 + mov ebx,10*65536+45 + mov eax,4 + mov ecx,0xffffff + mov esi,LLL + newline: + int 0x40 + add ebx,8 + add edx,LLL + cmp [edx],byte 'x' + jnz newline + + popa + ret + + drawtime: + mov ax,[time] ;hours 22 + mov cl,1 + call unpacktime + mov [text00+LLL*22+28],word bx + mov al,ah ;minutes + inc cl + call unpacktime + mov [text00+LLL*22+31],word bx + mov eax,[date] + mov ch,3 + call unpackdate + mov [text00+LLL*24+34],word bx ;year 24 + mov al,ah + mov ch,1 + call unpackdate + mov [text00+LLL*24+28],word bx ;month + bswap eax + mov al,ah + inc ch + call unpackdate + mov [text00+LLL*24+31],word bx ;day + + mov eax,13 + mov ebx,175*65536+85 + mov ecx,40*65536+245 + mov edx,0x80111199-19 + int 0x40 + + mov edx,text00 + mov ebx,10*65536+45 + mov eax,4 + mov ecx,0xffffff + mov esi,LLL + newline1: + int 0x40 + add ebx,8 + add edx,LLL + cmp [edx],byte 'x' + jnz newline1 + ret + + unpacktime: + cmp byte [blinkpar],cl ;translate packed number to ascii + jne unpack1 + chkblink: + bt dword [blinkpar],16 + jnc unpack1 + xor bx,bx + ret + unpackdate: + cmp byte [blinkpar+1],ch + je chkblink + unpack1: + xor bx,bx + mov bh,al + mov bl,al + and bh,0x0f + shr bl,4 + add bx,0x3030 + ret + + hexconvert: ;converting dec to hex in ascii + xor ebx,ebx + mov bl,al + and bl,15 + add ebx,hex + mov cl,[ebx] + mov [esi],cl + shr eax,4 + xor ebx,ebx + mov bl,al + and bl,15 + add ebx,hex + mov cl,[ebx] + dec esi + mov [esi],cl + shr eax,4 + xor ebx,ebx + mov bl,al + and bl,15 + add ebx,hex + mov cl,[ebx] + dec esi + mov [esi],cl + ret + +onoff: + cmp [syslang],4 + jne norus1 + mov ebx,'„€ ' + cmp eax,1 + je exitsub + mov ebx,'…’ ' + ret + norus1: + mov ebx,'ON ' + cmp eax,1 + je exitsub + mov ebx,'OFF ' + exitsub: + ret + +_midibase: + mov eax,21 + mov ebx,1 + mov ecx,[midibase] + int 0x40 + ret + +_cdbase: + mov eax,21 + mov ebx,3 + mov ecx,[cdbase] + int 0x40 + ret + +_hdbase: + mov eax,21 + mov ebx,7 + mov ecx,[hdbase] + int 0x40 + ret + +_sound_dma: + mov eax,21 + mov ebx,10 + mov ecx,[sound_dma] + int 0x40 + ret + +_lba_read: + mov eax,21 + mov ebx,11 + mov ecx,[lba_read] + int 0x40 + ret + +_pci_acc: + mov eax,21 + mov ebx,12 + mov ecx,[pci_acc] + int 0x40 + ret + +_f32p: + mov eax,21 + mov ebx,8 + mov ecx,[f32p] + int 0x40 + ret + +_sb16: + mov eax,21 + mov ebx,4 + mov ecx,[sb16] + int 0x40 + ret + +_wssp: + mov eax,21 + mov ebx,6 + mov ecx,[wssp] + int 0x40 + ret + +_syslang: + mov eax,21 + mov ebx,5 + mov ecx,[syslang] + int 0x40 + ret + +_mouse_speed: + mov eax,18 + mov ebx,19 + mov ecx,1 + mov edx,[mouse_speed] + int 0x40 + ret + +_mouse_delay: + mov eax,18 + mov ebx,19 + mov ecx,3 + mov edx,[mouse_delay] + int 0x40 + ret + +loadtxt: + cld + mov edi,text00 + mov ecx,488 ;28 + cmp [syslang],4 + jne norus + mov esi,textrus + jmp sload + norus: + mov esi,texteng + sload: + rep movsd + ret + +cleantxt: + xor eax,eax + mov ecx,428 + cld + mov edi,text00 + rep stosd + mov [text00+1711],byte 'x' + ret + +settime: + mov dx,0x70 + call startstopclk + dec dx + mov al,2 ;set minutes + out dx,al + inc dx + mov al,byte [time+1] + out dx,al + dec dx + mov al,4 ;set hours + out dx,al + inc dx + mov al,byte [time] + out dx,al + dec dx + mov al,7 ;set day + out dx,al + inc dx + mov al,byte [date+2] + out dx,al + dec dx + mov al,8 ;set month + out dx,al + inc dx + mov al,byte [date+1] + out dx,al + dec dx + mov al,9 ;set year + out dx,al + inc dx + mov al,byte [date] + out dx,al + dec dx + call startstopclk + ret + +startstopclk: + mov al,0x0b + out dx,al + inc dx + in al,dx + btc ax,7 + out dx,al + ret + +; DATA AREA +count: db 0x0 +blinkpar: dd 0x0 +time: dw 0x0 +date: dd 0x0 + +textrus: + + db ' §  MIDI ROLAND MPU-401 : 0x320 - + ąØ¬„­Øāģ' + db ' ' + db ' §  SoundBlaster 16 : 0x240 - + ąØ¬„­Øāģ' + db ' ' + db ' §  CD-ROM  : PRI.SLAVE - + ąØ¬„­Øāģ' + db ' ' + db ' §  †„-1 : PRI.MASTER - + ąØ¬„­Øāģ' + db ' ' + db 'Ÿ§ėŖ įØįā„¬ė : ENGLISH - + ąØ¬„­Øāģ' + db ' ' + db ' įŖ« ¤Ŗ  Ŗ« ¢Ø āćąė : ENGLISH - + ąØ¬„­Øāģ' + db ' ' + db ' §  WSS : 0x200 - + ąØ¬„­Øāģ' + db ' ' + db ' §¤„« FAT32 ­  †„-1 : 1 - + ąØ¬„­Øāģ' + db ' ' + db '‡¢ćŖ®¢®© Ŗ ­ « DMA : 1 - + ąØ¬„­Øāģ' + db ' ' + db '‚Ŗ«īēØāģ LBA : OFF - + ąØ¬„­Øāģ' + db ' ' + db '„®įāćÆ Ŗ čØ­„ PCI : OFF - + ąØ¬„­Øāģ' + db ' ' + db '‘Øįā„¬­®„ ¢ą„¬ļ : 0:00 - + ‚ė”®ą ' + db ' ' + db '‘Øįā„¬­ ļ ¤ ā  (¬,¤,£) : 00/00/00 - + ‚ė”®ą ' + db ' ' + db '‘Ŗ®ą®įāģ Ŗćąį®ą  ¬ėčØ : 1 - + ąØ¬„­Øāģ' + db ' ' + db '‡ ¤„ą¦Ŗ  ćįŖ®ą„­Øļ ¬ėčØ : 0x00a - + ąØ¬„­Øāģ' + db ' ' + db '‚ˆŒ€ˆ…: ąØ¬„­Øāģ ¢į„ ' + db 'ˆ‘Ž‹œ‡“‰’… „Ž‘’“ Š FAT ‘ Ž‘’ŽŽ†Ž‘’œž! ' + db '… ‡€“„œ’… ‘Ž•€ˆ’œ €‘’Ž‰Šˆ ‘®åą ­Øāģ ¢į„ ' + db 'x' + +texteng: + + db 'MIDI: ROLAND MPU-401 BASE : 0x320 - + APPLY ' + db ' ' + db 'SOUND: SB16 BASE : 0x240 - + APPLY ' + db ' ' + db 'CD-ROM BASE : PRI.SLAVE - + APPLY ' + db ' ' + db 'HARDDISK-1 BASE : PRI.MASTER - + APPLY ' + db ' ' + db 'SYSTEM LANGUAGE : ENGLISH - + APPLY ' + db ' ' + db 'KEYBOARD LAYOUT : ENGLISH - + APPLY ' + db ' ' + db 'WINDOWS SOUND SYSTEM BASE : 0x200 - + APPLY ' + db ' ' + db 'FAT32-1 PARTITION IN HD-1 : 1 - + APPLY ' + db ' ' + db 'SOUND DMA CHANNEL : 1 - + APPLY ' + db ' ' + db 'LBA READ ENABLED : OFF - + APPLY ' + db ' ' + db 'PCI ACCESS FOR APPL. : OFF - + APPLY ' + db ' ' + db 'SYSTEM TIME : 0:00 - + SELECT ' + db ' ' + db 'SYSTEM DATE (M,D,Y) : 00/00/00 - + SELECT ' + db ' ' + db 'Mouse pointer speed : 1 - + APPLY ' + db ' ' + db 'Mouse pointer delay : 0x00a - + APPLY ' + db ' ' + db 'NOTE: APPLY ALL ' + db 'TEST FAT FUNCTIONS WITH EXTREME CARE ' + db 'SAVE YOUR SETTINGS BEFORE QUIT MENUET SAVE ALL ' + db 'x' + +labelt: + db '€‘’Ž‰Š€ “‘’Ž‰‘’‚ DEVICE SETUP ' + +hex db '0123456789ABCDEF' + +alt_general: + +; 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' + + +en_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' + + +fr_keymap: + + db '6',27 + db '&Ž"',39,'(-_“)=',8,9 + db 'azertyuiop^$',13 + db '~qsdfghjklm’',0,0,'*wxcvbn,;:!',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + +fr_keymap_alt_gr: + + + db '6',27 + db 28,'~#{[|˜\^@]}',8,9 + db 'azertyuiop^$',13 + db '~qsdfghjklm’',0,0,'*wxcvbn,;:!',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + + +ge_keymap: + + db '6',27 + db '1234567890?[',8,9 + db 'qwertzuiop',203,'~',13 + db '~asdfghjkl',194,193,'1',0,39,'yxcvbnm,.-',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + +ru_keymap: + + db '6',27 + db '1234567890-=',8,9 + db '©ęćŖ„­£čé§åź',13 + db 0,"äė¢ Æą®«¤¦ķ" + db 0xf1, '-/' + db "ļēį¬Øāģ”ī",'.-','45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + +et_keymap: + + db '6',27 + db '1234567890+“',8,9 + db 'qwertyuiopüõ',13 + db '~asdfghjklöä','1',0,'ZXCVBNM;:_',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + +read_fileinfo: + dd 0 + dd 0 + dd 0 + dd 56 + dd keyboard + db 0 + dd file_name + +save_fileinfo: + dd 2 + dd 0 + dd 0 + dd 56 + dd keyboard +file_name: db '/hd0/1/kolibri/etc/setup.dat',0 + +I_PARAM dd 0 + +keyboard dd 0x0 +midibase dd 0x320 +cdbase dd 0x2 +sb16 dd 0x220 +syslang dd 0x1 +wss dd 0x1 +wssp dd 0x0 +hdbase dd 0x1 +f32p dd 0x1 +sound_dma dd 0x1 +lba_read dd 0x1 +pci_acc dd 0x1 +mouse_speed dd 0x3 +mouse_delay dd 0x10 +text00: + + +I_END: +table_area: diff --git a/kernel/branches/hd_kolibri/apps/vrr_m/build.bat b/kernel/branches/hd_kolibri/apps/vrr_m/build.bat new file mode 100644 index 0000000000..68ecfa3cf8 --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/vrr_m/build.bat @@ -0,0 +1,2 @@ +fasm vrr_m.asm vrr_m +pause diff --git a/kernel/branches/hd_kolibri/apps/vrr_m/macros.inc b/kernel/branches/hd_kolibri/apps/vrr_m/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/vrr_m/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/apps/vrr_m/vrr_m.asm b/kernel/branches/hd_kolibri/apps/vrr_m/vrr_m.asm new file mode 100644 index 0000000000..20b4beaf1b --- /dev/null +++ b/kernel/branches/hd_kolibri/apps/vrr_m/vrr_m.asm @@ -0,0 +1,123 @@ +; +; ąØ¬„ą Æą®£ą ¬¬ė ¤«ļ MenuetOS +; ®§¢ćēØ¢ „ā Ŗ®¤ ­ ¦ ā®© Ŗ« ¢ØčØ ;) +; +; Š®¬ÆØ«Øą®¢ āģ FASM'®¬ +; +; ‘¬. ā Ŗ¦„: +; template.asm - ÆąØ¬„ą Æą®įā„©č„© Æą®£ą ¬¬ė (­®¢ė©!) +; rb.asm - Ŗ®­ā„Ŗįā­®„ ¬„­ī ą ”®ē„£® įā®«  +; example2.asm - ÆąØ¬„ą ¬„­ī Ø ¤®Æ®«­Øā„«ģ­ėå ®Ŗ®­ +; example3.asm - ÆąØ¬„ą ¬„­ī, ą„ «Ø§®¢ ­­®£® Æ®-¤ąć£®¬ć +;--------------------------------------------------------------------- + + use32 ; ¢Ŗ«īēØāģ 32-”Øā­ė© ą„¦Ø¬  įį„¬”«„ą  + org 0x0 ;  ¤ą„į ęØļ į ­ć«ļ + + db 'MENUET01' ; 8-” ©ā­ė© ؤ„­āØäØŖ ā®ą MenuetOS + dd 0x01 ; ¢„ąįØļ § £®«®¢Ŗ  (¢į„£¤  1) + dd START ;  ¤ą„į Æ„ą¢®© Ŗ®¬ ­¤ė + dd I_END ; ą §¬„ą Æą®£ą ¬¬ė + dd 0x1000 ; Ŗ®«Øē„įā¢® Æ ¬ļāØ + dd 0x1000 ;  ¤ą„į ¢„ąčØ­ė įāķŖ  + dd 0x0 ;  ¤ą„į ”ćä„ą  ¤«ļ Æ ą ¬„āą®¢ (­„ ØįÆ®«ģ§ć„āįļ) + dd 0x0 ; § ą„§„ą¢Øą®¢ ­® + +include 'MACROS.INC' ; ¬ Ŗą®įė ®”«„£ē īā ¦Ø§­ģ  įį„¬”«„ąéØŖ®¢! + +;--------------------------------------------------------------------- +;--- €—€‹Ž Žƒ€ŒŒ› ---------------------------------------------- +;--------------------------------------------------------------------- + +START: +; mcall 5,10 + mov ecx, 1 + mov edx, drvinfo + push @f + jmp call_driver +@@: +; jmp run_launcher + + mov ecx, 2 + push @f +call_driver: + mcall 21,13 + ret +@@: +; cmp eax,-1 + inc eax + je run_launcher +; cmp ecx,280 +; je change_vrr +; cmp ecx,277 +; je change_vrr +; cmp ecx,6 +; je change_vrr +; cmp ecx,7 +; je change_vrr +; jmp run_launcher +change_vrr: +; mov ax,cx +; dec cx +; shl cx,1 +; xor edx,edx +; mov dx,[vidmode+ecx] +; mov ebx,ecx +; shl ebx,2 +; add ebx,ecx ; ebx=ebx*5 +; shr ax,8 +; dec ax +; shl ax,1 +; add ebx,eax +; ror edx,16 +; mov dx,[_m1+ebx] +; rol edx,16 + ;mov eax,ecx + mov eax, 10 + cmp cx,277+3 + je yes_277 + cmp cx,274+3 + jne yes_280 + yes_274: + add al,10 + yes_277: + add al,10 + yes_280: + mov edx, [_m1+eax-2] + lea dx, [ecx-3] + push run_launcher + mov ecx, 3 + jmp call_driver +run_launcher: + mcall 70,launcher + mcall -1 + +launcher: + dd 7 + dd 0 + dd 0 + dd 0 + dd 0 + db 0 +prog: dd autorun_prog + +autorun_prog db '/hd0/1/kolibri/bin/launcher',0 +I_END: ; ¬„āŖ  Ŗ®­ę  Æą®£ą ¬¬ė + db ? ; system loader will zero all memory after program end + ; this byte will be terminating zero for launcher string +; \begin{Serge} + ; A you really believe it? + ; Įėąęåķ, źņī āåšóåņ, ņåļėī åģó ķą ńāåņå! +; \end{Serge} +drvinfo: ; 512 bytes driver info area +; +0 - Full driver name +; +32 - Driver version +; +64 - Word List of support video modes (max 32 positions) +; +128 - 5 words list of support vertical rate to each present mode + org $+32 +drvver: + org $+32 +vidmode: + org $+64 +_m1: + org drvinfo+200h diff --git a/kernel/branches/hd_kolibri/kernel/blkdev/cd_drv.inc b/kernel/branches/hd_kolibri/kernel/blkdev/cd_drv.inc new file mode 100644 index 0000000000..5eba26bcdc --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/cd_drv.inc @@ -0,0 +1,554 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;********************************************************** +; Ķåļīńšåäńņāåķķą’ šąįīņą ń óńņšīéńņāīģ ŃD (ATAPI) +;********************************************************** +; Ąāņīš čńõīäķīćī ņåźńņą Źóėąźīā Āėąäčģčš Ćåķķąäüåāč÷. +; Ąäąļņąöč’ č äīšąįīņźą Mario79 + +; Ļšīöåäóšą äė’ ļīėķīćī ń÷čņūāąķč’ āńåõ +; äąķķūõ čē ńåźņīšą źīģļąźņ-äčńźą +; Ąāņīš ņåźńņą ļšīćšąģģū Źóėąźīā Āėąäčģčš Ćåķķąäüåāč÷. + + +; Ģąźńčģąėüķīå źīėč÷åńņāī ļīāņīšåķčé īļåšąöčč ÷ņåķč’ +MaxRetr equ 3 +; Ļšåäåėüķīå āšåģ’ īęčäąķč’ ćīņīāķīńņč ź ļščåģó źīģąķäū +; (ā ņčźąõ) +BSYWaitTime equ 1000 ;2 + +;************************************************* +;* ĻĪĖĶĪÅ ×ŅÅĶČÅ ŃÅŹŅĪŠĄ ŹĪĢĻĄŹŅ-ÄČŃŹĄ * +;* Ń÷čņūāąžņń’ äąķķūå ļīėüēīāąņåė’, čķōīšģąöč’ * +;* ńóįźąķąėą č źīķņšīėüķą’ čķōīšģąöč’ * +;* Āõīäķūå ļąšąģåņšū ļåšåäąžņń’ ÷åšåē ćėīįąėüķūå * +;* ļåšģåķķūå: * +;* 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 +; call test_mario79 + popa + ret + +;******************************************** +;* ×ŅÅĶČÅ ŃÅŹŅĪŠĄ Ń ĻĪĀŅĪŠĄĢČ * +;* Ģķīćīźšąņķīå ļīāņīšåķčå ÷ņåķč’ ļšč ńįī’õ * +;******************************************** +ReadCDWRetr: + pusha +; Öčźė, ļīźą źīģąķäą ķå āūļīėķåķą óńļåųķī čėč ķå +; čń÷åšļąķī źīėč÷åńņāī ļīļūņīź + mov ECX,MaxRetr +@@NextRetr: +; Ļīäąņü źīģąķäó + call ReadCD + cmp [DevErrorCode],0 + je @@End_4 +; Ēąäåšęźą ķą 2,5 ńåźóķäū + mov EAX,[timer_ticks] + add EAX,250 ;50 +@@Wait: + call change_task + cmp EAX,[timer_ticks] + ja @@Wait + loop @@NextRetr +; call test_mario79 +; Ńīīįłåķčå īį īųčįźå +; mov SI,offset ErrS +; call FatalError +@@End_4: + popa + 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 +; Ēąäąņü šåęčģ 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 +; call test_mario79 + cmp [DevErrorCode],0 ;ļšīāåščņü źīä īųčįźč + jne @@End_8 ;ēąźīķ÷čņü, ńīõšąķčā źīä īųčįźč + +; Īęčäąķčå ćīņīāķīńņč äčńźīāīäą ź ļščåģó +; ļąźåņķīé źīģąķäū + mov DX,[ATABasePortAddr] + add DX,7 ;ļīšņ 1õ7h +@@WaitDevice0: + call change_task + ; Ļšīāåščņü āšåģ’ āūļīėķåķč’ źīģąķäū + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,BSYWaitTime + ja @@Err1_1 ;īųčįźą ņąéģ-ąóņą + ; Ļšīāåščņü ćīņīāķīńņü + in AL,DX + test AL,80h ;ńīńņī’ķčå ńčćķąėą BSY + jnz @@WaitDevice0 + test AL,1 ;ńīńņī’ķčå ńčćķąėą ERR + jnz @@Err6 + test AL,08h ;ńīńņī’ķčå ńčćķąėą DRQ + jz @@WaitDevice0 +; Ļīńėąņü ļąźåņķóž źīģąķäó + 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 +@@WaitDevice1: + call change_task + ; Ļšīāåščņü āšåģ’ āūļīėķåķč’ źīģąķäū + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,MaxCDWaitTime + ja @@Err1_1 ;īųčįźą ņąéģ-ąóņą + ; Ļšīāåščņü ćīņīāķīńņü + in AL,DX + test AL,80h ;ńīńņī’ķčå ńčćķąėą BSY + jnz @@WaitDevice1 + test AL,1 ;ńīńņī’ķčå ńčćķąėą ERR + jnz @@Err6_temp + test AL,08h ;ńīńņī’ķčå ńčćķąėą DRQ + jz @@WaitDevice1 + cli +; Ļščķ’ņü įėīź äąķķūõ īņ źīķņšīėėåšą + mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf + ; Ēąćšóēčņü ąäšåń šåćčńņšą äąķķūõ źīķņšīėėåšą + mov DX,[ATABasePortAddr] ;ļīšņ 1x0h + ; Ēąćšóēčņü ā ń÷åņ÷čź šąēģåš įėīźą ā įąéņąõ + mov CX,[CDBlockSize] + ; Āū÷čńėčņü šąēģåš įėīźą ā 16-šąēš’äķūõ ńėīāąõ + shr CX,1 ;šąēäåėčņü šąēģåš įėīźą ķą 2 + ; Ļščķ’ņü įėīź äąķķūõ + 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 +; Ēąäąņü šåęčģ 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 +; Īęčäąķčå ļīäņāåšęäåķč’ ļščåģą źīģąķäū + 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 +; Ļšīāåščņü ēķą÷åķčå źīäą šåęčģą + 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 ecx,0xfff + mov eax,[timer_ticks] + mov [TickCounter_1],eax +@@WaitHDReady_2: + call change_task + ; Ļšīāåščņü āšåģ’ īęčäąķč’ +; dec ecx +; cmp ecx,0 +; je @@Err1 + mov eax,[timer_ticks] + sub eax,[TickCounter_1] + cmp eax,BSYWaitTime ;300 ;īęčäąņü 3 ńåź. + ja @@Err1_4 ;īųčįźą ņąéģ-ąóņą + ; Ļšī÷čņąņü šåćčńņš ńīńņī’ķč’ + 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 +; ÖČŹĖ ĪĘČÄĄĶČß ĆĪŅĪĀĶĪŃŅČ ÓŃŅŠĪÉŃŅĀĄ +@@SendCommand: + ; Ļīäąņü źīģąķäó ļšīāåšźč ćīņīāķīńņč + call SendPacketNoDatCommand + call change_task + ; Ļšīāåščņü źīä īųčįźč + cmp [DevErrorCode],0 + je @@End_11 + ; Ļšīāåščņü āšåģ’ īęčäąķč’ ćīņīāķīńņč + mov EAX,[timer_ticks] + sub EAX,[WURStartTime] + cmp EAX,MaxCDWaitTime + jb @@SendCommand + ; Īųčįźą ņąéģ-ąóņą + mov [DevErrorCode],1 +@@End_11: + 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 - ķīģåš äčńźą ķą źąķąėå. * +;************************************************* +UnloadMedium: + pusha +; Ī÷čńņčņü įóōåš ļąźåņķīé źīģąķäū + call clear_packet_buffer +; Ńōīšģčšīāąņü źīģąķäó START/STOP UNIT + ; Ēąäąņü źīä źīģąķäū + mov [PacketCommand],word 1Bh + ; Ēąäąņü īļåšąöčž čēāėå÷åķč’ ķīńčņåė’ + mov [PacketCommand+4],word 00000010b +; Ļīäąņü źīģąķäó + call SendPacketNoDatCommand + 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/hd_kolibri/kernel/blkdev/cdrom.inc b/kernel/branches/hd_kolibri/kernel/blkdev/cdrom.inc new file mode 100644 index 0000000000..75f6c3c59b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/cdrom.inc @@ -0,0 +1,269 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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/hd_kolibri/kernel/blkdev/fdc.inc b/kernel/branches/hd_kolibri/kernel/blkdev/fdc.inc new file mode 100644 index 0000000000..3544c8d553 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/fdc.inc @@ -0,0 +1,82 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +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_filesave: ;ebx: cluster to be saved. + pusha ;returns immediately. does not trigger a write. + mov eax,ebx + add eax,31 + mov bl,18 + div bl + mov ah,0 + add eax,OS_BASE+0xD201 + mov [eax],byte 1 ;This track is now dirty. + popa +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/hd_kolibri/kernel/blkdev/flp_drv.inc b/kernel/branches/hd_kolibri/kernel/blkdev/flp_drv.inc new file mode 100644 index 0000000000..a2c8a43e63 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/flp_drv.inc @@ -0,0 +1,623 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;********************************************************** +; Ķåļīńšåäńņāåķķą’ šąįīņą ń źīķņšīėėåšīģ ćčįźīćī äčńźą +;********************************************************** +; Ąāņīš čńõīäķīćī ņåźńņą Źóėąźīā Āėąäčģčš Ćåķķąäüåāč÷. +; Ąäąļņąöč’ č äīšąįīņźą 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/hd_kolibri/kernel/blkdev/hd_drv.inc b/kernel/branches/hd_kolibri/kernel/blkdev/hd_drv.inc new file mode 100644 index 0000000000..b5f854022c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/hd_drv.inc @@ -0,0 +1,871 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Low-level driver for HDD access +; DMA support by Mario79 + +;************************************************************************** +; +; 0x600008 - 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 ) +; +; +65536 - cache entries +; +;************************************************************************** + +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,OS_BASE+0x600000+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 + cmp [dma_hdd], 1 + jnz .nodma + call hd_read_dma + jmp @f +.nodma: + call hd_read_pio +@@: + + lea esi,[edi*8+OS_BASE+0x600000] + 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,OS_BASE+0x600000+65536 + 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,OS_BASE+0x600000+65536 + 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,OS_BASE+0x600000+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+OS_BASE+0x600000] + mov [esi],eax ; sector number + + yes_in_cache_write: + + mov dword [esi+4],2 ; write - differs from hd + + shl edi,9 + add edi,OS_BASE+0x600000+65536 + mov esi,ebx + mov ecx,512/4 + cld + rep movsd ; move data + hd_write_access_denied: + pop edi esi ecx + ret + + +write_cache: +;----------------------------------------------------------- +; write all changed sectors to disk +;----------------------------------------------------------- + push eax ecx edx esi edi + + ; write difference ( 2 ) from cache to hd + + mov ecx,cache_max + mov esi,OS_BASE+0x600000+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 [allow_dma_write], 1 + jnz .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], 64 + 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 +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,OS_BASE+0x600000+65536 ; esi = from memory position + mov ecx,256 + mov edx,[hdbase] + cld + rep outsw +; sti + + call enable_ide_int + pop esi ecx + + 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: + + mov ecx,cache_max*10/100 + mov edi,[cache_search_start] + + search_for_empty: + + inc edi + cmp edi,cache_max + jbe inside_cache + mov edi,1 + + inside_cache: + + cmp dword [edi*8+OS_BASE+0x600000+4],2 ; get cache slot info + 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: + + mov [cache_search_start],edi + found_slot_access_denied: + ret + +align 4 +clear_hd_cache: + + push eax ecx edi + mov edi,OS_BASE+0x600000 + mov ecx,16384 + xor eax,eax + cld + rep stosd ; clear hd cache with 0 + mov [cache_search_start],eax + mov [fat_in_cache],-1 + mov [fat_change],0 + pop edi ecx eax + ret + +save_hd_wait_timeout: + + push eax + mov eax,[timer_ticks];[0xfdf0] + 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 ;[0xfdf0],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" +; jmp $ + 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 OS_BASE+284000h + dw 2000h + dw 8000h + +dma_cur_sector dd not 40h +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_write 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 [0xFFFF], 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 [0xFFFF], 1 + call do_change_task +.noswitch: + popad + popfd + ret + +align 4 +hd_read_dma: + push eax + push edx + 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+0x284000 + push ecx esi edi + mov esi, eax + shl edi, 9 + add edi, OS_BASE+0x610000 + mov ecx, 512/4 + cld + rep movsd + pop edi esi ecx + pop edx + pop eax + ret +.notread: + mov eax, IDE_descriptor_table-OS_BASE + mov dword [eax+OS_BASE], 0x284000 + mov word [eax+4+OS_BASE], 0x2000 + 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 + pop edx + pop eax + mov [dma_cur_sector], eax + jmp hd_read_dma + +align 4 +write_cache_chain: + push esi + mov eax, IDE_descriptor_table + mov edx, [cache_chain_pos] + shl edx, 9 + add edx, OS_BASE+0x610000 + mov [eax], edx + movzx edx, [cache_chain_size] + shl edx, 9 + mov [eax+4], dx + jmp do_write_dma +write_cache_sector: + push esi + mov eax, IDE_descriptor_table + mov edx, edi + shl edx, 9 + add edx, OS_BASE+0x610000 + mov [eax], edx + mov word [eax+4], 0x200 +do_write_dma: + 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} diff --git a/kernel/branches/hd_kolibri/kernel/blkdev/rd.inc b/kernel/branches/hd_kolibri/kernel/blkdev/rd.inc new file mode 100644 index 0000000000..842df11abc --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/rd.inc @@ -0,0 +1,2473 @@ +$Revision: 442 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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 + +filedelete: +;-------------------------------------------- +; +; filedelete - sys floppy +; in: +; eax - pointer to filename 11 chars +; +; out: +; eax - 0 = successful, 5 = file not found +; +;-------------------------------------------- + + sub esp,32 + call expand_filename + + push eax ebx ecx edx esi edi + + call rd_findfile + je fifoundd + pop edi esi edx ecx ebx eax ;file not found + add esp,32 + mov eax,5 + ret + + fifoundd: + + mov [edi-11],byte 0xE5 ;mark filename deleted + add edi,0xf + movzx eax,word [edi] + mov edi,eax ;edi = cluster + + frnewd: + + shl edi,1 ;find next cluster from FAT + add edi,RAMDISK_FAT + movzx eax,word [edi] + mov [edi],word 0x0 ;clear fat chain cluster + mov edi,eax + cmp edi,dword 0xff8 ;last cluster ? + jb frnewd + + pop edi esi edx ecx ebx eax + add esp,32 + xor eax,eax ; file found + ret + + + +filesave: +;---------------------------------------------------------- +; +; filesave - sys floppy +; +; eax points to filename 11 chars +; +; eax ; pointer to file name +; ebx ; buffer +; ecx ; count to write in bytes +; edx ; 0 create new , 1 append +; +;----------------------------------------------------------- + + sub esp,32 + call expand_filename + test edx,edx + jnz fsdel + pusha + call filedelete + popa + + fsdel: + + call ramdisk_free_space + cmp ecx,edi + jbe rd_do_save + add esp,32 + mov eax,8 ;disk full + ret + + rd_do_save: + + push eax ebx ecx edx esi edi + + mov edi,RAMDISK+512*18+512 ;Point at directory + mov edx,224 +1 + ; find an empty spot for filename in the root dir + l20ds: + dec edx + jz frnoreadds + l21ds: + cmp [edi],byte 0xE5 + jz fifoundds + cmp [edi],byte 0x0 + jz fifoundds + add edi,32 ; Advance to next entry + jmp l20ds + fifoundds: + + push edi ; move the filename to root dir + mov esi,[esp+4+20] + mov ecx,11 + cld + rep movsb + pop edi + mov edx,edi + add edx,11+0xf ; edx <- cluster save position + mov ebx,[esp+12] ; save file size + mov [edi+28],ebx + mov [edi+11],byte 0x20 ; attribute +; Ivan Poddubny 11/12/2003: +call get_date_for_file ; from FAT32.INC +mov [edi+24],ax ; date +call get_time_for_file ; from FAT32.INC +mov [edi+22],ax ; time +; End + mov edi,RAMDISK_FAT ;pointer to first cluster + mov ecx,2849 + cld + frnewds: + xor ax,ax + repne scasw + mov ebx,2848 + sub ebx,ecx + mov [edx],bx ; save next cluster pos. to prev cl. + mov edx,edi ; next save pos abs mem add + dec edx + dec edx + call fdc_filesave + pusha ; move save to floppy cluster + add ebx,31 + shl ebx,9 + add ebx,RAMDISK + mov eax,[esp+32+16] + mov ecx,512 + call memmove + popa + + mov eax,[esp+12] + cmp eax,512 + jbe flnsa + sub eax,512 + mov [esp+12],eax + add dword [esp+16], 512 + jmp frnewds + + flnsa: + mov [edi-2],word 4095 ; mark end of file - last cluster + + frnoreadds: + + pop edi esi edx ecx ebx eax + add esp,32 + +; pusha +; cli +; call fdc_commitfile +; sti +; popa + + xor eax,eax ;ok write + 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->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 + 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: + 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] +.succ: + pop edi + popad + clc + ret +.break: + jecxz .noplace + inc edi + mov al, '1' +@@: + xchg al, [edi] + inc edi + cmp al, ' ' + mov al, '0' + jnz @b + jmp .succ +.noplace: + dec edi + cmp edi, [esp] + jz .err + add dword [esp], 8 + mov word [edi], '~1' + inc edi + inc edi +@@: + mov byte [edi], '0' + 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 edi, ecx + jbe .skip +@@: + dec edi + mov al, ' ' + xchg al, [edi] + dec ebx + mov [ebx], al + 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 ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + push ramdisk_root_extend_dir + push ramdisk_root_next_write + push ebp + push ramdisk_root_first + push ramdisk_root_next + jmp .common1 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 +; check existence + mov byte [ebp], 0 + call rd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + 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)] + 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_RamdiskExecute - LFN variant for executing on sys floppy +; +; esi points to ramdisk filename (e.g. 'launcher') +; ebp points to full filename (e.g. '/rd/1/launcher') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_RamdiskExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_RamdiskExecute.flags - second entry +; +; esi points to ramdisk filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov edx, [eax+4] ; cluster + lea esi, [edx+31] + shl esi, 9 + add esi, RAMDISK + mov ecx, 512/4 + rep movsd + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov dx, [edx*2+RAMDISK_FAT] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + 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/hd_kolibri/kernel/blkdev/rdsave.inc b/kernel/branches/hd_kolibri/kernel/blkdev/rdsave.inc new file mode 100644 index 0000000000..243674092d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/blkdev/rdsave.inc @@ -0,0 +1,30 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +iglobal +saverd_fileinfo: + dd 2 ; subfunction: write + dd 0 ; (reserved) + dd 0 ; (reserved) + dd 1440*1024 ; size 1440 Kb + dd 0x100000 - std_application_base_address ; base address + db 0 +.name: + dd ? +endg +sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) + call restorefatchain + mov eax, saverd_fileinfo - std_application_base_address + mov [saverd_fileinfo.name], ebx + pushad + push eax + call file_system_lfn + pop eax + popad + mov [esp+36], eax + ret diff --git a/kernel/branches/hd_kolibri/kernel/boot/ETFONT.FNT b/kernel/branches/hd_kolibri/kernel/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 + +; Now int 16 is used for keyboard support. +; This is shorter, simpler and more reliable. +if 0 +getkey: push ecx + push edx + add ebx,0x0101 + xor eax,eax + + gk1: + in al,0x60 + mov cl,al + gk0: + in al,0x60 + cmp al,cl + je gk0 + cmp ax,11 + jg gk0 + gk0_1: + mov cl,al + +; add al,47 +; mov [ds:keyinbs-0x10000],al +; mov si,keyinbs-0x10000 +; call printplain + + gk12: + in al,0x60 + cmp al,cl + je gk12 + cmp ax,240 + jne gk13 + mov al,cl + jmp gk14 + gk13: + add cl,128 + cmp al,cl + jne gk1 + sub al,128 + gk14: + + movzx edx,bl + cmp eax,edx + jb gk1 + movzx edx,bh + cmp eax,edx + jg gk1 + test ebx,0x010000 + jnz gk3 + mov cx,0x1000 + mov dx,cx + add eax,47 + mov cx,ax + cmp cx,58 + jb gk_nozero + sub cx,10 + gk_nozero: + mov [ds:keyin-0x10000],cl + mov si,keyin-0x10000 + call printplain + gk3: + sub eax,48 + pop edx + pop ecx + ret +end if + +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 +} + +;pagetable_set: +;eax - physical address +;es:di - page table +;ecx - number of pages to map +; or al, 7 +;@@: +; stosd +; add eax, 1000h +; loop @b +; ret + +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-0x10000 +sayerr_plain: + call printplain + jmp $ +@@: + pop si + ret + +;========================================================================= +; +; 16 BIT CODE +; +;========================================================================= + + +start_of_code: + cld +; \begin{diamond}[02.12.2005] + cmp ax, 'KL' + jnz @f + mov word [cs:cfgmanager.loader_block-0x10000], si + mov word [cs:cfgmanager.loader_block+2-0x10000], ds +@@: +; \end{diamond}[02.12.2005] + + + mov word [cs:bx_from_load - 0x10000], bx ; {SPraid}[13.03.2007] + + +; 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-10000h ; 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-10000h ; 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-10000h ; ET_FNT1 + mov bx,1000h ; + mov cx,255 ; 256 symbols + mov dx,0h ; 0 - position of first symbol + mov ax,1100h + int 10h +end if + +; draw frames + push 0xb800 + pop es + xor di, di +; mov si,d80x25-0x10000 +; mov cx,80*25 +; mov ah,1*16+15 +; dfl1: +; lodsb +; stosw +; loop dfl1 + mov ah, 1*16+15 +; draw top + mov si, d80x25_top - 0x10000 + mov cx, d80x25_top_num * 80 +@@: + lodsb + stosw + loop @b +; draw spaces + mov si, space_msg - 0x10000 + mov cx, 25 - d80x25_top_num - d80x25_bottom_num +dfl1: + push cx + push si + mov cx, 80 +@@: + lodsb + stosw + loop @b + pop si + pop cx + loop dfl1 +; draw bottom + mov si, d80x25_bottom - 0x10000 + mov cx, d80x25_bottom_num * 80 +@@: + lodsb + stosw + loop @b + + mov byte [space_msg-0x10000+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-0x10000 +sayerr: + call print + jmp $ + cpugood: + +; set up esp + movzx esp, sp + +; FLUSH 8042 KEYBOARD CONTROLLER + +;// mike.dld [ + ; mov al,0xED + ; out 0x60,al + ; or cx,-1 + ; @@: + ; in al,0x64 + ; test al,2 + ; jz @f + ; loop @b + ; @@: + ; mov al,0 + ; out 0x60,al + ; or cx,-1 + ; @@: + ; in al,0x64 + ; test al,2 + ; jz @f + ; loop @b + ; @@: +;// mike.dld ] + +; mov ecx,10000 +; fl1: +; in al,0x64 +; loop fl1 +; test al,1 +; jz fl2 +; in al,0x60 +; jmp fl1 +; fl2: + +;**************************************************************** +; The function is modified Mario79 +;***************************************************************** +; wait_kbd: ; variant 1 +; mov cx,2500h ;ēąäåšęźą ļīš’äźą 10 ģńåź +; test_kbd: +; in al,64h ;÷čņąåģ ńīńņī’ķčå źėąāčąņóšū +; test al,2 ;ļšīāåšźą įčņą ćīņīāķīńņč +; loopnz test_kbd + + 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 + mov si, 0 ; 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 + mov si, 0 ; 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 + mov si, 0 + 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 + +; --------------- APM --------------------- + push 0 + pop es + mov 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 - 0x10000 + 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 + ; init selectors + movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment + shl eax, 4 + mov [apm_code_32 - 0x10000 + 2], ax + shr eax, 16 + mov [apm_code_32 - 0x10000 + 4], al + movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment + shl ecx, 4 + mov [apm_code_16 - 0x10000 + 2], cx + shr ecx, 16 + mov [apm_code_16 - 0x10000 + 4], cl + movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment + shl edx, 4 + mov [apm_data_16 - 0x10000 + 2], dx + shr edx, 16 + mov [apm_data_16 - 0x10000 + 4], dl + mov [es : 0x9040], ebx ; offset of APM entry point +apm_end: + _setcursor d80x25_top_num, 0 +; ----------------------------------------- + +; DISPLAY VESA INFORMATION + + push 0 + pop es + mov ax,0x4f00 + mov di,0xa000 + int 0x10 + cmp ax,0x004f + mov si, novesa-0x10000 + jnz @f + mov bx, word [es:di+0x12] + shl ebx,16 + mov [es:0x9050], ebx + mov ax,[es:di+4] + add ax,'0'*256+'0' + mov si,vervesa-0x10000 + mov [si+vervesa_off], ah + mov [si+vervesa_off+2], al +@@: call print + +; \begin{diamond}[30.11.2005] +cfgmanager: +; settings: +; a) preboot_graph = graphical mode +; preboot_gprobe = probe this mode? +; b) preboot_dma_write = use DMA write? +; c) preboot_vrrm = use VRR? +; d) preboot_device = from what boot? + mov di, preboot_graph-0x10000 +; check bootloader block + cmp [.loader_block-0x10000], -1 + jz .noloaderblock + les bx, [.loader_block-0x10000] + cmp byte [es:bx], 1 + mov si, loader_block_error-0x10000 + jnz sayerr + test byte [es:bx+1], 1 + jz @f +; image in memory present + cmp [di+preboot_device-preboot_graph], 0 + jnz @f + mov [di+preboot_device-preboot_graph], 3 +@@: +.noloaderblock: +; determine default settings + mov [.bSettingsChanged-0x10000], 0 + cmp byte [di], 0 + jnz .preboot_gr_end + mov [di+preboot_gprobe-preboot_graph], 0 + mov al, [vervesa+vervesa_off-0x10000] + cmp al, 'x' + jz .novesa + cmp al, '1' + jz .vesa12 + mov [di+preboot_gprobe-preboot_graph], 2 + mov al, 3 + jmp @f +.vesa12: + mov al, 7 + jmp @f +.novesa: + mov al, 10 +@@: + mov [di], al +.preboot_gr_end: + cmp [di+preboot_dma_write-preboot_graph], 1 + adc [di+preboot_dma_write-preboot_graph], 0 + cmp [di+preboot_vrrm-preboot_graph], 1 + adc [di+preboot_vrrm-preboot_graph], 0 + cmp [di+preboot_device-preboot_graph], 1 + adc [di+preboot_device-preboot_graph], 0 +; notify user + mov si, linef-0x10000 + call print + mov si, start_msg-0x10000 + call print + mov si, time_msg-0x10000 + call print +; get start time + call .gettime + mov [.starttime-0x10000], eax + mov word [.timer-0x10000], .newtimer + mov word [.timer-0x10000+2], cs +.printcfg: + _setcursor 9,0 + mov si, current_cfg_msg-0x10000 + call print + mov si, curvideo_msg-0x10000 + call print + mov al, [preboot_graph-0x10000] + cmp al, 8 + ja .pnovesa + mov dl, al + and eax, 3 + mov si, [modes_msg-0x10000+eax*2] + call printplain + mov si, modevesa20-0x10000 + cmp dl, 4 + jbe @f + mov si, modevesa12-0x10000 +@@: + call printplain + cmp dl, 4 + ja .x + mov si, probeno_msg-0x10000 + cmp [preboot_gprobe-0x10000], 2 + jnz @f + mov si, probeok_msg-0x10000 +@@: + call printplain +.x: + jmp .c +.pnovesa: + cmp al, 9 + mov si, mode9-0x10000 + jz @b + mov si, mode10-0x10000 + jmp @b +.c: + mov si, linef-0x10000 + call printplain + mov si, dma_msg-0x10000 + cmp [preboot_dma_write-0x10000], 1 + call .say_on_off + mov si, vrrm_msg-0x10000 + cmp [preboot_vrrm-0x10000], 1 + call .say_on_off + mov si, preboot_device_msg-0x10000 + call print + mov al, [preboot_device-0x10000] + and eax, 3 + mov si, [preboot_device_msgs-0x10000+eax*2] + call printplain +.wait: + _setcursor 25,0 ; out of screen +; set timer interrupt handler + cli + push 0 + pop es + mov eax, [es:8*4] + mov [.oldtimer-0x10000], eax + mov eax, [.timer-0x10000] + mov [es:8*4], eax + sti +; wait for keypressed + mov ah, 0 + int 16h + push ax +; restore timer interrupt + push 0 + pop es + mov eax, [.oldtimer-0x10000] + mov [es:8*4], eax + mov [.timer-0x10000], eax + _setcursor 7,0 + mov si, space_msg-0x10000 + call printplain + 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 .wait + _setcursor 15,0 + mov si,bdev-0x10000 + call print + mov bx,'13' + call getkey + mov [preboot_device-0x10000], al + _setcursor 13,0 +.d: + mov [.bSettingsChanged-0x10000], 1 + mov si, space_msg-0x10000 + call printplain + _setcursor 15,0 + mov cx, 6 +@@: + call printplain + loop @b + jmp .printcfg +.change_a: + _setcursor 15,0 + mov si, gr_mode-0x10000 + call printplain + mov bx, '09' + call getkey + mov [preboot_graph-0x10000], al + cmp al, 4 + ja @f + mov si, probetext-0x10000 + call printplain + mov bx, '12' + call getkey + mov [preboot_gprobe-0x10000], al +@@: + _setcursor 10,0 + jmp .d +.change_b: + _setcursor 15,0 + mov si, ask_dma-0x10000 + call print + mov bx, '12' + call getkey + mov [preboot_dma_write-0x10000], al + _setcursor 11,0 + jmp .d +.change_c: + _setcursor 15,0 + mov si, vrrmprint-0x10000 + call print + mov bx, '12' + call getkey + mov [preboot_vrrm-0x10000], al + _setcursor 12,0 + jmp .d +.say_on_off: + pushf + call print + mov si, on_msg-0x10000 + popf + jz @f + mov si, off_msg-0x10000 +@@: call printplain + ret +; 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 + org $+0x10000 +.loader_block dd -1 + org $-0x10000 +.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-0x10000] + pushad + call .gettime + sub eax, [.starttime-0x10000] + 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-0x10000], cl +else if lang eq et + cmp al, 1 + ja @f + mov [time_str+9-0x10000], ' ' + mov [time_str+10-0x10000],' ' +@@: +else +; wait 5/4/3/2 seconds, 1 second + cmp al, 1 + mov cl, 's' + ja @f + mov cl, ' ' +@@: mov [time_str+9-0x10000], cl +end if + add al, '0' + mov [time_str+1-0x10000], al + mov si, time_msg-0x10000 + _setcursor 7,0 + call print + _setcursor 25,0 + popad + pop ds + iret +.timergo: + push 0 + pop es + mov eax, [.oldtimer-0x10000] + mov [es:8*4], eax + mov sp, 0EC00h +.continue: + sti + _setcursor 6,0 + mov si, space_msg-0x10000 + call printplain + call printplain + _setcursor 6,0 + mov si, loading_msg-0x10000 + call print + _setcursor 15,0 + cmp [.bSettingsChanged-0x10000], 0 + jz .load + cmp [.loader_block-0x10000], -1 + jz .load + les bx, [.loader_block-0x10000] + mov eax, [es:bx+3] + push ds + pop es + test eax, eax + jz .load + push eax + mov si, save_quest-0x10000 + 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-0x10000+80], 186 + pop eax + push cs + push .cont + push eax + retf +.loadc: + pop eax +.cont: + push cs + pop ds + mov si, space_msg-0x10000 + mov byte [si+80], 0 + _setcursor 15,0 + call printplain + _setcursor 15,0 +.load: +; \end{diamond}[02.12.2005] + +; ASK GRAPHICS MODE + + movzx ax, [preboot_graph-0x10000] + push 0 + pop es +; address is gr_table+6*(ax-1)-0x10000 + add ax, ax + lea si, [gr_table-0x10000 + eax + eax*2 - 6] + mov bx,[si+0] + mov cx,[si+2] + mov dx,[si+4] + cmp al, 9*2 + mov al, 32 ; BPP + jb @f + mov [es:0x9000], al + mov dword [es:0x9018], 0xFFFFFFFF; 0x800000 + @@: + mov [es:0x9008],bx + mov [es:0x900A],cx + mov [es:0x900C],dx + test bh, bh + jz nov + +; USE DEFAULTS OR PROBE + +; bx - mode : cx - x size : dx - y size + cmp [preboot_gprobe-0x10000], 1 + jz noprobe + + mov bx,0x100 + newprobe: + inc bx + cmp bx,0x17f + mov si,prnotfnd-0x10000 + jz sayerr + + probemore: + push cx + mov ax,0x4f01 + mov cx,bx + and cx,0xfff + mov di,0xa000 + int 0x10 + pop cx + + test byte [es:di], 80h ; lfb? + jz newprobe + cmp [es:di+0x12], cx ; x size? + jnz newprobe + cmp [es:di+0x14], dx ; y size? + jnz newprobe + cmp byte [es:di+0x19], 32 ;24 + jb newprobe + +; add bx,0100000000000000b + or bh, 40h + mov [es:0x9008],bx + + noprobe: + + +; FIND VESA 2.0 LFB & BPP + + mov ax,0x4f01 + mov cx,bx + and cx,0xfff + mov di,0xa000 + int 0x10 + ; LFB + mov eax,[es:di+0x28] + mov [es:0x9018],eax + ; ---- vbe voodoo + BytesPerLine equ 0x10 + mov ax, [es:di+BytesPerLine] + mov [es:0x9001],ax + ; BPP + mov al,byte [es:di+0x19] + mov [es:0x9000],al + nov: + cmp al,24 + mov si,bt24-0x10000 + jz bppl + cmp al,32 + mov si,bt32-0x10000 + jz bppl + mov si,btns-0x10000 + jmp sayerr + bppl: + call print + + +; FIND VESA 1.2 PM BANK SWITCH ADDRESS + + push es + mov ax,0x4f0A + xor bx, bx + int 0x10 + xor eax,eax + mov ax,es + shl eax,4 + movzx ebx,di + add eax,ebx + mov bx,[es:di] + add eax,ebx + pop es + mov [es:0x9014],eax + + +; GRAPHICS ACCELERATION +; force yes + mov [es:0x901C], byte 1 + +; DMA WRITE + + mov al, [preboot_dma_write-0x10000] + mov [es:0x901F],al + +; VRR_M USE + + mov al,[preboot_vrrm-0x10000] + mov [es:0x9030],al + mov [es:0x901E],byte 1 + +; BOOT DEVICE + + mov al, [preboot_device-0x10000] + dec al + mov [boot_dev-0x10000],al + +; READ DISKETTE TO MEMORY + +; cmp [boot_dev-0x10000],0 + jne no_sys_on_floppy + mov si,diskload-0x10000 + call print + xor ax, ax ; reset drive + xor dx, dx + int 0x13 +; now load floppy image to memory +; at first load boot sector and first FAT table + mov cx, 0x0001 ; startcyl,startsector + xor dx, dx ; starthead,drive + mov al, 1+9 ; no of sectors to read + mov bx, 0xB000 ; es:bx -> data area + call boot_read_floppy +; and copy them to extended memory + mov si, movedesc-0x10000 + mov [si+8*2+3], bh + push es + push ds + pop es + mov cx, 256*10 + mov ah, 0x87 + int 0x15 + test ah, ah + jz @f +sayerr_floppy: + mov dx, 0x3f2 + mov al, 0 + out dx, al + mov si, memmovefailed-0x10000 + jmp sayerr_plain +@@: + add dword [si+8*3+2], 512*10 +; copy FAT to second copy + mov byte [si+8*2+3], 0xB2 + mov cx, 256*9 + mov ah, 0x87 + int 0x15 + pop es + test ah, ah + jnz sayerr_floppy + add dword [si+8*3+2], 512*9 +; calculate total number of sectors to read + mov ax, 1+9+14 ; boot+FAT+root + mov di, 0xB203 +.calc_loop: + test word [es:di], 0xFFF + jz @f + inc ax +@@: + test word [es:di+1], 0xFFF0 + jz @f + inc ax +@@: + add di, 3 + cmp di, 0xB200+1440*3 + jb .calc_loop + push ax + mov bp, 1+9 ; already read sectors +; now read rest + mov byte [si+8*2+3], 0xA0 + mov di, 2-14 ; absolute sector-31 + mov cx, 0x0002 ; cylinder=0, sector=2 + mov dx, 0x0100 ; head=1, disk=0 +.read_loop: +; determine whether sector must be read + cmp di, 2 + jl .read + mov bx, di + shr bx, 1 + jnc .even + test word [es:bx+di+0xB200], 0xFFF0 + jmp @f +.even: + test word [es:bx+di+0xB200], 0xFFF +@@: + jz .skip +.read: + mov bx, 0xA000 + mov al, 1 ; 1 sector + call boot_read_floppy + inc bp + push es + push ds + pop es + pusha + mov cx, 256 + mov ah, 0x87 + int 0x15 + test ah, ah + popa + pop es + jnz sayerr_floppy +.skip: + add dword [si+8*3+2], 512 + inc cx + cmp cl, 19 + jnz @f + mov cl, 1 + inc dh + cmp dh, 2 + jnz @f + mov dh, 0 + inc ch +@@: + pop ax + push ax + pusha +; draw percentage +; total sectors: ax +; read sectors: bp + xchg ax, bp + mov cx, 100 + mul cx + div bp + aam + xchg al, ah + add ax, '00' + mov si, pros-0x10000 + cmp [si], ax + jz @f + mov [si], ax + call printplain +@@: + popa + inc di + cmp di, 2880-31 + jnz .read_loop + +; mov cx, 0x0001 ; startcyl,startsector +; xor dx, dx ; starthead,drive +; push word 80*2 ; read no of sect +; reads: +; pusha +; xor si,si +; newread: +; mov bx,0xa000 ; es:bx -> data area +; mov ax,0x0200+18 ; read, no of sectors to read +; int 0x13 +; test ah, ah +; jz goodread +; inc si +; cmp si,10 +; jnz newread +; mov si,badsect-0x10000 +;sayerr_plain: +; call printplain +; jmp $ +; goodread: +; ; move -> 1mb +; mov si,movedesc-0x10000 +; push es +; push ds +; pop es +; mov cx,256*18 +; mov ah,0x87 +; int 0x15 +; pop es +; +; test ah,ah ; was the move successfull ? +; je goodmove +; mov dx,0x3f2 ; floppy motor off +; mov al,0 +; out dx,al +; mov si,memmovefailed-0x10000 +; jmp sayerr_plain +; goodmove: +; +; add dword [movedesc-0x10000+0x18+2], 512*18 +; popa +; inc dh +; cmp dh,2 +; jnz bb2 +; mov dh,0 +; inc ch +; pusha ; print prosentage +; mov si,pros-0x10000 +; shr ch, 2 +; mov al, '5' +; test ch, 1 +; jnz @f +; mov al, '0' +;@@: +; mov [si+1], al +; shr ch, 1 +; add ch, '0' +; mov [si], ch +; call printplain +; popa +; bb2: +; pop ax +; dec ax +; push ax +; jnz reads +; readdone: +; pop ax + mov si,backspace2-0x10000 + call printplain + mov si,okt-0x10000 + call printplain + no_sys_on_floppy: + xor ax, ax ; reset drive + xor dx, dx + int 0x13 + mov dx,0x3f2 ; floppy motor off + mov al,0 + out dx,al + + +; SET GRAPHICS + + xor ax, ax + mov es, ax + + mov ax,[es:0x9008] ; vga & 320x200 + mov bx, ax + cmp ax,0x13 + je setgr + cmp ax,0x12 + je setgr + mov ax,0x4f02 ; Vesa +setgr: + int 0x10 + test ah,ah + mov si, fatalsel-0x10000 + jnz sayerr +; 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/hd_kolibri/kernel/boot/booteng.inc b/kernel/branches/hd_kolibri/kernel/boot/booteng.inc new file mode 100644 index 0000000000..b9fe6d6965 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/booteng.inc @@ -0,0 +1,94 @@ +$Revision: 437 $ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +d80x25_bottom: + db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Display: EGA/CGA",13,10,0 +vervesa db "Version of Vesa: Vesa x.x",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 Colors: [9] 320x200, " + db "VGA 16 Colors: [0] 640x480",13,10 + db 186," Select mode: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",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 +;askmouse db " Mouse at:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Select 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 writing? [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 "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-use preloaded ram-image from kernel restart]: ",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 +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 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +modevesa20 db " with 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 mode)",0 +probeok_msg db " (check nonstandard modes)",0 +dma_msg db " [b] Use DMA for HDD writing:",0 +on_msg db " on",13,10,0 +off_msg db " off",13,10,0 +vrrm_msg db " [c] Use VRR:",0 +preboot_device_msg db " [d] Floppy image: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +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 +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 diff --git a/kernel/branches/hd_kolibri/kernel/boot/bootet.inc b/kernel/branches/hd_kolibri/kernel/boot/bootet.inc new file mode 100644 index 0000000000..956004fdc9 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/bootet.inc @@ -0,0 +1,94 @@ +$Revision: 437 $ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +d80x25_bottom: + db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Ekraan: EGA/CGA",13,10,0 +vervesa db "Vesa versioon: Vesa x.x",13,10,0 +vervesa_off=20 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 värvi: [9] 320x200, " + db "VGA 16 värvi: [0] 640x480",13,10 + db 186," Vali reziim: ",0 +bt24 db "Bitti pikseli kohta: 24",13,10,0 +bt32 db "Bitti pikseli kohta: 32",13,10,0 +vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" + db " ainult:",13,10 + db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 +;askmouse db " Hiir:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Vali port [1-3]: ",0 +;no_com1 db 13,10,186, " No COM1 mouse",0 +;no_com2 db 13,10,186, " No COM2 mouse",0 +ask_dma db "Use DMA for HDD writing? [1-jah/2-ei]: ",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]: ",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-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +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] Use DMA for HDD writing:",0 +on_msg db " sees",13,10,0 +off_msg db " väljas",13,10,0 +vrrm_msg db " [c] Kasuta VRR:",0 +preboot_device_msg db " [d] Disketi kujutis: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +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 +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 diff --git a/kernel/branches/hd_kolibri/kernel/boot/bootge.inc b/kernel/branches/hd_kolibri/kernel/boot/bootge.inc new file mode 100644 index 0000000000..2e97749f04 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/bootge.inc @@ -0,0 +1,99 @@ +$Revision: 437 $ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +d80x25_bottom: +; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' +; db 'NO WARRANTY ',186 +; db 186,' See file COPYING for details ' +; db ' ',186 + + db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' + db ' Garantie vertrieben ',186 + db 186,' Details stehen in der Datei COPYING ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Anzeige: EGA/CGA ",13,10,0 +vervesa db "Vesa-Version: Vesa ",13,10,0 +vervesa_off=22 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 Farben: [9] 320x200, " + db "VGA 16 Farben: [0] 640x480",13,10 + db 186," Waehle Modus: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",13,10,0 +vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 +;askmouse db " Maus angeschlossen an:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Waehle Port [1-3]: ",0 +;no_com1 db 13,10,186, " Keine COM1 Maus",0 +;no_com2 db 13,10,186, " Keine COM2 Maus",0 +ask_dma db "Nutze DMA zum HDD Aufschreiben? [1-ja/2-nein]: ",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]: ",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-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +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 +on_msg db " an",13,10,0 +off_msg db " aus",13,10,0 +vrrm_msg db " [c] Nutze VRR:",0 +preboot_device_msg db " [d] Diskettenimage: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +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 +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 diff --git a/kernel/branches/hd_kolibri/kernel/boot/bootru.inc b/kernel/branches/hd_kolibri/kernel/boot/bootru.inc new file mode 100644 index 0000000000..414ebd8781 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/bootru.inc @@ -0,0 +1,95 @@ +$Revision: 437 $ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +d80x25_bottom: + db 186,' Kolibri OS ®į­®¢ ­  ­  Menuet OS Ø ­„ Æą„¤®įā ¢«ļ„ā ' + db '­ØŖ ŖØå £ ąa­āØ©. ',186 + db 186,' ®¤ą®”­„„ į¬®āąØā„ ä ©« GNU.TXT ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "‚ؤ„®Ŗ ąā : EGA/CGA",13,10,0 +vervesa db "‚„ąįØļ VESA: Vesa x.x",13,10,0 +vervesa_off=19 +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 –¢„ā®¢: [9] 320x200, " + db "VGA 16 –¢„ā®¢: [0] 640x480",13,10 + db 186," ‚ė”„ąØā„ ¢Ø¤„®ą„¦Ø¬: ",0 +bt24 db "ƒ«ć”Ø­  ę¢„ā : 24",13,10,0 +bt32 db "ƒ«ć”Ø­  ę¢„ā : 32",13,10,0 +vrrmprint db "ˆįÆ®«ģ§®¢ āģ VRR? (ē įā®ā  Ŗ ¤ą®¢ ¢ėč„ 60 ƒę" + db " ā®«ģŖ® ¤«ļ Æ„ą„室®¢:",13,10 + db 186," 1024*768>800*600 Ø 800*600>640*480) [1-¤ , 2-­„ā]: ",0 +;askmouse db "Œėčģ:" ; 186, " " +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " ‚ė”„ąØā„ Æ®ąā [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 "ˆįÆ®«ģ§®¢ āģ DMA ¤«ļ § ÆØįØ ­  HDD? [1-¤ /2-­„ā]: ",0 +;gr_direct db 186," ˆįÆ®«ģ§®¢ āģ «Ø­„©­ė© ¢Ø¤„®”ćä„ą? " +; db "[1-¤ /2-­„ā]: ",0 +;mem_model db 13,10,186," Ž”ź+¬ Æ ¬ļāØ [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0 +;bootlog db 13,10,186," ą®į¬®āą„āģ ¦ćą­ « § £ąć§ŖØ? [1-­„ā/2-¤ ]: ",0 +bdev db "‡ £ąć§Øāģ ®”ą § ا [1-¤ØįŖ„ā ; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-ØįÆ®«ģ§®¢ āģ 榄 § £ąć¦„­­ė© ®”ą §]: ",0 +probetext db 13,10,13,10,186," ‘ā ­¤ ąā­ė© ¢Ø¤„®ą„¦Ø¬? [1-¤ , " + db "2-Æą®¢„ąØāģ ¤ąć£Ø„ (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 "ŽčØ”Ŗ  - ‚ؤ„®ą„¦Ø¬ ­„ ­ ©¤„­.",0 +;modena db "ŽčØ”Ŗ  - ’ą„”ć„āįļ Æ®¤¤„ą¦Ŗ  VBE 0x112+.",0 +not386 db "ŽčØ”Ŗ  - ’ą„”ć„āįļ Æą®ę„įį®ą 386+.",0 +btns db "ŽčØ”Ŗ  - „ ¬®£ć ®Æą„¤„«Øāģ £«ć”Ø­ć ę¢„ā .",0 +fatalsel 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 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +modevesa20 db " į LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 ę¢„ā®¢",0 +mode10 db "640x480, VGA 16 ę¢„ā®¢",0 +probeno_msg db " (įā ­¤ ąā­ė© ¢Ø¤„®ą„¦Ø¬)",0 +probeok_msg db " (Æą®¢„ąØāģ ­„įā ­¤ ąā­ė„ ą„¦Ø¬ė)",0 +dma_msg db " [b] ˆįÆ®«ģ§®¢ ­Ø„ DMA ¤«ļ § ÆØįØ ­  HDD:",0 +on_msg db " ¢Ŗ«",13,10,0 +off_msg db " ¢ėŖ«",13,10,0 +vrrm_msg db " [c] ˆįÆ®«ģ§®¢ ­Ø„ VRR:",0 +preboot_device_msg db " [d] Ž”ą § ¤ØįŖ„āė: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +pdm1 db "­ įā®ļé ļ ¤ØįŖ„ā ",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "ØįÆ®«ģ§®¢ āģ 榄 § £ąć¦„­­ė© ®”ą §",13,10,0 +loading_msg db "ˆ¤ńā § £ąć§Ŗ  KolibriOS...",0 +save_quest db "‡ Æ®¬­Øāģ ā„ŖćéØ„ ­ įāą®©ŖØ? [y/n]: ",0 +loader_block_error db "ŽčØ”Ŗ  ¢ ¤ ­­ėå ­ ē «ģ­®£® § £ąć§ēØŖ , Æą®¤®«¦„­Ø„ ­„¢®§¬®¦­®.",0 diff --git a/kernel/branches/hd_kolibri/kernel/boot/bootstr.inc b/kernel/branches/hd_kolibri/kernel/boot/bootstr.inc new file mode 100644 index 0000000000..e82fb85f0e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/bootstr.inc @@ -0,0 +1,52 @@ +; 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/hd_kolibri/kernel/boot/et.inc b/kernel/branches/hd_kolibri/kernel/boot/et.inc new file mode 100644 index 0000000000..c4cf3afbc5 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/et.inc @@ -0,0 +1,7 @@ +$Revision: 425 $ +; Full ASCII code font +; only õ and ä added +; Kaitz +ET_FNT: + fontfile file "ETFONT.FNT" + diff --git a/kernel/branches/hd_kolibri/kernel/boot/preboot.inc b/kernel/branches/hd_kolibri/kernel/boot/preboot.inc new file mode 100644 index 0000000000..7bf23ca5c5 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/preboot.inc @@ -0,0 +1,34 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +display_modechg db 0 ; display mode change for text, yes/no (0 or 2) + ; + ; !! Important note !! + ; + ; Must be set to 2, to avoid two screenmode + ; changes within a very short period of time. + +display_atboot db 0 ; show boot screen messages ( 2-no ) + +preboot_graph db 3 ; graph mode +preboot_gprobe db 1 ; probe vesa3 videomodes (1-no, 2-yes) +preboot_vrrm db 1 ; use VRR_M (1-yes, 2- no) +preboot_dma_write db 2 ; use DMA for writing to HDD (1-yes, 2-no) +preboot_device db 2 ; boot device + ; (1-floppy 2-harddisk 3-kernel restart) + ;!!!! 0 - autodetect !!!! +preboot_blogesc db 1 ; start immediately after bootlog + + if $>10200h +ERROR: prebooting parameters must fit in first sector!!! + end if +hdsysimage db 'KOLIBRI IMG' ; load from +image_save db 'KOLIBRI IMG' ; save to +preboot_lfb db 0 +preboot_bootlog db 0 + diff --git a/kernel/branches/hd_kolibri/kernel/boot/ru.inc b/kernel/branches/hd_kolibri/kernel/boot/ru.inc new file mode 100644 index 0000000000..5122818435 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/ru.inc @@ -0,0 +1,93 @@ +$Revision: 425 $ +; 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 \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/boot/shutdown.inc b/kernel/branches/hd_kolibri/kernel/boot/shutdown.inc new file mode 100644 index 0000000000..410972bcd3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/boot/shutdown.inc @@ -0,0 +1,545 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +system_shutdown: ; shut down the system + call stop_all_services + + push 3 ; stop playing cd + pop eax + call sys_cd_audio + cld + + mov al,[0x2f0000+0x9030] + cmp al,1 + jl no_shutdown_parameter + cmp al,4 + jle yes_shutdown_param + no_shutdown_parameter: + +; movzx ecx,word [0x2f0000+0x900A] +; movzx esi,word [0x2f0000+0x900C] +; imul ecx,esi ;[0xfe04] +;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen +; push ecx +; mov esi,[0xfe80] +; cmp esi,32*0x100000 +; jbe no_darken_screen +; mov edi,16*0x100000 +; push esi edi +; sdnewpix: +; lodsd +; shr eax,1 +; and eax,0x7f7f7f7f +; stosd +; loop sdnewpix +; pop ecx +; pop esi edi +; rep movsd +; no_darken_screen: + +; read shutdown code: +; 1) display shutdown "window" + + mov eax,[0xfe00] + shr eax,1 + lea esi,[eax+220] ; x end + sub eax,220 ; x start + + mov ebx,[ScreenHeight] + shr ebx,1 + mov [shutdownpos],ebx + lea ebp,[ebx+105] ; y end + sub ebx,120 ; y start + + xor edi,edi + inc edi ; force putpixel & dtext + mov ecx,0x0000ff + +; vertical loop begin + sdnewpix1: + push eax ; save x start + +; horizontal loop begin + sdnewpix2: + + call [putpixel] + + inc eax + cmp eax,esi + jnz sdnewpix2 +; horizontal loop end + + dec ecx ; color + pop eax ; restore x start + + inc ebx ; advance y pos + cmp ebx,ebp + jnz sdnewpix1 +; vertical loop end + +; 2) display text strings +; a) version + mov eax,[0xfe00] + shr eax,1 + shl eax,16 + mov ax,word [shutdownpos] + push eax + sub eax,(220-27)*10000h + 105 + mov ebx,0xffff00 + mov ecx,version + push 34 + pop edx + call dtext + +; b) variants + add eax,105+33 + push 6 + pop esi +; mov ebx,0xffffff + mov bl,0xFF + mov ecx,shutdowntext + mov dl,40 + newsdt: + call dtext + add eax,10 + add ecx,edx + dec esi + jnz newsdt + +; 3) load & display rose.txt + mov eax,rosef-std_application_base_address ; load rose.txt + xor ebx,ebx + push 2 + pop ecx + mov edx,0x90000 + push edx + push 12 + pop esi + push edi ; may be destroyed + + pushad + push eax + call file_system_lfn ; by SPraid fileread + pop eax + popad + pop edi + + pop ecx + inc ecx ; do not display stars from rose.txt + pop eax + add eax,20*10000h - 110 + + mov ebx,0x00ff00 + push 27 + pop edx + + nrl: + call dtext +; sub ebx,0x050000 + ror ebx, 16 + sub bl, 0x05 + ror ebx, 16 + add eax,8 + add ecx,31 + cmp cx,word 0x0001+25*31 + jnz nrl + + call checkVga_N13 + + yes_shutdown_param: + cli + + mov eax,kernel ; load kernel.mnt to 0x8000:0 + push 12 + pop esi + xor ebx,ebx + or ecx,-1 + mov edx,0x80000 + call fileread + + mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0 + mov edi,0x40000 + mov ecx,1000 + rep movsb + + mov eax,0x2F0000 ; restore 0x0 - 0xffff + xor ebx,ebx + mov ecx,0x10000 + call memmove + + call restorefatchain + + mov al, 0xFF + out 0x21, al + out 0xA1, al + + mov word [0x467+0],pr_mode_exit-0x10000 + mov word [0x467+2],0x1000 + + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al + + mov al,0xFE + out 0x64,al + hlt + +use16 + +pr_mode_exit: +org $-0x10000 + +; setup stack + mov ax, 3000h + mov ss, ax + mov esp, 0EC00h +; setup ds + push cs + pop ds + + lidt [old_ints_h-0x10000] +;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 + call pause_key + cmp al,6 + jae nbw + mov bl,al + nbw2: + in al,0x60 + call pause_key + 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 ; 1 = write floppy + js nbw + jnz no_floppy_write + call floppy_write + jmp temp_3456 ;nbw + no_floppy_write: + + 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 + + pause_key: + mov cx,100 + pause_key_1: + loop pause_key_1 + ret + +rdelay: + ret + +iglobal + kernel db 'KERNEL MNT' +; shutdown_parameter db 0 +endg + +restart_kernel: + + mov ax,0x0003 ; set text mode for screen + int 0x10 + + jmp 0x4000:0000 + + +restart_kernel_4000: + cli + +; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0 +; +; new_kernel_block_move: +; +; mov ebx,0 +; +; new_kernel_byte_move: +; +; mov ax,di +; add ax,0x7000 +; mov es,ax +; mov dl,[es:bx] +; mov es,di +; mov [es:bx],dl +; +; inc ebx +; cmp ebx,65536 +; jbe new_kernel_byte_move +; +; add di,0x1000 +; cmp di,0x2000 +; jbe new_kernel_block_move + push ds + pop es + mov cx, 0x8000 + push cx + mov ds, cx + xor si, si + xor di, di + rep movsw + push 0x9000 + pop ds + push 0x2000 + pop es + pop cx + rep movsw + + wbinvd ; write and invalidate cache + +; mov ax,0x1000 +; mov es,ax +; mov ax,0x3000 +; mov ss,ax +; mov sp,0xec00 +; restore timer + 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-0x10000 + mov ax, 'KL' + jmp 0x1000:0000 + +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 +;!!!!!!!!!!!!!!!!!!!!!!!! +fwwritedone: + ret +org $+0x10000 +flm db 0 +org $-0x10000 + +floppy_write: ; write diskette image to physical floppy + + cmp [flm-0x10000],byte 1 + je fwwritedone + mov [flm-0x10000],byte 1 + + xor ax, ax ; reset drive + xor dx, dx + int 0x13 + + mov cx,0x0001 ; startcyl,startsector +; mov dx,0x0000 ; starthead,drive + xor dx, dx + mov ax, 80*2 ; read no of sect + + fwwrites: + push ax + + ; move 1mb+ -> 0:a000 + + pusha + mov si,fwmovedesc -0x10000 + mov cx,256*18 + mov ah,0x87 + push ds + pop es + int 0x15 + add dword [fwmovedesc-0x10000+0x12], 512*18 + popa + + xor si,si + mov es,si + fwnewwrite: + mov bx,0xa000 ; es:bx -> data area + mov ax,0x0300+18 ; read, no of sectors to read + int 0x13 + + test ah, ah + jz fwgoodwrite + + inc si + cmp si,10 + jnz fwnewwrite + +; can't access diskette - return + pop ax + ret + + fwgoodwrite: + inc dh + cmp dh,2 + jnz fwbb2 + mov dh,0 + inc ch + fwbb2: + pop ax + dec ax + jnz fwwrites + ret +org $+0x10000 + 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 +org $-0x10000 +use32 +org $+0x10000 +uglobal + shutdownpos dd 0x0 +endg + +iglobal +if lang eq en +shutdowntext: + db "IT'S SAFE TO POWER OFF COMPUTER OR " + db ' ' + db '1) SAVE RAMDISK TO FLOPPY ' + db '2) APM - POWEROFF ' + db '3) REBOOT ' + db '4) RESTART KERNEL ' +else if lang eq ru +shutdowntext: + db "„§®Æ į­®„ ¢ėŖ«īē„­Ø„ Ŗ®¬Æģīā„ą  Ø«Ø " + db ' ' + db '1) ‘®åą ­Øāģ ą ¬¤ØįŖ ­  ¤ØįŖ„āć ' + db '2) APM - ¢ėŖ«īē„­Ø„ ÆØā ­Øļ ' + db '3) „ą„§ £ąć§Ŗ  įØįā„¬ė ' + db '4) „įā ąā ļ¤ą  ا Ž‡“ ' +else +shutdowntext: + db "SIE KOENNEN DEN COMPUTER NUN AUSSCHALTEN" + db ' ' + db '1) RAMDISK AUF DISK SPEICHERN ' + db '2) APM - AUSSCHALTEN ' + db '3) NEUSTARTEN ' + db '4) KERNEL NEU STARTEN ' +end if +rosef: + dd 0,0,0,1024,0x90000-std_application_base_address + db '/rd/1/ROSE.TXT',0 +endg diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/allirqs.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/allirqs.inc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/bootlog.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/bootlog.inc new file mode 100644 index 0000000000..e6a80178b3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/bootlog.inc @@ -0,0 +1,31 @@ +boot_log: + pushad + + mov eax,10*65536 + mov ax,word [boot_y] + add [boot_y],dword 10 + mov ebx,0x80ffffff ; ASCIIZ string with white color + mov ecx,esi + mov edi,1 + call dtext + + mov [novesachecksum],1000 + call checkVga_N13 + + cmp [preboot_blogesc],byte 1 + je .bll2 + + cmp esi,boot_tasking + jne .bll2 + ; begin ealex 04.08.05 +; in al,0x61 +; and al,01111111b +; out 0x61,al + ; end ealex 04.08.05 +.bll1: in al,0x60 ; wait for ESC key press + cmp al,129 + jne .bll1 + +.bll2: popad + + ret diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/bootmsg.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/bootmsg.inc new file mode 100644 index 0000000000..83cf435e6e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/bootmsg.inc @@ -0,0 +1,25 @@ +iglobal + 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_mtrr db 'Setting MTRR',0 + boot_tasking db 'All set - press ESC to start',0 +endg + +iglobal + boot_y dd 10 +endg diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/bootstrap.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/bootstrap.inc new file mode 100644 index 0000000000..9d7c97f09a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/bootstrap.inc @@ -0,0 +1,49 @@ +align 4 +B32: +include "clear.inc" +include "rmode.inc" +include "graphaddr.inc" +include "sysenter.inc" + call mem_test + call init_mtrr + call init_mem + call init_page_map +include "paging.inc" +include "graphbase.inc" + + call build_scheduler ; sys32.inc +; LOAD IDT + lidt [cs:idtreg] + cli + +include 'detect/disks.inc' +;include 'rdload.inc' + call calculatefatchain +include 'vmodeld.inc' +include "loadfont.inc" +include "printmem.inc" +include "redirirq.inc" +include "timer.inc" +include "setmouse.inc" +include "windef.inc" +include "setbgr.inc" +include "resirq.inc" +include "setports.inc" +include "ostask.inc" + call init_cursors +include "tsc.inc" + call set_variables + call stack_init + call fdc_init +include "palette.Inc" +include "loadskn.inc" +include "firstapp.inc" +include "kbset.inc" +include "tasking.Inc" +include "allirqs.inc" +sti +jmp $ ; wait here for timer to take control + + + + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/clear.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/clear.inc new file mode 100644 index 0000000000..913e308196 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/clear.inc @@ -0,0 +1,32 @@ +; CLEAR 0x280000-0xF00000 + + xor eax,eax + mov edi,0x280000 + mov ecx,(0x100000*0xF-0x280000) / 4 + cld + rep stosd +; CLEAR 0x80000-0x90000 +; xor eax,eax + + mov edi,0x80000 + mov ecx,(0x90000-0x80000)/4 +; cld + rep stosd + +; CLEAR KERNEL UNDEFINED GLOBALS + mov edi, endofcode + mov ecx, (uglobals_size/4)+4 + rep stosd + +; SAVE & CLEAR 0-0xffff + + mov esi,0x0000 + mov edi,0x2F0000 + mov ecx,0x10000 / 4 + cld + rep movsd + xor eax,eax + mov edi,0 + mov ecx,0x10000 / 4 + cld + rep stosd \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_fd.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_fd.inc new file mode 100644 index 0000000000..e8e590c66a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_fd.inc @@ -0,0 +1,28 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;*************************************************** +; ļšåäāąščņåėüķą’ ī÷čńņźą īįėąńņč ņąįėčöū +; ļīčńź č ēąķåńåķčå ā ņąįėčöó ļščāīäīā 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/hd_kolibri/kernel/bootstrap/detect/dev_hdcd.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_hdcd.inc new file mode 100644 index 0000000000..38aba3d979 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_hdcd.inc @@ -0,0 +1,382 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;****************************************************** +; ļīčńź ļščāīäīā 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/hd_kolibri/kernel/bootstrap/detect/disks.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/disks.inc new file mode 100644 index 0000000000..9c8d4b0981 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/disks.inc @@ -0,0 +1,5 @@ +$Revision: 425 $ +include 'dev_fd.inc' +include 'dev_hdcd.inc' +include 'sear_par.inc' + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/detect/sear_par.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/sear_par.inc new file mode 100644 index 0000000000..cc76d0dc97 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/detect/sear_par.inc @@ -0,0 +1,125 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;**************************************************** +; ļīčńź ėīćč÷åńźčõ äčńźīā ķą īįķąšóęåķķūõ 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 + + +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_ide: + +;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/hd_kolibri/kernel/bootstrap/firstapp.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/firstapp.inc new file mode 100644 index 0000000000..05f7134107 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/firstapp.inc @@ -0,0 +1,28 @@ +; LOAD FIRST APPLICATION + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],dword 1 + cli + cmp byte [0x2f0000+0x9030],1 + jne no_load_vrr_m + + mov ebp, vrr_m + xor ebx, ebx + xor edx, edx + call fs_execute + cmp eax,2 ; if vrr_m app found (PID=2) + je first_app_found + +no_load_vrr_m: + mov ebp, firstapp + xor ebx, ebx + xor edx, edx + call fs_execute + cmp eax,2 ; continue if a process has been loaded + je first_app_found + mov eax, 0xDEADBEEF ; otherwise halt + hlt +first_app_found: + cli + + ;mov [TASK_COUNT],dword 2 + mov [CURRENT_TASK],dword 1 ; set OS task fisrt diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/graphaddr.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/graphaddr.inc new file mode 100644 index 0000000000..9338e09226 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/graphaddr.inc @@ -0,0 +1,51 @@ +; GRAPHICS ADDRESSES + + ;mov eax,0x100000*8 ; LFB address + ;cmp [0xfe0c],word 0x13 + ;je no_d_lfb + ;cmp [0xfe0c],word 0x12 + ;je no_d_lfb + ;cmp [0x2f0000+0x901e],byte 1 + ;jne no_d_lfb + mov byte [0x2f0000+0x901e],0x0 + mov eax,[0x2f0000+0x9018] + ;no_d_lfb: + 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 [0xe024],dword Vesa12_getpixel24 + cmp [ScreenBPP],byte 24 + jz ga24 + mov [PUTPIXEL],dword Vesa12_putpixel32 + mov [0xe024],dword Vesa12_getpixel32 + ga24: + jmp v20ga24 + setvesa20: + mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 + mov [0xe024],dword Vesa20_getpixel24 + cmp [ScreenBPP],byte 24 + jz v20ga24 + v20ga32: + mov [PUTPIXEL],dword Vesa20_putpixel32 + mov [0xe024],dword Vesa20_getpixel32 + v20ga24: + cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 + jne no_mode_0x12 + mov [PUTPIXEL],dword VGA_putpixel + mov [0xe024],dword Vesa20_getpixel32 + no_mode_0x12: + + call test_cpu +; btr [cpu_caps], CAPS_SSE ;test: dont't use sse code +; btr [cpu_caps], CAPS_SSE2 ;test: don't use sse2 + +; btr [cpu_caps], CAPS_FXSR ;test: disable sse support + ;all sse commands rise #UD exption +; btr [cpu_caps], CAPS_PSE ;test: don't use large pages +; btr [cpu_caps], CAPS_PGE ;test: don't use global pages +; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR + bts [cpu_caps], CAPS_TSC ;force use rdtsc diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/graphbase.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/graphbase.inc new file mode 100644 index 0000000000..f09e0683be --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/graphbase.inc @@ -0,0 +1,7 @@ +;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 + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/kbset.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/kbset.inc new file mode 100644 index 0000000000..de7a3e7a81 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/kbset.inc @@ -0,0 +1,28 @@ +; 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 ] + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/loadfont.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/loadfont.inc new file mode 100644 index 0000000000..34f7ae4a76 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/loadfont.inc @@ -0,0 +1,30 @@ +; LOAD FONTS I and II + + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],dword 1 + mov [TASK_BASE],dword TASK_DATA + + pushad + push eax + mov eax,char - std_application_base_address + call file_system_lfn + mov eax,char2 - std_application_base_address + call file_system_lfn + pop eax + popad + + +; mov esi,char +; xor ebx,ebx +; mov ecx,2560;26000 +; mov edx,FONT_I +; call fs_RamdiskRead + +; mov esi,char2 +; xor ebx,ebx +; mov ecx,2560;26000 +; mov edx,FONT_II +; call fs_RamdiskRead + + mov esi,boot_fonts + call boot_log diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/loadskn.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/loadskn.inc new file mode 100644 index 0000000000..655683b8ca --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/loadskn.inc @@ -0,0 +1,8 @@ +; LOAD DEFAULT SKIN + + mov esi,_skin_file_default + mov edi,_skin_file + movsd + movsd + movsd + call load_skin \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/ostask.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/ostask.inc new file mode 100644 index 0000000000..6ba5c7a789 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/ostask.inc @@ -0,0 +1,63 @@ +; SET UP OS TASK + + mov esi,boot_setostask + call boot_log + +; mov eax, fpu_data +; mov dword [SLOT_BASE+APPDATA.fpu_state], eax +; mov dword [SLOT_BASE+APPDATA.fpu_handler], 0 +; mov dword [SLOT_BASE+APPDATA.sse_handler], 0 + + ; 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] + mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi + add edi, RING0_STACK_SIZE + mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi + + mov esi, fpu_data + mov ecx, 512/4 + cld + rep movsd + + mov dword [SLOT_BASE+256+APPDATA.fpu_handler], 0 + mov dword [SLOT_BASE+256+APPDATA.sse_handler], 0 + + mov ebx, [def_cursor] + mov dword [SLOT_BASE+256+APPDATA.cursor], ebx + + 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 + + ; task list + 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 + + mov edi,tss_data+tss_step + mov ecx, (tss_step)/4 + xor eax, eax + cld + rep stosd + + mov edi,tss_data+tss_step + mov [edi+TSS._ss0], os_data + mov eax,cr3 + mov [edi+TSS._cr3],eax + mov [edi+TSS._eip],osloop + mov [edi+TSS._eflags],dword 0x11202 ; sti and resume + mov eax, [os_stack] + add eax, RING0_STACK_SIZE + mov [edi+TSS._esp], eax + mov [edi+TSS._cs],os_code + mov [edi+TSS._ss],os_data + mov [edi+TSS._ds],os_data + mov [edi+TSS._es],os_data + mov [edi+TSS._fs],os_data + mov [edi+TSS._gs],os_data + + mov ax,tss0 + ltr ax diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/paging.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/paging.inc new file mode 100644 index 0000000000..b937924ad0 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/paging.inc @@ -0,0 +1,53 @@ +; ENABLE PAGING + mov eax, sys_pgdir + mov cr3, eax + + mov eax,cr0 + or eax,CR0_PG + mov cr0,eax + + call init_kernel_heap + stdcall kernel_alloc, RING0_STACK_SIZE+512 + mov [os_stack], eax + + call init_LFB + call init_fpu + + call init_malloc + + stdcall alloc_kernel_space, 0x4F000 + 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 + + 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 + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/palette.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/palette.inc new file mode 100644 index 0000000000..ced0de6029 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/palette.inc @@ -0,0 +1,16 @@ + +; 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: diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/printmem.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/printmem.inc new file mode 100644 index 0000000000..875d151a10 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/printmem.inc @@ -0,0 +1,13 @@ +; 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 diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/rdload.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/rdload.inc new file mode 100644 index 0000000000..279cb66e92 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/rdload.inc @@ -0,0 +1,102 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; READ RAMDISK IMAGE FROM HD + + cmp [boot_dev],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 + 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: +yes_sys_on_hd: diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/redirirq.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/redirirq.inc new file mode 100644 index 0000000000..393dca76f3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/redirirq.inc @@ -0,0 +1,13 @@ +; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f + + mov esi,boot_irqs + call boot_log + call rerouteirqs + + mov esi,boot_tss + call boot_log + + mov esi,boot_devices + call boot_log + call detect_devices + diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/resirq.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/resirq.inc new file mode 100644 index 0000000000..4831f414f2 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/resirq.inc @@ -0,0 +1,5 @@ +; RESERVE SYSTEM IRQ'S JA PORT'S + + mov esi,boot_resirqports + call boot_log + call reserve_irqs_ports diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/rmode.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/rmode.inc new file mode 100644 index 0000000000..1289409e97 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/rmode.inc @@ -0,0 +1,37 @@ +; SAVE REAL MODE VARIABLES + mov ax, [0x2f0000 + 0x9031] + mov [IDEContrRegsBaseAddr], ax +; --------------- APM --------------------- + mov eax, [0x2f0000 + 0x9040] ; entry point + mov dword[apm_entry], eax + mov word [apm_entry + 4], apm_code_32 - gdts + + mov eax, [0x2f0000 + 0x9044] ; version & flags + mov [apm_vf], eax +; ----------------------------------------- +; movzx eax,byte [0x2f0000+0x9010] ; mouse port +; mov [0xF604],byte 1 ;al + mov al, [0x2F0000+0x901F] ; DMA writing + mov [allow_dma_write], al + mov al,[0x2f0000+0x9000] ; bpp + mov [ScreenBPP],al + movzx eax,word [0x2f0000+0x900A] ; X max + dec eax + mov [ScreenWidth],eax + mov [screen_workarea.right],eax + movzx eax,word [0x2f0000+0x900C] ; Y max + dec eax + mov [ScreenHeight],eax + mov [screen_workarea.bottom],eax + movzx eax,word [0x2f0000+0x9008] ; screen mode + mov [SCR_MODE],eax + mov eax,[0x2f0000+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,[0x2f0000+0x9001] ; for other modes + mov [BytesPerScanLine],ax + @@: diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/setbgr.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/setbgr.inc new file mode 100644 index 0000000000..6b06d6db78 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/setbgr.inc @@ -0,0 +1,5 @@ +; SET BACKGROUND DEFAULTS + + mov esi,boot_bgr + call boot_log + call calculatebackground \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/setmouse.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/setmouse.inc new file mode 100644 index 0000000000..dc8a46a999 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/setmouse.inc @@ -0,0 +1,7 @@ +; SET MOUSE + + mov esi,boot_setmouse + call boot_log + call setmouse + + mov [pci_access_enabled],1 diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/setports.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/setports.inc new file mode 100644 index 0000000000..d8fa4727a3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/setports.inc @@ -0,0 +1,5 @@ +; SET PORTS FOR IRQ HANDLERS + + mov esi,boot_setrports + call boot_log + call setirqreadports \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/switch.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/switch.inc new file mode 100644 index 0000000000..0a1c18c46d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/switch.inc @@ -0,0 +1,65 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SWITCH TO 32 BIT PROTECTED MODE ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +os_data = os_data_l-gdts ; GDTs +os_code = os_code_l-gdts +int_code equ int_code_l-gdts +int_data equ int_data_l-gdts +tss0sys equ tss0sys_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 + + + +; CR0 Flags - Protected mode and Paging + + mov ecx, CR0_PE + +; Enabling 32 bit protected mode + + sidt [cs:old_ints_h-0x10000] + + 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:gdts-0x10000] ; Load GDT + mov eax, cr0 ; Turn on paging // protected mode + or eax, ecx + and eax, 10011111b *65536*256 + 0xffffff ; caching enabled + mov cr0, eax + jmp $+2 +org $+0x10000 + mov ax,os_data ; Selector for os + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + mov esp,0x3ec00 ; Set stack + jmp pword os_code:B32 ; jmp to enable 32 bit mode + +if gdte >= $ +error 'GDT overlaps with used code!' +end if diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/sysenter.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/sysenter.inc new file mode 100644 index 0000000000..ba0494645d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/sysenter.inc @@ -0,0 +1,43 @@ +; -------- 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, 0x1B0013 + + mov eax, syscall_entry + mov ecx, MSR_AMD_STAR + wrmsr +.noSYSCALL: +; ----------------------------------------- \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/tasking.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/tasking.inc new file mode 100644 index 0000000000..26fac2438c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/tasking.inc @@ -0,0 +1,6 @@ +; START MULTITASKING + + mov esi,boot_tasking + call boot_log + + ; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/timer.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/timer.inc new file mode 100644 index 0000000000..12c372f1d3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/timer.inc @@ -0,0 +1,10 @@ + ; TIMER SET TO 1/100 S + + mov esi,boot_timer + call boot_log + 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 \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/tsc.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/tsc.inc new file mode 100644 index 0000000000..87f9f69260 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/tsc.inc @@ -0,0 +1,15 @@ +; READ TSC / SECOND + + mov esi,boot_tsc + call boot_log + call _rdtsc + mov ecx,eax + mov esi,250 ; wait 1/4 a second + call delay_ms + call _rdtsc + sub eax,ecx + shl eax,2 + mov [CPU_FREQ],eax ; save tsc / sec + mov ebx, 1000000 + div ebx + mov [stall_mcs], eax diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/vmodeld.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/vmodeld.inc new file mode 100644 index 0000000000..cc82337b88 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/vmodeld.inc @@ -0,0 +1,38 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; Load of videomode driver in memory +; +; (driver is located at 0x760000-0x768000 - 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 [OS_BASE+0x760000],eax ; + mov [OS_BASE+0x760100],byte 0xC3 ; Instruction RETN - driver loop + + pushad + push eax + mov eax, vmode - std_application_base_address + call file_system_lfn + pop eax + popad + +; mov esi, vmode +; xor ebx, ebx +; mov ecx, 0x8000 ; size of memory area for driver +; mov edx, OS_BASE+0x760000 ; Memory position of driver +; call fs_RamdiskRead diff --git a/kernel/branches/hd_kolibri/kernel/bootstrap/windef.inc b/kernel/branches/hd_kolibri/kernel/bootstrap/windef.inc new file mode 100644 index 0000000000..0a6ce82522 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bootstrap/windef.inc @@ -0,0 +1,5 @@ +; SET PRELIMINARY WINDOW STACK AND POSITIONS + + mov esi,boot_windefs + call boot_log + call setwindowdefaults diff --git a/kernel/branches/hd_kolibri/kernel/build.bat b/kernel/branches/hd_kolibri/kernel/build.bat new file mode 100644 index 0000000000..671f296168 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/build.bat @@ -0,0 +1,114 @@ +@echo off + +set languages=en ru ge et +set drivers=sound sis infinity ati2d +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 Probably at runing has been created error +echo For help 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 not founded + echo Enter valide languege + echo [%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 not valide + echo Enter valide target + echo [%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 + echo building 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 .. +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 ... + + del /Q bin\drivers\*.* + del /Q bin\skins\*.* + del /Q bin\*.* + rmdir bin\drivers + rmdir bin\skins + rmdir 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 \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/bus/pci/pci16.inc b/kernel/branches/hd_kolibri/kernel/bus/pci/pci16.inc new file mode 100644 index 0000000000..1884b9cd71 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bus/pci/pci16.inc @@ -0,0 +1,50 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +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/hd_kolibri/kernel/bus/pci/pci32.inc b/kernel/branches/hd_kolibri/kernel/bus/pci/pci32.inc new file mode 100644 index 0000000000..78429a426b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/bus/pci/pci32.inc @@ -0,0 +1,363 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; Credits: ;; +;; Ralf Brown ;; +;; Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;*************************************************************************** +; 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 [0x2F0000+0x9022] + ret + +pci_fn_1: + cmp al,1 + jnz pci_fn_2 + + ; PCI function 1: get last bus in AL + mov al,[0x2F0000+0x9021] + ret + +pci_fn_2: + cmp al,2 + jne pci_fn_3 + ; PCI function 2: get pci access mechanism + mov al,[0x2F0000+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 +;*************************************************************************** + +align 4 + +pci_read_reg: + cmp byte [0x2F0000+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 +;*************************************************************************** + +align 4 + +pci_write_reg: + cmp byte [0x2F0000+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 diff --git a/kernel/branches/hd_kolibri/kernel/const.inc b/kernel/branches/hd_kolibri/kernel/const.inc new file mode 100644 index 0000000000..d38fbad25b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/const.inc @@ -0,0 +1,576 @@ +$Revision: 434 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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) + +OS_BASE equ 0 + +window_data equ (OS_BASE+0x0000000) + +CURRENT_TASK equ (OS_BASE+0x0003000) +TASK_COUNT equ (OS_BASE+0x0003004) +CURRENT_RING0_ESP equ (OS_BASE+0x0003008) +TASK_BASE equ (OS_BASE+0x0003010) +TASK_DATA equ (OS_BASE+0x0003020) +TASK_EVENT equ (OS_BASE+0x0003020) + +mouseunder equ (OS_BASE+0x0006900) +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_X equ (OS_BASE+0x000FB0A) +MOUSE_Y equ (OS_BASE+0x000FB0C) + +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) +;LFBSize equ (OS_BASE+0x02f9050) + +ScreenWidth equ (OS_BASE+0x000FE00) +ScreenHeight 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 0x003EC00 + +FONT_II equ (OS_BASE+0x003EC00) +FONT_I equ (OS_BASE+0x003F600) +DRIVE_DATA equ (OS_BASE+0x0040000) +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) + +; unused? +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) +IMG_BACKGROUND equ (OS_BASE+0x0300000) +WinMapAddress equ (OS_BASE+0x0460000) +display_data equ (OS_BASE+0x0460000) + +;unused ? +HD_CACHE equ (OS_BASE+0x0600000) + +stack_data_start equ (OS_BASE+0x0700000) +eth_data_start equ (OS_BASE+0x0700000) +stack_data equ (OS_BASE+0x0704000) +stack_data_end equ (OS_BASE+0x071ffff) +VMODE_BASE equ (OS_BASE+0x0760000) +resendQ equ (OS_BASE+0x0770000) + +skin_data equ (OS_BASE+0x0778000) + + +tss_data equ (OS_BASE+0x780000) +draw_data equ (OS_BASE+0x988000) + +HEAP_BASE equ (OS_BASE+0x98B000) + +LFB_BASE equ 0x7DC00000 + +page_tabs equ 0x7FC00000 +master_tab equ 0x7FDFF000 +app_page_tabs equ 0x7FE00000 + +sys_pgdir equ OS_BASE+0x00050000 +sys_master_tab equ OS_BASE+0x00051000 +sys_pgmap equ OS_BASE+0x00052000 + + + +new_app_base equ 0x80000000 + +twdw equ (CURRENT_TASK-window_data) + +std_application_base_address equ new_app_base +RING0_STACK_SIZE equ (0x2000-512) ;512 įąéņ äė’ źīķņåźńņą FPU + +;PAGES_USED equ 4 + +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 SYS_VARS +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .cpu_caps dd ? + dd ? + dd ? + 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_max 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 + +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/hd_kolibri/kernel/core/debug.inc b/kernel/branches/hd_kolibri/kernel/core/debug.inc new file mode 100644 index 0000000000..a4eb83bf17 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/debug.inc @@ -0,0 +1,507 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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_TASK] + shl eax, 8 + mov [eax+SLOT_BASE+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 ebx, eax + shr ebx, 5 + push 2 + pop eax + jmp sys_system + +debug_suspend: +; in: ebx=pid +; destroys eax,ebx + call get_debuggee_slot + jc .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 + call get_debuggee_slot + jc .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 + add edx, std_application_base_address + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .ret + imul eax, tss_step/32 + add eax, tss_data + mov edi, edx + cmp [eax+TSS._cs], app_code + jnz .ring0 + lea esi, [eax+TSS._eip] + shr ecx, 2 + rep movsd + jmp .ret +.ring0: +; note that following code assumes that all interrupt/exception handlers +; saves ring-3 context by push ds es, pushad in this order + mov esi, [eax+TSS._esp0] +; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad + sub esi, 8+12+8+20h + lodsd + mov [edi+24h], eax + lodsd + mov [edi+20h], eax + lodsd + mov [edi+1Ch], eax + lodsd + lodsd + mov [edi+14h], eax + lodsd + mov [edi+10h], eax + lodsd + mov [edi+0Ch], eax + lodsd + mov [edi+8], eax + add esi, 8 + lodsd + mov [edi], eax + lodsd + lodsd + mov [edi+4], eax + lodsd + 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 + add edx, std_application_base_address + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .stiret + imul eax, tss_step/32 + add eax, tss_data + mov esi, edx + cmp [eax+TSS._cs], app_code + jnz .ring0 + lea edi, [eax+TSS._eip] + shr ecx, 2 + rep movsd + jmp .stiret +.ring0: + mov edi, [eax+TSS._esp0] + sub edi, 8+12+8+20h + mov eax, [esi+24h] + stosd + mov eax, [esi+20h] + stosd + mov eax, [esi+1Ch] + stosd + scasd + mov eax, [esi+14h] + stosd + mov eax, [esi+10h] + stosd + mov eax, [esi+0Ch] + stosd + mov eax, [esi+8] + stosd + add edi, 8 + mov eax, [esi] + stosd + scasd + mov eax, [esi+4] + stosd + mov eax, [esi+18h] + 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 + add edx, std_application_base_address + jc .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 +.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 + 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 + add esi, std_application_base_address + 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 + add esi, std_application_base_address + 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: +; int 1 = #DB + save_ring3_context + cld + mov ax, os_data + mov ds, ax + mov es, ax + mov eax, dr6 + test ax, ax + jns @f +; this is exception from task switch +; set DRx registers for task and continue + mov eax, [CURRENT_TASK] + shl eax, 8 + add eax, SLOT_BASE+APPDATA.dbg_regs + mov ecx, [eax+0] + mov dr0, ecx + mov ecx, [eax+4] + mov dr1, ecx + mov ecx, [eax+8] + mov dr2, ecx + mov ecx, [eax+0Ch] + mov dr3, ecx + xor ecx, ecx + mov dr6, ecx + mov ecx, [eax+10h] + mov dr7, ecx + restore_ring3_context + iretd +@@: + push eax + xor eax, eax + mov dr6, eax +; test if debugging + cli + mov eax, [CURRENT_TASK] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + add esp, 28h+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/hd_kolibri/kernel/core/detect/commouse.inc b/kernel/branches/hd_kolibri/kernel/core/detect/commouse.inc new file mode 100644 index 0000000000..5b4a281954 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/detect/commouse.inc @@ -0,0 +1,143 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;************************************************** +;* ĻĪČŃŹ ĢŪŲČ ĻĪ ĻĪŃĖÅÄĪĀĄŅÅĖÜĶŪĢ ĻĪŠŅĄĢ * +;* Ļšīöåäóšą ļīäćīņąāėčāąåņ ćėīįąėüķūå ļåšåģåķķūå * +;* COMPortNum č COMPortBaseAddr äė’ ļīäļšīćšąģģū * +;* óńņąķīāźč īįšąįīņ÷čźą ļšåšūāąķč’ * +;************************************************** +; Ąāņīš čńõīäķīćī ņåźńņą Źóėąźīā Āėąäčģčš Ćåķķąäüåāč÷. +; Ąäąļņąöč’ č äīšąįīņźą Mario79 + +Detect_COM_Mouse: + pusha + call MSMouseSearch + cmp AL,'M' + jne @f + mov [com1_mouse_detected],1 + pusha + + mov eax,4 + shl eax,2 + mov [irq_owner+eax],byte 1 + + inc dword [RESERVED_PORTS] + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x3f0 + mov [RESERVED_PORTS+edi+8],dword 0x3ff + + popa + mov esi,boot_setmouse_type+22 + call boot_log + @@: + sub [COMPortBaseAddr],100h + call MSMouseSearch + cmp AL,'M' + jne @f + mov [com2_mouse_detected],1 + pusha + + mov eax,3 + shl eax,2 + mov [irq_owner+eax],byte 1 + + inc dword [RESERVED_PORTS] + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x2f0 + mov [RESERVED_PORTS+edi+8],dword 0x2ff + + popa + mov esi,boot_setmouse_type+44 + call boot_log + @@: + popa + jmp end_detecting_mouse + +MSMouseSearch: + ; ĻĪČŃŹ ĢŪŲČ ×ÅŠÅĒ COM-ĻĪŠŅŪ +MouseSearch: + ; Óńņąķąāėčāąåģ ńźīšīńņü + ; ļščåģą/ļåšåäą÷č 1200 įīä + mov DX,[COMPortBaseAddr] + add DX,3 + in AL,DX + or AL,80h ;óńņąķīāčņü įčņ DLAB + out DX,AL + mov DX,[COMPortBaseAddr] + mov AL,60h ;1200 įīä + out DX,AL + inc DX + mov AL,0 + out DX,AL + ; Óńņąķīāčņü äėčķó ńėīāą 7 įčņ, 1 ńņīļīāūé įčņ, + ; ÷åņķīńņü ķå źīķņšīėčšīāąņü + mov DX,[COMPortBaseAddr] + add DX,3 + mov AL,00000010b + out DX,AL + ; Ēąļšåņčņü āńå ļšåšūāąķč + mov DX,[COMPortBaseAddr] + inc DX + mov AL,0 + out DX,AL +; Ļšīāåščņü, ÷ņī óńņšīéńņāī ļīäźėž÷åķī č ’āė’åņń +; ģūųüž ņčļą MSMouse + ; Īņźėž÷čņü ļčņąķčå ģūųč č ļšåšūāąķč + mov DX,[COMPortBaseAddr] + add DX,4 ;šåćčńņš óļšąāėåķč’ ģīäåģīģ + mov AL,0 ;ńįšīńčņü DTR, RTS č OUT2 + out DX,AL + ; Īęčäąņü 5 "ņčźīā" (0,2 ń) + mov ecx,0xffff +dT_1: + dec ecx + cmp ecx,0 + jne dT_1 + mov ecx,0xffff + ; Āźėž÷čņü ļčņąķčå ģūųč + mov AL,11b ;óńņąķīāčņü DTR č RTS + out DX,AL + ; Ī÷čńņčņü šåćčńņš äąķķūõ + mov DX,[COMPortBaseAddr] + in AL,DX +; Öčźė īļšīńą ļīšņą +WaitData: + ; Īęčäąņü åłå 10 "ņčźīā" + dec ecx + cmp ecx,0 + je NoMouse + ; Ļšīāåščņü ķąėč÷čå čäåķņčōčźąöčīķķīćī įąéņą + mov DX,[COMPortBaseAddr] + add DX,5 + in AL,DX + test AL,1 ;Äąķķūå ćīņīāū? + jz WaitData + ; Āāåńņč äąķķūå + mov DX,[COMPortBaseAddr] + in AL,DX +NoMouse: + ret + +iglobal +COMPortBaseAddr dw 3F8h +;COMPortNum dw 0 +endg + +iglobal +boot_setmouse_type db 'Detected - PS2 mouse',0 + db 'Detected - COM1 mouse',0 + db 'Detected - COM2 mouse',0 +endg + +end_detecting_mouse: + diff --git a/kernel/branches/hd_kolibri/kernel/core/detect/ps2mouse.inc b/kernel/branches/hd_kolibri/kernel/core/detect/ps2mouse.inc new file mode 100644 index 0000000000..7cab9a6973 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/detect/ps2mouse.inc @@ -0,0 +1,139 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +MouseSearch_PS2: + jmp MouseSearch_PS2_begin + +mouse_error equ MouseSearch_PS2_begin.error + + kb_cmd_c: + call kb_cmd + jmp check_kbd + + kb_write_c: + call kb_write + jmp check_kbd + + kb_read_c: + call kb_read + ;jmp check_kbd + + check_kbd: + cmp ah, 1 + je mouse_error + ret + +uglobal + mouse_cmd_byte db 0 + mouse_nr_tries db 0 + mouse_nr_resends db 0 + + mouse_error_esp dd 0 +endg + + + mouse_cmd: + mov [mouse_cmd_byte], al + mov [mouse_nr_resends], 5 + .resend: + mov bl, 0xd4 + call kb_cmd_c + mov al, [mouse_cmd_byte] + call kb_write_c + + call mouse_read + + cmp al, 0xFA ; ack + jne .noack + ret + .noack: + cmp al, 0xFE ; resend + jne .noresend + dec [mouse_nr_resends] + jnz .resend + .noresend: + jmp mouse_error + + + mouse_read: + mov [mouse_nr_tries], 100 + .repeat: + call kb_read + cmp ah, 1 + jne .fin + mov esi, 10 + call delay_ms + dec [mouse_nr_tries] + jnz .repeat + jmp mouse_error + .fin: + ret + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MouseSearch_PS2_begin: + pushad + + mov [mouse_error_esp], esp + + mov bl, 0xAD ; disable keyboard interface + call kb_cmd_c + + mov bl, 0xA8 ; enable mouse interface + call kb_cmd_c + + mov al, 0xFF ; reset + call mouse_cmd + + ; now the mouse is in Reset Mode + ; get the Basic Assurance Test completion code + call mouse_read + cmp al, 0xAA + jne .error ; dead mouse + + ; get device ID + call mouse_read + cmp al, 0x00 + jne .error ; unknown device + + ; reset completed successfully + + ; enable mouse interrupt - IRQ12 + mov bl, 0x20 ; read command byte + call kb_cmd_c + call kb_read_c + or al, 10b + push eax + mov bl, 0x60 ; write command byte + call kb_cmd_c + pop eax + call kb_write_c + + mov al, 0xF4 ; enable data reporting + call mouse_cmd + + mov [ps2_mouse_detected], 1 + mov bl, 0xAE ; enable keyboard interface + call kb_cmd + + mov esi, boot_setmouse_type + call boot_log + + jmp .finish + + +.error: + mov esp, [mouse_error_esp] ; clear stack frame + mov [ps2_mouse_detected], 0 + mov bl, 0xA7 ; disable mouse interface + call kb_cmd + mov bl, 0xAE ; enable keyboard interface + call kb_cmd + +.finish: + popad diff --git a/kernel/branches/hd_kolibri/kernel/core/dll.inc b/kernel/branches/hd_kolibri/kernel/core/dll.inc new file mode 100644 index 0000000000..ef80189a78 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/dll.inc @@ -0,0 +1,1084 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +DRV_COMPAT equ 4 ;minimal required drivers version +DRV_CURRENT equ 4 ;current drivers model version + +DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT + +align 4 +proc attach_int_handler stdcall, irq:dword, handler:dword + + mov ebx, [irq] ;irq num + test ebx, ebx + jz .err + mov eax, [handler] + test eax, eax + jz .err + mov [irq_tab+ebx*4], eax + stdcall enable_irq, [irq] + 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 eax + mov eax, 1 + jmp .main +align 4 +.irq_2: + push eax + mov eax, 2 + jmp .main +align 4 +.irq_3: + push eax + mov eax, 3 + jmp .main +align 4 +.irq_4: + push eax + mov eax, 4 + jmp .main +align 4 +.irq_5: + push eax + mov eax, 5 + jmp .main +align 4 +.irq_6: + push eax + mov eax, 6 + jmp .main +align 4 +.irq_7: + push eax + mov eax, 7 + jmp .main +align 4 +.irq_8: + push eax + mov eax, 8 + jmp .main +align 4 +.irq_9: + push eax + mov eax, 9 + jmp .main +align 4 +.irq_10: + push eax + mov eax, 10 + jmp .main +align 4 +.irq_11: + push eax + mov eax, 11 + jmp .main +align 4 +.irq_12: + push eax + mov eax, 12 + jmp .main +align 4 +.irq_13: + push eax + mov eax, 13 + jmp .main +align 4 +.irq_14: + push eax + mov eax, 14 + jmp .main +align 4 +.irq_15: + push eax + mov eax, 15 + jmp .main + +align 16 +.main: + save_ring3_context + mov bx, os_data + mov ds, bx + mov es, bx + + mov ebx, [irq_tab+eax*4] + test ebx, ebx + jz .exit + + call ebx + +.exit: + restore_ring3_context + + cmp eax, 8 + mov al, 0x20 + jb @f + out 0xa0, al +@@: + out 0x20, al + + pop eax + iret + +align 4 +proc get_notify stdcall, p_ev:dword + +.wait: + mov ebx,[CURRENT_TASK] + shl ebx,8 + test dword [ebx+SLOT_BASE+0xA8],EVENT_NOTIFY + jz @f + and dword [ebx+SLOT_BASE+0xA8], not EVENT_NOTIFY + mov edi, [p_ev] + mov dword [edi], EV_INTR + mov eax, [ebx+SLOT_BASE+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 + 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 + ret +endp + +align 4 +proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword + 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 + ret +endp + +align 4 +proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + 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 + 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: + test ebx, ebx + jz .fail + add ebx, new_app_base + + mov eax, [ebx+handle] + cmp [eax+SRV.magic], ' SRV' + jne .fail + + cmp [eax+SRV.size], SRV_SIZE + jne .fail + + add [ebx+input], new_app_base + add [ebx+output], new_app_base + + 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 +reg_service: +.sz_name equ esp+4 +.handler equ esp+8 + mov eax, [.sz_name] + test eax, eax + jz .fail + + mov ebx, [.handler] + test ebx, ebx + jz .fail + + mov eax, SRV_SIZE + call malloc ;call alloc_service + test eax, eax + jz .fail + + mov edi, eax + mov esi, [.sz_name] + mov ecx, 16/4 + rep movsd + + 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 + ret 8 +.fail: + xor eax, eax + ret 8 + +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] + sub ebx, new_app_base + mov ecx, [info] + sub ecx, new_app_base + + 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] + sub ebx, new_app_base + 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] + sub ebx, new_app_base + sub esi, new_app_base + + 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] + sub eax, new_app_base + 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 + + 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 + sub ecx, ebx + xor eax, eax + cld + rep stosb + mov ebx, [file_size] + pop eax + ret +.cleanup: + stdcall kernel_free, [file] +.fail: + xor eax, eax + xor ebx, ebx + 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: + 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 14+16+4+1 ; '/rd/1/drivers/.obj' +; endl +;----------------------------------------- + file_name rb 23+16+4+1 ; '/hd0/1/kolibri/drivers/.obj' + endl + + lea edx, [file_name] + + mov dword [edx] , '/hd0' + mov dword [edx+4] , '/1/k' + mov dword [edx+8] , 'olib' + mov dword [edx+12], 'ri/d' + mov dword [edx+16], 'rive' + mov word [edx+20], 'rs' + mov byte [edx+22], '/' + mov esi, [driver_name] + lea edi, [edx+23] + mov ecx, 16 +;--------------------------------------- +; lea edx, [file_name] +; mov dword [edx], '/rd/' +; mov dword [edx+4], '1/dr' +; mov dword [edx+8], 'iver' +; mov word [edx+12], 's/' +; mov esi, [driver_name] +; lea edi, [edx+14] +; 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, 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, 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] + 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_TASK] + shl ecx,8 + add ecx, SLOT_BASE+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 + + +;szSound db 'SOUND',0 +;szInfinity db 'INFINITY',0 +szHwMouse db 'ATI2D',0 + +szSTART db 'START',0 +szEXPORTS db 'EXPORTS',0 +szIMPORTS db 'IMPORTS',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 + +align 4 +create_cursor dd 0 +set_hw_cursor dd 0 +hw_restore dd 0 diff --git a/kernel/branches/hd_kolibri/kernel/core/exports.inc b/kernel/branches/hd_kolibri/kernel/core/exports.inc new file mode 100644 index 0000000000..922203bdaa --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/exports.inc @@ -0,0 +1,117 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 + + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',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 + 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 + + 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 + szSetHwCursor db 'SetHwCursor',0 + szHwCursorRestore db 'HwCursorRestore', 0 + szHwCursorCreate db 'HwCursorCreate', 0 + + szSysMsgBoardStr db 'SysMsgBoardStr', 0 + szGetCurrentTask db 'GetCurrentTask',0 + szLFBAddress db 'LFBAddress',0 + szLoadFile db 'LoadFile',0 + szSendEvent db 'SendEvent',0 + + +align 16 +kernel_export: + dd szRegService , reg_service + dd szGetService , get_service + dd szServiceHandler , srv_handler + dd szAttachIntHandler, attach_int_handler + dd szFpuSave , fpu_save + dd szFpuRestore , fpu_restore + + dd szPciApi , pci_api + dd szPciRead32 , pci_read32 + dd szPciRead8 , pci_read8 + dd szPciWrite8 , pci_write8 + + dd szAllocPage , alloc_page + dd szAllocPages , alloc_pages + dd szFreePage , free_page + dd szMapPage , map_page + dd szMapSpace , map_space + dd szGetPgAddr , get_pg_addr + dd szCommitPages , commit_pages ;not implemented + dd szReleasePages , release_pages + + dd szAllocKernelSpace, alloc_kernel_space + dd szFreeKernelSpace , free_kernel_space + dd szKernelAlloc , kernel_alloc + dd szKernelFree , kernel_free + dd szUserAlloc , user_alloc + dd szUserFree , user_free + dd szKmalloc , malloc + dd szKfree , free + + 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 + dd szSetHwCursor , set_hw_cursor + dd szHwCursorRestore , hw_restore + dd szHwCursorCreate , create_cursor + + dd szSysMsgBoardStr , sys_msg_board_str + dd szGetCurrentTask , get_curr_task + dd szLoadFile , load_file + dd szSendEvent , send_event +exp_lfb: + dd szLFBAddress , 0 + dd 0 + +endg + diff --git a/kernel/branches/hd_kolibri/kernel/core/fpu.inc b/kernel/branches/hd_kolibri/kernel/core/fpu.inc new file mode 100644 index 0000000000..eaac048d52 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/fpu.inc @@ -0,0 +1,283 @@ +$Revision: 435 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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, os_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 1 + 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 + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [ss:CURRENT_TASK] + shl ebx, 8 + + mov eax, [ss:ebx+SLOT_BASE+APPDATA.fpu_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [ss:edx+new_app_base], 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 + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [ss:CURRENT_TASK] + shl ebx, 8 + + mov eax, [ss:ebx+SLOT_BASE+APPDATA.sse_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [ss:edx+new_app_base], 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/hd_kolibri/kernel/core/heap.inc b/kernel/branches/hd_kolibri/kernel/core/heap.inc new file mode 100644 index 0000000000..3cc76f1c9e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/heap.inc @@ -0,0 +1,1095 @@ +$Revision: 448 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + +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 + 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_block: + mov ecx, eax + shr ecx, 12 + dec ecx + cmp ecx, 63 + jle .get_index + mov ecx, 63 +.get_index: + lea esi, [mem_block_mask] + xor ebx, ebx + or edx, -1 + + cmp ecx, 32 + jb .bit_test + + sub ecx, 32 + add ebx, 32 + add esi, 4 +.bit_test: + shl edx, cl + and edx, [esi] +.find: + bsf edi, edx + jz .high_mask + add ebx, edi + mov edi, [mem_block_list+ebx*4] +.check_size: + cmp eax, [edi+block_size] + ja .next + ret + +.high_mask: + add esi, 4 + cmp esi, mem_block_mask+8 + jae .err + add ebx, 32 + mov edx, [esi] + jmp .find +.next: + mov edi, [edi+list_fd] + test edi, edi + jnz .check_size +.err: + xor edi, edi + ret + +align 4 +proc 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 +endp + +proc 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 +endp + +align 4 +proc alloc_kernel_space stdcall, size:dword + local block_ind:DWORD + + 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_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 + 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 + ret +.error: + xor eax, eax + mov [heap_mutex], eax + ret +endp + +align 4 +proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword + + 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 + 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 + ret +.fail: + xor eax, eax + mov [heap_mutex], eax + ret +endp + +align 4 +proc kernel_alloc stdcall, size:dword + locals + lin_addr dd ? + pages_count dd ? + endl + + 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] + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc kernel_free stdcall, base:dword + push ebx esi + + mov ebx, heap_mutex + call wait_mutex ;ebx + + mov eax, [base] + mov esi, [mem_used.fd] +@@: + cmp esi, mem_used.fd-MEM_LIST_OFFSET + je .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_fd] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + and [heap_mutex], 0 + + push ecx + mov ecx, [esi+block_size]; + shr ecx, 12 + call release_pages ;eax, ecx + pop ecx + stdcall free_kernel_space, [base] + pop esi ebx + ret +.fail: + and [heap_mutex], 0 + pop esi ebx + ret +endp + +restore block_next +restore block_prev +restore block_list +restore block_base +restore block_size +restore block_flags + +;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; + +HEAP_TOP equ 0x5FC00000 + +align 4 +proc init_heap + + mov ebx,[CURRENT_TASK] + shl ebx,8 + mov eax, [SLOT_BASE+APPDATA.heap_top+ebx] + test eax, eax + jz @F + sub eax,[SLOT_BASE+APPDATA.heap_base+ebx] + sub eax, 4096 + ret +@@: + mov esi, [SLOT_BASE+APPDATA.mem_size+ebx] + add esi, 4095 + and esi, not 4095 + mov [SLOT_BASE+APPDATA.mem_size+ebx], esi + mov eax, HEAP_TOP + mov [SLOT_BASE+APPDATA.heap_base+ebx], esi + mov [SLOT_BASE+APPDATA.heap_top+ebx], eax + + sub eax, esi + add esi, new_app_base + shr esi, 10 + mov ecx, eax + sub eax, 4096 + or ecx, FREE_BLOCK + mov [page_tabs+esi], ecx + ret +.exit: + xor eax, eax + ret +endp + +align 4 +proc user_alloc stdcall, alloc_size:dword + + mov ecx, [alloc_size] + add ecx, (4095+4096) + and ecx, not 4095 + + mov ebx, [CURRENT_TASK] + shl ebx, 8 + mov esi, dword [ebx+SLOT_BASE+APPDATA.heap_base]; heap_base + mov edi, dword [ebx+SLOT_BASE+APPDATA.heap_top]; heap_top + add esi, new_app_base + add edi, new_app_base +l_0: + cmp esi, edi + jae m_exit + + mov ebx, esi + shr ebx, 12 + mov eax, [page_tabs+ebx*4] + test eax, FREE_BLOCK + jz test_used + and eax, 0xFFFFF000 + cmp eax, ecx ;alloc_size + jb m_next + jz @f + + mov edx, esi + add edx, ecx + sub eax, ecx; + or eax, FREE_BLOCK + shr edx, 12 + mov [page_tabs+edx*4], eax + +@@: + or ecx, USED_BLOCK + mov [page_tabs+ebx*4], ecx + shr ecx, 12 + dec ecx + inc ebx +@@: + mov dword [page_tabs+ebx*4], 2 + inc ebx + dec ecx + jnz @B + + mov edx, [CURRENT_TASK] + shl edx, 8 + mov ebx, [alloc_size] + add ebx, 0xFFF + and ebx, not 0xFFF + add ebx, [SLOT_BASE+APPDATA.mem_size+edx] + call update_mem_size + + mov eax, esi + add eax, 4096 + sub eax, new_app_base + ret +m_next: + add esi, eax + jmp l_0 +test_used: + test eax, USED_BLOCK + jz m_exit + + and eax, 0xFFFFF000 + add esi, eax + jmp l_0 +m_exit: + xor eax, eax + ret +endp + +align 4 +proc user_free stdcall, base:dword + + mov esi, [base] + test esi, esi + jz .exit + + xor ebx, ebx + sub esi, 4096 + shr esi, 12 + mov eax, [page_tabs+esi*4] + test eax, USED_BLOCK + jz .not_used + + and eax, not 4095 + mov ecx, eax + or eax, FREE_BLOCK + mov [page_tabs+esi*4], eax + inc esi + sub ecx, 4096 + shr ecx, 12 + mov ebx, ecx +.release: + xor eax, eax + xchg eax, [page_tabs+esi*4] + test eax, 1 + jz @F + call free_page + mov eax, esi + shl eax, 12 + invlpg [eax] +@@: + inc esi + dec ecx + jnz .release +.not_used: + mov edx, [CURRENT_TASK] + shl edx, 8 + mov esi, dword [edx+SLOT_BASE+APPDATA.heap_base]; heap_base + mov edi, dword [edx+SLOT_BASE+APPDATA.heap_top]; heap_top + sub ebx, [edx+SLOT_BASE+APPDATA.mem_size] + neg ebx + call update_mem_size + call user_normalize + ret +.exit: + xor eax, eax + inc eax + ret +endp + +user_normalize: +; in: esi=heap_base, edi=heap_top +; out: eax=0 <=> OK +; destroys: ebx,edx,esi,edi + add esi, new_app_base + add edi, new_app_base + shr esi, 12 + shr edi, 12 +@@: + mov eax, [page_tabs+esi*4] + test eax, USED_BLOCK + jz .test_free + shr eax, 12 + add esi, eax + jmp @B +.test_free: + test eax, 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 ebx, USED_BLOCK + jz .next_free + + shr ebx, 12 + add edx, ebx + mov esi, edx + jmp @B +.next_free: + test ebx, 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 + new_app_base - 0x1000] + shr ecx, 12 + mov edx, [page_tabs+ecx*4] + test edx, USED_BLOCK + jnz @f +; attempt to realloc invalid pointer +.ret0: + pop edx ecx + xor eax, eax + ret +@@: + 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_TASK] + shl edx, 8 + mov ebx, [SLOT_BASE+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, [SLOT_BASE+APPDATA.heap_base+edx] + mov edi, [SLOT_BASE+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_TASK] + shl edx, 8 + shl ebx, 12 + sub ebx, [SLOT_BASE+APPDATA.mem_size+edx] + neg ebx + call update_mem_size + pop edx ecx ebx + lea eax, [ecx+1-(new_app_base shr 12)] + shl eax, 12 + push eax + add ecx, ebx + add edx, ecx + shl ebx, 12 + jz .ret + push esi + mov esi, [CURRENT_TASK] + shl esi, 8 + mov esi, [SLOT_BASE+APPDATA.heap_top+esi] + shr esi, 12 +@@: + cmp edx, esi + jae .merge_done + mov eax, [page_tabs+edx*4] + test al, USED_BLOCK + jz .merge_done + and dword [page_tabs+edx*4], 0 + and eax, not 0xFFF + add ebx, eax + add edx, 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_TASK] + shl eax, 8 + mov eax, [SLOT_BASE+APPDATA.heap_top+eax] + add eax, new_app_base + shr eax, 12 + cmp edx, eax + jae .cant_inplace + mov eax, [page_tabs+edx*4] + shr eax, 12 + add eax, edx + cmp eax, ebx + jb .cant_inplace + sub eax, ebx + 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-(new_app_base shr 12)] + 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_TASK] + shl edx, 8 + shl ebx, 12 + add ebx, [SLOT_BASE+APPDATA.mem_size+edx] + call update_mem_size + pop eax edx ecx + ret +.cant_inplace: + push esi edi + mov eax, [CURRENT_TASK] + shl eax, 8 + mov esi, [SLOT_BASE+APPDATA.heap_base+eax] + mov edi, [SLOT_BASE+APPDATA.heap_top+eax] + add esi, new_app_base + add edi, new_app_base + 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, eax + 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 + sub eax, new_app_base + 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 +@@: + xor eax, eax + xchg eax, [page_tabs+ecx*4] + mov [page_tabs+esi*4], eax + mov eax, ecx + shl eax, 12 + invlpg [eax] + inc ecx + inc esi + dec ebx + dec edx + jnz @b + push ebx + mov edx, [CURRENT_TASK] + shl edx, 8 + shl ebx, 12 + add ebx, [SLOT_BASE+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/hd_kolibri/kernel/core/idle.inc b/kernel/branches/hd_kolibri/kernel/core/idle.inc new file mode 100644 index 0000000000..772d4c8be1 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/idle.inc @@ -0,0 +1,57 @@ +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 \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/core/mainloop.inc b/kernel/branches/hd_kolibri/kernel/core/mainloop.inc new file mode 100644 index 0000000000..cb77c75c9c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/mainloop.inc @@ -0,0 +1,22 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; 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 + jmp osloop +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MAIN OS LOOP END ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/core/malloc.inc b/kernel/branches/hd_kolibri/kernel/core/malloc.inc new file mode 100644 index 0000000000..44554f33e4 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/malloc.inc @@ -0,0 +1,1001 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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, 0x20000 + + 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 + jl @B + + ret + + + + diff --git a/kernel/branches/hd_kolibri/kernel/core/memory.inc b/kernel/branches/hd_kolibri/kernel/core/memory.inc new file mode 100644 index 0000000000..827014dc9a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/memory.inc @@ -0,0 +1,1662 @@ +$Revision: 448 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +tmp_page_tab equ HEAP_BASE + +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, 0x400000 + xchg ebx, dword [edi] + cmp dword [edi], 'TEST' + xchg ebx, dword [edi] + je @b + mov [MEM_AMOUNT], edi + + and eax, not (CR0_CD+CR0_NW) ;enable caching + mov cr0, eax + mov eax, edi + mov [LFBSize], 0x00800000 + ret +endp + +align 4 +proc init_mem + + mov eax, [MEM_AMOUNT] + + mov [pg_data.mem_amount], eax + mov [pg_data.kernel_max], eax + + shr eax, 12 + mov edx, eax + mov [pg_data.pages_count], eax + mov [pg_data.kernel_pages], eax + + shr eax, 3 + mov [pg_data.pagemap_size], eax + + shr edx, 10 + cmp edx, 3 + ja @f + inc edx ;at least 4Mb for kernel heap +@@: + mov [pg_data.kernel_tables], edx + + xor eax, eax + mov edi, sys_pgdir + mov ecx, 2048 + cld + rep stosd + + mov edx, sys_pgdir + bt [cpu_caps], CAPS_PSE + jnc .no_PSE + + mov ebx, cr4 + or ebx, CR4_PSE + mov eax, PG_LARGE+PG_SW + bt [cpu_caps], CAPS_PGE + jnc @F + or eax, PG_GLOBAL + or ebx, CR4_PGE +@@: + mov cr4, ebx + sub [pg_data.kernel_tables], 2 + + mov [edx], eax + add eax, 0x00400000 + mov [edx+4], eax + add edx, 8 + + mov eax, 0x800000+PG_SW + mov ecx, (HEAP_BASE-0x800000)/4096 + jmp .map_low +.no_PSE: + mov eax, PG_SW + mov ecx, HEAP_BASE/4096 +.map_low: + mov edi, tmp_page_tab +@@: ; + stosd + add eax, 0x1000 + dec ecx + jnz @B + + mov ecx, [pg_data.kernel_tables] + shl ecx, 10 + xor eax, eax + rep stosd + + mov ecx, [pg_data.kernel_tables] + mov eax, tmp_page_tab+PG_SW + mov edi, edx + +.map_kernel_tabs: + + stosd + add eax, 0x1000 + dec ecx + jnz .map_kernel_tabs + + mov dword [sys_pgdir+(page_tabs shr 20)], sys_pgdir+PG_SW + ret +endp + +align 4 +proc init_page_map + + mov edi, sys_pgmap + mov ecx, (HEAP_BASE/4096)/32 ;384/4 + mov ebx, ecx + xor eax,eax + cld + rep stosd + + not eax + mov ecx, [pg_data.pagemap_size] + sub ecx, ebx + shr ecx, 2 + rep stosd + + lea edi, [sys_pgmap+ebx*4] ;+384 + mov edx, [pg_data.pages_count] + mov ecx, [pg_data.kernel_tables] + add ecx, (HEAP_BASE/4096) and 31 + sub edx, HEAP_BASE/4096 + sub edx, ecx + mov [pg_data.pages_free], edx + + xor eax, eax + mov ebx, ecx + shr ecx, 5 + rep stosd + + not eax + mov ecx, ebx + and ecx, 31 + shl eax, cl + mov [page_start], edi; sys_pgmap+384 + stosd + + mov ebx, sys_pgmap + add ebx, [pg_data.pagemap_size] + mov [page_end], ebx + + mov [pg_data.pg_mutex], 0 + + ret +endp + +align 4 +proc alloc_page + + pushfd + cli + mov ebx, [page_start] + mov ecx, [page_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 [page_start],ebx + sub ebx, sys_pgmap + lea eax, [eax+ebx*8] + shl eax, 12 + dec [pg_data.pages_free] + popfd + ret +endp + +align 4 +proc alloc_pages stdcall, count:dword + pushfd + 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 + popfd + ret +.next: + inc ecx + cmp ecx, ebx + jb .find + popfd + xor eax, eax + ret +.ok: + sub ecx, edi + inc ecx + 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 + 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 + +; param +; eax= page base + page flags +; ebx= liear address +; ecx= count + +align 4 +commit_pages: + + 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 + invlpg [edi] + add edi, edx + add eax, edx + inc ebx + dec ecx + jnz @B + mov [pg_data.pg_mutex],ecx +.fail: + 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] + invlpg [edi] + + 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 + +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 +@@: + mov edx, LFB_BASE + mov esi, [LFBAddress] + mov edi, [LFBSize] + 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 + shr edx, 20 + mov ecx, edx +@@: + mov [sys_pgdir+edx], esi + add edx, 4 + add esi, 0x00400000 + dec edi + jnz @B + + bt [cpu_caps], CAPS_PGE + jnc @F + or dword [sys_pgdir+ecx], 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 .map_page_tables + + 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_TASK] + shl edx,8 + cmp [SLOT_BASE+APPDATA.heap_base+edx],0 + jne .exit + + mov esi, [SLOT_BASE+APPDATA.mem_size+edx] + 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 + invlpg [ebx+std_application_base_address] + 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: + add edi, new_app_base + add esi, new_app_base + + 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 shl 8 +; ebx = new memory size +; destroys eax,ecx,edx + + mov [SLOT_BASE+APPDATA.mem_size+edx],ebx +;search threads and update +;application memory size infomation + mov ecx,[SLOT_BASE+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 + pushad + + mov ebp, esp + mov eax, cr2 + push eax + push ds + push es + + mov ax, 0x10 + mov ds, ax + mov es, ax + + inc [pg_data.pages_faults] + + mov ebx, [ebp-4] + + cmp ebx, 0x80000000 + jae .user_space + + cmp ebx, app_page_tabs + jae .alloc + + cmp ebx, page_tabs + jae .tab_space + + cmp ebx, 0x7DC00000 + jae .lfb_addr + + jmp .kernel_space + +.user_space: + shr ebx, 12 + mov ecx, ebx + shr ecx, 10 + mov edx, [master_tab+ecx*4] + test edx, 1 + jz .fail + + mov eax, [page_tabs+ebx*4] + test eax, 2 + jz .fail +.alloc: + call alloc_page + and eax, eax + jz .exit + + 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: + pop es + pop ds + mov esp, ebp + popad + add esp, 4 + iretd +.fail: + pop es + pop ds + mov esp, ebp + popad + add esp, 4 + + save_ring3_context ;debugger support + + mov bl, 14 + jmp exc_c + iretd + +.kernel_space: +; shr ebx, 12 +; mov eax, [page_tabs+ebx*4] +; shr ebx, 10 +; mov eax, [master_tab+ebx*4] + jmp .exit +.old_addr: +; shr ebx, 12 +; mov eax, [page_tabs+ebx*4] +; shr ebx, 10 +; mov eax, [master_tab+ebx*4] + jmp .exit +.lfb_addr: +; shr ebx, 22 +; ;mov ecx, [sys_page_dir] +; mov eax, [master_tab+ebx*4] + jmp .exit +.tab_space: +; shr ebx, 12 +; mov eax, [page_tabs+ebx*4] +; shr ebx, 10 +; ;mov ecx, [sys_page_dir] +; mov eax, [master_tab+ebx*4] + jmp .exit +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,dword PG_UW + mov ebx, [ofs] + shr ebx, 22 + mov esi, [ipc_pdir] + mov edi, [ipc_ptab] + mov eax, [esi+ebx*4] + and eax, 0xFFFFF000 + test eax, eax + jz .exit + stdcall map_page,edi,eax,dword 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 + 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 + +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_TASK] + shl eax,8 + add eax, SLOT_BASE + pushf + cli + mov [eax+0xA0],ebx ;set fields in extended information area + mov [eax+0xA4],ecx + + add ebx, new_app_base + add ecx, ebx + add ecx, 4095 + and ecx, not 4095 + +.touch: mov eax, [ebx] + add ebx, 0x1000 + cmp ebx, ecx + jna .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 ? + 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 + add edi, new_app_base + and ebx, 0xFFF + mov [dst_offset], ebx + + mov esi, [eax+SLOT_BASE+0xa4] + mov [buf_size], esi + + stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\ + edi, esi + + mov edi, [dst_offset] + add edi, [ipc_tmp] + cmp dword [edi], 0 + jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now + + mov ebx, dword [edi+4] + mov edx, ebx + add ebx, 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 + mov edi, [dst_offset] + add edi, [ipc_tmp] + 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: + popf + xor eax, eax + ret +.no_pid: + popf + mov eax, 4 + ret +.no_ipc_area: + popf + xor eax, eax + inc eax + ret +.ipc_blocked: + popf + mov eax, 2 + ret +.buffer_overflow: + popf + mov eax, 3 + ret +endp + +align 4 +sysfn_meminfo: + + add ebx, new_app_base + cmp ebx, new_app_base + jb .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 + add ebx, new_app_base + stdcall user_free, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 14 + ja @f + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + stdcall get_event_ex, ebx, ecx + mov [esp+36], eax + ret +@@: + cmp eax, 15 + ja @f + mov ecx, [CURRENT_TASK] + shl ecx, 8 + mov eax, [ecx+SLOT_BASE+APPDATA.fpu_handler] + mov [ecx+SLOT_BASE+APPDATA.fpu_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 16 + ja @f + + test ebx, ebx + jz .fail + add ebx, new_app_base + cmp ebx, new_app_base + jb .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_TASK] + shl ecx, 8 + mov eax, [ecx+SLOT_BASE+APPDATA.sse_handler] + mov [ecx+SLOT_BASE+APPDATA.sse_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 19 + ja @f + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + stdcall load_library, ebx + mov [esp+36], eax + ret + +@@: + cmp eax, 20 + ja .fail + mov eax, ecx + call user_realloc + mov [esp+36], eax + ret + +.fail: + xor eax, eax + mov [esp+36], eax + ret + +align 4 +proc strncmp stdcall, str1:dword, str2:dword, count:dword + + mov ecx,[count] + jecxz .end + + mov ebx,ecx + + mov edi,[str1] + mov esi,edi + xor eax,eax + repne scasb + neg ecx ; cx = count - strlen + add ecx,ebx ; strlen + count - strlen + +.okay: + mov edi,esi + mov esi,[str2] + repe cmpsb + mov al,[esi-1] + xor ecx,ecx + + cmp al,[edi-1] + ja .str2_big + je .end + +.str1_big: + sub ecx,2 + +.str2_big: + not ecx +.end: + mov eax,ecx + ret +endp + +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], eax + mov [cpu_caps+4], 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], ebx + mov [cpu_vendor+4], edx + mov [cpu_vendor+8], ecx + cmp ebx, dword [intel_str] + jne .check_AMD + cmp edx, dword [intel_str+4] + jne .check_AMD + cmp ecx, dword [intel_str+8] + jne .check_AMD + mov [cpu_Intel], 1 + cmp eax, 1 + jl .end_cpuid + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + + shr eax, 8 + and eax, 0x0f + ret +.end_cpuid: + mov eax, [cpu_type] + ret + +.check_AMD: + cmp ebx, dword [AMD_str] + jne .unknown + cmp edx, dword [AMD_str+4] + jne .unknown + cmp ecx, dword [AMD_str+8] + jne .unknown + mov [cpu_AMD], 1 + cmp eax, 1 + jl .unknown + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + ret +.unknown: + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + ret +endp + +MEM_WB equ 6 ;write-back memory +MEM_WC equ 1 ;write combined memory +MEM_UC equ 0 ;uncached memory + +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 + + stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB + stdcall set_mtrr, dword 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 + +iglobal +align 4 + intel_str db "GenuineIntel",0 + AMD_str db "AuthenticAMD",0 +endg + +uglobal +align 16 + irq_tab rd 16 + + MEM_FreeSpace 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 + + fdd_buff rd 1 + LFBSize rd 1 + + stall_mcs rd 1 +;;CPUID information + + cpu_vendor rd 3 + cpu_sign rd 1 + cpu_info rd 1 + +;;;;; cursors data + +align 16 +cur_saved_data rb 4096 + +def_cursor rd 1 +hw_cursor rd 1 + +scr_width rd 1 +scr_height 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 + +endg + +uglobal +align 16 + fpu_data: + rb 512 + + mst MEM_STATE + + mem_block_map rb 512 + event_map rb 64 + mem_block_list rd 64 + mem_block_mask rd 2 + + srv.fd rd 1 + srv.bk 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 + + 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 rd 1 +endg + +if 0 + push eax + push edx + mov edx, 0x400 ;bocsh + mov al,0xff ;bocsh + out dx, al ;bocsh + pop edx + pop eax +end if + +align 4 +k_strrchr: + push eax + xor eax,eax + or ecx,-1 + repne scasb + add ecx,1 + neg ecx + sub edi,1 + pop eax + std + repne scasb + cld + add edi,1 + + cmp [edi],al + jne @F + mov eax,edi + ret +@@: + xor eax,eax + ret + +align 4 +proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword + mov eax, [dest] + mov esi, [src] + mov ecx, [maxlen] + test eax, eax + jz .L9 + test esi, esi + jz .L9 + test ecx, ecx + jz .L9 + + sub esi, eax + jmp .L1 + +align 4 +.L2: + mov edx, [esi+eax] + mov [eax], dl + test dl, dl + jz .L7 + + mov [eax+1], dh + test dh, dh + jz .L6 + + shr edx, 16 + mov [eax+2],dl + test dl, dl + jz .L5 + + mov [eax+3], dh + test dh, dh + jz .L4 + add eax, 4 +.L1: + sub ecx, 4 + jae .L2 + + add ecx, 4 + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + dec ecx + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + dec ecx + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + jmp .L9 + +.L4: dec ecx + inc eax + +.L5: dec ecx + inc eax + +.L6: dec ecx + inc eax +.L7: + add ecx,3 + jz .L9 +.L8: + mov byte [ecx+eax], 0 +.L3: + dec ecx + jnz .L8 +.L9: + ret +endp + +if 0 + +magic equ 0xfefefeff + +k_strlen: + mov eax,[esp+4] + mov edx, 3 + + and edx, eax + jz .L1 + jp .L0 + + cmp dh, byte [eax] + je .L2 + + inc eax + cmp dh, byte [eax] + + je .L2 + + inc eax + xor edx, 2 + + jz .L1 +.L0: + cmp dh, [eax] + je .L2 + + inc eax + xor edx, edx + +.L1: + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + dec edx + jnc .L3 + + xor edx, ecx + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + + and edx, not magic + je .L1 + +.L3: sub eax ,4 + sub ecx, magic + + cmp cl, 0 + jz .L2 + + inc eax + test ch, ch + jz .L2 + + shr ecx, 16 + inc eax + + cmp cl,0 + jz .L2 + + inc eax + +.L2: + sub eax, [esp+4] + ret + +end if diff --git a/kernel/branches/hd_kolibri/kernel/core/sched.inc b/kernel/branches/hd_kolibri/kernel/core/sched.inc new file mode 100644 index 0000000000..15cba6ea65 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/sched.inc @@ -0,0 +1,217 @@ +$Revision: 434 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; IRQ0 HANDLER (TIMER INTERRUPT) ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 32 +irq0: + save_ring3_context + mov ax, os_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 + + restore_ring3_context + iret + + .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: + restore_ring3_context + iret + + +align 4 +change_task: + + pushfd + cli + pushad + + call update_counters +; \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} + 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 + call _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 + push ebx + shl ebx, 8 + mov ebx, [SLOT_BASE + ebx + APPDATA.pl0_stack] + add ebx, RING0_STACK_SIZE + mov [CURRENT_RING0_ESP], ebx + pop ebx + + cmp al, 5 + jne .noevents + call get_event_for_app + test eax, eax + jz .waiting_for_event + mov [event_sched], eax + mov [edi+TASKDATA.state], byte 0 + .noevents: + .found: + mov [CURRENT_TASK],ebx + mov [TASK_BASE],edi + call _rdtsc + mov [edi+TASKDATA.counter_add],eax + + xor eax, eax + cmp ebx, [prev_slot] + sete al +ret + +; in: ebx = TSS selector index +do_change_task: + shl ebx, 3 + xor eax, eax + add ebx, tss0 + mov [far_jump.sel], bx ; selector + mov [far_jump.offs], eax ; offset + jmp pword [far_jump] + inc [context_counter] ;noname & halyavin +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 diff --git a/kernel/branches/hd_kolibri/kernel/core/sync.inc b/kernel/branches/hd_kolibri/kernel/core/sync.inc new file mode 100644 index 0000000000..4a1cc8285d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/sync.inc @@ -0,0 +1,117 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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/hd_kolibri/kernel/core/sys32.inc b/kernel/branches/hd_kolibri/kernel/core/sys32.inc new file mode 100644 index 0000000000..f4f685b8f0 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/sys32.inc @@ -0,0 +1,849 @@ +$Revision: 434 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +idtreg: + dw 8*0x41-1 + dd idts+8 + +build_process_gdt_tss_pointer: + + mov ecx,tss_data + mov edi,0 + setgdtl2: + mov [edi+gdts+ tss0 +0], word tss_step + mov [edi+gdts+ tss0 +2], cx + mov eax,ecx + shr eax,16 + mov [edi+gdts+ tss0 +4], al + mov [edi+gdts+ tss0 +7], ah + mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b + add ecx,tss_step + add edi,8 + cmp edi,8*(max_processes+5) + jbe setgdtl2 + + ret + +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 + 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, p_irq2 , p_irq3 ;irq_serv.irq_3 + dd p_irq4 ,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,p_irq12,irqD ,p_irq14,p_irq15 + + times 16 dd unknown_interrupt + + dd i40 +endg + +macro save_ring3_context +{ + push ds es + pushad +} +macro restore_ring3_context +{ + popad + pop es ds +} + +; 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, 1, 2, 3, 4, 5, 6, 9, 15, 18 +exc_w_code 8, 10, 11, 12, 13, 14, 17 + +exc_c: + mov ax, os_data + mov ds, ax + mov es, ax + +; test if debugging + cli + mov eax, [CURRENT_TASK] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + add esp, 28h + movzx eax, bl + mov [error_interrupt], eax + call show_error_parameters + + 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 + +writehex: + pusha + + mov edi, [write_error_to] + mov esi, 8 + @@: + mov ecx, eax + and ecx, 0xf + + mov cl,[ecx+hexletters] + mov [edi],cl + dec edi + + shr eax,4 + dec esi + jnz @b + + popa + ret + +iglobal + hexletters db '0123456789ABCDEF' + + error_interrupt dd -1 + + process_error db 'K : Process - forced terminate INT: 00000000',13,10,0 + process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0 + process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0 + system_error db 'K : Kernel error',13,10,0 +endg + +uglobal + write_error_to dd 0x0 +endg + +show_error_parameters: + + mov [write_error_to],process_pid+43 + mov eax,[CURRENT_TASK] + shl eax, 5 + mov eax,[CURRENT_TASK+TASKDATA.pid+eax] + call writehex + + mov [write_error_to],process_error+43 + mov eax,[error_interrupt] + call writehex + + cmp dword [esp+4+4], os_code ; CS + jnz @f + mov esi,system_error + call sys_msg_board_str + @@: + mov eax, [esp+4] ; EIP + + mov [write_error_to],process_eip+43 + call writehex + + mov esi,process_error + call sys_msg_board_str + + mov esi,process_pid + call sys_msg_board_str + + mov esi,process_eip + call sys_msg_board_str + + ret + + + +; irq1 -> hid/keyboard.inc + + +macro irqh [num] +{ + forward + p_irq#num : + save_ring3_context + mov edi, num + jmp irq_c +} + +irqh 2,5,7,8,9,10,11 + + irq_c: + mov ax, os_data + mov ds, ax + mov es, ax + call irqhandler + restore_ring3_context + iret + +p_irq6: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call fdc_irq + call ready_for_next_irq + restore_ring3_context + iret + +p_irq3: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + cmp [com2_mouse_detected],0 + je old_irq3_handler + call check_mouse_data_com2 + jmp p_irq3_1 + old_irq3_handler: + mov edi,3 + call irqhandler + p_irq3_1: + restore_ring3_context + iret + +p_irq4: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + cmp [com1_mouse_detected],0 + je old_irq4_handler + call check_mouse_data_com1 + jmp p_irq4_1 + old_irq4_handler: + mov edi,4 + call irqhandler + p_irq4_1: + restore_ring3_context + iret + +p_irq12: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call check_mouse_data_ps2 + restore_ring3_context + iret + +p_irq14: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call [irq14_func] + call ready_for_next_irq_1 + restore_ring3_context + iret +p_irq15: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + 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, 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: + + push edi + + mov esi,edi ; 1 + shl esi,6 ; 1 + add esi,irq00read ; 1 + shl edi,12 ; 1 + add edi,IRQ_SAVE + mov ecx,16 + + mov [check_idle_semaphore],5 + + irqnewread: + dec ecx + js irqover + + mov dx,[esi] ; 2+ + + cmp dx,0 ; 1 + jz irqover + cmp [esi+3],byte 1 ; 2 ; byte read + jne noirqbyte ; 4-11 + + in al,dx + + mov edx,[edi] + cmp edx,4000 + je irqfull + mov ebx,edi + add ebx,0x10 + add ebx,edx + mov [ebx],al + inc edx + mov [edi],edx + + add esi,4 + jmp irqnewread + + noirqbyte: + + + cmp [esi+3],byte 2 ; word read + jne noirqword + + in ax,dx + + mov edx,[edi] + cmp edx,4000 + je irqfull + mov ebx,edi + add ebx,0x10 + add ebx,edx + mov [ebx],ax + add edx,2 + mov [edi],edx + add esi,4 + jmp irqnewread + + noirqword: + irqfull: + irqover: + + mov al,0x20 ; ready for next irq + out 0x20,al + + pop ebx + cmp ebx,7 + jbe noa0 + out 0xa0,al + noa0: + + 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 + add esp, 4 + ret +@@: + mov esi,process_terminating + call sys_msg_board_str +@@: + cli + cmp [application_table_status],0 + je term9 + sti + call change_task + jmp @b +term9: + call set_application_table_status + + 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] + mov esi, msg_obj_destroy + call sys_msg_board_str + 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 + mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] + + stdcall kernel_free, ebx + + mov edi, [.slot] + shl edi,8 + add edi,SLOT_BASE + 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 + + pusha ; remove all irq reservations + mov eax,esi + shl eax, 5 + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] + mov edi,irq_owner + mov ecx,16 + newirqfree: + scasd + jne nofreeirq + mov [edi-4],dword 0 + nofreeirq: + loop 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, ebx + mov eax, 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 + 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 + call build_interrupt_table + + ret + diff --git a/kernel/branches/hd_kolibri/kernel/core/syscall.inc b/kernel/branches/hd_kolibri/kernel/core/syscall.inc new file mode 100644 index 0000000000..bc9631e580 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/syscall.inc @@ -0,0 +1,238 @@ +$Revision: 434 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSTEM CALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 32 +i40: +; diamond, 27.03.2007: handler does not require disabled interrupts +; so interrupts remain enabled when calling int 0x40 + push ds es + pushad + cld + + mov ax,word os_data + mov ds,ax + mov es,ax + + ; 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] + + ; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler +; sti + push eax + and edi,0xff + call dword [servetable+edi*4] + pop eax +; cli + + popad + pop es ds + iretd + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSENTER ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;uglobal +;times 100 db ? +;sysenter_stack: +;endg + +align 32 +SYSENTER_VAR equ 0 +sysenter_entry: + ; Ķąńņšąčāąåģ ńņåź + ; cli sysenter clear IF + ; push eax + ; mov eax, [ss:CURRENT_TASK] + ; shl eax, 8 + ; mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack] + ; lea esp, [eax + RING0_STACK_SIZE] ; configure ESP + ; mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + mov esp, [ss:CURRENT_RING0_ESP] + + sti + ;------------------ + push ds es + pushad + cld + + mov ax, word os_data + mov ds, ax + mov es, ax + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + mov edx, [SYSENTER_VAR] ; eip + mov ecx, [SYSENTER_VAR + 4] ; esp + sysexit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSCALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +syscall_entry: + + ; cli syscall clear IF + xchg esp, [ss:CURRENT_RING0_ESP] + push ecx + lea ecx, [esp+4] + xchg ecx, [ss:CURRENT_RING0_ESP] + sti + push ecx + mov ecx, [ecx] + + ; mov [ss:sysenter_stack - 4], eax + ; mov eax, [ss:CURRENT_TASK] + ; shl eax, 8 + ; mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack] + ; lea esp, [eax + RING0_STACK_SIZE] ; configure ESP + ; mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + + ;------------------ + push ds es + pushad + cld + + mov ax, word os_data + mov ds, ax + mov es, ax + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + + mov ecx, [ss:esp+4] + pop esp + sysret + +iglobal + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; SYSTEM FUNCTIONS TABLE ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + servetable: + + 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;undefined_syscall ; 19-reserved + dd sys_midi ; 20-ResetMidi and OutputMidi + dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. + dd sys_settime ; 22-setting date,time,clock and alarm-clock + dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent + dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd sys_sb16 ; 25-SetSb16 + dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. + dd undefined_syscall ; 27-reserved + dd sys_sb16II ; 28-SetSb16 + dd sys_date ; 29-GetDate + dd undefined_syscall ; 30-reserved + dd undefined_syscall ; 31-reserved + dd syscall_delramdiskfile ; 32-DelRamdiskFile + dd syscall_writeramdiskfile; 33-WriteRamdiskFile + dd undefined_syscall ; 34-reserved + dd syscall_getpixel ; 35-GetPixel + dd syscall_readstring ; 36-ReadString (not yet ready) + dd readmousepos ; 37-GetMousePosition_ScreenRelative,. + dd syscall_drawline ; 38-DrawLine + dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. + dd set_app_param ; 40-WantEvents + dd syscall_getirqowner ; 41-GetIrqOwner + dd get_irq_data ; 42-ReadIrqData + dd sys_outport ; 43-SendDeviceData + dd sys_programirq ; 44-ProgramIrqs + dd reserve_free_irq ; 45-ReserveIrq and FreeIrq + dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea + dd 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 user_events ; 54-User events + dd sound_interface ; 55-Sound interface + dd undefined_syscall ; 56-reserved + dd undefined_syscall ; 57-reserved + dd file_system ; 58-Common file system interface + dd undefined_syscall ; 59-reserved + 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 + + times 255 - ( ($-servetable) /4 ) dd undefined_syscall + + dd sys_end ; -1-end application +endg diff --git a/kernel/branches/hd_kolibri/kernel/core/sysfn.inc b/kernel/branches/hd_kolibri/kernel/core/sysfn.inc new file mode 100644 index 0000000000..2fe7aa5570 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/sysfn.inc @@ -0,0 +1,4012 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; KERNEL FUNCTIONS ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +reserve_irqs_ports: + + pushad + + mov [irq_owner+4*0],byte 1 ; timer + mov [irq_owner+4*1],byte 1 ; keyboard + mov [irq_owner+4*5],byte 1 ; sound blaster + mov [irq_owner+4*6],byte 1 ; floppy diskette + mov [irq_owner+4*13],byte 1 ; math co-pros + mov [irq_owner+4*14],byte 1 ; ide I + mov [irq_owner+4*15],byte 1 ; ide II +; movzx eax,byte [0xf604] ; mouse irq +; dec eax +; add eax,mouseirqtable +; movzx eax,byte [eax] +; shl eax,2 +; mov [irq_owner+eax],byte 1 + + + ; 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 + + +; cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff +; jne ripl1 +; inc dword [0x2d0000] +; mov edi,[0x2d0000] +; shl edi,4 +; mov [0x2d0000+edi+0],dword 1 +; mov [0x2d0000+edi+4],dword 0x3f0 +; mov [0x2d0000+edi+8],dword 0x3ff +; ripl1: +; cmp [0xf604],byte 3 ; com2 mouse -> 0x2f0-0x2ff +; jne ripl2 +; inc dword [0x2d0000] +; mov edi,[0x2d0000] +; shl edi,4 +; mov [0x2d0000+edi+0],dword 1 +; mov [0x2d0000+edi+4],dword 0x2f0 +; mov [0x2d0000+edi+8],dword 0x2ff +; ripl2: + + popad + ret + +iglobal +mouseirqtable db 12 ; ps2 + db 4 ; com1 + db 3 ; com2 +endg + +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,[0x2f0000+0x900c] + shr ax,1 + shl eax,16 + mov ax,[0x2f0000+0x900A] + shr ax,1 + mov [MOUSE_X],eax + pop eax + + mov byte [SB16_Status],0 ; Minazzi Paolo + mov [display_data-12],dword 1 ; tiled background + mov [BTN_ADDR],dword BUTTON_INFO ; address of button list + + ;!! IP 04.02.2005: + mov [next_usage_update], 100 + mov byte [0xFFFF], 0 ; change task if possible + + ret + +;* mouse centered - start code- Mario79 +mouse_centered: + push eax + mov eax,[ScreenWidth] + shr eax,1 + mov [MOUSE_X],ax + mov eax,[ScreenHeight] + 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 + + + +align 4 +sys_sb16: + + cmp word [sb16],word 0 + jnz sb16l1 + mov [esp+36],dword 1 + ret + sb16l1: + mov [esp+36],dword 0 + cmp eax,1 ; set volume - main + jnz sb16l2 + mov dx,word [sb16] + add dx,4 + mov al,0x22 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + inc edx + out dx,al + ret + sb16l2: + + cmp eax,2 ; set volume - cd + jnz sb16l3 + mov dx,word [sb16] + add dx,4 + mov al,0x28 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + add edx,1 + out dx,al + ret + sb16l3: + mov [esp+36],dword 2 + ret + + +align 4 + +sys_sb16II: + + cmp word [sb16],word 0 + jnz IIsb16l1 + mov [esp+36],dword 1 + ret + IIsb16l1: + + cmp eax,1 ; set volume - main + jnz IIsb16l2 + ; L + mov dx,word [sb16] + add dx,4 + mov al,0x30 + out dx,al + mov eax,ebx + inc edx + out dx,al + ; R + mov dx,word [sb16] + add dx,4 + mov al,0x31 + out dx,al + mov eax,ebx + inc edx + out dx,al + mov [esp+36],dword 0 + ret + IIsb16l2: + + cmp eax,2 ; set volume - cd + jnz IIsb16l3 + ; L + mov dx,word [sb16] + add dx,4 + mov al,0x36 + out dx,al + mov eax,ebx + inc edx + out dx,al + ; R + mov dx,word [sb16] + add dx,4 + mov al,0x37 + out dx,al + mov eax,ebx + inc edx + out dx,al + mov [esp+36],dword 0 + ret + IIsb16l3: + + mov [esp+36],dword 2 + 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: + + cmp eax,0xffff ; length > 0 ? + jge cont_displ + ret + cont_displ: + + cmp eax,61*0x10000 ; length <= 60 ? + jb cont_displ2 + ret + cont_displ2: + + pushad + + cmp al,1 ; ecx is a pointer ? + jne displnl1 + mov ebx,[ebx+std_application_base_address] + displnl1: + sub esp,64 + + cmp ah,0 ; DECIMAL + jne no_display_desnum + shr eax,16 + and eax,0x3f + push eax + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,10 + d_desnum: + xor edx,edx + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_desnum + pop eax + 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,0x3f + push eax + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,16 + d_hexnum: + xor edx,edx + div ebx + add edx,hexletters + mov dl,[edx] + mov [edi],dl + dec edi + loop d_hexnum + pop eax + 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,0x3f + push eax + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,2 + d_binnum: + xor edx,edx + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_binnum + pop eax + call draw_num_text + add esp,64 + popad + ret + no_display_binnum: + + add esp,64 + popad + ret + + +draw_num_text: + + ; dtext + ; + ; eax x & y + ; ebx color + ; ecx start of text + ; edx length + ; edi 1 force + +; mov edi,[CURRENT_TASK] +; shl edi,8 +; add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] +; rol eax,16 +; add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] +; rol eax,16 + + mov edx,eax + mov ecx,64+4 + sub ecx,eax + add ecx,esp + mov eax,[esp+64+32-8+4] + push edx ; add window start x & y + mov edx,[TASK_BASE] + mov ebx,[edx-twdw+WDATA.box.left] + add ebx, [(edx-CURRENT_TASK)*8+SLOT_BASE+APPDATA.wnd_clientbox.left] + shl ebx,16 + add ebx,[edx-twdw+WDATA.box.top] + add ebx, [(edx-CURRENT_TASK)*8+SLOT_BASE+APPDATA.wnd_clientbox.top] + add eax,ebx + pop edx + mov ebx,[esp+64+32-12+4] + and ebx, not 0x80000000 ; force counted string + mov esi, [esp+64+4+4] + mov edi, [esp+64+4] + jmp dtext + +read_string: + + ; eax read_area + ; ebx color of letter + ; ecx color of background + ; edx number of letters to read + ; esi [x start]*65536 + [y_start] + + ret + + +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 +; 4=sb16 base , base io address +; 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 nsyse3 + 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 + + nsyse3: + + cmp eax,4 ; SB + jnz nsyse4 + cmp ebx,0x100 + jb nsyse4 + mov edx,65535 + cmp edx,ebx + jb nsyse4 + mov word [sb16],bx + ret + 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,10 ; SOUND DMA CHANNEL + jne no_set_sound_dma + cmp ebx,3 + ja sys_setup_err + mov [sound_dma],ebx + ret + no_set_sound_dma: + + 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 +; 4=sb16 base , base io address +; 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,4 + jne ngsyse4 + mov eax,[sb16] + mov [esp+36],eax + ret + ngsyse4: + + 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,10 + jnz ngsyse10 + mov eax,[sound_dma] + mov [esp+36],eax + ret + ngsyse10: + 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 + +iglobal +align 4 +mousefn dd msscreen, mswin, msbutton, msset + dd app_load_cursor + dd app_set_cursor + dd app_delete_cursor +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 + + cmp eax, 6 + 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 +msset: + ret + +app_load_cursor: + add ebx, new_app_base + cmp ebx, new_app_base + jb 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' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +ret + + +sys_end: + + mov eax,[TASK_BASE] + mov [eax+TASKDATA.state], 3 ; terminate this program + + waitterm: ; wait here for termination + mov eax,5 + call delay_hs + jmp waitterm + +iglobal +align 4 +sys_system_table: + dd sysfn_shutdown ; 1 = system shutdown + 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_param ; 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 +sysfn_num = ($ - sys_system_table)/4 +endg + +sys_system: + dec eax + cmp eax, sysfn_num + jae @f + jmp dword [sys_system_table + eax*4] +@@: + ret + +sysfn_shutdown: ; 18.1 = BOOT + mov [0x2f0000+0x9030],byte 0 + for_shutdown_parameter: + + mov eax,[TASK_COUNT] + add eax,2 + mov [shutdown_processes],eax + mov [SYS_SHUTDOWN],al + and dword [esp+36], 0 + ret + uglobal + shutdown_processes: dd 0x0 + endg + +sysfn_terminate: ; 18.2 = TERMINATE + cmp ebx,2 + jb noprocessterminate + mov edx,[TASK_COUNT] + cmp ebx,edx + ja noprocessterminate + mov eax,[TASK_COUNT] + shl ebx,5 + mov edx,[ebx+CURRENT_TASK+TASKDATA.pid] + add ebx,CURRENT_TASK+TASKDATA.state + cmp byte [ebx], 9 + jz noprocessterminate + + ;call MEM_Heap_Lock ;guarantee that process isn't working with heap + mov [ebx],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,ebx + call pid_to_slot + test eax,eax + jz .not_found + mov ebx,eax + cli + call sysfn_terminate + mov [application_table_status],0 + sti + and dword [esp+36],0 + ret +.not_found: + mov [application_table_status],0 + or dword [esp+36],-1 + ret + +sysfn_activate: ; 18.3 = ACTIVATE WINDOW + cmp ebx,2 + jb .nowindowactivate + cmp ebx,[TASK_COUNT] + ja .nowindowactivate + + mov [window_minimize], 2 ; restore window if minimized + + movzx esi, word [WIN_STACK + ebx*2] + cmp esi, [TASK_COUNT] + je .nowindowactivate ; already active + + mov edi, ebx + shl edi, 5 + add edi, window_data + movzx esi, word [WIN_STACK + ebx * 2] + lea esi, [WIN_POS + esi * 2] + call waredraw +.nowindowactivate: + ret + +sysfn_getidletime: ; 18.4 = GET IDLETIME + mov eax,[idleusesec] + mov [esp+36], eax + ret + +sysfn_getcpuclock: ; 18.5 = GET TSC/SEC + mov eax,[CPU_FREQ] + mov [esp+36], 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+36],eax + ret + +sysfn_sound_flag: ; 18.8 = get/set sound_flag + cmp ebx,1 + jne nogetsoundflag + movzx eax,byte [sound_flag] ; get sound_flag + mov [esp+36],eax + ret + nogetsoundflag: + cmp ebx,2 + jnz nosoundflag + xor byte [sound_flag], 1 + nosoundflag: + ret + +sysfn_shutdown_param: ; 18.9 = system shutdown with param + cmp ebx,1 + jl exit_for_anyone + cmp ebx,4 + jg exit_for_anyone + mov [0x2f0000+0x9030],bl + jmp for_shutdown_parameter + +sysfn_minimize: ; 18.10 = minimize window + mov [window_minimize],1 + exit_for_anyone: + ret + +sysfn_getdiskinfo: ; 18.11 = get disk info table + cmp ebx,1 + jnz full_table + small_table: + call for_all_tables + mov ecx,10 + cld + rep movsb + ret + for_all_tables: + mov edi,[TASK_BASE] + mov edi,[edi+TASKDATA.mem_start] + add edi,ecx + mov esi,DRIVE_DATA + ret + full_table: + cmp ebx,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+36], 0 + ret + +sysfn_getversion: ; 18.13 = get kernel ID and version + mov edi,[TASK_BASE] + mov edi,[edi+TASKDATA.mem_start] + add edi,ebx + mov esi,version_inf + mov ecx,version_end-version_inf + cld + 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 + mov [esp+36],dword 0 + ret + +sysfn_centermouse: ; 18.15 = mouse centered + call mouse_centered + mov [esp+36],dword 0 + ret + +sysfn_mouse_acceleration: ; 18.19 = set/get mouse features + cmp ebx,0 ; get mouse speed factor + jnz .set_mouse_acceleration + xor eax,eax + mov ax,[mouse_speed_factor] + mov [esp+36],eax + ret + .set_mouse_acceleration: + cmp ebx,1 ; set mouse speed factor + jnz .get_mouse_delay + mov [mouse_speed_factor],cx + ret + .get_mouse_delay: + cmp ebx,2 ; get mouse delay + jnz .set_mouse_delay + mov eax,[mouse_delay] + mov [esp+36],eax + ret + .set_mouse_delay: + cmp ebx,3 ; set mouse delay + jnz .set_pointer_position + mov [mouse_delay],ecx + ret + .set_pointer_position: + cmp ebx,4 ; set mouse pointer position + jnz .end + mov [MOUSE_Y],cx ;y + ror ecx,16 + mov [MOUSE_X],cx ;x + rol ecx,16 + .end: + ret + +sysfn_getfreemem: + mov eax, [pg_data.pages_free] + shl eax, 2 + mov [esp+36],eax + ret + +sysfn_getallmem: + mov eax,[MEM_AMOUNT] + shr eax, 10 + mov [esp+36],eax + ret + +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,6,5,0 ; version 0.6.5.0 + db UID_KOLIBRI + db 'Kolibri',0 +version_end: +endg + +UID_NONE=0 +UID_MENUETOS=1 ;official +UID_KOLIBRI=2 ;russian + +sys_cachetodiskette: +; pushad +; cmp eax,1 +; jne no_write_all_of_ramdisk +; call fdc_writeramdisk +; popad +; ret +; no_write_all_of_ramdisk: +; cmp eax,2 +; jne no_write_part_of_ramdisk +; call fdc_commitflush +; popad +; ret +; no_write_part_of_ramdisk: +; cmp eax,3 +; jne no_set_fdc +; call fdc_set +; popad +; ret +; no_set_fdc: +; cmp eax,4 +; jne no_get_fdc +; popad +; call fdc_get +; mov [esp+36],ecx +; ret +; no_get_fdc: +; popad +; ret + cmp eax,1 + jne no_floppy_a_save + mov [flp_number],1 + jmp save_image_on_floppy + no_floppy_a_save: + cmp eax,2 + jne no_floppy_b_save + mov [flp_number],2 + save_image_on_floppy: + call save_image + mov [esp+36],dword 0 + cmp [FDC_Status],0 + je yes_floppy_save + no_floppy_b_save: + mov [esp+36],dword 1 + yes_floppy_save: + ret + +uglobal +; bgrchanged dd 0x0 +endg + +sys_background: + + cmp eax,1 ; BACKGROUND SIZE + jnz nosb1 + cmp ebx,0 + je sbgrr + cmp ecx,0 + je sbgrr + mov [display_data-8],ebx + mov [display_data-4],ecx +; mov [bgrchanged],1 + sbgrr: + ret + nosb1: + + cmp eax,2 ; SET PIXEL + jnz nosb2 + mov edx,0x160000-16 + cmp edx,ebx + jbe nosb2 + mov edx,[ebx] + and edx,0xFF000000 ;255*256*256*256 + and ecx,0x00FFFFFF ;255*256*256+255*256+255 + add edx,ecx + mov [ebx+IMG_BACKGROUND],edx +; mov [bgrchanged],1 + ret + nosb2: + + cmp eax,3 ; DRAW BACKGROUND + jnz nosb3 +draw_background_temp: +; cmp [bgrchanged],1 ;0 +; je nosb31 +;draw_background_temp: +; mov [bgrchanged],1 ;0 + mov [REDRAW_BACKGROUND],byte 1 + mov [background_defined], 1 + nosb31: + ret + nosb3: + + cmp eax,4 ; TILED / STRETCHED + jnz nosb4 + cmp ebx,[display_data-12] + je nosb41 + mov [display_data-12],ebx +; mov [bgrchanged],1 + nosb41: + ret + nosb4: + + cmp eax,5 ; BLOCK MOVE TO BGR + jnz nosb5 + ; bughere + mov edi, [TASK_BASE] + add ebx, [edi+TASKDATA.mem_start] + ; mov esi, ebx + ; mov edi, ecx + mov eax, ebx + mov ebx, ecx + add ecx, edx + cmp ecx, 0x160000-16 + ja .fin + ; add edi, 0x300000 + add ebx, IMG_BACKGROUND + mov ecx, edx + cmp ecx, 0x160000-16 + ja .fin +; mov [bgrchanged],1 + ; cld + ; rep movsb + call memmove + .fin: + ret + nosb5: + + ret + + +align 4 + +sys_getbackground: + + cmp eax,1 ; SIZE + jnz nogb1 + mov eax,[display_data-8] + shl eax,16 + mov ax,[display_data-4] + 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] + and eax, 0xFFFFFF + mov [esp+36],eax + ret + nogb2: + + cmp eax,4 ; TILED / STRETCHED + jnz nogb4 + mov eax,[display_data-12] + nogb4: + mov [esp+36],eax + ret + + +align 4 + +sys_getkey: + mov [esp+36],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 esi,0xf402 + ; mov edi,0xf401 + ; cld + ; rep movsb + mov eax, KEY_BUFF+1 + mov ebx, KEY_BUFF + call memmove + pop eax +.ret_eax: + mov [esp+36],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+36],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 + mov [BTN_COUNT],byte 0 + mov [esp+36],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 +; + + mov edi,[TASK_BASE] ; eax = return area + add eax,[edi + TASKDATA.mem_start] + + cmp ebx,-1 ; who am I ? + jne no_who_am_i + mov ebx,[CURRENT_TASK] + no_who_am_i: + + push eax ; return area + push ebx ; process number + + push ebx + push ebx + push eax + + ; return memory usage + + xor edx,edx + mov eax,0x20 + mul ebx + add eax,CURRENT_TASK+TASKDATA.cpu_usage + mov ebx,eax + pop eax + mov ecx,[ebx] + mov [eax],ecx + pop ebx + mov cx, [WIN_STACK + ebx * 2] + mov [eax+4],cx + mov cx, [WIN_POS + ebx * 2] + mov [eax+6],cx + push eax + mov eax,ebx + shl eax,8 + add eax,SLOT_BASE+APPDATA.app_name + pop ebx + add ebx,10 + mov ecx,11 + call memmove + + ; memory usage + + xor eax,eax + mov edx,0x100000*16 + pop ecx ; get gdt of tss + cmp ecx,1 + je os_mem + shl ecx,8 + mov edx,[SLOT_BASE+ecx+APPDATA.mem_size] ;0x8c + mov eax,std_application_base_address + ; eax run base -> edx used memory + os_mem: + dec edx + mov [ebx+12],eax + mov [ebx+16],edx + + ; PID (+30) + + mov eax,[esp] + shl eax,5 + add eax,CURRENT_TASK+TASKDATA.pid + mov eax,[eax] + mov [ebx+20],eax + + ; window position and size + + mov esi,[esp] + shl esi,5 + add esi,window_data + WDATA.box + mov edi,[esp+4] + add edi,34 + mov ecx,4 + cld + rep movsd + + ; Process state (+50) + + mov eax,[esp] + shl eax,5 + add eax,CURRENT_TASK+TASKDATA.state + mov eax,[eax] + mov [ebx+40],ax + + ; Window client area box + + mov esi,[esp] + shl esi,8 + add esi,SLOT_BASE+APPDATA.wnd_clientbox + lea edi,[ebx+44] + mov ecx,4 + rep movsd + + ; Window state + + mov esi,[esp] + shl esi,5 + add esi,window_data + WDATA.box + mov al,[esi+window_data+WDATA.fl_wstate] + mov [edi],al + + pop ebx + pop eax + + ; return number of processes + + mov eax,[TASK_COUNT] + mov [esp+36],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+36],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+36],ecx + ret + + +; redraw status + +sys_redrawstat: + + cmp eax,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 eax,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,[ScreenWidth] + mov [edx+RECT.right],eax + mov eax,[ScreenHeight] + 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 edi,ecx + shr edi,16+8 + and edi,15 + + cmp edi,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 edi,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 edi,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 edi,3 ; type IV - skinned window + jne nosyswIV + + ; parameter for drawwindow_IV + push 0 + mov edi, [TASK_COUNT] + movzx edi, word [WIN_POS + edi*2] + cmp edi, [CURRENT_TASK] + jne @f + inc dword [esp] + @@: + + inc [mouse_pause] + call [disable_mouse] + call sys_set_window + call [disable_mouse] + call drawwindow_IV + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswIV: + + 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 + jne .not_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 ecx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] + or ecx,ecx + jz @f + add ecx,[edi+twdw+TASKDATA.mem_start] + + movzx eax,[edi+window_data+WDATA.fl_wstyle] + and al,0x0F + cmp al,3 + jne .not_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] + cwde + cdq + mov ebx,6 + idiv ebx + or eax,eax + js @f + mov edx,eax + mov eax,dword[_skinmargins.left-2] + mov ax,word[_skinh] + sub ax,[_skinmargins.bottom] + sub ax,[_skinmargins.top] + sar ax,1 + adc ax,0 + add ax,[_skinmargins.top] + add ax,-3 + add eax,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 + cwde + cdq + mov ebx,6 + idiv ebx + or eax,eax + js @f + mov edx,eax + mov eax,0x00080007 + add eax,ebp +.dodraw: + mov ebx,[common_colours+16];0x00FFFFFF + or ebx, 0x80000000 + xor edi,edi + call dtext + + @@: +;-------------------------------------------------------------- + dec [mouse_pause] + call [draw_pointer] + ret + +iglobal +align 4 +window_topleft dd \ + 1, 21,\ + 0, 0,\ + 5, 20,\ + 5, ? +endg + +set_window_clientbox: + push eax ecx edi + + mov eax,[_skinh] + mov [window_topleft+4*7],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 edi,[CURRENT_TASK] + shl edi,5 + add edi,window_data + + ; colors + mov [edi+WDATA.cl_workarea],ecx + mov [edi+WDATA.cl_titlebar],edx + mov [edi+WDATA.cl_frames],esi + + ; check flag (?) + test [edi+WDATA.fl_wdrawn],1 + jnz newd + + push eax + mov eax,[timer_ticks] ;[0xfdf0] + add eax,100 + mov [new_window_starting],eax + pop eax + + mov word[edi+WDATA.box.width],ax + mov word[edi+WDATA.box.height],bx + sar eax,16 + sar ebx,16 + mov word[edi+WDATA.box.left],ax + mov word[edi+WDATA.box.top],bx + + 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] + + sub edi,window_data + shl edi,3 + add edi,SLOT_BASE + + and cl,0x0F + mov [edi+APPDATA.wnd_caption],0 + cmp cl,3 + jne @f + mov [edi+APPDATA.wnd_caption],esi + @@: mov esi,[esp+0] + + add edi, APPDATA.saved_box + movsd + movsd + movsd + movsd + pop edi esi ecx + + push eax ebx ecx edx +;;; mov eax, 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 + pop edx ecx ebx eax + + 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 + + mov ecx,10 ; wait 1/10 second + .wmrl3: + call [draw_pointer] + mov eax,1 + call delay_hs + loop .wmrl3 + + mov [window_move_pr],0 + + .window_move_return: + + ret + +;type_background_1: +; cmp [0xfff0],byte 0 ; background update ? +; jz temp_nobackgr +; mov [0xfff0],byte 2 +; call change_task +; mov [draw_data+32+0],dword 0 +; mov [draw_data+32+4],dword 0 +; mov eax,[ScreenWidth +; mov ebx,[0xfe04] +; mov [draw_data+32+8],eax +; mov [draw_data+32+12],ebx +; call drawbackground +; mov [0xfff0],byte 0 +; mov [MOUSE_BACKGROUND],byte 0 +;temp_nobackgr: +; 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 +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,[ScreenWidth] ; 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 + +uglobal + mouse_active db 0 +endg +iglobal + cpustring db '/hd0/1/kolibri/bin/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 ; SPraid 8.03.2007 + ;lea esi,[ebp+6] + ;xor ebx,ebx ; no parameters + ;xor edx,edx ; no flags + ;call fs_RamdiskExecute.flags + 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 00100000b + loop set_mouse_event + mouse_not_active: + + + cmp [REDRAW_BACKGROUND],byte 0 ; background update ? + jz nobackgr + cmp [background_defined], 0 + jz nobackgr + mov [REDRAW_BACKGROUND],byte 2 + call change_task + mov [draw_data+32 + RECT.left],dword 0 + mov [draw_data+32 + RECT.top],dword 0 + mov eax,[ScreenWidth] + mov ebx,[ScreenHeight] + 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] + sub dl,2 + + cmp [SYS_SHUTDOWN],dl + jne no_mark_system_shutdown + + mov edx,0x3040 + movzx ecx,byte [SYS_SHUTDOWN] + add ecx,5 + markz: + mov [edx+TASKDATA.state],byte 3 + add edx,0x20 + loop markz + + no_mark_system_shutdown: + + call [disable_mouse] + + dec byte [SYS_SHUTDOWN] + + cmp [SYS_SHUTDOWN],byte 0 + 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 eax,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 edi,esi + jz ricino + + 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 ecx,1 + jne nobgrd + cmp esi,1 + je newdw8 + call drawbackground + + 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 [display_data-8],dword 4 ; size x + mov [display_data-4],dword 2 ; size y + + mov edi, IMG_BACKGROUND ; set background to black + xor eax, eax + mov ecx, 0x0fff00 / 4 + cld + rep stosd + + mov edi,display_data ; set os to use all pixels + mov eax,0x01010101 + mov ecx,0x15ff00 / 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: + push edi + + mov edi,[TASK_BASE] + mov [edi+TASKDATA.event_mask],eax + + pop edi + ret + + + +delay_hs: ; delay in 1/100 secs + push eax + push ecx + push edx + + mov edx,[timer_ticks] + add edx,eax + + newtic: + mov ecx,[timer_ticks] + cmp edx,ecx + jbe zerodelay + + call change_task + + jmp newtic + + zerodelay: + pop edx + pop ecx + pop eax + + 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 edi,[TASK_BASE] + add eax,[edi+TASKDATA.mem_start] + + cmp ebx,16 + jae .not_owner + mov edi,[TASK_BASE] + mov edi,[edi+TASKDATA.pid] + cmp edi,[irq_owner+ebx*4] + je spril1 +.not_owner: + mov [esp+36],dword 1 + ret + spril1: + + mov esi,eax + shl ebx,6 + add ebx,irq00read + mov edi,ebx + mov ecx,16 + cld + rep movsd + mov [esp+36],dword 0 + ret + + +align 4 + +get_irq_data: + cmp eax,16 + jae .not_owner + mov edx,eax ; check for correct owner + shl edx,2 + add edx,irq_owner + mov edx,[edx] + mov edi,[TASK_BASE] + mov edi,[edi+TASKDATA.pid] + cmp edx,edi + je gidril1 +.not_owner: + mov [esp+32],dword 2 ; ecx=2 + ret + + gidril1: + + mov ebx,eax + shl ebx,12 + add ebx,IRQ_SAVE + mov eax,[ebx] + mov ecx,1 + test eax,eax + jz gid1 + + dec eax + mov esi,ebx + mov [ebx],eax + movzx ebx,byte [ebx+0x10] + add esi,0x10 + mov edi,esi + inc esi + mov ecx,4000 / 4 + cld + rep movsd +; xor ecx,ecx ; as result of 'rep' ecx=0 + gid1: + mov [esp+36],eax + mov [esp+32],ecx + mov [esp+24],ebx + ret + + +set_io_access_rights: + + pushad + + mov edi,[CURRENT_TASK] + imul edi,tss_step + add edi,tss_data+128 +; add edi,128 + + 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 + + popad + + ret + + siar1: + + 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: + + mov ecx, 1 + cmp ebx, 16 + jae fril1 + test eax,eax + jz reserve_irq + + lea edi,[irq_owner+ebx*4] + mov edx,[edi] + mov eax,[TASK_BASE] + cmp edx,[eax+TASKDATA.pid] + jne fril1 + dec ecx + mov [edi],ecx + fril1: + mov [esp+36],ecx ; return in eax + ret + + reserve_irq: + + lea edi,[irq_owner+ebx*4] + cmp dword [edi], 0 + jnz ril1 + + mov edx,[TASK_BASE] + mov edx,[edx+TASKDATA.pid] + mov [edi],edx + dec ecx + ril1: + mov [esp+36],ecx ; return in eax + ret + +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 [display_data-12],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 + + mov edx,ecx + mov ecx,ebx + lea ebx, [eax+std_application_base_address] + +sys_putimage: + test ecx,0x80008000 + jnz .exit + test ecx,0x0000FFFF + jz .exit + test ecx,0xFFFF0000 + jnz @f + .exit: + ret + @@: + mov edi,[CURRENT_TASK] + shl edi,8 + add dx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol edx,16 + add dx,word[edi+SLOT_BASE+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: + lea edi, [esi+std_application_base_address] + mov esi, edx + mov edx, ecx + mov ecx, ebx + lea ebx, [eax+std_application_base_address] +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_TASK] + shl esi,8 + add eax,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ecx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + add edx,[esi+SLOT_BASE+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 +; mov bl,0xa8 ; enable mouse cmd +; call kb_cmd +; call kb_read ; read status +; mov bl,0x20 ; get command byte +; call kb_cmd +; call kb_read +; or al,3 ; enable interrupt +; mov bl,0x60 ; write command +; push eax +; call kb_cmd +; pop eax +; call kb_write +; mov bl,0xd4 ; for mouse +; call kb_cmd +; mov al,0xf4 ; enable mouse device +; call kb_write +; call kb_read ; read status return + + ; com1 mouse enable + + mov bx,0x3f8 ; combase + + mov dx,bx + add dx,3 + mov al,0x80 + out dx,al + + mov dx,bx + add dx,1 + mov al,0 + out dx,al + + mov dx,bx + add dx,0 + mov al,0x30*2 ; 0x30 / 4 + out dx,al + + mov dx,bx + add dx,3 + mov al,2 ; 3 + out dx,al + + mov dx,bx + add dx,4 + mov al,0xb + out dx,al + + mov dx,bx + add dx,1 + mov al,1 + out dx,al + + + ; com2 mouse enable + + mov bx,0x2f8 ; combase + + mov dx,bx + add dx,3 + mov al,0x80 + out dx,al + + mov dx,bx + add dx,1 + mov al,0 + out dx,al + + mov dx,bx + add dx,0 + mov al,0x30*2 + out dx,al + + mov dx,bx + add dx,3 + mov al,2 + out dx,al + + mov dx,bx + add dx,4 + mov al,0xb + out dx,al + + mov dx,bx + add dx,1 + mov al,1 + out dx,al + + 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 + +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 edi, msg_board_data +; mov esi, msg_board_data+1 +; movzx eax, byte [edi] + mov eax, msg_board_data+1 + mov ebx, msg_board_data + movzx edx, byte [ebx] + call memmove +; push ecx +; shr ecx, 2 +; cld +; rep movsd +; pop ecx +; and ecx, 3 +; rep movsb + 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,[ScreenWidth] + shl eax,16 + mov ax,[ScreenHeight] + 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 edx,[TASK_BASE] + add eax,[edx-twdw+WDATA.box.left] + add ebx,[edx-twdw+WDATA.box.top] + mov edi,[CURRENT_TASK] + shl edi,8 + add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + xor edi,edi ; no force +; mov edi,1 + call [disable_mouse] + jmp [putpixel] + +align 4 + +syscall_writetext: ; WriteText + + mov edi,[TASK_BASE] + mov ebp,[edi-twdw+WDATA.box.left] + push esi + mov esi,[CURRENT_TASK] + shl esi,8 + add ebp,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + shl ebp,16 + add ebp,[edi-twdw+WDATA.box.top] + add bp,word[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + pop esi + add ecx,[edi+TASKDATA.mem_start] + add eax,ebp + xor edi,edi + jmp dtext + +align 4 + +syscall_openramdiskfile: ; OpenRamdiskFile + + + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add eax,[edi] + add edx,[edi] + mov esi,12 + call fileread + mov [esp+36],ebx + ret + +align 4 + +syscall_drawrect: ; DrawRect + + mov edi,ecx + and edi,0x80FFFFFF + test ax,ax + je drectr + test bx,bx + je drectr + movzx ecx,ax + shr eax,16 + movzx edx,bx + shr ebx,16 + mov esi,[CURRENT_TASK] + shl esi,8 + add eax,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + add ecx,eax + add edx,ebx + jmp [drawbar] + drectr: + ret + +align 4 + +syscall_getscreensize: ; GetScreenSize + + movzx eax,word[ScreenWidth] + shl eax,16 + mov ax,[ScreenHeight] + mov [esp+36],eax + ret + +align 4 + +syscall_cdaudio: ; CD + + call sys_cd_audio + mov [esp+36],eax + ret + +align 4 + +syscall_delramdiskfile: ; DelRamdiskFile + + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add eax,[edi] + call filedelete + mov [esp+36],eax + ret + +align 4 + +syscall_writeramdiskfile: ; WriteRamdiskFile + + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add eax,[edi] + add ebx,[edi] + call filesave + mov [esp+36],eax + ret + +align 4 + +syscall_getpixel: ; GetPixel + mov ecx,[ScreenWidth] + inc ecx + xor edx,edx + div ecx + mov ebx,edx + xchg eax,ebx + call dword [0xe024] + mov [esp+36],ecx + ret + +align 4 + +syscall_readstring: ; ReadString + + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add eax,[edi] + call read_string + mov [esp+36],eax + ret + +align 4 + +syscall_drawline: ; DrawLine + + mov edi,[TASK_BASE] + movzx edx,word[edi-twdw+WDATA.box.left] + mov ebp,edx + mov esi,[CURRENT_TASK] + shl esi,8 + add ebp,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add dx,word[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + shl edx,16 + add ebp,edx + movzx edx,word[edi-twdw+WDATA.box.top] + add eax,ebp + mov ebp,edx + add ebp,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + add dx,word[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + shl edx,16 + xor edi,edi + add edx,ebp + add ebx,edx + jmp [draw_line] + +align 4 + +syscall_getirqowner: ; GetIrqOwner + cmp eax,16 + jae .err + shl eax,2 + add eax,irq_owner + mov eax,[eax] + mov [esp+36],eax + ret +.err: + or dword [esp+36], -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 + +user_events: ; User event times + + mov eax,0x12345678 + mov [esp+36],eax + + 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 + +align 4 +paleholder: + 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 + +@@: call pword [apm_entry] ; call APM BIOS + 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+36],dword -1 + ret + + + diff --git a/kernel/branches/hd_kolibri/kernel/core/taskman.inc b/kernel/branches/hd_kolibri/kernel/core/taskman.inc new file mode 100644 index 0000000000..662c944257 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/taskman.inc @@ -0,0 +1,1133 @@ +$Revision: 437 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 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 +} + +virtual at 0 + TSS TSS +end virtual + +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 +} + + +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 [cmdline], ebx + mov [flags], edx + +; [ebp] pointer to filename + + lea eax, [filename] + mov dword [eax+1020],0 ;force terminate + ;string + stdcall k_strncpy, eax, [ebp], 1023 + + lea eax, [cmdline] + mov dword [eax+252], 0 + stdcall k_strncpy, eax, [cmdline], 255 + + lea eax, [filename] + stdcall load_file, eax + mov ecx, -ERROR_FILE_NOT_FOUND + test eax, eax + jz .err_file + + mov [file_base], eax + mov [file_size], ebx + + lea ebx, [hdr_cmdline] + call test_app_header + mov ecx, -0x1F + test eax, eax + jz .err_hdr + + mov esi, new_process_loading + call sys_msg_board_str ; write message to message board + +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + +; pushfd +; cli + + 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 edi, [filename] + mov al, '/' + call k_strrchr ; 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 + add edi, new_app_base + 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 esi, sys_pgdir + mov edi, [tmp_task_pdir] + mov ecx, (page_tabs shr 20)/4 + cld + rep movsd + + mov eax, [dir_addr] + or eax, PG_SW + stosd ; [(page_tabs shr 20)]= eax + + mov ecx, 0x800/4 + xor eax, eax + rep stosd + + mov eax, [dir_addr] + 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 +.reserve: + stosd + invlpg [edx] + add edx, 4096 + dec ecx + jnz .reserve +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 esi, [CURRENT_TASK] + mov ebx, esi + shl esi,8 + mov [SLOT_BASE+esi+0xB8],eax + imul ebx,tss_step + add ebx,tss_data + mov [ebx+28], 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 + 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] + add esi, 0x800 + mov edi, 0x800/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 + +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 + mov [r_count], ecx + 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 [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 + mov [w_count], ecx + 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 [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 +.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_TASK] + shl esi,8 + add esi,SLOT_BASE + 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 + + 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 + +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 + + mov esi, fpu_data + mov ecx, 512/4 + cld + 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 + + 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 don't need parameters + + mov eax, edx + add eax, 256 + jc @f + + cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] + ja @f + + add edx, new_app_base + stdcall k_strncpy, edx, [cmd_line], 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 + add edx, new_app_base + stdcall k_strncpy, edx, [app_path], 1024 +@@: + mov ebx,[slot] + mov eax,ebx + shl ebx,5 +; 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 + + mov ecx,ebx + add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data +;set draw data to full screen + + mov [ecx+0],dword 0 + mov [ecx+4],dword 0 + mov eax,[ScreenWidth] + mov [ecx+8],eax + mov eax,[ScreenHeight] + mov [ecx+12],eax + + mov edi,[slot] + imul edi,tss_step + add edi,tss_data + mov ecx,128/4 + xor eax, eax + cld + rep stosd +;Add IO access table - bit array of permitted ports + not eax + mov ecx,2048 + rep stosd ; access to 4096*8=65536 ports + sub edi, tss_step + +;set cr3 register in TSS of application + mov ecx, [slot] + shl ecx, 8 + mov eax,[SLOT_BASE+ecx+APPDATA.dir_table] + mov [edi+TSS._cr3],eax + + mov esi,[params] + mov eax, [esi+0x08] ;app_eip + mov [edi+TSS._eip],eax ;set eip in TSS + mov eax, [esi+0x0C] ;app_esp + mov [edi+TSS._esp],eax ;set stack in TSS + mov [edi+TSS._eflags],dword 0x1202 + + mov [edi+TSS._cs],app_code ;selector of code segment + mov [edi+TSS._ss],app_data + mov [edi+TSS._ds],app_data + mov [edi+TSS._es],app_data + mov [edi+TSS._fs],app_data + mov [edi+TSS._gs],graph_data ;selector of graphic segment + mov [edi+TSS._io],word 128 + mov [edi+TSS._ss0], os_data + mov ebx, [pl0_stack] + add ebx, RING0_STACK_SIZE + mov [edi+TSS._esp0],ebx + + mov ecx, edi ;ecx - address of application TSS + mov ebx,[slot] + shl ebx,3 +;set TSS descriptor + mov [ebx+gdts+tss0+0],word tss_step ;limit (size) + mov [ebx+gdts+tss0+2],cx ;part of offset + shr ecx,16 + mov [ebx+gdts+tss0+4],cl ;part of offset + mov [ebx+gdts+tss0+7],ch ;part of offset + mov [ebx+gdts+tss0+5],word 01010000b*256+11101001b ;system flags + +;flush keyboard and buttons queue + mov [KEY_COUNT],byte 0 + mov [BTN_COUNT],byte 0 + + mov edi,[slot] + shl edi,5 + add edi,window_data + mov ebx,[slot] + movzx esi,word [WIN_STACK+ebx*2] + lea esi,[WIN_POS+esi*2] + call windowactivate ;gui initialization + + mov ebx,[slot] + shl ebx,5 + mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running +; set if debuggee + mov eax, [flags] + test byte [flags], 1 + jz .no_debug + mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended + mov eax,[CURRENT_TASK] + mov [SLOT_BASE+ebx*8+0xac],eax ;set debugger PID - current +.no_debug: + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + ret +endp + + + +include "debug.inc" + +iglobal + 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 +endg + diff --git a/kernel/branches/hd_kolibri/kernel/core/vmodeint.inc b/kernel/branches/hd_kolibri/kernel/core/vmodeint.inc new file mode 100644 index 0000000000..9ee0e5c35c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/core/vmodeint.inc @@ -0,0 +1,55 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; 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 [ScreenWidth] [ScreenHeight] + popd [old_screen_height] [old_screen_width] + or eax,-1 ; If driver is absent then eax does not change + call 0x760100 ; 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,[ScreenWidth] + jnz @f + sub ebx,[ScreenHeight] + jz .resolution_wasnt_changed + jmp .lp1 + @@: sub ebx,[ScreenHeight] + .lp1: sub [screen_workarea.right],eax + sub [screen_workarea.bottom],ebx + + call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] + call calculatescreen + + .resolution_wasnt_changed: + ret + .no_vmode_drv_access: diff --git a/kernel/branches/hd_kolibri/kernel/docs/COPYING.TXT b/kernel/branches/hd_kolibri/kernel/docs/COPYING.TXT new file mode 100644 index 0000000000..f6213b69c6 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/docs/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/hd_kolibri/kernel/docs/apm.txt b/kernel/branches/hd_kolibri/kernel/docs/apm.txt new file mode 100644 index 0000000000..5b253195ed --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/docs/memmap.txt b/kernel/branches/hd_kolibri/kernel/docs/memmap.txt new file mode 100644 index 0000000000..ce9f14685a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/docs/memmap.txt @@ -0,0 +1,225 @@ +$Revision: 425 $ +; +; 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 +; +; Runtime: +; +; 0000 -> 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. +; +; 10000 -> 3DBFF kernel, 32-bit run-time code (up to 183 Kb) +; 3DC00 -> 3EBFF stack at boot time (4Kb) +; 3EC00 -> 3F5FF basic text font II +; 3F600 -> 3FFFF basic text font I +; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79) + +; 50000 -> 50FFF main page directory +; 50200 -> 5FFFF pages bitmap + +; 60000 -> 7FFFF free (128 Kb) +; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries +; +; 00 11db name of app running +; 10 108db floating point unit save area +; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore +; 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 +; +; 90000 -> 9FFFF tmp +; A0000 -> AFFFF screen access area +; B0000 -> FFFFF bios rest in peace -area +; 100000 -> 27FFFF diskette image +; 280000 -> 281FFF ramdisk fat +; 282000 -> 283FFF floppy fat +; +; 284000 -> 29FFFF free (112 Kb) +; +; 2A0000 -> 2B00ff wav device data +; 2C0000 -> 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 +; +; 2C4000 -> 2CFFFF free (48Kb) +; +; 2D0000 -> 2DFFFF reserved port area +; +; 0000 dword no of port areas reserved +; 0010 dword process id +; dword start port +; dword end port +; dword 0 +; +; 2E0000 -> 2EFFFF irq data area +; 2F0000 -> 2FFFFF low memory save +; +; 300000 -> 45FFFF background image, max 1,375 M +; +; 460000 -> 5FFFFF display info +; +; 600000 -> 6FFFFF hd cache +; +; 700000 -> 71ffff tcp memory (128 kb) +; 720000 -> 75ffff free (256 kb) +; +; 760000 -> 76ffff !vrr driver +; 770000 -> 777fff tcp memory ( 32 kb) +; +; 780000 -> 987FFF TSS and IO map for (8192*8)=65536 ports +; (128+8192)*256 = 2129920 = 0x208000 +; +; 988000 -> 98AFFF 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 +; +; +; 0x0098B000 -> kernel heap +; +; 0x01FFFFFF heap min limit +; 0x7DBFFFFF heap max limit +; 0x7DC00000 -> 0x7FBFFFFF LFB 32Mb +; 0x7DC00000 -> 0x7E3FFFFF application available LFB 8Mb +; 0x7E400000 -> 0x7FBFFFFF kernel LFB part 24 Mb +; 0x7FC00000 -> 0x7FFFFFFF page tables 4Mb +; 0x80000000 -> 0xFFFFFFFF application 2Gb + + + diff --git a/kernel/branches/hd_kolibri/kernel/docs/readme.txt b/kernel/branches/hd_kolibri/kernel/docs/readme.txt new file mode 100644 index 0000000000..ec023bd936 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/docs/readme.txt @@ -0,0 +1,53 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Copyright (C) KolibriOS team 2004-2007. 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 +;; +;; 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. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/docs/sysfuncr.txt b/kernel/branches/hd_kolibri/kernel/docs/sysfuncr.txt new file mode 100644 index 0000000000..63e5e24592 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/docs/sysfuncr.txt @@ -0,0 +1,4519 @@ +‘ˆ‘’…Œ›… ”“Š–ˆˆ Ž…€–ˆŽŽ‰ ‘ˆ‘’…Œ› Kolibri 0.6.5.0 + +®¬„ą äć­ŖęØØ Æ®¬„é „āįļ ¢ ą„£Øįāą eax. +‚ė§®¢ įØįā„¬­®© äć­ŖęØØ ®įćé„įā¢«ļ„āįļ Ŗ®¬ ­¤®© "int 0x40". +‚į„ ą„£Øįāąė, Ŗą®¬„ ļ¢­® ćŖ § ­­ėå ¢ ¢®§¢ą é „¬®¬ §­ ē„­ØØ, + ¢Ŗ«īē ļ ą„£Øįāą ä« £®¢ eflags, į®åą ­ļīāįļ. + + +====================================================================== +============== ”ć­ŖęØļ 0 - ®Æą„¤„«Øāģ Ø ­ ąØį®¢ āģ ®Ŗ­®. ============= +====================================================================== +ŽÆą„¤„«ļ„ā ®Ŗ­® ÆąØ«®¦„­Øļ. Øįć„ā ą ¬Ŗć ®Ŗ­ , § £®«®¢®Ŗ Ø ą ”®ēćī +®”« įāģ. „«ļ ®Ŗ®­ į® įŖØ­®¬ ®Æą„¤„«ļ„ā įā ­¤ ąā­ė„ Ŗ­®ÆŖØ § ŖąėāØļ Ø +¬Ø­Ø¬Ø§ ęØØ. + ą ¬„āąė: + * eax = 0 - ­®¬„ą äć­ŖęØØ + * ebx = [Ŗ®®ą¤Ø­ ā  Æ® ®įØ x]*65536 + [ą §¬„ą Æ® ®įØ x] + * ecx = [Ŗ®®ą¤Ø­ ā  Æ® ®įØ y]*65536 + [ą §¬„ą Æ® ®įØ y] + * edx = 0xXYRRGGBB, £¤„: + * Y = įāØ«ģ ®Ŗ­ : + * Y=0 - āØÆ I - ®Ŗ­® äØŖįØą®¢ ­­ėå ą §¬„ą®¢ + * Y=1 - ā®«ģŖ® ®Æą„¤„«Øāģ ®”« įāģ ®Ŗ­ , ­Øē„£® ­„ ąØį®¢ āģ + * Y=2 - āØÆ II - ®Ŗ­® ا¬„­ļ„¬ėå ą §¬„ą®¢ + * Y=3 - ®Ŗ­® į® įŖØ­®¬ + * ®įā «ģ­ė„ ¢®§¬®¦­ė„ §­ ē„­Øļ (®ā 4 ¤® 15) § ą„§„ą¢Øą®¢ ­ė, + ¢ė§®¢ äć­ŖęØØ į ā ŖØ¬Ø Y Ø£­®ąØąć„āįļ + * RR, GG, BB = į®®ā¢„āįā¢„­­® Ŗą į­ ļ, §„«„­ ļ, įØ­ļļ + į®įā ¢«ļīéØ„ ę¢„ā  ą ”®ē„© ®”« įāØ ®Ŗ­  + (Ø£­®ąØąć„āįļ ¤«ļ įāØ«ļ Y=2) + * X = DCBA (”Øāė) + * A = 1 - ć ®Ŗ­  „įāģ § £®«®¢®Ŗ; ¤«ļ įāØ«ļ Y=3  ¤ą„į įāą®ŖØ + § £®«®¢Ŗ  § ¤ ńāįļ ¢ 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 į § £®«®¢Ŗ®¬ (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 = ¢ėį®ā  ا®”ą ¦„­Øļ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * äć­ŖęØļ ­„ ¢®§¢ą é „ā §­ ē„­Øļ +‡ ¬„ē ­Øļ: + * ą®¢„ą®Ŗ ­  Ŗ®ąą„Ŗā­®įāģ ­„ ¤„« „āįļ. “įā ­®¢Ŗ  į«ØčŖ®¬ ”®«ģčØå + §­ ē„­Ø© ÆąØ¢„¤ńā Ŗ ā®¬ć, ēā® ¢ ä®­ ¢®©¤ćā ¤ ­­ė„ §  £ą ­Øę„© + ”ćä„ą  ä®­®¢®£® ا®”ą ¦„­Øļ.  §¬„ą ”ćä„ą  = 0x160000-0x10, ēā® + į®®ā¢„āįā¢ć„ā ¬ Ŗįج «ģ­ė¬ ą §¬„ą ¬ 800*600. (800*600*3=0x15F900) + * „«ļ ®”­®¢«„­Øļ ķŖą ­  (Æ®į«„ § ¢„ąč„­Øļ į„ąØØ Ŗ®¬ ­¤, ą ”®ā īéØå į + ä®­®¬) ¢ė§ė¢ ©ā„ Æ®¤äć­ŖęØī 3 Æ„ą„ąØį®¢ŖØ ä®­ . + * …įāģ Æ ą­ ļ äć­ŖęØļ Æ®«ćē„­Øļ ą §¬„ą®¢ ä®­®¢®£® ا®”ą ¦„­Øļ - + Æ®¤äć­ŖęØļ 1 äć­ŖęØØ 39. + +====================================================================== += ”ć­ŖęØļ 15, Æ®¤äć­ŖęØļ 2 - Æ®įā ¢Øāģ ā®ēŖć ­  ä®­®¢®¬ ا®”ą ¦„­ØØ. = +====================================================================== + ą ¬„āąė: + * eax = 15 - ­®¬„ą äć­ŖęØØ + * ebx = 2 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = į¬„é„­Ø„ + * edx = ę¢„ā ā®ēŖØ 0xRRGGBB +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * äć­ŖęØļ ­„ ¢®§¢ą é „ā §­ ē„­Øļ +‡ ¬„ē ­Øļ: + * ‘¬„é„­Ø„ ¤«ļ ā®ēŖØ į Ŗ®®ą¤Ø­ ā ¬Ø (x,y) ¢ėēØį«ļ„āįļ Ŗ Ŗ + (x+y*xsize)*3. + * …į«Ø ćŖ § ­­®„ į¬„é„­Ø„ Æą„¢ėč „ā 0x160000-16 = + 1.375 Mb - 16 bytes, ¢ė§®¢ Ø£­®ąØąć„āįļ. + * „«ļ ®”­®¢«„­Øļ ķŖą ­  (Æ®į«„ § ¢„ąč„­Øļ į„ąØØ Ŗ®¬ ­¤, ą ”®ā īéØå į + ä®­®¬) ¢ė§ė¢ ©ā„ Æ®¤äć­ŖęØī 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 * ēØį«® ÆØŖį„«„© +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * äć­ŖęØļ ­„ ¢®§¢ą é „ā §­ ē„­Øļ +‡ ¬„ē ­Øļ: + * …į«Ø ”«®Ŗ ¢ė«„§ „ā §  £ą ­Øęć 0x160000-16 = 1.375 Mb - 16 bytes, + ā® ¢ė§®¢ Ø£­®ąØąć„āįļ. + * –¢„ā Ŗ ¦¤®£® ÆØŖį„«ļ åą ­Øāįļ Ŗ Ŗ 3-” ©ā­ ļ ¢„«ØēØ­  BBGGRR. + * ØŖį„«Ø ä®­®¢®£® ا®”ą ¦„­Øļ § ÆØįė¢ īāįļ Æ®į«„¤®¢ ā„«ģ­® + į«„¢  ­ Æą ¢®, į¢„ąåć ¢­Ø§. + * ‘¬„é„­Ø„ ÆØŖį„«ļ į Ŗ®®ą¤Ø­ ā ¬Ø (x,y) „įāģ (x+y*xsize)*3. + * „«ļ ®”­®¢«„­Øļ ķŖą ­  (Æ®į«„ § ¢„ąč„­Øļ į„ąØØ Ŗ®¬ ­¤, ą ”®ā īéØå į + ä®­®¬) ¢ė§ė¢ ©ā„ Æ®¤äć­ŖęØī 3 Æ„ą„ąØį®¢ŖØ ä®­ . + +====================================================================== +============= ”ć­ŖęØļ 16 - į®åą ­Øāģ ą ¬¤ØįŖ ­  ¤ØįŖ„āć. ============= +====================================================================== + ą ¬„āąė: + * eax = 16 - ­®¬„ą äć­ŖęØØ + * ebx = 1 Ø«Ø ebx = 2 - ­  Ŗ Ŗćī ¤ØįŖ„āć į®åą ­ļāģ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * eax = 1 - ®čØ”Ŗ  + +====================================================================== +============== ”ć­ŖęØļ 17 - Æ®«ćēØāģ Ŗ®¤ ­ ¦ ā®© Ŗ­®ÆŖØ. ============= +====================================================================== +‡ ”Øą „ā Ŗ®¤ ­ ¦ ā®© Ŗ­®ÆŖØ Ø§ ”ćä„ą . + ą ¬„āąė: + * eax = 17 - ­®¬„ą äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * „į«Ø ”ćä„ą Æćįā, ¢®§¢ą é „āįļ eax=1 + * „į«Ø ”ćä„ą ­„Æćįā, ā® ¢®§¢ą é „āįļ al=0, įā ąčØ„ 24 ”Øā  eax + į®¤„ą¦ ā ؤ„­āØäØŖ ā®ą Ŗ­®ÆŖØ (¢ ē įā­®įāØ, ¢ ah ®Ŗ §ė¢ „āįļ + ¬« ¤čØ© ” ©ā ؤ„­āØäØŖ ā®ą ; „į«Ø ¢į„ Ŗ­®ÆŖØ Ø¬„īā ؤ„­āØäØŖ ā®ą, + ¬„­ģčØ© 256, ā® ¤«ļ ą §«Øē„­Øļ ¤®įā ā®ē­® ah) +‡ ¬„ē ­Øļ: + * "ćä„ą" åą ­Øā ā®«ģŖ® ®¤­ć Ŗ­®ÆŖć, ÆąØ ­ ¦ āØØ ­®¢®© Ŗ­®ÆŖØ + Ø­ä®ą¬ ęØļ ® įā ą®© ā„ąļ„āįļ. + * ąØ ¢ė§®¢„ ķā®© äć­ŖęØØ ÆąØ«®¦„­Ø„¬ į ­„ ŖāØ¢­ė¬ ®Ŗ­®¬ + ¢®§¢ą é „āįļ ®ā¢„ā "”ćä„ą Æćįā". + +====================================================================== +======== ”ć­ŖęØļ 18, Æ®¤äć­ŖęØļ 1 - § ¢„ąčØāģ ą ”®āć įØįā„¬ė. ======== +====================================================================== + ą ¬„āąė: + * eax = 18 - ­®¬„ą äć­ŖęØØ + * ebx = 1 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * ¢į„£¤  ¢®§¢ą é „āįļ eax = 0 Ŗ Ŗ ÆąØ§­ Ŗ ćįÆ„å  +‡ ¬„ē ­Øļ: + *   Æ®į«„¤­„¬ č £„ Æ®ļ¢«ļ„āįļ ¬„­ī ¢ė室  ا įØįā„¬ė, ®¦Ø¤ īé„„ + ą„ ŖęØØ Æ®«ģ§®¢ ā„«ļ. + * ‘¬®āąØ ā Ŗ¦„ Æ®¤äć­ŖęØī 9, § ¢„ąč„­Ø„ ą ”®āė įØįā„¬ė į Æ ą ¬„āą®¬, + ēā®”ė 䮹įØą®¢ āģ ¢ė”®ą ¢ ¬„­ī ¢ė室 . + +====================================================================== +==== ”ć­ŖęØļ 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 = Æ ą ¬„āą: + * 1 = ­  Æ®į«„¤­„¬ č £„ § ¢„ąč„­Øļ ą ”®āė į®åą ­Øāģ ą ¬¤ØįŖ ­  + ¤ØįŖ„āć, Æ®į«„ ē„£® ¢ė¢„įāØ ¬„­ī ¢ė室  Ø § Æą®įØāģ ć + Æ®«ģ§®¢ ā„«ļ ¤ «ģ­„©čØ„ ¤„©įā¢Øļ + * 2 = ¢ėŖ«īēØāģ Ŗ®¬Æģīā„ą + * 3 = Æ„ą„§ £ąć§Øāģ Ŗ®¬Æģīā„ą + * 4 = Æ„ą„§ ÆćįāØāģ ļ¤ą® ا ä ©«  kernel.mnt ­  ą ¬¤ØįŖ„ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * ÆąØ ­„¢„ą­®¬ ecx ą„£Øįāąė ­„ ¬„­ļīāįļ (ā.„. eax=18) + * ÆąØ Æą ¢Ø«ģ­®¬ ¢ė§®¢„ ¢į„£¤  ¢®§¢ą é „āįļ ÆąØ§­ Ŗ ćįÆ„å  eax=0 +‡ ¬„ē ­Øļ: + * „ į«„¤ć„ā Æ®« £ āģįļ ­  ¢®§¢ą é „¬®„ §­ ē„­Ø„ ÆąØ ­„¢„ą­®¬ + ¢ė§®¢„, ®­® ¬®¦„ā ا¬„­Øāģįļ ¢ Æ®į«„¤ćīéØå ¢„ąįØļå ļ¤ą . + * Œ®¦­® ØįÆ®«ģ§®¢ āģ Æ®¤äć­ŖęØī 1, ēā®”ė ­  Æ®į«„¤­„¬ č £„ + § ¢„ąč„­Øļ ą ”®āė Æ®«ģ§®¢ ā„«ģ į ¬ ą„č «, ēā® „¬ć ­ć¦­®. + * „ ą„Ŗ®¬„­¤ć„āįļ ØįÆ®«ģ§®¢ āģ §­ ē„­Ø„ ecx=1 (ēā®”ė ­„ ą §¤ą ¦ āģ + Æ®«ģ§®¢ ā„«ļ ا«Øč­Ø¬Ø ¢®Æą®į ¬Ø); į®åą ­Øāģ ą ¬¤ØįŖ ­  ¤ØįŖ„āć + ¬®¦­® äć­ŖęØ„© 16 (Ŗ®ā®ą ļ ¤®ÆćįŖ „ā ćā®ē­„­Ø„, ­  Ŗ Ŗćī ج„­­® + ¤ØįŖ„āć ÆØį āģ),   § ¢„ąčØāģ ą ”®āć į ¬„­ī ¢ė室  ¬®¦­® 榄 + ćÆ®¬ļ­ćā®© Æ®¤äć­ŖęØ„© 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 +db 'name',0 - ASCIIZ-įāą®Ŗ  į ج„­„¬ +„«ļ ļ¤ą  Kolibri 0.6.5.0: +db 0,6,5,0 +db 2 +db 'Kolibri',0 + +====================================================================== +====================== ”ć­ŖęØļ 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] +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * äć­ŖęØļ ­„ ¢®§¢ą é „ā §­ ē„­Øļ +‡ ¬„ē ­Øļ: + * „Ŗ®¬„­¤ć„¬ ļ įŖ®ą®įāģ ¬ėčØ (¢ Æ®¤Æ®¤äć­ŖęØØ 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: ą §¬„ą ­ Ø”®«ģč„£® ¢ė¤„«„­­®£® ”«®Ŗ  ¢ Ŗćē„ ļ¤ą  + (§ ą„§„ą¢Øą®¢ ­®) + +====================================================================== +==================== ”ć­ŖęØļ 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. = +====================================================================== + ą ¬„āąė: + * eax = 21 - ­®¬„ą äć­ŖęØØ + * ebx = 4 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = ­®¬„ą ” §®¢®£® Æ®ąā  +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * eax = -1 - ®čØ”®ē­ė© ­®¬„ą Æ®ąā  +‡ ¬„ē ­Øļ: + * ®¬„ą Æ®ąā  ¤®«¦„­ 椮¢«„ā¢®ąļāģ ćį«®¢Øļ¬ 0x100<=ecx<=0xFFFF. + * “įā ­®¢Ŗ  ” §ė ­ć¦­  ¤«ļ ą ”®āė äć­ŖęØ© 25, 28, 55. + * ®«ćēØāģ ćįā ­®¢«„­­ė© ” §®¢ė© Æ®ąā ¬®¦­® ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 4 äć­ŖęØØ 26. + +====================================================================== +========= ”ć­ŖęØļ 21, Æ®¤äć­ŖęØļ 5 - ćįā ­®¢Øāģ ļ§ėŖ įØįā„¬ė. ======== +====================================================================== + ą ¬„āąė: + * eax = 21 - ­®¬„ą äć­ŖęØØ + * ebx = 5 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = ļ§ėŖ įØįā„¬ė (1=eng, 2=fi, 3=ger, 4=rus) +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 +‡ ¬„ē ­Øļ: + * Ÿ§ėŖ įØįā„¬ė - £«®” «ģ­ ļ įØįā„¬­ ļ Æ„ą„¬„­­ ļ, ­ØŖ Ŗ + ­„ ØįÆ®«ģ§ć„¬ ļ į ¬Ø¬ ļ¤ą®¬, ®¤­ Ŗ® ÆąØ«®¦„­Ø„ @panel ąØįć„ā + į®®ā¢„āįā¢ćīéćī ØŖ®­Ŗć. + * ą®¢„ą®Ŗ ­  Ŗ®ąą„Ŗā­®įāģ ­„ ¤„« „āįļ, Æ®įŖ®«ģŖć ļ¤ą® ķāć + Æ„ą„¬„­­ćī ­„ ØįÆ®«ģ§ć„ā. + * ®«ćēØāģ ļ§ėŖ įØįā„¬ė ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 5 äć­ŖęØØ 26. + +====================================================================== +=========== ”ć­ŖęØļ 21, Æ®¤äć­ŖęØļ 7 - ćįā ­®¢Øāģ ” §ć HD. =========== +====================================================================== + §  HD ­ć¦­  ¤«ļ ®Æą„¤„«„­Øļ, ­  Ŗ Ŗ®© ¦ńįāŖØ© ¤ØįŖ ÆØį āģ, ÆąØ +ØįÆ®«ģ§®¢ ­ØØ ćįā ą„¢č„£® įØ­ā ŖįØį  /HD ¢ ćįā ą„¢č„© äć­ŖęØØ 58; +ÆąØ ØįÆ®«ģ§®¢ ­ØØ į®¢ą„¬„­­®£® įØ­ā ŖįØį  /HD0,/HD1,/HD2,/HD3 +” §  ćįā ­ ¢«Ø¢ „āįļ  ¢ā®¬ āØē„įŖØ. + ą ¬„āąė: + * eax = 21 - ­®¬„ą äć­ŖęØØ + * ebx = 7 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = ” §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 +‡ ¬„ē ­Øļ: + * ‹ī”®„ ÆąØ«®¦„­Ø„ ¢ «ī”®© ¬®¬„­ā ¢ą„¬„­Ø ¬®¦„ā ا¬„­Øāģ ” §ć. + * „ į«„¤ć„ā ا¬„­ļāģ ” §ć, Ŗ®£¤  Ŗ Ŗ®„-­Ø”ć¤ģ ÆąØ«®¦„­Ø„ ą ”®ā „ā + į ¦ńįāŖج ¤ØįŖ®¬. …į«Ø ­„ å®āØā„ £«īŖ®¢ įØįā„¬ė. + * ®«ćēØāģ ćįā ­®¢«„­­ćī ” §ć ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 7 äć­ŖęØØ 26. + * ‘«„¤ć„ā ā Ŗ¦„ ®Æą„¤„«Øāģ ØįÆ®«ģ§ć„¬ė© ą §¤„« ¦ńįāŖ®£® ¤ØįŖ  + Æ®¤äć­ŖęØ„© 8. + +====================================================================== +========== ”ć­ŖęØļ 21, Æ®¤äć­ŖęØļ 8 - ćįā ­®¢Øāģ ą §¤„« HD. ========== +====================================================================== + §¤„« HD ­ć¦„­ ¤«ļ ®Æą„¤„«„­Øļ, ­  Ŗ Ŗ®© ą §¤„« ¦ńįāŖ®£® ¤ØįŖ  +ÆØį āģ, ÆąØ ØįÆ®«ģ§®¢ ­ØØ ćįā ą„¢č„£® įØ­ā ŖįØį  /HD ¢ ćįā ą„¢č„© +äć­ŖęØØ 58; ÆąØ ØįÆ®«ģ§®¢ ­ØØ į®¢ą„¬„­­®£® įØ­ā ŖįØį  +/HD0,/HD1,/HD2,/HD3 ” §  Ø ą §¤„« ćįā ­ ¢«Ø¢ īāįļ  ¢ā®¬ āØē„įŖØ. + ą ¬„āąė: + * eax = 21 - ­®¬„ą äć­ŖęØØ + * ebx = 8 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = ą §¤„« HD (įēØā ļ į 1) +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 +‡ ¬„ē ­Øļ: + * ‹ī”®„ ÆąØ«®¦„­Ø„ ¢ «ī”®© ¬®¬„­ā ¢ą„¬„­Ø ¬®¦„ā ا¬„­Øāģ ą §¤„«. + * „ į«„¤ć„ā ا¬„­ļāģ ą §¤„«, Ŗ®£¤  Ŗ Ŗ®„-­Ø”ć¤ģ ÆąØ«®¦„­Ø„ ą ”®ā „ā + į ¦ńįāŖج ¤ØįŖ®¬. …į«Ø ­„ å®āØā„ £«īŖ®¢ įØįā„¬ė. + * ®«ćēØāģ ćįā ­®¢«„­­ė© ą §¤„« ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 8 + äć­ŖęØØ 26. + * ą®¢„ą®Ŗ ­  Ŗ®ąą„Ŗā­®įāģ ­„ ¤„« „āįļ. + * “§­ āģ ēØį«® ą §¤„«®¢ ­  ¦ńįāŖ®¬ ¤ØįŖ„ ¬®¦­® ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 11 äć­ŖęØØ 18. + * ‘«„¤ć„ā ā Ŗ¦„ ®Æą„¤„«Øāģ ØįÆ®«ģ§ć„¬ćī ” §ć ¦ńįāŖ®£® ¤ØįŖ  + Æ®¤äć­ŖęØ„© 7. + +====================================================================== +===== ”ć­ŖęØļ 21, Æ®¤äć­ŖęØļ 10 - ćįā ­®¢Øāģ Ŗ ­ « DMA ¤«ļ §¢ćŖ . ==== +====================================================================== + ą ¬„āąė: + * eax = 21 - ­®¬„ą äć­ŖęØØ + * ebx = 10 - ­®¬„ą Æ®¤äć­ŖęØØ + * ecx = ­®¬„ą Ŗ ­ «  (®ā 0 ¤® 3 ¢Ŗ«īēØā„«ģ­®) +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * eax = -1 - ­„¢„ą­ė© ­®¬„ą Ŗ ­ «  +‡ ¬„ē ­Øļ: + * ®¬„ą Ŗ ­ «  DMA ØįÆ®«ģ§ć„āįļ ¢ + Æ®¤äć­ŖęØØ 1 äć­ŖęØØ 55. + * ®«ćēØāģ Ŗ ­ « DMA ¤«ļ §¢ćŖ  ¬®¦­® ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 10 äć­ŖęØØ 26. + +====================================================================== +====================== ”ć­ŖęØļ 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. + +====================================================================== +============== ”ć­ŖęØļ 25 - ćįā ­®¢Øāģ £ą®¬Ŗ®įāģ SBPro. ============== +====================================================================== + ą ¬„āąė: + * eax = 25 - ­®¬„ą äć­ŖęØØ + * ebx = ēā® ćįā ­ ¢«Ø¢ āģ: + * 1 - ćįā ­®¢Øāģ ®”éćī £ą®¬Ŗ®įāģ + * 2 - ćįā ­®¢Øāģ £ą®¬Ŗ®įāģ CD-audio + * cl = ćą®¢„­ģ £ą®¬Ŗ®įāØ: įā ąčØ„ 4 ”Øā  ¤«ļ «„¢®© Ŗ®«®­ŖØ, + ¬« ¤čØ„ 4 - ¤«ļ Æą ¢®© +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * eax = 1 - ­„ ®Æą„¤„«„­  ” §  SB + * eax = 2 - ­„¢„ą­ ļ Æ®¤äć­ŖęØļ +‡ ¬„ē ­Øļ: + * ą„¤¢ ąØā„«ģ­® ­ć¦­® ®Æą„¤„«Øāģ ” §®¢ė© Æ®ąā SB ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 4 äć­ŖęØØ 21. + * ‘¬®āąØ ā Ŗ¦„ äć­ŖęØī 28 + ćįā ­®¢ŖØ §¢ćŖ  ¤«ļ ”®«„„ Æ®§¤­„£® įā ­¤ ąā  SB16. + +====================================================================== +===== ”ć­ŖęØļ 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. == +====================================================================== + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 4 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ­®¬„ą ” §®¢®£® Æ®ąā  +‡ ¬„ē ­Øļ: + * “įā ­®¢Ŗ  ” §ė ­ć¦­  ¤«ļ ą ”®āė äć­ŖęØ© 25, 55. + * “įā ­®¢Øāģ ” §®¢ė© Æ®ąā ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 4 äć­ŖęØØ 21. + +====================================================================== +========== ”ć­ŖęØļ 26, Æ®¤äć­ŖęØļ 5 - Æ®«ćēØāģ ļ§ėŖ įØįā„¬ė. ========= +====================================================================== + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 5 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ļ§ėŖ įØįā„¬ė (1=eng, 2=fi, 3=ger, 4=rus) +‡ ¬„ē ­Øļ: + * Ÿ§ėŖ įØįā„¬ė - £«®” «ģ­ ļ įØįā„¬­ ļ Æ„ą„¬„­­ ļ, ­ØŖ Ŗ + ­„ ØįÆ®«ģ§ć„¬ ļ į ¬Ø¬ ļ¤ą®¬, ®¤­ Ŗ® ÆąØ«®¦„­Ø„ @panel ąØįć„ā + į®®ā¢„āįā¢ćīéćī ØŖ®­Ŗć (ØįÆ®«ģ§ćļ ®ÆØįė¢ „¬ćī äć­ŖęØī). + * “įā ­®¢Øāģ ļ§ėŖ įØįā„¬ė ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 5 äć­ŖęØØ 21. + +====================================================================== +============ ”ć­ŖęØļ 26, Æ®¤äć­ŖęØļ 7 - Æ®«ćēØāģ ” §ć HD. ============ +====================================================================== + §  HD ­ć¦­  ¤«ļ ®Æą„¤„«„­Øļ, ­  Ŗ Ŗ®© ¦ńįāŖØ© ¤ØįŖ ÆØį āģ, ÆąØ +ØįÆ®«ģ§®¢ ­ØØ ćįā ą„¢č„£® įØ­ā ŖįØį  /HD ¢ ćįā ą„¢č„© äć­ŖęØØ 58; +ÆąØ ØįÆ®«ģ§®¢ ­ØØ į®¢ą„¬„­­®£® įØ­ā ŖįØį  /HD0,/HD1,/HD2,/HD3 +” §  ćįā ­ ¢«Ø¢ „āįļ  ¢ā®¬ āØē„įŖØ. + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 7 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ” §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‡ ¬„ē ­Øļ: + * ‹ī”®„ ÆąØ«®¦„­Ø„ ¢ «ī”®© ¬®¬„­ā ¢ą„¬„­Ø ¬®¦„ā ا¬„­Øāģ ” §ć. + * “įā ­®¢Øāģ ” §ć ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 7 äć­ŖęØØ 21. + * ®«ćēØāģ ØįÆ®«ģ§ć„¬ė© ą §¤„« ¦ńįāŖ®£® ¤ØįŖ  ¬®¦­® Æ®¤äć­ŖęØ„© 8. + +====================================================================== +=========== ”ć­ŖęØļ 26, Æ®¤äć­ŖęØļ 8 - Æ®«ćēØāģ ą §¤„« HD. =========== +====================================================================== + §¤„« HD ­ć¦„­ ¤«ļ ®Æą„¤„«„­Øļ, ­  Ŗ Ŗ®© ą §¤„« ¦ńįāŖ®£® ¤ØįŖ  +ÆØį āģ, ÆąØ ØįÆ®«ģ§®¢ ­ØØ ćįā ą„¢č„£® įØ­ā ŖįØį  /HD ¢ ćįā ą„¢č„© +äć­ŖęØØ 58; ÆąØ ØįÆ®«ģ§®¢ ­ØØ į®¢ą„¬„­­®£® įØ­ā ŖįØį  +/HD0,/HD1,/HD2,/HD3 ” §  Ø ą §¤„« ćįā ­ ¢«Ø¢ īāįļ  ¢ā®¬ āØē„įŖØ. + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 8 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ą §¤„« HD (įēØā ļ į 1) +‡ ¬„ē ­Øļ: + * ‹ī”®„ ÆąØ«®¦„­Ø„ ¢ «ī”®© ¬®¬„­ā ¢ą„¬„­Ø ¬®¦„ā ا¬„­Øāģ ą §¤„«. + * “įā ­®¢Øāģ ą §¤„« ¬®¦­® ¢ė§®¢®¬ Æ®¤äć­ŖęØØ 8 äć­ŖęØØ 21. + * “§­ āģ ēØį«® ą §¤„«®¢ ­  ¦ńįāŖ®¬ ¤ØįŖ„ ¬®¦­® ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 11 äć­ŖęØØ 18. + * ®«ćēØāģ ØįÆ®«ģ§ć„¬ćī ” §ć ¦ńįāŖ®£® ¤ØįŖ  ¬®¦­® Æ®¤äć­ŖęØ„© 7. + +====================================================================== +=== ”ć­ŖęØļ 26, Æ®¤äć­ŖęØļ 9 - Æ®«ćēØāģ §­ ē„­Ø„ įēńāēØŖ  ¢ą„¬„­Ø. === +====================================================================== + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 9 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ēØį«® į®āėå ¤®«„© į„Ŗć­¤ė, Æą®č„¤čØå į ¬®¬„­ā  + § ÆćįŖ  įØįā„¬ė +‡ ¬„ē ­Øļ: + * ‘ēńāēØŖ ”„ąńāįļ Æ® ¬®¤ć«ī 2^32, ēā® į®®ā¢„āįā¢ć„ā ­„¬­®£Ø¬ ”®«„„ + 497 įćā®Ŗ. + * ‘Øįā„¬­®„ ¢ą„¬ļ ¬®¦­® Æ®«ćēØāģ äć­ŖęØ„© 3. + +====================================================================== +====== ”ć­ŖęØļ 26, Æ®¤äć­ŖęØļ 10 - Æ®«ćēØāģ Ŗ ­ « DMA ¤«ļ §¢ćŖ . ===== +====================================================================== + ą ¬„āąė: + * eax = 26 - ­®¬„ą äć­ŖęØØ + * ebx = 10 - ­®¬„ą Æ®¤äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ­®¬„ą Ŗ ­ «  (®ā 0 ¤® 3 ¢Ŗ«īēØā„«ģ­®) +‡ ¬„ē ­Øļ: + * ®¬„ą Ŗ ­ «  DMA ØįÆ®«ģ§ć„āįļ ¢ Æ®¤äć­ŖęØØ 1 äć­ŖęØØ 55. + * “įā ­®¢Øāģ Ŗ ­ « DMA ¤«ļ §¢ćŖ  ¬®¦­® ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 10 äć­ŖęØØ 21. + +====================================================================== +====================== ”ć­ŖęØļ 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. ============== +====================================================================== + ą ¬„āąė: + * eax = 28 - ­®¬„ą äć­ŖęØØ + * ebx = ēā® ćįā ­ ¢«Ø¢ āģ: + * 1 - ćįā ­®¢Øāģ ®”éćī £ą®¬Ŗ®įāģ + * 2 - ćįā ­®¢Øāģ £ą®¬Ŗ®įāģ CD-audio + * cl = ćą®¢„­ģ £ą®¬Ŗ®įāØ (0=off, 0xFF=max) +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * eax = 1 - ­„ ®Æą„¤„«„­  ” §  SB + * eax = 2 - ­„¢„ą­ ļ Æ®¤äć­ŖęØļ +‡ ¬„ē ­Øļ: + * ą„¤¢ ąØā„«ģ­® ­ć¦­® ®Æą„¤„«Øāģ ” §®¢ė© Æ®ąā SB ¢ė§®¢®¬ + Æ®¤äć­ŖęØØ 4 äć­ŖęØØ 21. + * ā  äć­ŖęØļ Æą„¤®įā ¢«ļ„ā ”®«ģč„ ¢ ąØ ­ā®¢ ¤«ļ £ą®¬Ŗ®įāØ, + ē„¬ äć­ŖęØļ 25. + +====================================================================== +================ ”ć­ŖęØļ 29 - Æ®«ćēØāģ įØįā„¬­ćī ¤ āć. =============== +====================================================================== + ą ¬„āąė: + * eax = 29 - ­®¬„ą äć­ŖęØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0x00DDMMYY, £¤„ + (ØįÆ®«ģ§ć„āįļ ¤¢®Øē­®-¤„įļāØē­®„ Ŗ®¤Øą®¢ ­Ø„, BCD) + * YY = ¤¢„ ¬« ¤čØ„ ęØäąė £®¤  (00..99) + * MM = ¬„įļę (01..12) + * DD = ¤„­ģ (01..31) +‡ ¬„ē ­Øļ: + * ‘Øįā„¬­ćī ¤ āć ¬®¦­® ćįā ­®¢Øāģ äć­ŖęØ„© 22. + +====================================================================== +================ ”ć­ŖęØļ 32 - 椠«Øāģ ä ©« į ą ¬¤ØįŖ . =============== +====================================================================== + ą ¬„āąė: + * eax = 32 - ­®¬„ą äć­ŖęØØ + * ebx = ćŖ § ā„«ģ ­  جļ ä ©«  +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­®; Ø­ ē„ Ŗ®¤ ®čØ”ŖØ ä ©«®¢®© įØįā„¬ė +‡ ¬„ē ­Øļ: + * ā  äć­ŖęØļ ćįā ą„« ; äć­ŖęØļ 58 Æ®§¢®«ļ„ā ¢ėÆ®«­ļāģ + ā„ ¦„ ¤„©įā¢Øļ į ą įčØą„­­ė¬Ø ¢®§¬®¦­®įāļ¬Ø. + * ’„Ŗćé ļ ą„ «Ø§ ęØļ ¢®§¢ą é „ā ā®«ģŖ® §­ ē„­Øļ 0(ćįÆ„å) Ø + 5(ä ©« ­„ ­ ©¤„­). + * ˆ¬ļ ä ©«  ¤®«¦­® ”ėāģ «Ø”® ¢ 䮹¬ ā„ 8+3 įج¢®«®¢ (Æ„ą¢ė„ + 8 įج¢®«®¢ - į®”įā¢„­­® جļ, Æ®į«„¤­Ø„ 3 - ą įčØą„­Ø„, + Ŗ®ą®āŖØ„ ج„­  Ø ą įčØą„­Øļ ¤®Æ®«­ļīāįļ Æą®”„« ¬Ø), + «Ø”® ¢ 䮹¬ ā„ 8.3 įج¢®«®¢ "FILE.EXT"/"FILE.EX " + (جļ ­„ ”®«„„ 8 įج¢®«®¢, ā®ēŖ , ą įčØą„­Ø„ 3 įج¢®« , + ¤®Æ®«­„­­®„ ÆąØ ­„®”室ج®įāØ Æą®”„« ¬Ø). + ˆ¬ļ ä ©«  ¤®«¦­® ”ėāģ § ÆØį ­® § £« ¢­ė¬Ø ”ćŖ¢ ¬Ø. + ‡ ¢„ąč īéØ© įج¢®« į Ŗ®¤®¬ 0 ­„ ­ć¦„­ (­„ ASCIIZ-įāą®Ŗ ). + * ā  äć­ŖęØļ ­„ Æ®¤¤„ą¦Ø¢ „ā Æ Æ®Ŗ ­  ą ¬¤ØįŖ„. + +====================================================================== +=============== ”ć­ŖęØļ 33 - § ÆØį āģ ä ©« ­  ą ¬¤ØįŖ. =============== +====================================================================== + ą ¬„āąė: + * eax = 33 - ­®¬„ą äć­ŖęØØ + * ebx = ćŖ § ā„«ģ ­  جļ ä ©«  + * ecx = ćŖ § ā„«ģ ­  ¤ ­­ė„ ¤«ļ § ÆØįØ + * edx = ēØį«® ” ©ā ¤«ļ § ÆØįØ + * į«„¤ć„ā ćįā ­ ¢«Ø¢ āģ esi=0 +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­®, Ø­ ē„ Ŗ®¤ ®čØ”ŖØ ä ©«®¢®© įØįā„¬ė +‡ ¬„ē ­Øļ: + * ā  äć­ŖęØļ ćįā ą„« ; äć­ŖęØļ 70 Æ®§¢®«ļ„ā ¢ėÆ®«­ļāģ + ā„ ¦„ ¤„©įā¢Øļ į ą įčØą„­­ė¬Ø ¢®§¬®¦­®įāļ¬Ø. + * …į«Ø ćŖ § āģ ­„­ć«„¢®„ §­ ē„­Ø„ ¢ esi Ø ­  ą ¬¤ØįŖ„ 榄 „įāģ + ćŖ § ­­ė© ä ©«, ā® ”椄ā į®§¤ ­ „éń ®¤Ø­ ä ©« į ā„¬ ¦„ ج„­„¬. + * ‚ Æą®āØ¢­®¬ į«ćē „ ä ©« Æ„ą„§ ÆØįė¢ „āįļ. + * ˆ¬ļ ä ©«  ¤®«¦­® ”ėāģ «Ø”® ¢ 䮹¬ ā„ 8+3 įج¢®«®¢ + (Æ„ą¢ė„ 8 įج¢®«®¢ - į®”įā¢„­­® جļ, Æ®į«„¤­Ø„ 3 - ą įčØą„­Ø„, + Ŗ®ą®āŖØ„ ج„­  Ø ą įčØą„­Øļ ¤®Æ®«­ļīāįļ Æą®”„« ¬Ø), + «Ø”® ¢ 䮹¬ ā„ 8.3 įج¢®«®¢ "FILE.EXT"/"FILE.EX " + (جļ ­„ ”®«„„ 8 įج¢®«®¢, ā®ēŖ , ą įčØą„­Ø„ 3 įج¢®« , + ¤®Æ®«­„­­®„ ÆąØ ­„®”室ج®įāØ Æą®”„« ¬Ø). + ˆ¬ļ ä ©«  ¤®«¦­® ”ėāģ § ÆØį ­® § £« ¢­ė¬Ø ”ćŖ¢ ¬Ø. + ‡ ¢„ąč īéØ© įج¢®« į Ŗ®¤®¬ 0 ­„ ­ć¦„­ (­„ ASCIIZ-įāą®Ŗ ). + * ā  äć­ŖęØļ ­„ Æ®¤¤„ą¦Ø¢ „ā Æ Æ®Ŗ ­  ą ¬¤ØįŖ„. + +====================================================================== +============ ”ć­ŖęØļ 35 - Æą®ēØā āģ ę¢„ā ā®ēŖØ ­  ķŖą ­„. ============ +====================================================================== + ą ¬„āąė: + * eax = 35 + * ebx = y*xsize+x, £¤„ + * (x,y) = Ŗ®®ą¤Ø­ āė ā®ēŖØ (įēØā ļ ®ā 0) + * xsize = ą §¬„ą ķŖą ­  Æ® £®ąØ§®­ā «Ø +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = ę¢„ā 0x00RRGGBB +‡ ¬„ē ­Øļ: + * “§­ āģ ą §¬„ąė ķŖą ­  ¬®¦­® ¢ė§®¢®¬ äć­ŖęØØ 14. Ž”ą āØā„ ¢­Ø¬ ­Ø„, + ēā® ®­  ¢ėēØā „ā 1 ا ®”®Øå ą §¬„ą®¢. + * Š ¢Ø¤„®Æ ¬ļāØ „įāģ ā Ŗ¦„ Æąļ¬®© ¤®įāćÆ (”„§ ¢ė§®¢®¢ įØįā„¬­ėå + äć­ŖęØ©) ē„ą„§ į„«„Ŗā®ą gs.  ą ¬„āąė ā„Ŗćé„£® ¢Ø¤„®ą„¦Ø¬  + ¬®¦­® Æ®«ćēØāģ äć­ŖęØ„© 61. + +====================================================================== +==================== ”ć­ŖęØļ 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 ćįā ­®¢«„­ = Æą ¢ ļ Ŗ­®ÆŖ  ­ ¦ ā  + * Æą®ēØ„ ”Øāė į”ą®č„­ė + +------------------ ®¤äć­ŖęØļ 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) Ŗćąį®ą, ā® + ¢®įįā ­ ¢«Ø¢ „āįļ Ŗćąį®ą Æ® 欮«ē ­Øī (įā ­¤ ąā­ ļ įāą„«Ŗ ). + +====================================================================== +================== ”ć­ŖęØļ 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 - ­®¬„ą äć­ŖęØØ + * ebx = ­®¬„ą IRQ, 0..15 +‚®§¢ą é „¬®„ §­ ē„­Ø„: (įØāć ęØī ¬®¦­® ą §«ØēØāģ Æ® §­ ē„­Øī ecx) + * „į«Ø Æ®ā®Ŗ ­„ ļ¢«ļ„āįļ ¢« ¤„«ģꄬ IRQ + (Ø«Ø ­®¬„ą IRQ § ¤ ­ ­„¢„ą­®): + * ecx = 2 + * „į«Ø ¤ ­­ėå ­„ā: + * eax = 0 + * ecx = 1 + * ebx ą §ąćč „āįļ + * „į«Ø ¢įń ¢ Æ®ąļ¤Ŗ„ Ø ¤ ­­ė„ ”ė«Ø: + * eax = ą §¬„ą ¤ ­­ėå, „éń ­„ Æą®ēØā ­­ėå ا ”ćä„ą  (¢ ” ©ā å) + * ecx = 0 + * ebx = ®ē„ą„¤­®© ” ©ā +‡ ¬„ē ­Øļ: + * ą„¤¢ ąØā„«ģ­® Æ®ā®Ŗ ¤®«¦„­ § ą„§„ą¢Øą®¢ āģ ¤«ļ į„”ļ ćŖ § ­­ė© 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-ēØį«® + * bh = 0 - ®ā®”ą ¦ āģ ¢ ¤„įļāØē­®© įØįā„¬„ įēØį«„­Øļ + * bh = 1 - ®ā®”ą ¦ āģ ¢ č„įā­ ¤ę ā„ąØē­®© įØįā„¬„ + * bh = 2 - ®ā®”ą ¦ āģ ¢ ¤¢®Øē­®© įØįā„¬„ + * ”Øāė 16-21 = įŖ®«ģŖ® ęØäą ®ā®”ą ¦ āģ + * ”Øāė 22-31 § ą„§„ą¢Øą®¢ ­ė Ø ¤®«¦­ė ”ėāģ ćįā ­®¢«„­ė ¢ 0 + * 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 = ćŖ § ā„«ģ ­  ”«®Ŗ ¤«ļ äć­ŖęØØ 58, ¢ Ŗ®ā®ą®¬ ćįā ­®¢«„­® + Æ®«„ Æą®¬„¦ćā®ē­®£® ”ćä„ą  Ø ćŖ § ­® جļ ä ©«  +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­® + * Ø­ ē„ eax = Ŗ®¤ ®čØ”ŖØ ä ©«®¢®© įØįā„¬ė; „į«Ø ä ©« ­„ § ¤ ńā įŖØ­, + ā® ¢®§¢ą é „āįļ ®čØ”Ŗ  3 (­„ا¢„įā­ ļ ä ©«®¢ ļ įØįā„¬ ). +‡ ¬„ē ­Øļ: + * ąØ ćįÆ„č­®© § £ąć§Ŗ„ įŖØ­  ¢į„ ®Ŗ­  ا¢„é īāįļ ® ­„®”室ج®įāØ + Æ„ą„ąØį®¢ŖØ (į®”ėāØ„ 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. + * ”ć­ŖęØļ ¢®§¢ą é „ā ćÆą ¢«„­Ø„, į®®”éØ¢ Ŗ椠 į«„¤ć„ā Ø­ä®ą¬ ęØī + ® § Æą®į„. ‘ ¬® Æą®Ø£ąė¢ ­Ø„ ؤńā ­„§ ¢Øįج® ®ā Æą®£ą ¬¬ė. + * „ ­­ė„ ¤®«¦­ė į®åą ­ļāģįļ ¢ Æ ¬ļāØ Æ® Ŗą ©­„© ¬„ą„ + ¤® Ŗ®­ę  Æą®Ø£ąė¢ ­Øļ. + +====================================================================== +============== ”ć­ŖęØļ 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 - ēā„­Ø„ ä ©« /Æ ÆŖØ + * Æ®¤äć­ŖęØļ 1 - Æ„ą„§ ÆØįģ ä ©«  + * Æ®¤äć­ŖęØļ 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, Æ®¤äć­ŖęØļ 1 - Æ„ą„§ ÆØį āģ ä ©«. =========== +====================================================================== +…į«Ø ä ©« ­„ įćé„įā¢ć„ā, ®­ į®§¤ ńāįļ. +…į«Ø ä ©« įćé„įā¢ć„ā, ®­ Æ„ą„§ ÆØįė¢ „āįļ. + ą ¬„āąė: + * eax = 58 - ­®¬„ą äć­ŖęØØ + * ebx = ćŖ § ā„«ģ ­  Ø­ä®ą¬ ęØ®­­ćī įāąćŖāćąć +”®ą¬ ā Ø­ä®ą¬ ęØ®­­®© įāąćŖāćąė: + * +0: dword: 1 = ­®¬„ą Æ®¤äć­ŖęØØ + * +4: dword: Ø£­®ąØąć„āįļ (ćįā ­ ¢«Ø¢ ©ā„ ¢ 0) + * +8: dword: ēØį«® ” ©ā ¤«ļ § ÆØįØ + * +12 = +0xC: dword: ćŖ § ā„«ģ ­  ¤ ­­ė„ ¤«ļ § ÆØįØ + * +16 = +0x10: dword: ćŖ § ā„«ģ ­  ”ćä„ą ¤«ļ ą ”®āė įØįā„¬ė + (4096 ” ©ā) + * +20 = +0x14: ASCIIZ-جļ ä ©« , Æą ¢Ø«  䮹¬Øą®¢ ­Øļ جń­ ćŖ § ­ė ¢ + ®”鄬 ®ÆØį ­ØØ +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * eax = 0 - ćįÆ„č­®, Ø­ ē„ Ŗ®¤ ®čØ”ŖØ ä ©«®¢®© įØįā„¬ė + * ebx ą §ąćč „āįļ +‡ ¬„ē ­Øļ: + * ā  äć­ŖęØļ ćįā ą„« , ØįÆ®«ģ§ć©ā„ Æ®¤äć­ŖęØī 2 äć­ŖęØØ 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 +‚®§¢ą é „¬®„ §­ ē„­Ø„: + * ebx:eax = Ŗ®ÆØļ esi:edi +‡ ¬„ē ­Øļ: + * “Ŗ § ­Ø„ ¢ 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. + +‚į„ Æ®¤äć­ŖęØØ ÆąØ¬„­Ø¬ė ā®«ģŖ® Ŗ Æą®ę„įį ¬/Æ®ā®Ŗ ¬, § Æćé„­­ė¬ +ا ā„Ŗćé„£® äć­ŖęØ„© 58 Ø«Ø 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) +ąØ¬„ąė: + * '/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 +„®įāćÆ­ė„ Æ®¤äć­ŖęØØ: + * Æ®¤äć­ŖęØļ 0 - ēā„­Ø„ ä ©«  + * Æ®¤äć­ŖęØļ 1 - ēā„­Ø„ Æ ÆŖØ + * Æ®¤äć­ŖęØļ 2 - į®§¤ ­Ø„/Æ„ą„§ ÆØįģ ä ©«  + * Æ®¤äć­ŖęØļ 3 - § ÆØįģ ¢ įćé„įā¢ćīéØ© ä ©« + * Æ®¤äć­ŖęØļ 4 - ćįā ­®¢Ŗ  ą §¬„ą  ä ©«  + * Æ®¤äć­ŖęØļ 5 - Æ®«ćē„­Ø„  āąØ”ćā®¢ ä ©« /Æ ÆŖØ + * Æ®¤äć­ŖęØļ 6 - ćįā ­®¢Ŗ   āąØ”ćā®¢ ä ©« /Æ ÆŖØ + * Æ®¤äć­ŖęØļ 7 - § ÆćįŖ Æą®£ą ¬¬ė + * Æ®¤äć­ŖęØļ 8 - 椠«„­Ø„ ä ©« /Æ ÆŖØ + * Æ®¤äć­ŖęØļ 9 - į®§¤ ­Ø„ Æ ÆŖØ +„«ļ CD-ÆąØ¢®¤®¢ ¢ į¢ļ§Ø į  ÆÆ ą ā­ė¬Ø ®£ą ­Øē„­Øļ¬Ø ¤®įāćÆ­ė +ā®«ģŖ® Æ®¤äć­ŖęØØ 0,1,5 Ø 7, ¢ė§®¢ ¤ąć£Øå Æ®¤äć­ŖęØ© § ¢„ąčØāįļ +®čØ”Ŗ®© į Ŗ®¤®¬ 2. + +====================================================================== += ”ć­ŖęØļ 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. + +====================================================================== +========== ”ć­ŖęØļ -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/hd_kolibri/kernel/docs/sysfuncs.txt b/kernel/branches/hd_kolibri/kernel/docs/sysfuncs.txt new file mode 100644 index 0000000000..d0deac7c2a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/docs/sysfuncs.txt @@ -0,0 +1,4473 @@ +SYSTEM FUNCTIONS of OS Kolibri 0.6.5.0 + +Number of the function is located in the register eax. +The call of the system function is executed by "int 0x40" command. +All registers except explicitly declared in the returned value, + including eflags, are preserved. + + +====================================================================== +============== Function 0 - define and draw the window. ============== +====================================================================== +Defines an application window. Draws a frame of the window, header and +working area. For skinned windows defines standard close and minimize +buttons. +Parameters: + * eax = 0 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = 0xXYRRGGBB, where: + * Y = style of the window: + * Y=0 - type I - fixed-size window + * Y=1 - only define window area, draw nothing + * Y=2 - type II - variable-size window + * Y=3 - skinned window + * other possible values (from 4 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 style Y=3 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 style Y=3 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: + * There is no checks for correctness. The setting of too large + values will result that the background will contain data abroad + of buffer for the background image. Buffer size = 0x160000-0x10, + that corresponds to maximum size 800*600. (800*600*3=0x15F900) + * 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 0x160000-16 = 1.375 Mb - 16 bytes, + 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: + * If the block gets out abroad 0x160000-16 = 1.375 Mb - 16 bytes, + the call is ignored. + * 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 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 al=0, + 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). +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 1 - system shutdown. =========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 1 - subfunction number +Returned value: + * function always return eax = 0 as tag of success +Remarks: + * On the last step menu of exit from the system appears and waits + response of the user. + * See also subfunction 9, system shutdown with + the parameter to force the choice in the exit menu. + +====================================================================== += 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 +Ēąģå÷ąķč’: + * All folders in the given path must exist, otherwise function + returns value 5, "file not found". + +====================================================================== +=========== Function 18, subfunction 7 - get active window. ========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = number of the active window + (number of the slot of the thread with active window) +Remarks: + * Active window is at the top of the window stack and receives + messages on all keyboard input. + * To make a window active, use subfunction 3. + +====================================================================== +== Function 18, subfunction 8 - disable/enable the internal speaker. = +====================================================================== +If speaker sound is disabled, all calls to subfunction 55 of +function 55 are ignored. If speaker sound is enabled, +they are routed on builtin speaker. + +------------------- Subsubfunction 1 - get status. ------------------- +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 1 - number of the subsubfunction +Returned value: + * eax = 0 - speaker sound is enabled; 1 - disabled + +----------------- Subsubfunction 2 - toggle status. ------------------ +Toggles states of disable/enable. +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 2 - number of the subsubfunction +Returned value: + * function does not return value + +====================================================================== +== Function 18, subfunction 9 - system shutdown with the parameter. == +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 9 - subfunction number + * ecx = parameter: + * 1 = on the last step of shutdown save ramdisk on a floppy and + then show the exit menu and request further operations + from the user + * 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. + * It is not recommended to use value ecx=1 (to not irritate the user + with excessive questions); to save ramdisk on a floppy use + function 16 (which admits specification, on which floppy to + write), and to shutdown with the exit menu use already mentioned + subfunction 1. + +====================================================================== +===== 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 +db 'name',0 - ASCIIZ-string with the name +For Kolibri 0.6.5.0 kernel: +db 0,6,5,0 +db 2 +db 'Kolibri',0 + +====================================================================== +======= 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 +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 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. ===== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 4 - subfunction number + * ecx = number of the base port +Returned value: + * eax = 0 - success + * eax = -1 - erratic port number +Remarks: + * Number of the port must satisfy to conditions 0x100<=ecx<=0xFFFF. + * The installation of the base is necessary for + functions 25, 28, 55. + * To get base port use subfunction 4 of function 26. + +====================================================================== +========== Function 21, subfunction 5 - set system language. ========= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 5 - subfunction number + * ecx = system language (1=eng, 2=fi, 3=ger, 4=rus) +Returned value: + * eax = 0 +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon. + * Function does not check for correctness, as the kernel does not + use this variable. + * To get system language use subfunction 5 of function 26. + +====================================================================== +============== Function 21, subfunction 7 - set HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +syntax /HD in obsolete function 58; at usage of modern syntax +/HD0,/HD1,/HD2,/HD3 base is set automatically. +Parameters: + * eax = 21 - function number + * ebx = 7 - subfunction number + * ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Returned value: + * eax = 0 +Remarks: + * Any application at any time can change the base. + * Do not change base, when any application works with hard disk. + If you do not want system bugs. + * To get HD base use subfunction 7 of function 26. + * It is also necessary to define used partition of hard disk by + subfunction 8. + +====================================================================== +========= Function 21, subfunction 8 - set used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete syntax /HD and obsolete function 58; +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +base and partition are set automatically. +Parameters: + * eax = 21 - function number + * ebx = 8 - subfunction number + * ecx = HD partition (beginning from 1) +Return value: + * eax = 0 +Remarks: + * Any application at any time can change partition. + * Do not change partition when any application works with hard disk. + If you do not want system bugs. + * To get used partition use subfunction 8 of function 26. + * There is no correctness checks. + * To get the number of partitions of a hard disk use + subfunction 11 of function 18. + * It is also necessary to define used HD base by subfunction 7. + +====================================================================== +======== Function 21, subfunction 10 - set sound DMA channel. ======== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 10 - subfunction number + * ecx = number of channel (from 0 up to 3 inclusively) +Returned value: + * eax = 0 - success + * eax = -1 - incorrect channel number +Remarks: + * Number of DMA channel is used in subfunction 1 of function 55. + * To get sound DMA channel use subfunction 10 of function 26. + +====================================================================== + 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 +Ēąģå÷ąķč’: + * Previously CD base port must be defined by call to + subfunction 3 of function 21. + +====================================================================== +=================== Function 25 - set SBPro volume. ================== +====================================================================== +Parameters: + * eax = 25 - function number + * ebx = what to set: + * 1 - set common volume + * 2 - set CD-audio volume + * cl = volume level: high 4 bits for the left column, + low 4 bits for the right one +Returned value: + * eax = 0 - success + * eax = 1 - SB base is not defined + * eax = 2 - incorrect subfunction +Remarks: + * Previously SB base port must be defined by + subfunction 4 of function 21. + * See also function 28 which sets + volume for the later standard SB16. + +====================================================================== +======== 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. ===== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = base port number +Remarks: + * Bae port is used by functions 25, 55. + * To set base port use subfunction 4 of function 21. + +====================================================================== +========== Function 26, subfunction 5 - get system language. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = system language (1=eng, 2=fi, 3=ger, 4=rus) +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon (using this function). + * To set system language use subfunction 5 of function 21. + +====================================================================== +============== Function 26, subfunction 7 - get HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +syntax /HD in obsolete function 58; at usage of modern syntax +/HD0,/HD1,/HD2,/HD3 base is set automatically. +Parameters: + * eax = 26 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Remarks: + * Any application in any time can change HD base. + * To set base use subfunction 7 of function 21. + * To get used partition of hard disk use subfunction 8. + +====================================================================== +========= Function 26, subfunction 8 - get used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete syntax /HD in obsolete function 58; +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +base and partition are set automatically. +Parameters: + * eax = 26 - function number + * ebx = 8 - subfunction number +Returned value: + * eax = HD partition (beginning from 1) +Remarks: + * Any application in any time can change partition. + * To set partition use subfunction 8 of function 21. + * To get number of partitions on a hard disk use + subfunction 11 of function 18. + * To get base of used hard disk, use subfunction 7. + +====================================================================== +=== Function 26, subfunction 9 - get the value of the time counter. == +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = number of 1/100s of second, past from the system boot time +Remarks: + * Counter takes modulo 2^32, that correspond to a little more + than 497 days. + * To get system time use function 3. + +====================================================================== +======== Function 26, subfunction 10 - get sound DMA channel. ======== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 10 - subfunction number +Returned value: + * eax = number of the channel (from 0 to 3 inclusive) +Remarks: + * Number of the DMA channel is used by subfunction 1 of function 55. + * To set the sound DMA channel use subfunction 10 of function 21. + +====================================================================== +===================== 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. =================== +====================================================================== +Parameters: + * eax = 28 - function number + * ebx = what to install: + * 1 - install common volume + * 2 - install CD-audio volume + * cl = volume level (0=off, 0xFF=max) +Returned value: + * eax = 0 - success + * eax = 1 - SB base is not defined + * eax = 2 - incorrect subfunction +Remarks: + * Previously SB base port must be defined by + subfunction 4 of function 21. + * This function gives more variants for volume, that function 25. + +====================================================================== +=================== 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 32 - delete file from ramdisk. ============== +====================================================================== +Parameters: + * eax = 32 - function number + * ebx = pointer to the filename +Returned value: + * eax = 0 - success; otherwise file system error code +Remarks: + * This function is obsolete; function 58 allows to fulfill + the same operations with the extended possibilities. + * The current implementation returns only values 0(success) and + 5(file not found). + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +================ Function 33 - write file to ramdisk. ================ +====================================================================== +Parameters: + * eax = 33 - function number + * ebx = pointer to the filename + * ecx = pointer to data for writing + * edx = number of bytes for writing + * should be set esi=0 +Returned value: + * eax = 0 - success, otherwise file system error code +Remarks: + * This function is obsolete; function 70 allows to fulfil + the same operations with extended possibilities. + * If esi contains non-zero value and selected file already exists, + one more file with the same name will be created. + * Otherwise file will be overwritten. + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +======= Function 35 - read the color of a pixel on the screen. ======= +====================================================================== +Parameters: + * eax = 35 + * ebx = y*xsize+x, where + * (x,y) = coordinates of a pixel (beginning from 0) + * xsize = horizontal screen size +Returned value: + * eax = color 0x00RRGGBB +Remarks: + * To get screen sizes use function 14. Pay attention, + that it subtracts 1 from both sizes. + * There is also direct access (without any system calls) + to videomemory through the selector gs. To get parameters of + the current videomode, use function 61. + +====================================================================== +=================== Function 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 + * 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). + +====================================================================== +====================== 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 - read IRQ data. ==================== +====================================================================== +When an IRQ occurs, the system reads data from ports indicated +earlier by function 44 and writes this data to +internal buffer. This function reads out data from that buffer +bytewise. +Parameters: + * eax = 42 - function number + * ebx = IRQ number, 0..15 +Returned value: (use value of ecx to distinguish) + * if the thread is not IRQ owner (or IRQ number is incorrect): + * ecx = 2 + * if there is no data: + * eax = 0 + * ecx = 1 + * ebx destroyed + * if all is ok: + * eax = byte size of data, not yet read from buffer + * ecx = 0 + * ebx = current byte +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-number + * bh = 0 - display in decimal number system + * bh = 1 - display in hexadecimal system + * bh = 2 - display in binary system + * įčņū 16-21 = how many digits to display + * įčņū 22-31 reserved and must be set to 0 + * 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 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 1 - rewrite file + * 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 1 - rewrite file. ============= +====================================================================== +If the file does not exist, it is created. +If the file exists, it is rewritten. +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 1 = subfunction number + * +4: dword: ignored (set to 0) + * +8: dword: number of bytes to write + * +12 = +0xC: dword: pointer to data to write + * +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 destroyed +Remarks: + * This function is obsolete, use subfunction 2 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 +4096 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: + * ebx:eax = copy of esi:edi +Ēąģå÷ąķč’: + * 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 are applicable only to processes/threads started +from the current by function 58 or 70 with set debugging flag. +Debugging of multithreaded programs is not supported yet. +The full list of subfunctions: + * subfunction 0 - define data area for debug messages + * subfunction 1 - get contents of registers of debugged thread + * subfunction 2 - set contents of registers of debugged thread + * subfunction 3 - detach from debugged process + * subfunction 4 - suspend debugged thread + * subfunction 5 - resume debugged thread + * subfunction 6 - read from the memory of debugged process + * subfunction 7 - write to the memory of debugged process + * subfunction 8 - terminate debugged thread + * subfunction 9 - set/clear hardware breakpoint + +====================================================================== += Function 69, subfunction 0 - define data area fror debug messages. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 0 - subfunction number + * ecx = pointer +Format of data area: + * +0: dword: N = buffer size (not including this header) + * +4: dword: occupied place + * +8: N*byte: buffer +Returned value: + * function does not return value +Remarks: + * If the size field is negative, the buffer is considered locked + and at arrival of new message the system will wait. + For synchronization frame all work with the buffer by operations + lock/unlock + neg [bufsize] + * Data in the buffer are considered as array of items with variable + length - messages. Format of a message is explained in + general description. + +====================================================================== +===================== Function 69, subfunction 1 ===================== +============ Get contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 1 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes + * esi = pointer to context structure +Returned value: + * function does not return value +Format of context structure: (FPU is not supported yet) + * +0: dword: eip + * +4: dword: eflags + * +8: dword: eax + * +12 = +0xC: dword: ecx + * +16 = +0x10: dword: edx + * +20 = +0x14: dword: ebx + * +24 = +0x18: dword: esp + * +28 = +0x1C: dword: ebp + * +32 = +0x20: dword: esi + * +36 = +0x24: dword: edi +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===================== Function 69, subfunction 2 ===================== +============ Set contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 2 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes +Returned value: + * function does not return value +Format of context structure is shown in the description of +subfunction 1. +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===== Function 69, subfunction 3 - detach from debugged process. ===== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 3 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * If the process was suspended, it resumes execution. + +====================================================================== +======== Function 69, subfunction 4 - suspend debugged thread. ======= +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 4 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======== Function 69, subfunction 5 - resume debugged thread. ======== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 5 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== += Fucntion 69, subfunction 6 - read from memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 6 - subfunction number + * ecx = identifier + * edx = number of bytes to read + * esi = address in the memory of debugged process + * edi = pointer to buffer for data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of read bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +== Function 69, subfunction 7 - write to memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 7 - subfunction number + * ecx = identifier + * edx = number of bytes to write + * esi = address of memory in debugged process + * edi = pointer to data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of written bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======= Function 69, subfunction 8 - terminate debugged thread. ====== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 8 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * The function is similar to subfunction 2 of function 18 + with two differences: it requires first remark and + accepts PID rather than slot number. + +====================================================================== +===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 9 - subfunction number + * ecx = thread identifier + * dl = index of breakpoint, from 0 to 3 inclusively + * dh = flags: + * if high bit is cleared - set breakpoint: + * bits 0-1 - condition: + * 00 = breakpoint on execution + * 01 = breakpoint on read + * 11 = breakpoint on read/write + * bits 2-3 - length; for breakpoints on exception it must be + 00, otherwise one of + * 00 = byte + * 01 = word + * 11 = dword + * esi = breakpoint address; must be aligned according to + the length (i.e. must be even for word breakpoints, + divisible by 4 for dword) + * if high bit is set - clear breakpoint +Returned value: + * eax = 0 - success + * eax = 1 - error in the input data + * eax = 2 - (reserved, is never returned in the current + implementation) a global breakpoint with that index is already set +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * Hardware breakpoints are implemented through DRx-registers of + the processor, all limitations results from this. + * The function can reinstall the breakpoint, previously set + by it (and it does not inform on this). + Carry on the list of set breakpoints in the debugger. + * Breakpoints generate debug exception #DB, on which the system + notifies debugger. + * Breakpoints on write and read/write act after + execution of the caused it instruction. + +====================================================================== +==== Function 70 - work with file system with long names support. ==== +====================================================================== +Parameters: + * eax = 70 + * ebx = pointer to the information structure +Returned value: + * eax = 0 - success; otherwise file system error code + * some subfunctions return value in other registers too +General format of the information structure: + * +0: dword: subfunction number + * +4: dword: file offset + * +8: dword: high dword of offset (must be 0) or flags field + * +12 = +0xC: dword: size + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: n db: ASCIIZ-string with the filename + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with the filename +Specifications - in documentation on the appropriate subfunction. +Filename is case-insensitive. Russian letters must be written in +the encoding cp866 (DOS). +Format of filename: +/base/number/dir1/dir2/.../dirn/file, +where /base/number identifies device, on which file is located: +one of + * /RD/1 = /RAMDISK/1 to access ramdisk + * /FD/1 = /FLOPPYDISK/1 to access first floppy drive, + /FD/2 = /FLOPPYDISK/2 to access second one + * /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices + IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - partition number on the selected hard drive, varies from 1 + to 255 (on each hard drive the indexing starts from 1) + * /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to + CD on IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave) +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 +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. + +====================================================================== +=== 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 -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/hd_kolibri/kernel/drivers/ati2d.asm b/kernel/branches/hd_kolibri/kernel/drivers/ati2d.asm new file mode 100644 index 0000000000..1959dea3f6 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/ati2d.asm @@ -0,0 +1,1014 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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' + +DEBUG equ 1 + +VID_ATI equ 0x1002 + +LOAD_FROM_FILE equ 0 +LOAD_FROM_MEM equ 1 +LOAD_INDIRECT equ 2 +LOAD_SYSTEM equ 3 + +VIDEO_FREE equ 2 + +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 + +R8500 equ 0x514C ;R200 +R9000 equ 0x4966 ;RV250 +R9200 equ 0x5961 ;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 + +OS_BASE equ 0 +new_app_base equ 0x80000000 +SLOT_BASE equ 0x0080000 + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +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 wrr dest, src +{ + mov edi, [ati_io] + mov dword [edi+dest], src +} + + +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 .exit + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_ati + test eax, eax + jz .fail + + call init_ati + test eax, eax + jz .fail + + 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 .fail + mov dword [SetHwCursor], drvCursorPos ;enable hardware cursor + mov dword [HwCursorRestore], drv_restore + mov dword [HwCursorCreate], ati_cursor + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + +.exit: + xor eax, eax +; mov ebx, SetHwCursor +; mov dword [ebx], eax ;force disable hardware cursor + 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 ebx, [edi+io_code] + cmp ebx, VIDEO_FREE + jne .fail + + mov eax, [edi+input] + call video_free +.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, 4 + 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 + +align 4 +proc init_ati + + stdcall AllocKernelSpace, dword 0x10000 + test eax, eax + jz .fail + + mov [ati_io], eax + + stdcall PciRead32, [bus], [devfn], dword 0x18 + and eax, 0xFFFF0000 + mov esi, eax + + mov edi, [ati_io] + mov edx, 16 +@@: + stdcall MapPage,edi,esi,PG_SW+PG_NOCACHE + add edi, 0x1000 + add esi, 0x1000 + dec edx + jnz @B + + mov edi, [ati_io] + 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 drvShowCursor + xor eax, eax + inc eax +.fail: + ret +endp + +align 4 +drv_restore: + ret 8 + +align 4 +drvShowCursor: + 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 drvCursorPos 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 +engSetupSolidFill: + push ebp + mov ebp, esp + + push dword 3 + call engWaitForFifo + + wrr RD_DP_GUI_MASTER_CNTL, cmdSolidFill + + mov eax, [ebp+8] + wrr RD_DP_BRUSH_FRGD_CLR,eax + + mov edi, [ati_io] + mov dword [edi+RD_DP_CNTL],(RD_DST_X_LEFT_TO_RIGHT or RD_DST_Y_TOP_TO_BOTTOM) + leave + ret 4 + + +align 4 +drvSolidFill: +;x:word,y:word,w:word,h:word,color:dword + push ebp + mov ebp, esp +x equ ebp+8 +y equ ebp+12 +w equ ebp+16 +h equ ebp+20 +color equ ebp+24 + + push dword [ebp+24] + call engSetupSolidFill + + push dword 2 + call engWaitForFifo + + mov edi, [ati_io] + + mov eax, [y] + mov ebx, [x] + shl eax,16 + or eax, ebx + + mov ecx, [w] + mov edx, [h] + shl ecx,16 + or ecx, edx + mov [edi+RD_DST_Y_X], eax + mov [edi+RD_DST_WIDTH_HEIGHT], ecx + call engFlush + leave + ret 20 + +align 4 +devices dd (R8500 shl 16)+VID_ATI + dd (R9000 shl 16)+VID_ATI + dd (R9200 shl 16)+VID_ATI + dd (R9500 shl 16)+VID_ATI + dd (R9500P shl 16)+VID_ATI + dd (R9550 shl 16)+VID_ATI + dd (R9600 shl 16)+VID_ATI + dd (R9600XT shl 16)+VID_ATI + dd (R9700P shl 16)+VID_ATI + dd (R9800 shl 16)+VID_ATI + dd (R9800P shl 16)+VID_ATI + dd (R9800XT shl 16)+VID_ATI + dd 0 ;terminator + +version dd 0x00040004 + +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 +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 + +bus dd ? +devfn dd ? +ati_io dd ? + + + diff --git a/kernel/branches/hd_kolibri/kernel/drivers/codec.inc b/kernel/branches/hd_kolibri/kernel/drivers/codec.inc new file mode 100644 index 0000000000..4f2047181a --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/codec.inc @@ -0,0 +1,226 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + 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 + 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] + test ebx, ebx + jz .unknown + + cmp eax,ebx + jne .next + mov eax, [edi+4] + mov [codec.chip_ids], eax + ret +.next: + add edi, 8 + jmp @b +.unknown: + mov [codec.chip_ids], chip_unknown + 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 + +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 +chip_unknown db 'unknown chip', 13,10,0 + +CHIP_ANALOG equ 0x41445300 +CHIP_REALTEK equ 0x414C4700 +CHIP_CMEDIA equ 0x434D4900 + +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 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 0 + +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 0 + +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 0 + +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 + diff --git a/kernel/branches/hd_kolibri/kernel/drivers/ensoniq.asm b/kernel/branches/hd_kolibri/kernel/drivers/ensoniq.asm new file mode 100644 index 0000000000..6d4901e9b2 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/ensoniq.asm @@ -0,0 +1,1178 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;alpha version + +format MS COFF + + +include 'proc32.inc' +include 'imports.inc' + +DEBUG equ 1 + +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 0; +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0x80000000 + +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 + 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] + add ebx, new_app_base + 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/hd_kolibri/kernel/drivers/imports.inc b/kernel/branches/hd_kolibri/kernel/drivers/imports.inc new file mode 100644 index 0000000000..affd89511d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/imports.inc @@ -0,0 +1,142 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; all exported kernel functions and data + +if used RegService + extrn RegService +end if +if used GetService + extrn GetService +end if +if used ServiceHandler + extrn ServiceHandler +end if +if used AttachIntHandler + extrn AttachIntHandler +end if +if used FpuSave + extrn FpuSave +end if +if used FpuRestore + extrn FpuRestore +end if + +if used PciApi + extrn PciApi +end if +if used PciRead32 + extrn PciRead32 +end if +if used PciRead8 + extrn PciRead8 +end if +if used PciWrite8 + extrn PciWrite8 +end if + +if used AllocPage + extrn AllocPage +end if +if used AllocPages + extrn AllocPages +end if +if used FreePage + extrn FreePage +end if +if used MapPage + extrn MapPage +end if +if used MapSpace + extrn MapSpace +end if +if used GetPgAddr + extrn GetPgAddr +end if +if used CommitPages + extrn CommitPages +end if +if used ReleasePages + extrn ReleasePages +end if + +if used AllocKernelSpace + extrn AllocKernelSpace +end if +if used FreeKernelSpace + extrn FreeKernelSpace +end if +if used KernelAlloc + extrn KernelAlloc +end if +if used KernelFree + extrn KernelFree +end if +if used UserAlloc + extrn UserAlloc +end if +if used UserFree + extrn UserFree +end if +if used Kmalloc + extrn Kmalloc +end if +if used Kfree + extrn Kfree +end if + +if used CreateObject + extrn CreateObject +end if +if used DestroyObject + extrn DestroyObject +end if +if used CreateEvent + extrn CreateEvent +end if +if used RaiseEvent + extrn RaiseEvent +end if +if used WaitEvent + extrn WaitEvent +end if +if used DestroyEvent + extrn DestroyEvent +end if +if used ClearEvent + extrn ClearEvent +end if + +if used LoadCursor + extrn LoadCursor +end if +if used SetHwCursor + extrn SetHwCursor +end if +if used HwCursorRestore + extrn HwCursorRestore +end if +if used HwCursorCreate + extrn HwCursorCreate +end if + +if used SysMsgBoardStr + extrn SysMsgBoardStr +end if +if used GetCurrentTask + extrn GetCurrentTask +end if +if used LoadFile + extrn LoadFile +end if +if used SendEvent + extrn SendEvent +end if +if used LFBAddress + extrn LFBAddress +end if + diff --git a/kernel/branches/hd_kolibri/kernel/drivers/infinity.asm b/kernel/branches/hd_kolibri/kernel/drivers/infinity.asm new file mode 100644 index 0000000000..10de359987 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/infinity.asm @@ -0,0 +1,1286 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru + +format MS COFF + +include 'proc32.inc' +include 'main.inc' +include 'imports.inc' + +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 + +DEBUG equ 1 + + +OS_BASE equ 0 +new_app_base equ 0x80000000 +SLOT_BASE equ OS_BASE+0x0080000 + +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] + mov eax, [eax] + mov [eax+new_app_base], dword SOUND_VERSION + xor eax, eax + ret +@@: + cmp eax, SND_CREATE_BUFF + jne @F + mov ebx, [edi+input] + push edi + stdcall CreateBuffer,[ebx],[ebx+4] + pop edi + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], 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,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETFORMAT + jne @F + + movzx eax, word [edx+STREAM.format] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], eax + xor eax, eax + ret +@@: + cmp eax, SND_RESET + jne @F + stdcall ResetBuffer,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_SETPOS + jne @F + stdcall SetBufferPos,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETPOS + jne @F + push edi + stdcall GetBufferPos, [ebx] + pop edi + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], ebx + ret +@@: + cmp eax, SND_SETBUFF + jne @F + mov eax, [ebx+4] + add eax, new_app_base + stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12] + ret +@@: + cmp eax, SND_SETVOLUME + jne @F + stdcall SetBufferVol,[ebx],[ebx+4],[ebx+8] + ret +@@: + cmp eax, SND_GETVOLUME + jne @F + + mov eax, [edi+output] + mov ecx, [eax] + mov eax, [eax+4] + add ecx, new_app_base + add eax, new_app_base + stdcall GetBufferVol,[ebx],ecx,eax + ret +@@: + cmp eax, SND_SETPAN + jne @F + stdcall SetBufferPan,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETPAN + jne @F + mov eax, [edx+STREAM.pan] + mov ebx, [edi+output] + mov ebx, [ebx] + mov [ebx+new_app_base], eax + xor eax, eax + ret +@@: + cmp eax, SND_OUT + jne @F + + mov eax, [ebx+4] + add eax, new_app_base + stdcall wave_out, [ebx],eax,[ebx+8] + ret +@@: + cmp eax, SND_PLAY + jne @F + + stdcall play_buffer, [ebx],[ebx+4] + ret +@@: + cmp eax, SND_STOP + jne @F + + stdcall stop_buffer, [ebx] + ret +@@: + cmp eax, SND_GETBUFFSIZE + jne @F + mov eax, [edx+STREAM.in_size] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], eax + 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 + +TASK_COUNT equ 0x0003004 +CURRENT_TASK equ 0x0003000 + + +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_OUT+PCM_RING + jnz .fail + jmp .test_ok +.test_out: + test eax, PCM_RING+PCM_STATIC + jnz .fail + jmp .test_ok +.test_ring: + test eax, PCM_OUT+PCM_STATIC + jnz .fail +.test_ok: + mov ebx, [CURRENT_TASK] ;hack: direct accsess + shl ebx, 5 ;to kernel data + mov ebx, [CURRENT_TASK+ebx+4] + 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 eax, 0x10000 + test [format], PCM_RING + jz .waveout + + mov eax, [eax+STREAM.r_size] + add eax, 4095 + and eax, -4096 + add eax, eax +.waveout: + mov [ring_size], eax + mov ebx, eax + shr ebx, 12 + mov [ring_pages], ebx + + add eax, eax ;double ring size + stdcall AllocKernelSpace, eax + + 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 + + mov ebx, [ring_pages] + stdcall AllocPages, ebx + mov edi, [str] + mov ebx, [edi+STREAM.in_base] + mov ecx, [ring_pages] + or eax, PG_SW + push eax + push ebx + call CommitPages ;eax, ebx, ecx + mov ecx, [ring_pages] + pop ebx + pop eax + add ebx, [ring_size] + call CommitPages ;double mapped + + 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_STATIC+PCM_RING + jnz .fail + + cmp ax, PCM_ALL + je .fail + + mov esi,[src] + test esi, esi + jz .fail + + cmp esi, new_app_base + jb .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 ebx, [str] + mov [ebx+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 + + mov [edx+STREAM.in_count], 0 + 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_OUT+PCM_RING + jnz .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_OUT+PCM_RING + jnz .fail + + mov ebx, [edx+STREAM.in_rp] + 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 st0 + + fild word [r_vol] + + call .calc + + fistp word [edx+STREAM.r_amp] + 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 + 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 + locals + fpu_state rb 528 + endl + + 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 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 + +; parm +; 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 + mov edi, dword [ebx+STREAM.l_amp] + mov [eax+4], edi + add [ebx+STREAM.out_rp], 512 + sub [ebx+STREAM.out_count], 512 + + add eax, 8 + 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 16384, 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 (4 shl 16) or (SOUND_VERSION and 0xFFFF) + +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/hd_kolibri/kernel/drivers/main.inc b/kernel/branches/hd_kolibri/kernel/drivers/main.inc new file mode 100644 index 0000000000..51c2e0ef4d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/main.inc @@ -0,0 +1,163 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; (C) copyright Serge 2006-2007 +; email: infinity_sound@mail.ru + +SOUND_VERSION equ 0x01000100 + +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 + +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 ? + + .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 ? + + .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 34*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/hd_kolibri/kernel/drivers/mix_mmx.inc b/kernel/branches/hd_kolibri/kernel/drivers/mix_mmx.inc new file mode 100644 index 0000000000..5778cc823d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/drivers/mix_sse2.inc b/kernel/branches/hd_kolibri/kernel/drivers/mix_sse2.inc new file mode 100644 index 0000000000..aa450a61f8 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/drivers/mixer.asm b/kernel/branches/hd_kolibri/kernel/drivers/mixer.asm new file mode 100644 index 0000000000..864063382b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/mixer.asm @@ -0,0 +1,1102 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 rq 32 + +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 + + ; cmp eax, 1 + ; je .copy + + lea ebx, [mix_list] + stdcall mix_all, [output], ebx, eax +@@: + add [output], 512 + dec [main_count] + jnz .mix +.exit: + lea eax, [fpu_state+16] + and eax, -16 + call FpuRestore + ret +.copy: + lea eax, [mix_list] + stdcall copy_mem, [output], [eax] + jmp @B +.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 ? + ev_code dd ? ;EVENT + ev_offs dd ? + rd 4 + 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 word [esi+STREAM.format], PCM_2_16_48 + je .copy + + 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 +.copy: + mov ebx, esi + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @f + + sub edi, 64*1024 + mov [ebx+STREAM.out_wp], edi +@@: + mov esi, [ebx+STREAM.in_rp] + mov ecx, 16384/4 + cld + rep movsd + + mov [ebx+STREAM.out_wp], edi + + cmp esi, [ebx+STREAM.in_top] + jb @f + + sub esi, 0x10000 +@@: + mov [ebx+STREAM.in_rp], esi + + test eax, eax + jz .l_end + mov eax, [ebx+STREAM.notify_event] + mov ebx, [ebx+STREAM.notify_id] + mov ecx, EVENT_WATCHED + xor edx, edx + call RaiseEvent ;eax, ebx, ecx, edx +.l_end: + inc [stream_index] + dec [play_count] + jnz .l1 + ret +endp + +align 4 +proc refill stdcall, str:dword + locals + r_size rd 1 + 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 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 + +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, 8 + 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 + +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] + rep movsd + mov eax, 16384 + 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/hd_kolibri/kernel/drivers/proc32.inc b/kernel/branches/hd_kolibri/kernel/drivers/proc32.inc new file mode 100644 index 0000000000..98a1bd3342 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/drivers/sceletone.asm b/kernel/branches/hd_kolibri/kernel/drivers/sceletone.asm new file mode 100644 index 0000000000..72d7f0e2d8 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/sceletone.asm @@ -0,0 +1,163 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;driver sceletone + +format MS COFF + +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 + +DEBUG equ 1 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +STRIDE equ 4 ;size of row in devices table + +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 edi, [ioctl] +; mov eax, [edi+io_code] + + xor eax, eax + 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 ; pci device id +;VENDOR_ID equ ; device vendor id + + +;all initialized data place here + +align 4 +devices dd (DEVICE_ID shl 16)+VENDOR_ID + dd 0 ;terminator + +version dd 0x00030003 + +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/hd_kolibri/kernel/drivers/sis.asm b/kernel/branches/hd_kolibri/kernel/drivers/sis.asm new file mode 100644 index 0000000000..db9b69aea2 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/sis.asm @@ -0,0 +1,1180 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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' + +DEBUG equ 1 + +CPU_FREQ equ 2000d ;cpu freq in MHz + +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 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 0; 0x80400000 +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0x80000000 + +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 + + 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 + + stdcall AttachIntHandler, [ctrl.int_line], ac97_irq + + stdcall RegService, sz_sound_srv, service_proc + + mov esi, msgOk + call SysMsgBoardStr + 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] + add ebx, new_app_base + 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 + + 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 + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + 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] + + 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 + je .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: + 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 + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + and eax, not 0x08 + or eax, 0x02 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + 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, msgCRFail + call SysMsgBoardStr + end if +.fail: + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +proc 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] + ret +endp + +align 4 +proc 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] + ret +endp + +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 + +align 4 +.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 + + +include "codec.inc" + +align 4 +devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS + dd 0 + +version dd 0x00040004 + +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 +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 resret',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 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,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/hd_kolibri/kernel/drivers/sound.asm b/kernel/branches/hd_kolibri/kernel/drivers/sound.asm new file mode 100644 index 0000000000..c5ecbcdb5d --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/drivers/sound.asm @@ -0,0 +1,1419 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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' + +DEBUG equ 1 + +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 + +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 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 0; +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0x80000000 + +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 + + 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 + +; if REMAP_IRQ + +; call get_LPC_bus +; cmp eax, -1 +; jz .fail + +; mov [lpc_bus], 0 ;eax +; call remap_irq +; end if + + 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 + 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] + add ebx, new_app_base + 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 remap_irq ;for Intel chipsets ONLY !!! + mov eax, VALID_IRQ + bt eax, IRQ_LINE + jnc .exit + + mov edx, 0x4D0 + in ax,dx + bts ax, IRQ_LINE + out dx, aX + + stdcall PciWrite8, dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE + mov [ctrl.int_line], IRQ_LINE + +.exit: + ret +endp + +align 4 +proc ac97_irq + +; if DEBUG +; 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 ebx, VID_INTEL + jne @F + mov [ctrl.vendor_ids], msg_Intel + ret +@@: + cmp ebx, VID_NVIDIA + jne @F + mov [ctrl.vendor_ids], msg_NVidia +@@: + mov [ctrl.vendor_ids], 0 ;something wrong ? + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc get_LPC_bus ;for Intel chipsets ONLY !!! + locals + last_bus dd ? + bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call [PciApi] + cmp eax, -1 + je .err + + mov [last_bus], eax +.next_bus: + stdcall PciRead32, [bus], dword 0xF8, dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + cmp eax, 0x24D08086 + je .found +.next: + mov eax, [bus] + inc eax + cmp eax, [last_bus] + mov [bus], eax + jna .next_bus +.err: + xor eax, eax + dec eax + ret +.found: + mov eax, [bus] + 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 + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + 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 AllocKernelSpace, dword 0x2000 + mov edi, eax + stdcall MapPage, edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.codec_mem_base], edi + add edi, 0x1000 + stdcall MapPage, edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.ctrl_mem_base], edi + + 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] + + 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 +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 0x00040004 + +msg_ICH db 'Intel ICH', 13,10, 0 +msg_ICH0 db 'Intel ICH0', 13,10, 0 +msg_ICH2 db 'Intel ICH2', 13,10, 0 +msg_ICH3 db 'Intel ICH3', 13,10, 0 +msg_ICH4 db 'Intel ICH4', 13,10, 0 +msg_ICH5 db 'Intel ICH5', 13,10, 0 +msg_ICH6 db 'Intel ICH6', 13,10, 0 +msg_ICH7 db 'Intel ICH7', 13,10, 0 +msg_Intel db 'Intel Corp. ', 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',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 + +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/hd_kolibri/kernel/fdo.inc b/kernel/branches/hd_kolibri/kernel/fdo.inc new file mode 100644 index 0000000000..187f3a1805 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fdo.inc @@ -0,0 +1,428 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; 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 + 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 + call 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 + call 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/hd_kolibri/kernel/fs/fat12.inc b/kernel/branches/hd_kolibri/kernel/fs/fat12.inc new file mode 100644 index 0000000000..3d891995ae --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/fat12.inc @@ -0,0 +1,2793 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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_free_space: +;--------------------------------------------- +; +; returns free space in edi +; +;--------------------------------------------- + push eax ebx ecx + call read_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_2 + mov eax,0x282004 + xor edi,edi + mov ecx,2847 ;1448000/512 +rdfs1_1: + mov ebx,[eax] + and ebx,4095 + jne rdfs2_1 + add edi,512 +rdfs2_1: + add eax,2 + loop rdfs1_1 +fdc_status_error_2: + pop ecx ebx eax + 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 + + +floppy_filedelete: +;-------------------------------------------- +; +; filedelete - sys floppy +; in: +; eax - filename 11 chars - for root directory +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; out: +; eax - 0 = successful, 1 = file not found, 10 = access denied +; +;-------------------------------------------- + mov [path_pointer_flp],edi + mov [save_flag],0 + mov ebp,1 ; file not found as default +filedelete_newtry_1: + sub esp,32 + call expand_filename + push eax ebx ecx edx esi edi + call read_flp_fat + cmp [FDC_Status],0 + jne frnoreadd_1 + mov [FDD_Track],0 ; Öčėčķäš + mov [FDD_Head],1 ; Ńņīšīķą + mov [FDD_Sector],2 ; Ńåźņīš + call SeekTrack + mov dh,14 +l.20_2: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_4 + mov dl,16 + mov edi,FDD_BUFF + inc [FDD_Sector] +l.21_2: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifoundd_1 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + jne l.21_2 + dec dh + jne l.20_2 + jmp frnoreadd_1 + +fdc_status_error_4: + pop edi esi edx ecx ebx eax + add esp,32 + jmp fdc_status_error_1 + +fifoundd_1: + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + je fifoundd_2 + movzx eax, word [edi+0xf] + mov ebx,[path_pointer_flp] + add ebx,36 + call get_cluster_of_a_path_flp + jc frnoreadd_1_1 + mov edi,ebx + add edi,11 + jmp fifoundd_2_1 +fifoundd_2: + dec [FDD_Sector] +fifoundd_2_1: + mov [edi-11],byte 0xE5 ;mark filename deleted + movzx edi, word [edi+0xf] ;edi = cluster +frnewd_1: + shl edi,1 ;find next cluster from FAT + add edi,FLOPPY_FAT + mov eax,[edi] + mov [edi],word 0x0 ;clear fat chain cluster + and eax,4095 + mov edi,eax + cmp edi,dword 4095 ;last cluster ? + jz frnoreadd2_1 + jmp frnewd_1 + +frnoreadd2_1: + call WriteSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_4 + call save_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_4 +; pop edi esi edx ecx ebx eax +; add esp,32 + mov ebp,0 ; file found +; jmp filedelete_newtry_1 + jmp frnoreadd_1 + +frnoreadd_1_1: + cmp [FDC_Status],0 + jne fdc_status_error_4 +frnoreadd_1: + pop edi esi edx ecx ebx eax + add esp,32 + mov eax,ebp + ret + +floppy_filesave: +;---------------------------------------------------------- +; +; filesave - sys floppy +; +; eax ; pointer to file name 11 chars - for root directory +; ebx ; buffer +; ecx ; count to write in bytes +; edx ; 0 create new , 1 append +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; output : eax = 0 - ok +; 5 - file not found / directory not found +; 8 - disk full +; 10 - access denied +;----------------------------------------------------------- + mov [path_pointer_flp],edi + sub esp,32 + call expand_filename + cmp edx,0 + jnz fsdel_1 + pusha + call floppy_filedelete + cmp [FDC_Status],0 + jne fdc_status_error_6 + popa + mov [save_flag],1 +fsdel_1: + call floppy_free_space + cmp [FDC_Status],0 + jne fdc_status_error_6 + cmp ecx,edi + jb rd_do_save_1 + add esp,32 + mov eax,8 ; not enough free space + mov [flp_status],0 + ret + +fdc_status_error_6: + popa + add esp,32 + jmp fdc_status_error_1 + +rd_do_save_1: + push eax ebx ecx edx esi edi + call read_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_7 + push eax + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + jne fifoundds_2 + pop eax + mov [save_root_flag],1 + call read_flp_root + cmp [FDC_Status],0 + jne fdc_status_error_7 + mov edi,FLOPPY_BUFF ;Point at directory + mov edx,224 +1 + ; find an empty spot for filename in the root dir +l20ds_1: + sub edx,1 + jz frnoreadds_1 +l21ds_1: + cmp [edi],byte 0xE5 + jz fifoundds_1 + cmp [edi],byte 0x0 + jz fifoundds_1 + add edi,32 ; Advance to next entry + jmp l20ds_1 + +fifoundds_2: + pop eax + mov [save_root_flag],0 + mov [FDD_Track],0 ; Öčėčķäš + mov [FDD_Head],1 ; Ńņīšīķą + mov [FDD_Sector],2 ; Ńåźņīš + call SeekTrack + mov dh,14 +l.20_3: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_7 + mov dl,16 + mov edi,FDD_BUFF + inc [FDD_Sector] +l.21_3: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifoundds_3 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + jne l.21_3 + dec dh + jne l.20_3 +fdc_status_error_8: + pop edi esi edx ecx ebx eax + mov eax,5 ; file not found ? + mov ebx,-1 + add esp,32 + mov [flp_status],0 + ret + +fifoundds_3: + 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_7_1 +found_directory_for_writing_flp: + call analyze_directory_to_write_flp + jc fdc_status_error_7_1 + mov edi,ebx +fifoundds_1: + push edi ; move the filename to root dir + mov esi,[esp+4+20] + cmp [save_root_flag],0 + jne fifoundds_4 + mov esi,[pointer_file_name_flp] +fifoundds_4: + mov ecx,11 + cld + rep movsb + pop edi + mov edx,edi + add edx,11+0xf ; edx <- cluster save position + mov ebx,[esp+12] ; save file size + mov [edi+28],ebx + mov [edi+11],byte 0x20 ; attribute + call get_date_for_file ; from FAT32.INC + mov [edi+24],ax ; date + mov [edi+18],ax ; date + call get_time_for_file ; from FAT32.INC + mov [edi+22],ax ; time + xor ax,ax + mov [edi+20],ax + mov ebx,1 ; first cluster + cmp [save_root_flag],0 + jne frnewds_1 + call frnewds_2 + pusha + call WriteSectWithRetr + popa + cmp [FDC_Status],0 + jne fdc_status_error_7 + jmp frnewds_3 + +frnewds_1: + call frnewds_2 +frnewds_3: + pusha ; move save to floppy cluster + add ebx,31 + mov eax,ebx + mov esi,[esp+32+16] + call take_data_from_application_1 + call save_chs_sector + cmp [FDC_Status],0 + jne fdc_status_error_7 + popa + mov eax,[esp+12] + cmp eax,512 + jb flnsa_1 + sub eax,512 + mov [esp+12],eax + mov eax,[esp+16] + add eax,512 + mov [esp+16],eax + jmp frnewds_1 + +frnewds_2: + add ebx,1 + mov edi,ebx ; find free cluster in FAT + shl edi,1 + add edi,FLOPPY_FAT + mov eax,[edi] + and eax,4095 + jnz frnewds_2 + mov [edx],bx ; save next cluster pos. to prev cl. + mov edx,edi ; next save pos abs mem add + ret + +flnsa_1: + mov [edi],word 4095 ; mark end of file - last cluster + cmp [save_root_flag],1 + jne flnsa_2 + call save_flp_root + cmp [FDC_Status],0 + jne fdc_status_error_7 +flnsa_2: + call save_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_7 +frnoreadds_1: + pop edi esi edx ecx ebx eax + add esp,32 + mov eax,0 + mov [flp_status],0 + ret + +fdc_status_error_7_1: + cmp [FDC_Status],0 + je fdc_status_error_8 +fdc_status_error_7: + pop edi esi edx ecx ebx eax + add esp,32 + jmp fdc_status_error_1 + +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 + + +analyze_directory_to_write_flp: +;-------------------------------- +; input : EAX = first cluster of the directory +; output : IF CARRY=0 EAX = sector where the file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,EDI,EDI not changed +; IF CARRY=1 +;-------------------------------- + + push ecx + push edx + push esi + +adr561: + mov [clust_tmp_flp],eax + add eax,31 + pusha + call read_chs_sector + popa + cmp [FDC_Status],0 + jne error_found_file_analyze1 + + mov ecx,512/32 + mov ebx,FDD_BUFF + +adr1_analyze1: + cmp byte [ebx],0x00 + je found_file_analyze1 + cmp byte [ebx],0xe5 + je found_file_analyze1 + +avanti: + add ebx,32 + loop adr1_analyze1 + + 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 adr561 + + call get_free_FAT ;this block of code add a new cluster + ;for the directory because the directory + ;is full + + mov [edi],word 0x0fff + + mov eax,[clust_tmp_flp] + shl eax,1 ;find next cluster from FAT + add eax,FLOPPY_FAT + sub edi,FLOPPY_FAT + mov [eax],di + + pusha + mov ecx,512/4 + xor eax,eax + mov edi,FDD_BUFF + cld + rep stosd + popa + + mov eax,edi + add eax,31 + pusha + call save_chs_sector + popa + cmp [FDC_Status],0 + jne error_found_file_analyze1 + mov ebx,FDD_BUFF + +found_file_analyze1: + + pop esi + pop edx + pop ecx + clc ;file found + ret + +error_found_file_analyze1: + pop esi + pop edx + pop ecx + stc + ret + +get_free_FAT_flp: +;------------------------------------------ +; input : EAX = # cluster for start the searching +; output : EAX = # first cluster found free +;------------------------------------------- + push ebx + + mov ebx,1 +check_new_flp: + add ebx,1 + mov edi,ebx ; find free cluster in FAT + shl edi,1 + add edi,FLOPPY_FAT + mov eax,[edi] + and eax,4095 + cmp eax,0x0 + jnz check_new_flp + + pop ebx + 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, 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, 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, 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->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 + 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: + 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, 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, 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 ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + 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 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 +; check existence + mov byte [ebp], 0 + call fd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + 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 + lea eax, [edi-(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 + +if 0 +;---------------------------------------------------------------- +; +; fs_FloppyExecute - LFN variant for executing from floppy +; +; esi points to floppy filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/fd/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_FloppyExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_FloppyExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + call read_flp_fat + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov eax, [eax+4] ; cluster + add eax, 31 + call read_chs_sector + cmp [FDC_Status], 0 + jnz .err + pop edi + mov esi, FDD_BUFF + push edi + mov ecx, 512/4 + rep movsd + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+4] + mov dx, [edx*2+FLOPPY_FAT] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret +end if + +;---------------------------------------------------------------- +; +; 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/hd_kolibri/kernel/fs/fat32.inc b/kernel/branches/hd_kolibri/kernel/fs/fat32.inc new file mode 100644 index 0000000000..b5b681da33 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/fat32.inc @@ -0,0 +1,3527 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 +cluster dd 0 ; used by file_write,makedir,append +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 + +sector_tmp dd 0 ; used by rename,append,file_write +entry_pos dd 0 ; used by rename,append,file_write + +old_filesize dd 0 ; used by append +new_filepos dd 0 ; used by append +bytes2write dd 0 ; used by append + +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 + dir_entry: times 32 db 0 + + startpath: times 255 db 0 + + 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: + 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 + +free_hd_channel: + cmp [hdbase], 0x1F0 + jne .IDE_Channel_2 +.IDE_Channel_1: + mov [IDE_Channel_1],0 + 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: +;----------------------------------------------------------- +; input : EAX = # cluster for start the searching +; 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 + + gff_test: + cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2 + jbe gff_in_range + 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: + 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 + + +analyze_directory_to_write: +;----------------------------------------------------------- +; input : EAX = first cluster of the directory +; output : IF CARRY=0 EAX = sector where the empty pos is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,ESI,EDI not changed +; IF CARRY=1 disk full or fat corrupted +; Note : if cluster=0 it's changed to read rootdir +;----------------------------------------------------------- + push ecx edx edi + + adw_new_cluster: + mov [cluster_tmp],eax + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja adw_not_found ; too big cluster number, something is wrong + cmp eax,2 + jnb adw_data_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fs_type],16 + jne adw_data_cluster + mov eax,[ROOT_START] + mov edx,[ROOT_SECTORS] + mov [fat16_root],1 ; flag for fat16 rootdir + jmp adw_new_sector + + adw_data_cluster: + sub eax,2 + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + adw_new_sector: + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne adw_not_found + + mov ecx,512/32 ; count of dir entrys per sector = 16 + + adw_analyze: + cmp byte [ebx],0x00 ; is free entry? + je adw_found ; yes + cmp byte [ebx],0xe5 ; is deleted entry? + je adw_found ; yes + add ebx,32 ; position of next dir entry + dec ecx + jnz adw_analyze + + inc eax ; next sector + dec edx + jne adw_new_sector + cmp [fat16_root],1 ; end of fat16 rootdir + je adw_not_found + + mov eax,[cluster_tmp] + call get_FAT ; get next cluster + cmp [hd_error],0 + jne adw_not_found + + cmp eax,2 ; incorrect fat chain? + jb adw_not_found ; yes + cmp eax,[fatRESERVED] ; is it end of directory? + jb adw_new_cluster ; no. analyse it + + mov eax,2 ; this block of code add a new cluster + call get_free_FAT ; for the directory because the directory + jc adw_not_found ; is full + + mov edx,[fatEND] ; new end for directory + call set_FAT + cmp [hd_error],0 + jne adw_not_found + + push eax ; save new cluster + mov edx,eax + mov eax,[cluster_tmp] ; change last cluster to point new cluster + call set_FAT + cmp [hd_error],0 + jne adw_not_found_1 + + mov ecx,-1 ; remove 1 cluster from free disk space + call add_disk_free_space + cmp [hd_error],0 + jne adw_not_found_1 + + mov ecx,512/4 + xor eax,eax + mov edi,buffer + cld + rep stosd ; clear new directory cluster + pop eax + + sub eax,2 + mov ecx,[SECTORS_PER_CLUSTER] + imul eax,ecx + add eax,[DATA_START] + mov ebx,buffer + push eax ; save sector number + + adw_set_empty_directory: + call hd_write + cmp [hd_error],0 + jne adw_not_found_1 + + inc eax ; next sector + dec ecx + jnz adw_set_empty_directory + + pop eax + + adw_found: + pop edi edx ecx + clc ; free space found + ret + adw_not_found_1: + add esp,4 + adw_not_found: + pop edi edx ecx + stc ; free space not 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 + + +set_data_cluster: +;----------------------------------------------------------- +; input : EAX = cluster +; EBX = pointer to buffer +; output : if CARRY=0 ok +; if CARRY=1 cluster out of range +;----------------------------------------------------------- + push eax ebx edx + + cmp eax,[LAST_CLUSTER] + ja sdc_error ; too big cluster number, something is wrong + sub eax,2 + jb sdc_error ; don't allow rootdir write + + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + sdc_write: + call hd_write + cmp [hd_error],0 + jne sdc_error + + add ebx,512 ; update pointer + inc eax + dec edx + jnz sdc_write + pop edx ebx eax + clc + ret + + sdc_error: + pop edx ebx 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 + call hd_write +; cmp [hd_error],0 +; jne add_not_fs + + add_not_fs: + pop ebx eax + + add_dfs_no: + ret + + +file_write: +;-------------------------------------------------------------------------- +; INPUT : user-reg register-in-this meaning symbol-in-this-routine +; +; EAX EDI system call to write / +; EBX EAX (PAR0) pointer to file-name PAR0 +; EDX ECX (PAR1) pointer to buffer PAR1 +; ECX EBX (PAR2) file size PAR2 +; ESI EDX (PAR3) pointer to path PAR3 +; +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 8 - disk full +; 10 - access denied +;-------------------------------------------------------------------------- + cmp [fs_type], 16 + jz fat_ok_for_writing + cmp [fs_type], 32 + jz fat_ok_for_writing + push ERROR_UNKNOWN_FS + pop eax + ret + + fat_ok_for_writing: +; call reserve_hd1 + + pushad + + xor edi,edi ; don't allow directory remove + call file_delete ; try to delete the file first + cmp [hd_error],0 + jne exit_write_access_1 + + test eax,eax + jz old_deleted ; deleted ok + cmp eax,ERROR_FILE_NOT_FOUND + jnz exit_write_access ; it exist but can't delete + + old_deleted: + mov ebx,PUSHAD_EDX + call get_cluster_of_a_path + jnc found_directory_for_writing + cmp [hd_error],0 + jne exit_write_access + + exit_writing_with_error: + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + + mov [hd1_status],0 + mov eax,ERROR_FILE_NOT_FOUND + ret + + exit_writing_disk_full_clear: + cmp [hd_error],0 + jne exit_write_access_1 + mov eax,[sector_tmp] + mov ebx,buffer + call hd_read ; read directory sector + cmp [hd_error],0 + jne exit_write_access_1 + + mov edx,[entry_pos] + mov byte [edx],0xe5 ; mark as deleted + call hd_write + cmp [hd_error],0 + jne exit_write_access_1 + + mov eax,[edx+20-2] ; FAT entry + mov ax,[edx+26] + and eax,[fatMASK] + call clear_cluster_chain + + exit_writing_disk_full: + cmp [hd_error],0 + jne exit_write_access_1 + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + mov [hd1_status],0 + mov eax,ERROR_DISK_FULL + ret + + exit_write_access: + popad + call update_disk ; write all of cache and fat to hd + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + + exit_write_access_1: + popad + exit_write_access_2: + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + +found_directory_for_writing: + call analyze_directory_to_write + jc exit_writing_disk_full + + mov [sector_tmp],eax + mov [entry_pos],ebx + push eax ; save directory sector + mov eax,2 + call get_free_FAT + mov [cluster],eax ; first free cluster + pop eax + jc exit_writing_disk_full + + mov esi,PUSHAD_EAX ; file name + mov edi,ebx ; pointer in buffer + mov ecx,11 + cld + rep movsb + + mov esi,PUSHAD_EBX ; file size (bytes left) + mov [ebx+28],esi ; file size + mov ecx,[cluster] + mov [ebx+26],cx ; 16 bits low of cluster + shr ecx,16 + mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) + mov byte [ebx+11],0x20 ; attribute = archive + + call set_current_time_for_entry + + mov ebx,buffer ; save the directory name,length,cluster + call hd_write + cmp [hd_error],0 + jne exit_write_access_1 + + imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes + xor ecx,ecx ; cluster count + mov ebx,PUSHAD_ECX ; ebx = buffer + +hd_new_block_write: + + mov eax,[cluster] ; eax = block + call set_data_cluster + cmp [hd_error],0 + jne exit_write_access_1 + + sub esi,edi ; sub wrote bytes + jbe file_saved_OK ; end if all done + add ebx,edi ; update buffer position + + inc eax + call get_free_FAT ; next free in FAT + jc exit_writing_disk_full_clear + + mov edx,eax + xchg eax,[cluster] ; get old cluster and save new cluster + call set_FAT ; add it in cluster chain + cmp [hd_error],0 + jne exit_write_access_1 + + dec ecx ; update cluster count + jmp hd_new_block_write + +file_saved_OK: + + mov edx,[fatEND] ; new end for cluster chain + call set_FAT + cmp [hd_error],0 + jne exit_write_access_1 + + dec ecx ; update cluster count + + call add_disk_free_space ; remove clusters from free disk space + cmp [hd_error],0 + jne exit_write_access_1 + + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + mov [hd1_status],0 + xor eax,eax + 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 + + +file_delete: +;----------------------------------------------------- +; input : eax = file/directory name +; edx = path +; edi = 1 - allow directory remove else don't remove directory +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 10 - access denied +;----------------------------------------------------- + cmp [fs_type], 16 + jz file_del_fat_ok + cmp [fs_type], 32 + jz file_del_fat_ok + push ERROR_UNKNOWN_FS + pop eax + ret + + file_del_fat_ok: + pushad + + mov ebx,edx + call get_cluster_of_a_path + jc file_to_delete_not_found + + mov ebx,PUSHAD_EAX ; file/directory name + call analyze_directory + jc file_to_delete_not_found + + test byte [ebx+11],0x10 ; is it directory? + jnz delete_no_access + + delete_notdir: + call delete_entry_name + cmp [hd_error],0 + jne delete_no_access + + mov eax,ecx ; first cluster of file + call clear_cluster_chain + cmp [hd_error],0 + jne delete_no_access + + popad + xor eax,eax + ret + + delete_no_access_1: + add esp,4 + delete_no_access: + popad + mov eax,ERROR_ACCESS_DENIED + ret + + file_to_delete_not_found: + cmp [hd_error],0 + jne delete_no_access + popad + mov eax,ERROR_FILE_NOT_FOUND + 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 + + +delete_entry_name: +;----------------------------------------------------- +; input : eax = directory sector +; ebx = directory pointer in buffer +; longname_sec = 2 previous directory sectors +; output : ecx = first cluster +; change : eax,ebx,edx +;----------------------------------------------------- + mov byte [ebx],0xe5 + mov ecx,[ebx+20-2] ; first cluster of file + mov cx,[ebx+26] ; 0 length files start cluster = 0 + and ecx,[fatMASK] + + delete_empty: + sub ebx,32 + cmp ebx,buffer + jnb delete_test_long + + mov ebx,buffer + call hd_write ; write directory sector back + cmp [hd_error],0 + jne delete_name_end + + xor eax,eax + xchg eax,[longname_sec2] + xchg eax,[longname_sec1] + test eax,eax ; is there previous directory sector? + jz delete_name_end ; no + + mov ebx,buffer + call hd_read ; read previous sector + cmp [hd_error],0 + jne delete_name_end + + mov ebx,buffer+0x1e0 ; start from last entry + + delete_test_long: + mov dh,[ebx+11] ; file attribute + and dh,0xf + cmp dh,0xf + jne delete_write_buffer + + cmp byte [ebx],0x40 ; end of long dir entry? + mov byte [ebx],0xe5 + jb delete_empty + + delete_write_buffer: + mov ebx,buffer + call hd_write ; write directory sector back + + delete_name_end: + 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 + +read_hd_file: +;----------------------------------------------------------------- +; +; Converting old reading function for hd-application start. +; +; IN: +; +; eax - pointer to file (0 = read only first sector of drive: eg 'label') +; 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) +; +; For new read function +; +; EAX (PAR0) pointer to file-name +; ECX (PAR1) pointer to buffer +; EBX (PAR2) vt file blocks to read +; EDX (PAR3) pointer to path +; ESI vt first 512 block to read +; EDI if 0 - return root +;-------------------------------------------------------------------------- + + push ecx esi edi + mov esi,eax + mov edi,startpath + mov ecx,250 + cld + rep movsb + pop edi esi ecx + + mov eax,startpath + mov [eax+ebx-12],byte 0 + + push eax ebx ecx edx esi + + pop ecx ; pointer to buffer + add ecx,1024 + pop ebx ; number of blocks to read + pop esi ; first block to read + dec esi + pop eax ; file length + pop edx ; pointer to path + + mov edi,12 + lea eax,[eax+edx-12+1] + call file_read + + ret + +; \begin{diamond} +hd_find_lfn: +; in: esi->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 + 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: + 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 + mov eax, [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 ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + 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 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 +; check existence + mov byte [ebp], 0 + call hd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + 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 + mov eax, 2 + 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 + mov eax, edx + 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 + +if 0 ; starting from revision 237 execute is implemented in taskman.inc + ; through fs_XxxGetFileInfo and fs_XxxRead +;---------------------------------------------------------------- +; +; fs_HdExecute - LFN variant for executing from harddisk +; +; esi points to hd filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/hd0/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_HdExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_HdExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp [fat_type], 0 + jnz @f + mov eax, -ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call hd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + cmp [hd_error], 0 + jz @f + mov al, -11 +@@: + ret +.found: + mov eax, [edi+20-2] + mov ax, [edi+26] + push 0 + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 16 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + add eax, 4 + call fat_get_sector + mov ebx, edi + call hd_read + cmp [hd_error], 0 + jnz .err + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + lea edi, [edi+ecx+512] + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+8] + inc edx + cmp edx, [SECTORS_PER_CLUSTER] + jb @f + push eax + mov eax, [eax+4] + call get_FAT + cmp [hd_error], 0 + jnz .err + mov ecx, eax + pop eax + mov [eax+4], ecx + xor edx, edx +@@: + mov [eax+8], edx + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret +end if + +;---------------------------------------------------------------- +; +; 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/hd_kolibri/kernel/fs/fs.inc b/kernel/branches/hd_kolibri/kernel/fs/fs.inc new file mode 100644 index 0000000000..2b6b667487 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/fs.inc @@ -0,0 +1,841 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 = 1 ; write file /RamDisk/First 33 /HardDisk/First 56 +; 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: + + cmp dword [esp+20],1 ; WRITE + jne fs_noramdisk_write + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+8] ; buffer + mov ecx,[esp+12] ; count to write + mov edx,0 ; create new + call filesave + + ; eax=0 ok - eax=1 not enough free space + + jmp file_system_return + + fs_noramdisk_write: + 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: + + cmp dword [esp+20],1 ; WRITE + jne fs_noflpdisk_write + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+8] ; buffer + mov ecx,[esp+12] ; count to write + mov edx,0 ; create new + call floppy_filesave + + ; eax=0 ok - eax=1 not enough free space + + jmp file_system_return + + fs_noflpdisk_write: + + 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 + search_partition_array: + mov bl,[edx] + movzx ebx,bl + add eax,ebx + inc edx + loop search_partition_array + sub eax,ebx + 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: + + + cmp dword [esp+20],1 ; WRITE + jne fs_noharddisk_write + + mov eax,[esp+0] ; /fname + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + + mov ebx,[esp+12] ; count to write + mov ecx,[esp+8] ; buffer + mov edx,[esp+4] + add edx,12*2 ; path start + + call file_write + + mov edi,[esp+0] + mov byte [edi],'/' + + ; eax=0 ok - eax=1 not enough free space + + call free_hd_channel + and [hd1_status], 0 + jmp file_system_return + + + fs_noharddisk_write: + + + 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/hd_kolibri/kernel/fs/fs_lfn.inc b/kernel/branches/hd_kolibri/kernel/fs/fs_lfn.inc new file mode 100644 index 0000000000..8245468961 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/fs_lfn.inc @@ -0,0 +1,686 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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 +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 + + add eax, std_application_base_address +; parse file name + xchg ebx, eax + lea esi, [ebx+20] + mov ebp, esi ; for 'start app' function full path must be known + lodsb + test al, al + jnz @f + mov esi, [esi] + add esi, std_application_base_address + mov ebp, esi + lodsb +@@: + cmp dword [ebx], 7 + jne @F + mov edx, [ebx+4] + mov ebx, [ebx+8] + test ebx, ebx + jz .l1 + add ebx, new_app_base +.l1: + call fs_execute ; ebp, ebx, edx + mov [esp+36], eax + ret +@@: + cmp al, '/' + jz @f +.notfound: + mov dword [esp+36], 5 ; file not found + ret +@@: + cmp byte [esi], 0 + jz .rootdir + mov edi, rootdirs-8 + xor ecx, ecx + push esi +.scan1: + pop esi + add edi, ecx + scasd + scasd + mov cl, byte [edi] + jecxz .notfound + 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: + 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 + mov esi, [edi+4] +; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler + mov edi, edx + mov ecx, 32/4 + rep stosd + 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 + mov ecx, 40/4-2 + rep stosd + pop eax + push eax edx +; convert number in eax to decimal UNICODE string + push edi + push -'0' + mov cl, 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 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 [esp+36], eax + mov [esp+24], ebx + ret +; directory / +.rootdir: + cmp dword [ebx], 1 ; read folder? + jz .readroot +.access_denied: + mov dword [esp+36], 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 + 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], 1 ; 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: + pop eax + mov ebx, [edx+4] + xor eax, eax + dec ebp + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+36], eax + mov [esp+24], ebx + ret + +.found1: + pop eax + cmp byte [esi], 0 + jz .maindir +; 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 .notfound + imul ecx, 10 + add ecx, eax + jmp @b +.done1: + test ecx, ecx + jz .notfound + test al, al + jnz @f + dec esi +@@: +; 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 +; out: [esp+36]=image of eax, [esp+24]=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 [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + mov dword [esp+36], 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 ;fs_RamdiskExecute + 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 [esp+36], eax + mov [esp+24], 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 ;fs_FloppyExecute + 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 .nf + cmp cl, [DRIVE_DATA+1+eax] + jbe @f +.nf: + call free_hd_channel + and [hd1_status], 0 + mov dword [esp+36], 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 [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + call free_hd_channel + and [hd1_status], 0 + mov dword [esp+36], 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 ;fs_HdExecute + dd fs_HdDelete + dd fs_HdCreateFolder +fs_NumHdServices = ($ - fs_HdServices)/4 + +;******************************************************* +fs_OnCd0: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],0 + push 6 + jmp fs_OnCd +fs_OnCd1: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],1 + push 4 + jmp fs_OnCd +fs_OnCd2: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],0 + push 2 + jmp fs_OnCd +fs_OnCd3: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],1 + push 0 +fs_OnCd: + call reserve_cd_channel + pop eax + mov [hdpos], 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 [esp+36], 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 [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + call free_cd_channel + and [cd_status], 0 + mov dword [esp+36], 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 fs_CdExecute +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 +;******************************************************* + diff --git a/kernel/branches/hd_kolibri/kernel/fs/iso9660.inc b/kernel/branches/hd_kolibri/kernel/fs/iso9660.inc new file mode 100644 index 0000000000..4243ef69b9 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/iso9660.inc @@ -0,0 +1,833 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + +CDDataBuf equ 0x7000 + +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 al + shl eax,1 +; żņī źąņąėīć? + test [ebp-8],byte 2 + jz .file + inc al +.file: +; ģåņźą ņīģą ķå źąź ā FAT, ā żņīģ āčäå īņńóņńāóåņ +; ōąéė ķå ’āė’åņń’ ńčńņåģķūģ + shl eax,3 +; ōąéė ’āė’åņń’ ńźšūņūģ? (ąņščįóņ ńółåńņāīāąķčå) + test [ebp-8],byte 1 + jz .hidden + inc al +.hidden: + shl eax,1 +; ōąéė āńåćäą ņīėüźī äė’ ÷ņåķč’, ņąź źąź żņī CD + inc al + 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 ebp + call cd_find_lfn + pushfd + cmp [DevErrorCode], 0 + jz @f + popfd + pop ebp edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop ebp edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + + mov edi, edx + call cd_get_parameters_of_file_1 + and dword [edi+4], 0 + pop ebp edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_CdExecute - LFN variant for executing from CD +; +; esi points to hd filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/hd0/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_CdExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_CdExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call cd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + cmp [DevErrorCode], 0 + jz @f + mov al, -11 +@@: + ret +.found: + mov edi,[cd_current_pointer_of_input] + mov eax,[edi+2] + push 0 + push eax + push dword [edi+10] ; size + push .DoRead + call fs_execute + add esp, 16 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + cmp [eax+8],dword 0 + jne @f + mov ecx,[eax+4] + inc dword [eax+4] + mov [CDSectorAddress],ecx + mov [CDDataBuf_pointer],CDDataBuf ;edi + call ReadCDWRetr + cmp [DevErrorCode], 0 + jnz .err +@@: + push esi edi ecx + mov esi,512 + imul esi,[eax+8] + add esi,CDDataBuf + mov ecx,512/4 + cld + rep movsd + pop ecx edi esi + + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + lea edi, [edi+ecx+512] + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+8] + inc edx + cmp edx, 4 ; 2048/512=4 + jb @f + xor edx, edx +@@: + mov [eax+8], edx + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + +cd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and [cd_current_pointer_of_input] direntry + push eax esi +; 16 ńåźņīš ķą÷ąėī ķąįīšą äåńźščļņīšīā ņīģīā + mov [CDSectorAddress],dword 15 +.start: + inc dword [CDSectorAddress] + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr + cmp [DevErrorCode],0 + jne .access_denied +; ļšīāåšźą ķą āųčāīńņü + 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 + call cd_find_name_in_buffer + jnc .found + sub eax,2048 +; äčšåźņīšč’ ēąźīķ÷čėąńü? + cmp eax,0 + ja .read_to_buffer +; ķåņ čńźīģīćī żėåģåķņą öåļī÷źč +.access_denied: + pop esi eax + stc + ret +; čńźīģūé żėåģåķņ öåļī÷źč ķąéäåķ + .found: +; źīķåö ļóņč ōąéėą + cmp byte [esi-1], 0 + jz .done + mov eax,[cd_current_pointer_of_input] + push dword [eax+2] + pop dword [CDSectorAddress] ; ķą÷ąėī äčšåźņīščč + mov eax,[eax+2+8] ; šąēģåš äčšåźņīščč + jmp .mainloop +; óźąēąņåėü ōąéėą ķąéäåķ + .done: + pop esi eax + 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 ax + call char_todown + call ansi2uni_char + xchg ah,al + cld + scasw + pop ax + je .coincides + call char_toupper + call ansi2uni_char + xchg ah,al + cld + 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/hd_kolibri/kernel/fs/ntfs.inc b/kernel/branches/hd_kolibri/kernel/fs/ntfs.inc new file mode 100644 index 0000000000..d81e1f5614 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/ntfs.inc @@ -0,0 +1,1798 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 .okret + sub eax, 0x200 + add [ntfs_cur_read], eax + jmp .okret +.errread2: + pop ecx + add esp, 10h + jmp .errret +.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->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 + 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 +.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 + 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/hd_kolibri/kernel/fs/part_set.inc b/kernel/branches/hd_kolibri/kernel/fs/part_set.inc new file mode 100644 index 0000000000..2491bc9e99 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/fs/part_set.inc @@ -0,0 +1,452 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;************************************************************* +;* 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 + +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 + 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 + + cmp dword [hdpos],0 + je problem_hd + + pushad + 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 + + 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: + popad + +problem_hd: + 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 + + 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 + + ; 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 + + 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/hd_kolibri/kernel/gui/button.inc b/kernel/branches/hd_kolibri/kernel/gui/button.inc new file mode 100644 index 0000000000..6a17035159 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/button.inc @@ -0,0 +1,674 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 eax,16 + shr ebx,16 + mov edx,[TASK_BASE] + + add eax,[edx-twdw + WDATA.box.left] + add ebx,[edx-twdw + WDATA.box.top] + mov cx,ax + mov dx,bx + shl eax,16 + shl ebx,16 + mov ax,cx + mov bx,dx + add ax,word [esp+12] + mov esi,ebx + mov edi,0 + mov ecx,[esp+0] + call incecx + call [draw_line] + + movzx edx,word [esp+8] + add ebx,edx + shl edx,16 + add ebx,edx + mov ecx,[esp+0] + call dececx + call [draw_line] + + mov ebx,esi + push edx + mov edx,eax + shr edx,16 + mov ax,dx + mov edx,ebx + shr edx,16 + mov bx,dx + mov dx,[esp+8+4] + add bx,dx + pop edx + mov edi,0 + mov ecx,[esp+0] + call incecx + call [draw_line] + + mov esi,edx + mov dx,[esp+12] + add ax,dx + shl edx,16 + add eax,edx + add ebx,1*65536 + mov edx,esi + mov ecx,[esp+0] + 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: + + push edi + mov edi,[CURRENT_TASK] + shl edi,8 + rol eax,16 + add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol eax,16 + rol ebx,16 + add bx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol ebx,16 + pop edi + .forced: + + test ecx,0x80000000 + jnz remove_button + + push esi + push edi + push eax ; + push ebx ; + push ecx ; + push edx + + or ax,ax + jle noaddbutt + or bx,bx + jle noaddbutt + + test ecx,0x40000000 + jnz button_no_draw + + pushad ; button body + push ebx + shr eax,16 + shr ebx,16 + mov edx,[TASK_BASE] + mov esi,[edx-twdw + WDATA.box.left] + mov edi,[edx-twdw + WDATA.box.top] + add eax,esi + add ebx,edi + mov cx,ax + mov dx,bx + shl eax,16 + shl ebx,16 + mov ax,cx + mov bx,dx + movzx ecx,word [4+32+esp+12] + add eax,ecx + mov ecx,[4+32+esp+0] + cmp [buttontype],dword 0 + je @f + call incecx2 + @@: + movzx edi,word [esp] + + pop edx + and edx, 0xFFFF + + .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: + + and ecx,0xffff + + mov edi,[BTN_ADDR] + movzx eax,word [edi] + cmp eax,max_buttons + jge noaddbutt + 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 ebx,[esp+4] + mov [eax],bx ; bits 0-15 + shr ebx,16 + mov [eax-2+0xc],bx; bits 16-31 + add eax,2 ; x start + mov bx,[esp+12+2] + mov [eax],bx + add eax,2 ; x size + mov bx,[esp+12+0] + mov [eax],bx + add eax,2 ; y start + mov bx,[esp+8+2] + mov [eax],bx + add eax,2 ; y size + mov bx,[esp+8+0] + mov [eax],bx + + noaddbutt: + + pop edx + pop ecx + pop ebx + pop eax + pop edi + pop esi + + ret + + +remove_button: + + and ecx,0x7fffffff + + rnewba2: + + mov edi,[BTN_ADDR] + mov eax,edi + movzx ebx,word [edi] + inc bx + + rnewba: + + dec bx + jz rnmba + + add eax,0x10 + + mov dx,[CURRENT_TASK] + cmp dx,[eax] + jnz rnewba + + cmp cx,[eax+2] + jnz rnewba + + pushad + mov ecx,ebx + inc ecx + shl ecx,4 + mov ebx,eax + add eax,0x10 + call memmove + dec dword [edi] + popad + + 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 + 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 + jmp @f + 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 + @@: + + 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/hd_kolibri/kernel/gui/event.inc b/kernel/branches/hd_kolibri/kernel/gui/event.inc new file mode 100644 index 0000000000..4ea8596bc8 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/event.inc @@ -0,0 +1,692 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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_TASK] + shl ecx,8 + add ecx, SLOT_BASE+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_TASK] + shl edx,8 +; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0 +; je .switch + + add edx, SLOT_BASE+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_TASK] + shl edx,8 + add edx, SLOT_BASE + + 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+36],eax + ret + + +align 4 +sys_wait_event_timeout: + + mov ebx,[timer_ticks] + add ebx,eax + cmp ebx,[timer_ticks] + jna .swfet2 +.swfet1: + call get_event_for_app + test eax,eax + jne .eventoccur_time + call change_task + cmp ebx,[timer_ticks] + jg .swfet1 +.swfet2: + xor eax,eax +.eventoccur_time: + mov [esp+36],eax + ret + + +align 4 + +sys_waitforevent: + + call get_event_for_app + test eax,eax + jne eventoccur + newwait: + + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + + mov eax, [event_sched] + + eventoccur: + mov [esp+36],eax + ret + +get_event_for_app: + + pushad + + mov edi,[TASK_BASE] ; WINDOW REDRAW + test [edi+TASKDATA.event_mask],dword 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 + test [edi+TASKDATA.event_mask],dword 00100000b + jz no_mouse_event + mov eax,[CURRENT_TASK] + shl eax,8 + test [eax+SLOT_BASE+APPDATA.event_mask],dword 00100000b + jz no_mouse_event + and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-00100000b + popad + mov eax,6 + ret + no_mouse_event: + + + ;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW + test [edi+TASKDATA.event_mask],dword 16 + jz no_eventoccur5 + cmp [REDRAW_BACKGROUND],byte 2 + jnz no_eventoccur5 + popad + mov eax,5 + ret + no_eventoccur5: + + ;mov edi,[TASK_BASE] ; IPC + test [edi+TASKDATA.event_mask],dword 01000000b + jz no_ipc + mov eax,[CURRENT_TASK] + shl eax,8 + test [eax+SLOT_BASE+APPDATA.event_mask],dword 01000000b + jz no_ipc + and [eax+SLOT_BASE+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 + mov eax,[CURRENT_TASK] + shl eax,8 + test [eax+SLOT_BASE+APPDATA.event_mask],dword 10000000b + jz no_stack_event + and [eax+SLOT_BASE+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 + mov eax, [CURRENT_TASK] + shl eax, 8 + test byte [eax+SLOT_BASE+APPDATA.event_mask+1], byte 1 + jz .test_IRQ + and byte [eax+SLOT_BASE+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/hd_kolibri/kernel/gui/font.inc b/kernel/branches/hd_kolibri/kernel/gui/font.inc new file mode 100644 index 0000000000..c3f1f51c7e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/font.inc @@ -0,0 +1,115 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) + ; eax x & y + ; ebx style ( 0xX0000000 ) & color ( 0x00RRGGBB ) + ; X = ABnnb: + ; nn = font + ; A = 0 <=> output edx characters; otherwise output ASCIIZ string + ; B = 1 <=> fill background with color esi + ; ecx start of text + ; edi 1 force + + pushad + call [disable_mouse] + + mov ebp, ecx ; ebp=pointer to text + mov ecx, ebx ; ecx=color + movsx ebx, ax ; ebx=y + sar eax, 16 ; eax=x + cmp edx, 255 + jb .loop + mov edx, 255 +.loop: + test ecx, ecx + js .test_asciiz + dec edx + js .end + jmp @f +.test_asciiz: + cmp byte [ebp], 0 + jz .end +@@: + push edx + movzx edx, byte [ebp] + inc ebp + test ecx, 0x10000000 + jnz .font2 + pushad + 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+4] + 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 + pop edx + jmp .loop +.font2: + pushad + 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+4] + 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 + pop edx + jmp .loop +.end: + popad + ret diff --git a/kernel/branches/hd_kolibri/kernel/gui/mouse.inc b/kernel/branches/hd_kolibri/kernel/gui/mouse.inc new file mode 100644 index 0000000000..5046e86fe6 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/mouse.inc @@ -0,0 +1,248 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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/hd_kolibri/kernel/gui/skincode.inc b/kernel/branches/hd_kolibri/kernel/gui/skincode.inc new file mode 100644 index 0000000000..fe83047f2c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/skincode.inc @@ -0,0 +1,480 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +include "skindata.inc" + +;skin_data = 0x00778000 + +load_skin_file: +; eax = filename +; edx = destination + mov ebx,1 + or ecx,-1 + mov esi,12 +; call fileread + + pushad + push eax + sub edx,std_application_base_address + mov [skin_to_load.adr],edx + + ;sub eax,std_application_base_address + ;mov [skin_to_load.stradr],eax + mov [skin_to_load.stradr],_skin_file_default - std_application_base_address + mov eax,skin_to_load - std_application_base_address + call file_system_lfn + ;call fileread + pop eax + popad + ret + + + ret + + +skin_to_load: + dd 0,0,0 + dd 64*1024 + .adr dd 0 + db 0 + .stradr dd 0 + + +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_skin: + pushad + mov [_skinh],22 + mov eax,_skin_file + mov edx,skin_data + mov [edx+SKIN_HEADER.ident],'????' + call load_skin_file + cmp eax,ERROR_SUCCESS + je @f + cmp eax,ERROR_END_OF_FILE + jne .exit + @@: call parse_skin_data + .exit: + popad + 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/hd_kolibri/kernel/gui/skindata.inc b/kernel/branches/hd_kolibri/kernel/gui/skindata.inc new file mode 100644 index 0000000000..7fae8eed5c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/skindata.inc @@ -0,0 +1,64 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; WINDOW SKIN DATA +; + +iglobal + _skin_file_default db '/hd0/1/kolibri/etc/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 + + _skin_file rb 256 + +align 4 + +skin_udata.end: + +endg diff --git a/kernel/branches/hd_kolibri/kernel/gui/window.inc b/kernel/branches/hd_kolibri/kernel/gui/window.inc new file mode 100644 index 0000000000..fbaea19991 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/gui/window.inc @@ -0,0 +1,1799 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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, [ScreenWidth] ; 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, [ScreenWidth] + 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, [ScreenWidth] ; 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, [ScreenWidth] ; 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,[ScreenWidth] + mov [dlxe],eax + mov eax,[ScreenHeight] + 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;[ScreenWidth] + jl @f + mov [screen_workarea.left],eax + @@: cmp ebx,[ScreenWidth] + 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,[ScreenHeight] + jg .lp2 + mov [screen_workarea.bottom],ebx + .lp2: call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] + 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 + mov eax,ebx + mov edi,[TASK_BASE] + add ebx,[edi+TASKDATA.mem_start] ; abs start of info block + pushd [ebx+0] [ebx+4] [ebx+8] [ebx+12] + mov dword[ebx+0],0 ; read + mov dword[ebx+4],0 ; from the beginning + mov dword[ebx+8],64 ; 32 KBytes maximum + mov ecx,skin_data+64*512 + sub ecx,[edi+0x10] + mov dword[ebx+12],ecx ; destination + push eax + pushad + call file_system + popad + pop eax + popd [ebx+12] [ebx+8] [ebx+4] [ebx+0] + cmp eax,ERROR_SUCCESS + je @f + cmp eax,ERROR_END_OF_FILE + jne .exit + @@: cmp [skin_data+64*512+SKIN_HEADER.ident],'SKIN' + mov eax,ERROR_UNKNOWN_FS + jne .exit + mov esi,skin_data+64*512 + mov edi,skin_data + mov ecx,(64*512)/4 + rep movsd + call parse_skin_data + pushad + mov eax, 0 + mov ebx, 0 + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] + call calculatescreen + popad + mov dword[esp+32+36],0 + jmp redraw_screen_direct + .exit: + mov [esp+32+36],eax + popad + ret + no_set_skin: + + popad + ret + + +repos_windows: + mov ecx,[TASK_COUNT] + mov edi, OS_BASE+0x20*2 + mov byte[REDRAW_BACKGROUND],1 + 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,[ScreenWidth] +; 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,[ScreenHeight] +; 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 ? + + movzx eax,word [edi+WDATA.box.left] + movzx ebx,word [edi+WDATA.box.top] + movzx ecx,word [edi+WDATA.box.width] + movzx edx,word [edi+WDATA.box.height] + + mov esi,ecx ; check x pos + add esi,eax + cmp esi,[ScreenWidth] + jbe x_pos_ok + mov [edi+WDATA.box.left],dword 0 + xor eax, eax + x_pos_ok: + + mov esi,edx ; check y pos + add esi,ebx + cmp esi,[ScreenHeight] + jbe y_pos_ok + mov [edi+WDATA.box.top],dword 0 + mov ebx,0 + y_pos_ok: + + mov esi,ecx ; check x size + add esi,eax + cmp esi,[ScreenWidth] + jbe x_size_ok + mov ecx,[ScreenWidth] + mov [edi+WDATA.box.width],ecx + x_size_ok: + + mov esi,edx ; check y size + add esi,ebx + cmp esi,[ScreenHeight] + jbe y_size_ok + mov edx,[ScreenHeight] + mov [edi+WDATA.box.height],edx + y_size_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 + jne @f + 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 + 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 + + 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, 0x02000000 + 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 eax,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,[ScreenWidth] + mov bx,[ScreenHeight] + + 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 + + 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 + call set_window_clientbox + + no_window_shade: + + 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,[ScreenHeight] + jbe no_window_sizing + mov eax,[edi+WDATA.box.left] ; check X inside screen + add eax,[edi+WDATA.box.width] + cmp eax,[ScreenWidth] + jbe no_window_sizing + mov eax,[ScreenWidth] + sub eax,[edi+WDATA.box.width] + mov [edi+WDATA.box.left],eax + mov eax,[ScreenHeight] + 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_TASK] + shl eax,8 + + mov [eax+SLOT_BASE+APPDATA.wnd_shape],ebx + rsw_no_address: + + cmp eax,1 + jne rsw_no_scale + mov eax,[CURRENT_TASK] + shl eax,8 + mov byte [eax+SLOT_BASE+APPDATA.wnd_shape_scale], bl + rsw_no_scale: + + ret + + diff --git a/kernel/branches/hd_kolibri/kernel/hid/keyboard.inc b/kernel/branches/hd_kolibri/kernel/hid/keyboard.inc new file mode 100644 index 0000000000..2992c276d5 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/keyboard.inc @@ -0,0 +1,302 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;// 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 + 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 ] diff --git a/kernel/branches/hd_kolibri/kernel/hid/keymap.inc b/kernel/branches/hd_kolibri/kernel/hid/keymap.inc new file mode 100644 index 0000000000..63b283de46 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/keymap.inc @@ -0,0 +1,40 @@ +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' \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/hid/m_com1.inc b/kernel/branches/hd_kolibri/kernel/hid/m_com1.inc new file mode 100644 index 0000000000..9d1eef314b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/m_com1.inc @@ -0,0 +1,138 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Ķīģåš ļščķčģąåģīćī īņ ģūųč įąéņą +MouseByteNumber DB 0 +; Ņšåõįąéņīāą’ ńņšóźņóšą äąķķūõ, ļåšåäąāąåģą’ ģūųüž +FirstByte DB 0 +SecondByte DB 0 +ThirdByte DB 0 +timer_ticks_com dd 0 +;*************************************** +;* ĶĪĀŪÉ ĪĮŠĄĮĪŅ×ČŹ ĻŠÅŠŪĀĄĶČß ĪŅ ĢŪŲČ * +;*************************************** +check_mouse_data_com1: +; cmp [com1_mouse_detected],0 +; je @@EndMouseInterrupt +; Ļšīāåščņü ķąėč÷čå äąķķūõ + mov DX,3F8h ;[COMPortBaseAddr] + add DX,5 ;xFDh + in AL,DX + test AL,1 ;Äąķķūå ćīņīāū? + jz @@Error +; Āāåńņč äąķķūå + mov DX,3F8h ;[COMPortBaseAddr] ;xF8h + in AL,DX +; Ńįšīńčņü ńņąšųčé ķåēķą÷ąłčé įčņ + and AL,01111111b + +; Īļšåäåėčņü ļīš’äźīāūé ķīģåš ļščķčģąåģīćī įąéņą + cmp [MouseByteNumber],0 + je @@FirstByte + cmp [MouseByteNumber],1 + je @@SecondByte + cmp [MouseByteNumber],2 + je @@ThirdByte + jmp @@Error + +; Ńīõšąķčņü ļåšāūé įąéņ äąķķūõ +@@FirstByte: + test AL,1000000b ;Ļåšāūé įąéņ ļīńūėźč? + jz @@Error + mov [FirstByte],AL + inc [MouseByteNumber] ;óāåėč÷čņü ń÷åņ÷čź + jmp @@EndMouseInterrupt +; Ńīõšąķčņü āņīšīé įąéņ äąķķūõ +@@SecondByte: + test AL,1000000b + jnz @@Error + mov [SecondByte],AL + inc [MouseByteNumber] ;óāåėč÷čņü ń÷åņ÷čź + jmp @@EndMouseInterrupt +; Ńīõšąķčņü ņšåņčé įąéņ äąķķūõ +@@ThirdByte: + test AL,1000000b + jnz @@Error + mov [ThirdByte],AL ;óāåėč÷čņü ń÷åņ÷čź + mov [MouseByteNumber],0 +; (Ļąźåņ äąķķūõ īņ ģūųč ļščķ’ņ ļīėķīńņüž). +; Ēąļčńąņü ķīāīå ēķą÷åķčå ńīńņī’ķč’ źķīļīź ģūųč + mov al,[FirstByte] ;[0xfb01] + mov ah,al + shr al,3 + and al,2 + shr ah,5 + and ah,1 + add al,ah + mov [BTN_DOWN],al + mov [mouse_active],1 +; Ļščįąāčņü ļåšåģåłåķčå ļī X ź źīīšäčķąņå X + mov AL,[FirstByte] + shl AL,6 + or AL,[SecondByte] + cbw + call mouse_acceleration_com1 + add AX,[MOUSE_X] ;[XCoordinate] + ; Źóšńīš ķå äīėęåķ āūõīäčņü ēą ėåāóž čėč + ; ļšąāóž ćšąķčöó żźšąķą + js @@X1 + cmp AX,[ScreenWidth] ;ScreenLength + jb @@X2 + ; Óńņąķīāčņü źīīšäčķąņó X ļī ļšąāīé ćšąķčöå + mov AX,[ScreenWidth] ;ScreenLength-1 + dec ax + jmp @@X2 +@@X1: + ; Óńņąķīāčņü źīīšäčķąņó X ļī ėåāīé ćšąķčöå + xor AX,AX +@@X2: + mov [MOUSE_X],AX ;[XCoordinate] + ; Ļščįąāčņü ļåšåģåłåķčå ļī Y ź źīīšäčķąņå Y + mov AL,[FirstByte] + and AL,00001100b + shl AL,4 + or AL,[ThirdByte] + cbw + call mouse_acceleration_com1 + add AX,[MOUSE_Y] ;[YCoordinate] + ; Źóšńīš ķå äīėęåķ āūõīäčņü ēą āåšõķžž čėč + ; ķčęķžž ćšąķčöó żźšąķą + js @@Y1 + cmp AX,[ScreenHeight] ;ScreenHeigth + jb @@Y2 + ; Óńņąķīāčņü źīīšäčķąņó X ļī ķčęķåé ćšąķčöå + mov AX,[ScreenHeight] ;ScreenHeigth-1 + dec ax + jmp @@Y2 +@@Y1: + ; Óńņąķīāčņü źīīšäčķąņó X ļī āåšõķåé ćšąķčöå + xor AX,AX +@@Y2: + mov [MOUSE_Y],AX ;[YCoordinate] + mov eax,[timer_ticks] + mov [timer_ticks_com],eax + jmp @@EndMouseInterrupt + +@@Error: +; Ļšīčēīųåė ńįīé ā ļīš’äźå ļåšåäą÷č čķōīšģąöčč īņ +; ģūųč, īįķóėčņü ń÷åņ÷čź įąéņīā ļąźåņą äąķķūõ + mov [MouseByteNumber],0 +@@EndMouseInterrupt: + call ready_for_next_irq + ret + +mouse_acceleration_com1: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_com] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret diff --git a/kernel/branches/hd_kolibri/kernel/hid/m_com2.inc b/kernel/branches/hd_kolibri/kernel/hid/m_com2.inc new file mode 100644 index 0000000000..5f5a309f27 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/m_com2.inc @@ -0,0 +1,138 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Ķīģåš ļščķčģąåģīćī īņ ģūųč įąéņą +MouseByteNumber_1 DB 0 +; Ņšåõįąéņīāą’ ńņšóźņóšą äąķķūõ, ļåšåäąāąåģą’ ģūųüž +FirstByte_1 DB 0 +SecondByte_1 DB 0 +ThirdByte_1 DB 0 +timer_ticks_com_1 dd 0 +;*************************************** +;* ĶĪĀŪÉ ĪĮŠĄĮĪŅ×ČŹ ĻŠÅŠŪĀĄĶČß ĪŅ ĢŪŲČ * +;*************************************** +check_mouse_data_com2: +; cmp [com2_mouse_detected],0 +; je @@EndMouseInterrupt_1 +; Ļšīāåščņü ķąėč÷čå äąķķūõ + mov DX,2F8h ;[COMPortBaseAddr] + add DX,5 ;xFDh + in AL,DX + test AL,1 ;Äąķķūå ćīņīāū? + jz @@Error_1 +; Āāåńņč äąķķūå + mov DX,2F8h ;[COMPortBaseAddr] ;xF8h + in AL,DX +; Ńįšīńčņü ńņąšųčé ķåēķą÷ąłčé įčņ + and AL,01111111b + +; Īļšåäåėčņü ļīš’äźīāūé ķīģåš ļščķčģąåģīćī įąéņą + cmp [MouseByteNumber_1],0 + je @@FirstByte_1 + cmp [MouseByteNumber_1],1 + je @@SecondByte_1 + cmp [MouseByteNumber_1],2 + je @@ThirdByte_1 + jmp @@Error_1 + +; Ńīõšąķčņü ļåšāūé įąéņ äąķķūõ +@@FirstByte_1: + test AL,1000000b ;Ļåšāūé įąéņ ļīńūėźč? + jz @@Error_1 + mov [FirstByte_1],AL + inc [MouseByteNumber_1] ;óāåėč÷čņü ń÷åņ÷čź + jmp @@EndMouseInterrupt_1 +; Ńīõšąķčņü āņīšīé įąéņ äąķķūõ +@@SecondByte_1: + test AL,1000000b + jnz @@Error_1 + mov [SecondByte_1],AL + inc [MouseByteNumber_1] ;óāåėč÷čņü ń÷åņ÷čź + jmp @@EndMouseInterrupt_1 +; Ńīõšąķčņü ņšåņčé įąéņ äąķķūõ +@@ThirdByte_1: + test AL,1000000b + jnz @@Error_1 + mov [ThirdByte_1],AL ;óāåėč÷čņü ń÷åņ÷čź + mov [MouseByteNumber_1],0 +; (Ļąźåņ äąķķūõ īņ ģūųč ļščķ’ņ ļīėķīńņüž). +; Ēąļčńąņü ķīāīå ēķą÷åķčå ńīńņī’ķč’ źķīļīź ģūųč + mov al,[FirstByte_1] ;[0xfb01] + mov ah,al + shr al,3 + and al,2 + shr ah,5 + and ah,1 + add al,ah + mov [BTN_DOWN],al + mov [mouse_active],1 +; Ļščįąāčņü ļåšåģåłåķčå ļī X ź źīīšäčķąņå X + mov AL,[FirstByte_1] + shl AL,6 + or AL,[SecondByte_1] + cbw + call mouse_acceleration_com2 + add AX,[MOUSE_X] ;[XCoordinate] + ; Źóšńīš ķå äīėęåķ āūõīäčņü ēą ėåāóž čėč + ; ļšąāóž ćšąķčöó żźšąķą + js @@X1_1 + cmp AX,[ScreenWidth] ;ScreenLength + jb @@X2_1 + ; Óńņąķīāčņü źīīšäčķąņó X ļī ļšąāīé ćšąķčöå + mov AX,[ScreenWidth] ;ScreenLength-1 + dec ax + jmp @@X2_1 +@@X1_1: + ; Óńņąķīāčņü źīīšäčķąņó X ļī ėåāīé ćšąķčöå + xor AX,AX +@@X2_1: + mov [MOUSE_X],AX ;[XCoordinate] + ; Ļščįąāčņü ļåšåģåłåķčå ļī Y ź źīīšäčķąņå Y + mov AL,[FirstByte_1] + and AL,00001100b + shl AL,4 + or AL,[ThirdByte_1] + cbw + call mouse_acceleration_com2 + add AX,[MOUSE_Y] ;[YCoordinate] + ; Źóšńīš ķå äīėęåķ āūõīäčņü ēą āåšõķžž čėč + ; ķčęķžž ćšąķčöó żźšąķą + js @@Y1_1 + cmp AX,[ScreenHeight] ;ScreenHeigth + jb @@Y2_1 + ; Óńņąķīāčņü źīīšäčķąņó X ļī ķčęķåé ćšąķčöå + mov AX,[ScreenHeight] ;ScreenHeigth-1 + dec ax + jmp @@Y2_1 +@@Y1_1: + ; Óńņąķīāčņü źīīšäčķąņó X ļī āåšõķåé ćšąķčöå + xor AX,AX +@@Y2_1: + mov [MOUSE_Y],AX ;[YCoordinate] + mov eax,[timer_ticks] + mov [timer_ticks_com_1],eax + jmp @@EndMouseInterrupt_1 + +@@Error_1: +; Ļšīčēīųåė ńįīé ā ļīš’äźå ļåšåäą÷č čķōīšģąöčč īņ +; ģūųč, īįķóėčņü ń÷åņ÷čź įąéņīā ļąźåņą äąķķūõ + mov [MouseByteNumber_1],0 +@@EndMouseInterrupt_1: + call ready_for_next_irq + ret + +mouse_acceleration_com2: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_com_1] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret diff --git a/kernel/branches/hd_kolibri/kernel/hid/m_ps2.inc b/kernel/branches/hd_kolibri/kernel/hid/m_ps2.inc new file mode 100644 index 0000000000..b6b17cca13 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/m_ps2.inc @@ -0,0 +1,178 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Ķīģåš ļščķčģąåģīćī īņ ģūųč įąéņą +MouseByteNumber_2 DB 0 +; Ņšåõįąéņīāą’ ńņšóźņóšą äąķķūõ, ļåšåäąāąåģą’ ģūųüž +FirstByte_2 DB 0 +SecondByte_2 DB 0 +ThirdByte_2 DB 0 +timer_ticks_ps2 dd 0 + +;************************************** +;* ĪĮŠĄĮĪŅ×ČŹ ĻŠÅŠŪĀĄĶČß ĪŅ ĢŪŲČ PS/2 * +;************************************** +check_mouse_data_ps2: + cmp [ps2_mouse_detected],0 + je @@EndMouseInterrupt_2 + call Wait8042BufferEmpty ;ī÷čńņźą įóōåšą + in AL,0x60 ;ļīėó÷čņü ńźżķ-źīä +; Āūįčšąņü ļīš’äźīāūé ķīģåš ļščķčģąåģīćī įąéņą + cmp [MouseByteNumber_2],0 + je @@SaveFirstByte + cmp [MouseByteNumber_2],1 + je @@SaveSecondByte + cmp [MouseByteNumber_2],2 + je @@SaveThirdByte + jmp @@Error_2 +; Ēąļčńąņü ļåšāūé įąéņ ļīńūėźč +@@SaveFirstByte: + test AL,1000b ;ļåšāūé įąéņ ļīńūėźč? + jz @@Error_2 ;ńįīé ńčķõšīķčēąöčč + mov [FirstByte_2],AL + inc [MouseByteNumber_2] + jmp @@EndMouseInterrupt_2 +; Ēąļčńąņü āņīšīé įąéņ ļīńūėźč +@@SaveSecondByte: + mov [SecondByte_2],AL + inc [MouseByteNumber_2] + jmp @@EndMouseInterrupt_2 +; Ēąļčńąņü ņšåņčé įąéņ ļīńūėźč +@@SaveThirdByte: + mov [ThirdByte_2],AL + mov [MouseByteNumber_2],0 +; (ļąźåņ äąķķūõ īņ ģūųč ļščķ’ņ ļīėķīńņüž) +; Ēąļčńąņü ķīāīå ēķą÷åķčå įąéņą ńīńņī’ķč’ źķīļīź + mov al,[FirstByte_2] ;[0xfb01] + and eax,3 + mov [BTN_DOWN],al + mov [mouse_active],1 +; Āū÷čńėčņü ķīāóž X-źīīšäčķąņó źóšńīšą + ; Ēąķåńņč ā AX ļåšåģåłåķčå ļī X + mov AH,0 ;äóįėčšóåģ ēķąź āī āńå šąēš’äū AH + mov AL,[FirstByte_2] + test AL,10000b + jz @@M0 + mov AH,0FFh + ; Ēąķåńņč ā AL ģėąäųčé įąéņ +@@M0: + mov AL,[SecondByte_2] + call mouse_acceleration_ps2 + ; Āū÷čńėčņü ķīāīå ēķą÷åķčå źīīšäčķąņū + ; źóšńīšą ļī X + add AX,[MOUSE_X] ;[XCoordinate] + cmp AX,0 + jge @@M1 + mov AX,0 + jmp @@M2 +@@M1: + cmp AX,[ScreenWidth] ;ScreenLength + jl @@M2 + mov AX,[ScreenWidth] ;ScreenLength-1 + dec ax +@@M2: + mov [MOUSE_X],AX ;[XCoordinate] + +; Āū÷čńė’åģ ķīāóž Y-źīīšäčķąņó źóšńīšą + ; Ēąķåńņč ā AX ļåšåģåłåķčå ļī Y + mov AH,0 ;äóįėčšóåģ ēķąź āī āńå šąēš’äū AH + mov AL,[FirstByte_2] + test AL,100000b + jz @@M3 + mov AH,0FFh + ; Ēąķåńņč ā AL ģėąäųčé įąéņ +@@M3: + mov AL,[ThirdByte_2] + call mouse_acceleration_ps2 + ; Āū÷čńėčņü ķīāīå ēķą÷åķčå źīīšäčķąņū źóšńīšą + ; ļī Y (Y-źīīšäčķąņą ģūųč PS/2 ķąļšąāėåķą + ; ļšīņčāīļīėīęķī żźšąķķīé) + neg AX + add AX,[MOUSE_Y] ;[YCoordinate] + cmp AX,0 + jge @@M4 + mov AX,0 + jmp @@M5 +@@M4: + cmp AX,[ScreenHeight] ;ScreenHeigth + jl @@M5 + mov AX,[ScreenHeight] ;ScreenHeigth-1 + dec ax +@@M5: + mov [MOUSE_Y],AX ;[YCoordinate] + +; Ļīźąēąņü źóšńīš ā ķīāīé ļīēčöčč + mov eax,[timer_ticks] + mov [timer_ticks_ps2],eax + jmp @@EndMouseInterrupt_2 + +; Īįķąšóęåķ ńįīé ā ļīš’äźå ļåšåäą÷č čķōīšģąöčč īņ ģūųč +@@Error_2: + mov [MouseByteNumber_2],0 +; Ķīšģąėüķīå ēąāåšųåķčå ļšåšūāąķč +@@EndMouseInterrupt_2: + call ready_for_next_irq_1 + ret + +mouse_acceleration_ps2: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_ps2] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret +;*********************************************** +;* ĪĘČÄĄĶČÅ Ī×ČŃŅŹČ ĀÕĪÄĶĪĆĪ ĮÓŌÅŠĄ I8042 * +;* Ļšč āūõīäå čē ļšīöåäóšū: * +;* ōėąć ZF óńņąķīāėåķ - ķīšģąėüķīå ēąāåšųåķčå, * +;* ōėąć ZF ńįšīųåķ - īųčįźą ņąéģ-ąóņą. * +;*********************************************** +Wait8042BufferEmpty: +; push CX +; mov CX,0FFFFh ;ēąäąņü ÷čńėī öčźėīā īęčäąķč +;@@kb: +; in AL,64h ;ļīėó÷čņü ńņąņóń +; test AL,10b ;įóōåš i8042 ńāīįīäåķ? +; loopnz @@kb ;åńėč ķåņ, ņī öčźė +; pop CX + push ecx + xor ecx,ecx + @@: + in al,64h + test al,00000010b + loopnz @b + pop ecx + ;Åńėč ļšč āūõīäå čē ļīäļšīćšąģģū ńįšīųåķ + ;ōėąć ZF - īųčįźą + ret ;āīēāšąņ ā ļīäļšīćšąģģó + +;*************************************** +;* ĪĘČÄĄĶČÅ ĻĪŃŅÓĻĖÅĶČß ÄĄĶĶŪÕ ĪŅ ĢŪŲČ * +;*************************************** +WaitMouseData: +; push CX +; mov CX,0FFFFh ;ēąäąņü ÷čńėī öčźėīā īęčäąķč +;@@mouse: +; in AL,64h ;īļšīńčņü šåćčńņš ńņąņóńą +; test AL,100000b ;äąķķūå ļīńņóļčėč? +; loopz @@mouse ;åńėč ķåņ, ņī öčźė +; pop CX + push ecx + mov ECX,0FFFFh + @@: + in al,64h + test al,100000b + loopz @b + pop ecx + ;Åńėč ļšč āūõīäå čē ļīäļšīćšąģģū óńņąķīāėåķ + ;ōėąć ZF - īųčįźą + ret + diff --git a/kernel/branches/hd_kolibri/kernel/hid/mousedrv.inc b/kernel/branches/hd_kolibri/kernel/hid/mousedrv.inc new file mode 100644 index 0000000000..f28b97d7b7 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/mousedrv.inc @@ -0,0 +1,389 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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 + +mouse_delay dd 10 +mouse_speed_factor dw 3 + +include 'm_ps2.inc' +include 'm_com1.inc' +include 'm_com2.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 + jz @F + 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, [ScreenWidth] + inc ecx + mul ecx + + movzx edx, byte [display_data+ebx+eax] + shl edx, 8 + mov ecx, [edx+SLOT_BASE+APPDATA.cursor] + + cmp [ecx+CURSOR.magic], 'CURS' + jne .fail +; cmp [ecx+CURSOR.size], CURSOR_SIZE +; jne .fail + push ecx + call [set_hw_cursor] + popad + ret +.fail: + mov ecx, [def_cursor] + mov [edx+SLOT_BASE+APPDATA.cursor], ecx + push ecx + call [set_hw_cursor] + popad + ret + +@@: + 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,[ScreenWidth] + 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,[ScreenWidth] + 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,14 + cmp eax,ecx + jb no_mouse_disable + sub eax,14 + add ecx,[edx+8] + cmp eax,ecx + jg no_mouse_disable + mov ecx,[edx+4] + add ebx,20 + cmp ebx,ecx + jb no_mouse_disable + sub ebx,20 + 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 + diff --git a/kernel/branches/hd_kolibri/kernel/hid/set_dtc.inc b/kernel/branches/hd_kolibri/kernel/hid/set_dtc.inc new file mode 100644 index 0000000000..1f631d93da --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/hid/set_dtc.inc @@ -0,0 +1,199 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;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/hd_kolibri/kernel/kernel.asm b/kernel/branches/hd_kolibri/kernel/kernel.asm new file mode 100644 index 0000000000..d06bb0c652 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/kernel.asm @@ -0,0 +1,58 @@ +include 'macros.inc' + +$Revision: 435 $ + +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 + +use16 + org 0x0 + jmp start_of_code + +org $+0x10000 + +db 0 +dd servetable-0x10000 +draw_line dd __sys_draw_line +disable_mouse dd __sys_disable_mouse +draw_pointer dd __sys_draw_pointer +drawbar dd __sys_drawbar.forced +putpixel dd __sys_putpixel +version db 'Kolibri OS version 0.6.5.0 ',13,10,13,10,0 + +include "boot/preboot.inc" +include "kernel16.inc" +include "bootstrap/switch.inc" + +use32 + +include 'unpacker.inc' + +__DEBUG__ fix 1 +__DEBUG_LEVEL__ fix 1 + +include 'fdo.inc' +include "bootstrap/bootmsg.inc" +include "bootstrap/bootlog.inc" +include "vars1.inc" +include "bootstrap/bootstrap.inc" +include "core/mainloop.inc" +include "core/idle.inc" +include "kernel32.inc" +include "hid/keymap.inc" +include "vars2.inc" + +IncludeIGlobals +endofcode: +IncludeUGlobals +uglobals_size = $ - endofcode +diff16 "end of kernel code",0,$ + +__REV__ = __REV + +diff10 "revision",0,__REV__ diff --git a/kernel/branches/hd_kolibri/kernel/kernel16.inc b/kernel/branches/hd_kolibri/kernel/kernel16.inc new file mode 100644 index 0000000000..6b180998d3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/kernel16.inc @@ -0,0 +1,51 @@ +$Revision: 437 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; KERNEL16.INC ;; +;; ;; +;; Included 16 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. ;; +;; ;; +;; Copyright Ville Turjanmaa, see file COPYING for details. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;% +include + +;!!! +include "boot/bootstr.inc" ; language-independent boot messages +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 +else if lang eq et +include "boot/bootet.inc" ; estonian system boot messages +else +include "boot/bootge.inc" ; german system boot messages +;!!! +end if +if lang eq et +include "boot/et.inc" ; Estonian font +else if lang eq ru +include "boot/ru.inc" ; Russian font +end if + +; ńžäą äąķķūå ēąļčńūāąžņń’ ā 16 šąēš’äķīģ šåęčģå, ÷čņąžņń’ ā 32 šąēš’äķīģ +bx_from_load: ; ńņšóźņóšą äė’ õšąķåķč’ ļąšąģåņšīā- īņźóäą ćąųšóēčėčńü, įåšåņń’ ķčęå čē bx ; {SPraid}[13.03.2007] +.from_disc db 0 ; a,b,c,d - āčķ÷åńņåšū, r - šąģ äčńź +.from_part db 0,0 ; # äčńźą... ńčģāīė, ą ķå įąéņ. '1', ą ķå 1 + +org $-0x10000 + +include "boot/bootcode.inc" ; 16 bit system boot code + +include "bus/pci/pci16.inc" + +;% -include diff --git a/kernel/branches/hd_kolibri/kernel/kernel32.inc b/kernel/branches/hd_kolibri/kernel/kernel32.inc new file mode 100644 index 0000000000..0cd9c8d99e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/kernel32.inc @@ -0,0 +1,242 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;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 + +; 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 + + db 64 dup(?) ;+64 + + .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/exports.inc" +include "core/sysfn.inc" +; GUI stuff +include "gui/window.inc" +include "gui/event.inc" +include "gui/font.inc" +include "gui/button.inc" + +; shutdown + +include "boot/shutdown.inc" ; shutdown or restart + +; 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/sb16.inc" ; playback for Sound Blaster 16 +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" + +; 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" + +; 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 diff --git a/kernel/branches/hd_kolibri/kernel/kglobals.inc b/kernel/branches/hd_kolibri/kernel/kglobals.inc new file mode 100644 index 0000000000..048a47e1b5 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/kglobals.inc @@ -0,0 +1,67 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;------------------------------------------------------------------ +; 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/hd_kolibri/kernel/macros.inc b/kernel/branches/hd_kolibri/kernel/macros.inc new file mode 100644 index 0000000000..dc31e92896 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/macros.inc @@ -0,0 +1,97 @@ + +__REV = 0 + +macro $Revision a { + match =: Num =$,a \{ + if __REV < Num + __REV = Num + end if + \} +} + +$Revision: 426 $ + +; 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 8 + d = 48 + s shr ((8-%) shl 2) and $0F + if d > 57 + d = d + 65-57-1 + end if + display d + end repeat + display 13,10 +} +macro diff10 title,l1,l2 + { + local s,d,z,m + s = l2-l1 + z = 0 + m = 1000000000 + display title,': ' + repeat 10 + d = '0' + s / m + s = s - (s/m)*m + m = m / 10 + if d <> '0' + z = 1 + end if + if z <> 0 + display d + end if + end repeat + display 13,10 + } + +; \begin{diamond}[29.09.2006] +; may be useful for kernel debugging +; example 1: +; dbgstr 'Hello, World!' +; example 2: +; dbgstr 'Hello, World!', save_flags +macro dbgstr string*, f +{ +local a +iglobal_nested +a db 'K : ',string,13,10,0 +endg_nested +if ~ f eq + pushfd +end if + push esi + mov esi, a + call sys_msg_board_str + pop esi +if ~ f eq + popfd +end if +} +; \end{diamond}[29.09.2006] diff --git a/kernel/branches/hd_kolibri/kernel/makefile b/kernel/branches/hd_kolibri/kernel/makefile new file mode 100644 index 0000000000..d07df1b9c9 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/makefile @@ -0,0 +1,16 @@ +FASM=fasm +KSRC=kernel.asm +KOUT=kernel.mnt + +en: kernel.asm + rm -f lang.inc + echo lang fix en > lang.inc + $(FASM) $(KSRC) $(KOUT) +ru: kernel.asm + rm -f lang.inc + echo lang fix ru > lang.inc + $(FASM) $(KSRC) $(KOUT) + +clean: + rm -f $(KOUT) + rm -f lang.inc diff --git a/kernel/branches/hd_kolibri/kernel/network/eth_drv/arp.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/arp.inc new file mode 100644 index 0000000000..4fabddb8f8 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/arp.inc @@ -0,0 +1,550 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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] ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + + 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 + + ; 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 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 + call dword [drvr_transmit] ;transmit packet + + .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 + call dword [drvr_transmit] ; Call the drivers transmit function + + 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/hd_kolibri/kernel/network/eth_drv/drivers/3c59x.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/3c59x.inc new file mode 100644 index 0000000000..debb094473 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/3c59x.inc @@ -0,0 +1,2388 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; 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/hd_kolibri/kernel/network/eth_drv/drivers/i8255x.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/i8255x.inc new file mode 100644 index 0000000000..c714c98266 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/i8255x.inc @@ -0,0 +1,744 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************** +; 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_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +I8255x_reset: + 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: + 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 + mov [rxfd_link], eax + + mov eax, Ether_buffer + 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 + 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 + 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 + mov [confcmd_link], eax + + mov ax, 1 + mov [txfd_command], ax ; CmdIASetup + + mov ax, 0 + mov [txfd_status], ax + + mov eax, confcmd + 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 + 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_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 + 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 + mov [txfd_tx_desc_addr], eax + mov eax, hdr + 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 + mov [txfd_tx_buf_addr1], eax + mov eax, ecx + mov [txfd_tx_buf_size1], eax + + mov eax, txfd + 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/hd_kolibri/kernel/network/eth_drv/drivers/pcnet32.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/pcnet32.inc new file mode 100644 index 0000000000..303b3dd86b --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/pcnet32.inc @@ -0,0 +1,818 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;macro PutStr X +;{ +; local .__xyz1 +; local .__xyz2 +; push esi +; mov esi,.__xyz1 +; call sys_msg_board_str +; push eax +; mov eax,1 +; call delay_hs +; pop eax +; jmp .__xyz2 +;.__xyz1: +; db X +; db 13,10,0 +;.__xyz2: +; pop esi +;} +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 +.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 dword [pcnet32_private.rx_ring],pcnet32_rx_ring + mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring + 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 +; PutStr "ASEL, enable auto-negotiation" + 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 + and eax,0xffff + call dword [pcnet32_access.write_csr] + mov eax,pcnet32_private + 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: +; PutStr "hardware reset" + xor ebx,ebx + mov eax,0x0002 + call dword [pcnet32_access.write_csr] + xor ebx,ebx + call dword [pcnet32_access.read_csr] +; PutStr "PCNET reset complete" + 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 +; PutStr "Using WIO" + 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 +; PutStr "Using DWIO" + mov esi,pcnet32_dwio + jmp .L1 +.no_dev: +; PutStr "PCNET32 not found" + 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 +; PutStr "PCNET32 chip version OK" + 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 +; PutStr "Invalid chip rev" + jmp .no_dev +.L2: +; PutStr "PCnet/PCI 79C970" + jmp .L10 +.L3: +; PutStr "PCnet/PCI 79C970" + jmp .L10 +.L4: +; PutStr "PCnet/PCI II 79C970A" + mov [pcnet32_private.fdx],1 + jmp .L10 +.L5: +; PutStr "PCnet/FAST 79C971" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + mov [pcnet32_private.ltint],1 + jmp .L10 +.L6: +; PutStr "PCnet/FAST+ 79C972" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + jmp .L10 +.L7: +; PutStr "PCnet/FAST III 79C973" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + jmp .L10 +.L8: +; PutStr "PCnet/Home 79C978" + mov [pcnet32_private.fdx],1 + mov ebx,49 + call dword [pcnet32_access.read_bcr] + call dword [pcnet32_access.write_bcr] + jmp .L10 +.L9: +; PutStr "PCnet/FAST III 79C975" + 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 +; PutStr "MAC read" + call pcnet32_adjust_pci_device +; PutStr "PCI done" + 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 dword [pcnet32_private.rx_ring],pcnet32_rx_ring + mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring +; PutStr "Switching to 32" + 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 eax,eax + 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 +; PutStr "PCNETRX" + mov ecx,[ebx+pcnet32_rx_head.msg_length] + and ecx,0xfff + sub ecx,4 + mov [eth_rx_data_len],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 +; PutStr "PCNETTX" + 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 + 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: +; PutStr "PCNET: Send timeout" +.L3: + mov dword [edi+pcnet32_tx_head.base],0 + pop ecx + pop ebx + pop esi + pop edi + ret diff --git a/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8029.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8029.inc new file mode 100644 index 0000000000..887308c0a0 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8029.inc @@ -0,0 +1,959 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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! ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;******************************************************************** +; 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/hd_kolibri/kernel/network/eth_drv/drivers/rtl8139.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8139.inc new file mode 100644 index 0000000000..5acac10e2e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8139.inc @@ -0,0 +1,616 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + 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 + 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 + 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/hd_kolibri/kernel/network/eth_drv/drivers/rtl8169.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8169.inc new file mode 100644 index 0000000000..7ccc08537e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/rtl8169.inc @@ -0,0 +1,1208 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + 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/hd_kolibri/kernel/network/eth_drv/drivers/sis900.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/sis900.inc new file mode 100644 index 0000000000..df75e11797 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/drivers/sis900.inc @@ -0,0 +1,1152 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;******************************************************************** +; 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 ;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 ; 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 ; + 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 ; + 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 + 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], ebx + 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 + 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 +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 + 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/hd_kolibri/kernel/network/eth_drv/ethernet.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/ethernet.inc new file mode 100644 index 0000000000..04bb50ba2c --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/ethernet.inc @@ -0,0 +1,457 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;******************************************************************** +; 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/mtd80x.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 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 + +dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +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 + call dword [drvr_transmit] ; Call the drivers transmit function + + ; 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/hd_kolibri/kernel/network/eth_drv/pci.inc b/kernel/branches/hd_kolibri/kernel/network/eth_drv/pci.inc new file mode 100644 index 0000000000..b37aa6c366 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/eth_drv/pci.inc @@ -0,0 +1,349 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;*************************************************************************** +; +; 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/hd_kolibri/kernel/network/icmp.inc b/kernel/branches/hd_kolibri/kernel/network/icmp.inc new file mode 100644 index 0000000000..474e93b5ac --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/icmp.inc @@ -0,0 +1,192 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +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/hd_kolibri/kernel/network/ip.inc b/kernel/branches/hd_kolibri/kernel/network/ip.inc new file mode 100644 index 0000000000..6c1b9b3db3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/ip.inc @@ -0,0 +1,198 @@ +$Revision: 425 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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/hd_kolibri/kernel/network/queue.inc b/kernel/branches/hd_kolibri/kernel/network/queue.inc new file mode 100644 index 0000000000..6f44c1867f --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/queue.inc @@ -0,0 +1,219 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; 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/hd_kolibri/kernel/network/socket.inc b/kernel/branches/hd_kolibri/kernel/network/socket.inc new file mode 100644 index 0000000000..5f0eba8b51 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/socket.inc @@ -0,0 +1,930 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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] ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; 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: + Index2RealAddr ebx + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + 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/hd_kolibri/kernel/network/stack.inc b/kernel/branches/hd_kolibri/kernel/network/stack.inc new file mode 100644 index 0000000000..d46a88a649 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/stack.inc @@ -0,0 +1,1021 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;******************************************************************* +; 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/hd_kolibri/kernel/network/tcp.inc b/kernel/branches/hd_kolibri/kernel/network/tcp.inc new file mode 100644 index 0000000000..c759def8e7 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/tcp.inc @@ -0,0 +1,1300 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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/hd_kolibri/kernel/network/udp.inc b/kernel/branches/hd_kolibri/kernel/network/udp.inc new file mode 100644 index 0000000000..ba0418bee3 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/network/udp.inc @@ -0,0 +1,172 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; 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/hd_kolibri/kernel/proc32.inc b/kernel/branches/hd_kolibri/kernel/proc32.inc new file mode 100644 index 0000000000..99af424d72 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/proc32.inc @@ -0,0 +1,268 @@ +$Revision: 425 $ +; 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/hd_kolibri/kernel/skin/Thumbs.db b/kernel/branches/hd_kolibri/kernel/skin/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..b7583ad0f6a5a214b03901f280185f6c817c4aff GIT binary patch literal 9216 zcmeI030PCd7JzR^Lf9b?KtM$W+^8V3FPgf50!n3*9Yh6WFDe2qiQ`Q_3AyiFgg!rf?PuHXz4!S(Ciycr_nukK+%sq9%)=UT z>y>mxHZm=(LhuM56-ER0%CwTAOT1MU;-1*KO=Q#x;kwHY>;61>_O%srbrOvyO0QYtDm0a zz+$GV#Qeb@rLP?&VxEUp;P4<+IP1Nn)*lu4gl7aq05{b>mVZK#2@x%<6OdNC&;If+ z);{I~vAOf9?PGK3(d1xh|K*n77yK*wD?rhT$@a0nW0%-)OrQUlU%-68hw~rv2OrLV zGCY?CWB>{v3&;WT0QQP8c}2*TfZ4ztU@o8x%md~F3jh^B6~N>dLcR!C3@ibb0_wmQ zz%oDs&;*tPnEha7uyND@HUWBoK41VC0!Dx_U;?ZJRsmGtOJFsy23QNM155!kU_Gz_ zFb6CEOJE~_wT1B&TyF-f0UN*;umkLYEr0{y2si=GfD7OXxB>2f2e1|J1hxTKo&Sr3 z`E(qh1_ppOqOFLOg_*e-f&-)8iggfefuX?*2w-1G1o#q#h(rQ`C_*9$3Wrz%7VGe2!U;eh1xZ4}BBCIWDFrhWj~5`|v0j7pL3oZ3 z$VBP+TB`+RtUXB!LMST^$6OIoS(9EQYg5Zn)!w!%QdmSzewKow+QLPPmn_xM)zddH zG+MjP)NK6*a|>HL`z;QRPR`qRczOHm^!3}lCvVDNf zF!*+8c!WFp4$}*V;NPqDn`YDWB7k3QLG|3ibmZMy-@ zpc~2;D20pb8fXR)JK~VjJv*bL&zB{>@#1s4lZV#wm9$H!Zzbzdq_339+j~m=Ns@2f z?QL%}x^h)Id~1){b*^-K`DBFVgEmcB*8!2AJG0dCDlV zChH`MM0U}+2}_lGtzVnc15m_^&Fp+iYp1KxGf||b@?Z}KMYtaOG>Sv4Kys_vwG9>_2zL{%6*Y-&+{}Gwa8YCf9~3iXvS} z;g%>u*vsSvojSsow&QboU1@dv>+Q7QA!eVlBE7^r+@F8=9cz3v3PsLZo653=67r!$ zIMqI-rJvqG|H!LPxANcrKV|<5KhymawrBo33F425*a15)!1k}7QkNPCt$^{u(puO7 z?*RfJ3iWw^>ref{?(Vnv^HbZ$V!pSNt?2%#);<=-^#5?*{;|Zzcd#})v4a*!Sgi7Q z5*Ghq=QUV$pQ^tV$Qn+zKeK=SZ1>L`7A{<~INP1bX&;%Z^k~tYxJ_9RY8Q$ZhHaOQ zEsd{K9ZYzRB1a{QP~@%pP6k)wG>V+Oxw~-R`E!N*Ij-Z+jGofl)o!qQJ?Qn!Tfanj zD?0jZsykPlqj8sSS2phdT6UR@hs>+7WF4kd08f^!EOxr_rkA{&*3mJepUNBS467yk zM6RQVXrC#HFx)Kp8@4^ zP8u=$-8u;t^G`%_#a3KaMma73@j|@8LwG=>uK|&AAo4Xxygw^|EeC>3%54K5vKwSS zl)>tna5K|n{#{+z*~e5}Q*C}&7j`x=F=Zy}3Wk1o!D-o)|8IeZpGW+>XlDQa|FQpn zk!Q}w=mM!cIYArYPG*Pzwp?Ec)f=~>b2N6Q^~ck8PbE_O`4MXHK)RF7|b)(I}d zC-{Vi{Hmn~Eb2`bu~DQq&`47D)!x`m!!6-^s}^~yXPHyR8*CG|Gj8l+Nb<-x4j7K7 z@MPF5vJ>6swH$51Bi>lBu3A&UPB+>PZ`=4#lezrN@zAft%Q@FU*73!(QEAf zMn1#A-_pg!xuQ6aA@+UGQ)P{YytEM(UHdARKBgV6=~1WC?ae(e4NjD}0D=RaVUWL~aieLPj8s==WyEdQM!?N*7aTFm3BjFA(?W9IhPtZXkQ zd4yKJzVGYuyjdT=kv1CAL(38HV6m`ObhH$iS$^wn~)xNctGpy zW`(s<60HhRsy9y$cjPK>tKV8fZEPm-W11Az`wSwjQi~j7E$kQD#$}khI|Mc<$G6|{ zI+Cm}F89>a{p$9;Eibp2yCu#Vzh$Do&t!ZzdzjI-$$s?ClT691^&xv$tc!Q^qZRI! zcQz_KaH=-emf|-hD`m{3MRCTy;yh1HY~gvpd=>|daMI4SLyjM*z>L$?rR z-)T0481G*n)NmlHw>mTLhQF`>T&l@vL_|`)N9UbB60PL|jZ#}@nZs$PElfWY=Q}rj z_OG|aERD(^x|X&moD4kUv{ueb#H~6AMM~&9J>G8IL#^J7A}^0o9BSGI@|bhn9TTnQ zN+)Ip7V8J+J{Pe7MIa)Mn6p>_RBGM>y|c1->2B< z7ORFg_Xpao8?~0*o0@tkHI)Jf*Vd*Hv)wcT%oI?h?#G^356ZCRI`?%qEV8*Q#)hFk z3W`5mBe3-bTg#@_k*PIe`g((jOr@#yW7*95F%v)kcjMch~}&vf}@ZqOS` z^90f*-{Ba+P=f%?rj|32xEd7_-as&lO+A`0obL6*wPLDxvw7Hx!nirB9&Nr^AsRns z)E|p8Y~9iNf)wV+4QbPq=cbi5B$y=)=k9oN^NP>li;V{7W0&8PG*eF6!QH>MfWs>7 zm9%=ib!=siQGD9Bazg=LwNXnqbgkbvo;7Rs%@k6lkG)y%660%uPlH)i6&lb7o@w^q;W=jzyv%VI5(ms5|5T_~(c z=lXL>Y_fBc8(Iqvo9M-i-pX-wCM$L-P`g;RZwYS+XS1y=Z}>QIZr2-~ao&;Mm{&gF zAfjS=hY?Xk)vuDQe(GbOpt8UGT?gZZvbdiz=bT%am-yA*kb~Y`zbF-299~W>8{B@R zQgw&VPHOZEt?(1umYS`|*mU)F7cKixq32T1A1&-g6Tg>x_A+IxX{ejaSk7;RLuej} z&1h;Ub3S{rwMNp{;q{!O^&?r%oAUGef4->KdEB%r_Uvk8L`Btl3p22HBfU7Xe@^ln zTFKQA6v5xtad>E-8*P~XlENQ+xzkzux=^n|<-v+r&E7utl0*AZgjAF2#u&PIQ7fl< z34bsm%pxVv>tx&5q|r;_l^miFY;LHHj1=P#l`} z@5{M>u#LA}T+T^)_&qHDDpu1IDHc|Xy!1w@ zH7-&5OT&2r_b;a;wK_-4k-%w!Km=2D$6j#wQ5k?1gb_G7br1J9i?*+BG7_BE?uU fgQ>UAWL3-e&Tsf*EcY1d^e|$|ozCQcas>Vfx4Mss literal 0 HcmV?d00001 diff --git a/kernel/branches/hd_kolibri/kernel/skin/base.bmp b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/base_1.bmp b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/default.asm b/kernel/branches/hd_kolibri/kernel/skin/default.asm new file mode 100644 index 0000000000..88c6f15f12 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/left.bmp b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/me_skin.inc b/kernel/branches/hd_kolibri/kernel/skin/me_skin.inc new file mode 100644 index 0000000000..365964eb38 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/myblue.dtp b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/oper.bmp b/kernel/branches/hd_kolibri/kernel/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/hd_kolibri/kernel/skin/oper_1.bmp b/kernel/branches/hd_kolibri/kernel/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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 + +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/hd_kolibri/kernel/sound/sb16.inc b/kernel/branches/hd_kolibri/kernel/sound/sb16.inc new file mode 100644 index 0000000000..d1182eb6cb --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/sound/sb16.inc @@ -0,0 +1,354 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; SB16.INC ;; +;; ;; +;; Sound Blaster 16 functions for MenuetOS ;; +;; ;; +;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; - 11.07.2002 8 bit stereo mode - Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +SB16_load_music equ 0xc0000000 +SB16_play_music equ 0xc0000001 +DMAPage equ 0x2A +Rate equ 44100 +SB16Buffer equ 0x2A0000 +;SB16_Status equ SB16Buffer+65536 + +iglobal + sound_data_format dd 0x1 + sound_data_length dd 65536 + sound_data_freq dd 44100 +endg + +sound_interface: + + cmp eax,0 ; Load data + jne no_SB16_load_music + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add ebx,[edi] + call code_SB16_load_music + ret + no_SB16_load_music: + + cmp eax,1 ; Play data + jne no_SB16_play_music + call code_SB16_play_music + ret + no_SB16_play_music: + + cmp eax,2 ; Set data formats + jne no_SB16_data_format + cmp ebx,0 ; ebx=0 play format + jne no_sound_format + mov [sound_data_format],ecx ; 1=8b mono, 2=8b stereo + ret + no_sound_format: + cmp ebx,1 ; ebx=1 data length + jne no_sound_length + mov [sound_data_length],ecx ; + ret + no_sound_length: + cmp ebx,2 ; ebx=2 sound data frequency + jne no_sound_freq + mov [sound_data_freq],ecx + ret + no_sound_freq: + ret + + no_SB16_data_format: + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + 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 eax, [TASK_BASE] +; mov eax, [eax+0x10] ; address application im memory +; add eax, edx ; add offset Delay-Note string +; mov [memAdrNote], eax + mov [memAdrNote],edx + mov eax,[TASK_BASE] + mov eax,[eax+TASKDATA.pid] + mov [pidProcessNote],eax + xor eax, eax ; Ok! EAX = 0 + retFunc55: + mov [esp+36], eax ; return value EAX for application +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ret + + + + +code_SB16_play_music: + + cmp [sound_data_format],1 + jne no_sound_8bm + call sb_play_8b_mono + ret + no_sound_8bm: + + cmp [sound_data_format],2 + jne no_sound_8bs + call sb_play_8b_stereo + ret + no_sound_8bs: + + ret + + + + + +Blaster_command: + + push eax + push ecx + push edx + + mov dx,word [sb16] + add dx,0xc + mov cx,1000 + bcl1: + in al,dx + and al,128 + jz bcl2 + loop bcl1 + bcl2: + mov al,[esp+8] + mov dx,[esp+0] + add dx,word [sb16] + out dx,al + + pop edx + pop ecx + pop eax + + ret + + +sb_play_8b_stereo: + + pusha + + call sb_set_dma + + call sb_set_stereo + + mov dx,0xc + mov al,0xa8 + call Blaster_command + + mov al,0x40 + call Blaster_command + + mov al,245 + call Blaster_command + + mov al,0x48 + call Blaster_command + + mov al,0xff + call Blaster_command + call Blaster_command + + mov al,0x91 + call Blaster_command + + popa + ret + + + +sb_set_stereo: + + push eax + push edx + + call sb_wait + + mov dx,word [sb16] + add dx,0x4 + mov al,0xe + out dx,al + inc dx + in al,dx + and al,253 + or al,2 ; stereo + out dx,al + + pop edx + pop eax + ret + + + +code_SB16_load_music: + + cmp byte [SB16_Status],1 + je nol + mov edi,SB16Buffer + mov esi,ebx + mov ecx,65536/4 + cld + rep movsd +nol: ret + + +iglobal + dma_table db 0x87,0x83,0x81,0x82 +endg + + + +;-------------------------------- +; program dma +;-------------------------------- + +sb_set_dma: + + pusha + + mov eax,[sound_dma] + add eax,4 + out 0xa,al + + mov al,0 + out 0xc,al + + mov eax,[sound_dma] + add eax,0x48 + out 0xb,al + + mov edx,[sound_dma] + shl edx,1 + mov al,0 + out dx,al + + mov al,0 + out dx,al + + mov edx,[sound_dma] + add edx,dma_table + movzx edx,byte [edx] + mov al,DMAPage + out dx,al + + mov edx,[sound_dma] + shl edx,1 + inc edx + mov eax,[sound_data_length] + dec eax + and eax,0xff + ; mov al,(DataLength-1) and 0xff + out dx,al + + mov eax,[sound_data_length] + dec eax + shr eax,8 + ; mov al,(DataLength-1) shr 8 + out dx,al + + mov eax,[sound_dma] ; DMA + out 0xa,al + + popa + ret + + + +sb_play_8b_mono: + + + call sb_set_dma + + cmp byte [SB16_Status],1 + jne contsb16 + jmp retserve + contsb16: + + mov dx,word [sb16] + add dx,4 + mov ecx,[sound_dma] + mov ax,0x01 + shl ax,cl + shl ax,8 + add ax,0x81 + out dx,ax + + mov ax,0f280h ;enable irq5 + out dx,ax + + +adr1_SB: mov dx,word [sb16] + add dx,0ch + in al,dx + and al,080h + jnz adr1_SB + + call sb_set_stereo + + mov al,0d1h + out dx,al + + + mov dx,word [sb16] + add dx,0ch + + call sb_wait + + mov al,40h ; Rate + out dx,al + call sb_wait + mov al,256-1000000/Rate + out dx,al + + call sb_wait + + mov al,14h ; Datalength + out dx,al + call sb_wait + + mov eax,[sound_data_length] + dec eax + and eax,0xff + ;mov al,(DataLength-1) and 0xff + out dx,al + call sb_wait + mov eax,[sound_data_length] + dec eax + shr eax,8 + ;mov al,(DataLength-1) shr 8 + out dx,al + + retserve: + + ret + + +sb_wait: in al,dx ;wait + and al,080h + jnz sb_wait + + ret + + + + +;**************************************** +; END CODE SB16 by Minazzi Paolo +;*************************************** diff --git a/kernel/branches/hd_kolibri/kernel/unpacker.inc b/kernel/branches/hd_kolibri/kernel/unpacker.inc new file mode 100644 index 0000000000..8749125c2e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/unpacker.inc @@ -0,0 +1,512 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 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, [.p + .IsMatch*4 + eax + edx*4] + 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, .p+.Literal*4 + 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, [.p + .IsRep*4 + ebx*4] + call .RangeDecoderBitDecode + jnc .10 + lea eax, [.p + .IsRepG0*4 + ebx*4] + call .RangeDecoderBitDecode + jc .111 + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.p + .IsRep0Long*4 + eax + edx*4] + 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, [.p + .IsRepG1*4 + ebx*4] + call .RangeDecoderBitDecode + mov eax, [.rep1] + jnc .l3 +.l1: + lea eax, [.p + .IsRepG2*4 + ebx*4] + 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, .p + .RepLencoder*4 + 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, .p + .Lencoder*4 + 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, .p+.PosSlot*4 + 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, .p + (.SpecPos - 1)*4 + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx + jmp .l6 +.l5: + sub ecx, .kNumAlignBits + call .RangeDecoderDecodeDirectBits + mov ecx, .kNumAlignBits + shl eax, cl + add [.rep0], eax + mov eax, .p+.Align_*4 + 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.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/hd_kolibri/kernel/vars1.inc b/kernel/branches/hd_kolibri/kernel/vars1.inc new file mode 100644 index 0000000000..c94ee73e26 --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/vars1.inc @@ -0,0 +1,19 @@ +iglobal + firstapp db '/hd0/1/kolibri/bin/LAUNCHER',0 + vrr_m db '/hd0/1/kolibri/bin/VRR_M',0 + + char dd 0,0,0 + dd 2560 + dd 0x3F600 - std_application_base_address + db '/hd0/1/kolibri/FONTS/CHAR.MT',0 + char2 dd 0,0,0 + dd 2560 + dd 0x3EC00 - std_application_base_address + db '/hd0/1/kolibri/FONTS/CHAR2.MT',0 + bootpath db '/BOOT ' + bootpath2 db 0 + vmode dd 0,0,0 + dd 0x8000 + dd 0x760000 - std_application_base_address + db '/hd0/1/kolibri/drivers/VMODE.MDR',0 +endg diff --git a/kernel/branches/hd_kolibri/kernel/vars2.inc b/kernel/branches/hd_kolibri/kernel/vars2.inc new file mode 100644 index 0000000000..8cab65c72e --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/vars2.inc @@ -0,0 +1,99 @@ + + +; device irq owners +uglobal +irq_owner: ; process id + + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 +endg + + +; on irq read ports +uglobal + irq00read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq01read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq02read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq03read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq04read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq05read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq06read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq07read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq08read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq09read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq10read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq11read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq12read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq13read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq14read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq15read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +endg + +; status +uglobal + hd1_status dd 0x0 ; 0 - free : other - pid + application_table_status dd 0x0 ; 0 - free : other - pid +endg + +; device addresses +uglobal + mididp dd 0x0 + midisp dd 0x0 + + cdbase dd 0x0 + cdid dd 0x0 + + hdbase dd 0x1f0 ; for boot 0x1f0 + hdid dd 0x0 + hdpos dd 0x1 ; for boot 0x1 + fat32part dd 0x1 ; for boot 0x1 + + ;part2_ld dd 0x0 + +;* start code - Mario79 +mouse_pause dd 0 +MouseTickCounter dd 0 +ps2_mouse_detected db 0 +com1_mouse_detected db 0 +com2_mouse_detected db 0 +;* end code - Mario79 + +wraw_bacground_select db 0 + lba_read_enabled dd 0x1 ; 0 = disabled , 1 = enabled + pci_access_enabled dd 0x1 ; 0 = disabled , 1 = enabled + + sb16 dd 0x0 + + buttontype dd 0x0 + windowtypechanged dd 0x0 + +align 4 + cpu_caps dd 4 dup(0) + pg_data PG_DATA + heap_test dd ? + hd_entries rd 1 ;unused ? 0xfe10 +endg + +iglobal + keyboard dd 0x1 + sound_dma dd 0x1 + syslang dd 0x1 +endg + +if __DEBUG__ eq 1 + include_debug_strings +end if \ No newline at end of file diff --git a/kernel/branches/hd_kolibri/kernel/video/arrow.cur b/kernel/branches/hd_kolibri/kernel/video/arrow.cur new file mode 100644 index 0000000000000000000000000000000000000000..5e0790095507dbc1a32d8441a37e3306b44065c5 GIT binary patch literal 766 zcmds#F%H5o3`Ktdsbe~^wj)PiD@S6>f<%wj<1n&iL70~oq&Q5hIC+l0zm=*|q>UO4 zgO<2$q&?LE1~@^Z9ht!UL`RWXW0KgKru86GYMy7#Y}m48mMdW8R!)Bysrsi%hqL!< z?Z$)T_1%vLt95eM2TL&)-wPIFIgoW>D 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, [ScreenWidth] + 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, [ScreenWidth] + 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,[ScreenWidth] ; 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,[ScreenWidth] +; 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 + + + + + + +;--------------vbe voodoo ------------------------------------------------ +vesa20_drawbackground_tiled: + + call [disable_mouse] + + push ebp + push eax + push ebx + push ecx + push edx + + mov edx,dword [WinMapAddress-8] ; B + add edx,dword [WinMapAddress-8] ; +B + add edx,dword [WinMapAddress-8] ; +B + push edx + + mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) + mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X + add ebp, eax ; +X + + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + + dp3: ; MAIN LOOP + + cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) +; je ybgp +; +; jmp nbgp +; +; ybgp: + jne nbgp + + push eax + push ebx + + mov ecx,dword [WinMapAddress-8] ; B + xor edx,edx ; edx:=0 + div ecx ; Xstart/B + + ; eax=Int(qn) edx:=Rem + + lea esi,[edx+edx*2] ; esi:=edx*3 + + mov ecx,dword [WinMapAddress-4] ; ecx:=H + mov eax,[esp+0] ; eax:=Ystart + xor edx,edx ; + div ecx ; Ystart/H + + mov eax,edx ; eax:=Rem + xor edx,edx ; + mov ebx,[esp+8] ; ebx:=B*3 + mul ebx ; + add esi,eax ; + mov eax,[esi+IMG_BACKGROUND] + and eax,0xffffff + + xchg edi, ebp + stosw + shr eax,16 + stosb + xchg ebp, edi ; ebp+=3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + pop ebx + pop eax + + jmp hook1 + + nbgp: + add ebp,3 ; +3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + hook1: + + inc edi ; ptrBuffer++ + add esi,3 ; ptrImage+=3 + inc eax + cmp eax,[draw_data+32+RECT.right] ; X > xend? +; jg nodp3 +; jmp dp3 +; +; nodp3: + jle dp3 + + mov ebp,[draw_data+32+RECT.left] + + inc ebx + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X=X*2 + add ebp, eax ; +X=X*3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X=X*4 + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + cmp ebx,[draw_data+32+RECT.bottom] +; jg dp4 +; +; jmp dp3 +; +; dp4: + jle dp3 + + add esp,4 + + pop edx + pop ecx + pop ebx + pop eax + pop ebp + mov [EGA_counter],1 + call VGA_drawbackground + ret + +; ---------- + + +vesa20_drawbackground_stretch: + + call [disable_mouse] + + push ebp + push eax + push ebx + push ecx + push edx + + mov edx,dword [WinMapAddress-8] ; B + add edx,dword [WinMapAddress-8] ; +B + add edx,dword [WinMapAddress-8] ; +B + push edx + + mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) + mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X + add ebp, eax ; +X + + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + +sdp3: ; MAIN LOOP +cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) +jne snbgp +push eax +push ebx +mov eax,dword [WinMapAddress-8] +imul eax, [esp+4] ;4 +xor edx,edx +mov ebx,[ScreenWidth] +div ebx +mov cx,dx +lea esi,[eax+eax*2] +mov eax,dword [WinMapAddress-4] +imul eax, [esp+0] ;0 +xor edx,edx +mov ebx,[ScreenHeight] +div ebx +shl ecx,16 +mov cx,dx +imul eax, [esp+8] ;8 +add esi,eax +mov eax,[esi+IMG_BACKGROUND] +push eax +ror ecx,16 +xor eax,eax +mov ax,cx +shl eax,1 ; óģķīęåķčå ķą 2 +lea eax,[eax+eax*4] ; óģķīęåķčå ķą 5 +xor edx,edx +mov ebx,[ScreenWidth] +div ebx +cmp eax,5 +pop eax +jb @f +mov ebx,[esi+IMG_BACKGROUND+3] +call overlapping_of_points +@@: +push eax +ror ecx,16 +xor eax,eax +mov ax,cx +shl eax,1 ; óģķīęåķčå ķą 2 +lea eax,[eax+eax*4] ; óģķīęåķčå ķą +xor edx,edx +mov ebx,[ScreenHeight] +div ebx +cmp eax,5 +pop eax +jb @f +mov ebx,[display_data-8] +shl ebx,1 +add ebx,[display_data-8] +add ebx,IMG_BACKGROUND +add ebx,esi +mov ebx,[ebx] +call overlapping_of_points +@@: +and eax,0xffffff +xchg edi, ebp +stosw +shr eax,16 +stosb +xchg ebp, edi ; ebp+=3 +cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size +jz @f +inc ebp ; +1 +@@: +pop ebx +pop eax +jmp shook1 + +overlapping_of_points: +push ecx edi +mov ecx,eax +mov edx,ebx +xor eax,eax +mov al,cl +xor ebx,ebx +mov bl,dl +add eax,ebx +rcr eax,1 +xor edi,edi +mov di,ax +xor eax,eax +mov al,ch +xor ebx,ebx +mov bl,dh +add eax,ebx +rcr eax,1 +ror edi,8 +add edi,eax +ror ecx,8 +ror edx,8 +xor eax,eax +mov al,ch +xor ebx,ebx +mov bl,dh +add eax,ebx +rcr eax,1 +ror edi,8 +add eax,edi +ror eax,16 +pop edi ecx +ret + + snbgp: + add ebp,3 ; +3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + shook1: + + inc edi ; ptrBuffer++ + add esi,3 ; ptrImage+=3 + inc eax + cmp eax,[draw_data+32+RECT.right] ; X > xend? + jle sdp3 + + mov ebp,[draw_data+32+RECT.left] + + inc ebx + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X=X*2 + add ebp, eax ; +X=X*3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X=X*4 + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + cmp ebx,[draw_data+32+RECT.bottom] + jle sdp3 + + add esp,4 + + pop edx + pop ecx + pop ebx + pop eax + pop ebp + mov [EGA_counter],1 + call VGA_drawbackground + ret diff --git a/kernel/branches/hd_kolibri/kernel/video/vga.inc b/kernel/branches/hd_kolibri/kernel/video/vga.inc new file mode 100644 index 0000000000..48a59798bb --- /dev/null +++ b/kernel/branches/hd_kolibri/kernel/video/vga.inc @@ -0,0 +1,450 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +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 [0xfb0c] + 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/hd_kolibri/readme.txt b/kernel/branches/hd_kolibri/readme.txt new file mode 100644 index 0000000000..74db1f1220 --- /dev/null +++ b/kernel/branches/hd_kolibri/readme.txt @@ -0,0 +1,19 @@ +modified kernel from the standard kernel + +it load the first app (or vrr_m) and cpu from /hd0/1/kolibri/bin + +the skin is in /hd0/1/kolibri/etc/default.skn +the drivers ar loaded from /hd0/1/kolibri/drivers + +the ramdisk is'nt loaded when you chose to load it from the hard-drive (because it is'nt needed) + +you will also need to download the modified version of sommes app: + +launcher +vrr_m +@panel +@menu +setup +icon +jpegview +@rb \ No newline at end of file