From 5698c48f5e5d50dcda8373dc9b5e0c114c7b22ef Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Mon, 14 Dec 2009 16:31:01 +0000 Subject: [PATCH] tag for Kolibri 0.7.7.0 git-svn-id: svn://kolibrios.org@1320 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/tags/kolibri0.7.7.0/COPYING.TXT | 347 + kernel/tags/kolibri0.7.7.0/blkdev/cd_drv.inc | 929 +++ kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc | 271 + kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc | 71 + kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc | 626 ++ kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc | 928 +++ .../tags/kolibri0.7.7.0/blkdev/ide_cache.inc | 922 +++ kernel/tags/kolibri0.7.7.0/blkdev/rd.inc | 2266 +++++++ kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc | 32 + kernel/tags/kolibri0.7.7.0/boot/ETFONT.FNT | Bin 0 -> 4096 bytes kernel/tags/kolibri0.7.7.0/boot/bootcode.inc | 1191 ++++ kernel/tags/kolibri0.7.7.0/boot/booteng.inc | 110 + kernel/tags/kolibri0.7.7.0/boot/bootet.inc | 115 + kernel/tags/kolibri0.7.7.0/boot/bootge.inc | 120 + kernel/tags/kolibri0.7.7.0/boot/bootru.inc | 91 + kernel/tags/kolibri0.7.7.0/boot/bootstr.inc | 62 + kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc | 755 +++ kernel/tags/kolibri0.7.7.0/boot/et.inc | 16 + kernel/tags/kolibri0.7.7.0/boot/preboot.inc | 38 + kernel/tags/kolibri0.7.7.0/boot/rdload.inc | 125 + kernel/tags/kolibri0.7.7.0/boot/ru.inc | 102 + kernel/tags/kolibri0.7.7.0/boot/shutdown.inc | 209 + .../kolibri0.7.7.0/bootloader/boot_fat12.asm | 287 + .../kolibri0.7.7.0/bootloader/floppy1440.inc | 19 + .../kolibri0.7.7.0/bootloader/floppy1680.inc | 19 + .../kolibri0.7.7.0/bootloader/floppy1743.inc | 19 + .../kolibri0.7.7.0/bootloader/floppy2880.inc | 19 + kernel/tags/kolibri0.7.7.0/bootloader/readme | 43 + kernel/tags/kolibri0.7.7.0/build.bat | 142 + kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc | 51 + kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc | 483 ++ kernel/tags/kolibri0.7.7.0/const.inc | 767 +++ kernel/tags/kolibri0.7.7.0/core/conf_lib.inc | 297 + kernel/tags/kolibri0.7.7.0/core/debug.inc | 416 ++ kernel/tags/kolibri0.7.7.0/core/dll.inc | 1689 +++++ kernel/tags/kolibri0.7.7.0/core/export.inc | 39 + kernel/tags/kolibri0.7.7.0/core/exports.inc | 153 + kernel/tags/kolibri0.7.7.0/core/ext_lib.inc | 320 + kernel/tags/kolibri0.7.7.0/core/fpu.inc | 183 + kernel/tags/kolibri0.7.7.0/core/heap.inc | 1538 +++++ kernel/tags/kolibri0.7.7.0/core/malloc.inc | 1025 +++ kernel/tags/kolibri0.7.7.0/core/memory.inc | 1465 +++++ kernel/tags/kolibri0.7.7.0/core/peload.inc | 318 + kernel/tags/kolibri0.7.7.0/core/sched.inc | 311 + kernel/tags/kolibri0.7.7.0/core/string.inc | 188 + kernel/tags/kolibri0.7.7.0/core/sync.inc | 119 + kernel/tags/kolibri0.7.7.0/core/sys32.inc | 844 +++ kernel/tags/kolibri0.7.7.0/core/syscall.inc | 261 + kernel/tags/kolibri0.7.7.0/core/taskman.inc | 1168 ++++ kernel/tags/kolibri0.7.7.0/core/v86.inc | 935 +++ kernel/tags/kolibri0.7.7.0/data16.inc | 55 + kernel/tags/kolibri0.7.7.0/data32.inc | 467 ++ .../tags/kolibri0.7.7.0/detect/biosdisk.inc | 81 + kernel/tags/kolibri0.7.7.0/detect/biosmem.inc | 43 + kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc | 30 + .../tags/kolibri0.7.7.0/detect/dev_hdcd.inc | 385 ++ kernel/tags/kolibri0.7.7.0/detect/disks.inc | 15 + .../tags/kolibri0.7.7.0/detect/getcache.inc | 212 + .../tags/kolibri0.7.7.0/detect/sear_par.inc | 153 + kernel/tags/kolibri0.7.7.0/docs/apm.txt | 518 ++ .../tags/kolibri0.7.7.0/docs/loader_doc.txt | 88 + kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt | 4626 +++++++++++++ kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt | 4529 +++++++++++++ kernel/tags/kolibri0.7.7.0/drivers/codec.inc | 283 + .../tags/kolibri0.7.7.0/drivers/com_mouse.asm | 382 ++ .../tags/kolibri0.7.7.0/drivers/ensoniq.asm | 1177 ++++ .../tags/kolibri0.7.7.0/drivers/imports.inc | 89 + .../tags/kolibri0.7.7.0/drivers/infinity.asm | 1306 ++++ kernel/tags/kolibri0.7.7.0/drivers/main.inc | 164 + .../tags/kolibri0.7.7.0/drivers/mix_mmx.inc | 247 + .../tags/kolibri0.7.7.0/drivers/mix_sse2.inc | 145 + kernel/tags/kolibri0.7.7.0/drivers/mixer.asm | 1262 ++++ kernel/tags/kolibri0.7.7.0/drivers/proc32.inc | 268 + .../kolibri0.7.7.0/drivers/sb16/CONFIG.INC | 50 + .../kolibri0.7.7.0/drivers/sb16/README.TXT | 72 + .../tags/kolibri0.7.7.0/drivers/sb16/SB16.INC | 297 + .../tags/kolibri0.7.7.0/drivers/sb16/sb16.asm | 393 ++ .../tags/kolibri0.7.7.0/drivers/sceletone.asm | 177 + kernel/tags/kolibri0.7.7.0/drivers/sis.asm | 1307 ++++ kernel/tags/kolibri0.7.7.0/drivers/sound.asm | 1473 +++++ kernel/tags/kolibri0.7.7.0/drivers/uart.asm | 976 +++ .../tags/kolibri0.7.7.0/drivers/usb/urb.inc | 115 + .../tags/kolibri0.7.7.0/drivers/usb/usb.asm | 435 ++ kernel/tags/kolibri0.7.7.0/drivers/vmode.asm | 736 +++ kernel/tags/kolibri0.7.7.0/fdo.inc | 439 ++ kernel/tags/kolibri0.7.7.0/fs/fat12.inc | 2272 +++++++ kernel/tags/kolibri0.7.7.0/fs/fat32.inc | 2917 +++++++++ kernel/tags/kolibri0.7.7.0/fs/fs.inc | 797 +++ kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc | 1145 ++++ kernel/tags/kolibri0.7.7.0/fs/iso9660.inc | 757 +++ kernel/tags/kolibri0.7.7.0/fs/ntfs.inc | 1815 ++++++ kernel/tags/kolibri0.7.7.0/fs/parse_fn.inc | 236 + kernel/tags/kolibri0.7.7.0/fs/part_set.inc | 481 ++ kernel/tags/kolibri0.7.7.0/gui/button.inc | 643 ++ kernel/tags/kolibri0.7.7.0/gui/event.inc | 487 ++ kernel/tags/kolibri0.7.7.0/gui/font.inc | 132 + kernel/tags/kolibri0.7.7.0/gui/mouse.inc | 250 + kernel/tags/kolibri0.7.7.0/gui/skincode.inc | 467 ++ kernel/tags/kolibri0.7.7.0/gui/skindata.inc | 64 + kernel/tags/kolibri0.7.7.0/gui/window.inc | 1823 ++++++ kernel/tags/kolibri0.7.7.0/hid/keyboard.inc | 343 + kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc | 456 ++ kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc | 203 + kernel/tags/kolibri0.7.7.0/imports.inc | 27 + kernel/tags/kolibri0.7.7.0/init.inc | 437 ++ kernel/tags/kolibri0.7.7.0/kernel.asm | 5785 +++++++++++++++++ kernel/tags/kolibri0.7.7.0/kernel32.inc | 279 + kernel/tags/kolibri0.7.7.0/kglobals.inc | 69 + kernel/tags/kolibri0.7.7.0/macros.inc | 106 + kernel/tags/kolibri0.7.7.0/make.sh | 33 + kernel/tags/kolibri0.7.7.0/makefile | 48 + kernel/tags/kolibri0.7.7.0/memmap.inc | 248 + .../kolibri0.7.7.0/network/eth_drv/arp.inc | 556 ++ .../network/eth_drv/drivers/3c59x.inc | 2378 +++++++ .../network/eth_drv/drivers/forcedeth.inc | 2692 ++++++++ .../network/eth_drv/drivers/i8255x.inc | 760 +++ .../network/eth_drv/drivers/pcnet32.inc | 848 +++ .../network/eth_drv/drivers/rtl8029.inc | 959 +++ .../network/eth_drv/drivers/rtl8139.inc | 621 ++ .../network/eth_drv/drivers/rtl8169.inc | 1219 ++++ .../network/eth_drv/drivers/sis900.inc | 1158 ++++ .../network/eth_drv/ethernet.inc | 509 ++ .../kolibri0.7.7.0/network/eth_drv/pci.inc | 351 + kernel/tags/kolibri0.7.7.0/network/icmp.inc | 193 + kernel/tags/kolibri0.7.7.0/network/ip.inc | 244 + kernel/tags/kolibri0.7.7.0/network/queue.inc | 229 + kernel/tags/kolibri0.7.7.0/network/socket.inc | 1107 ++++ kernel/tags/kolibri0.7.7.0/network/stack.inc | 1024 +++ kernel/tags/kolibri0.7.7.0/network/tcp.inc | 1169 ++++ kernel/tags/kolibri0.7.7.0/network/udp.inc | 155 + kernel/tags/kolibri0.7.7.0/proc32.inc | 271 + .../sec_loader/trunk/boot/PrimaryLoader.txt | 91 + .../sec_loader/trunk/boot/after_win/build.bat | 2 + .../sec_loader/trunk/boot/after_win/fat.inc | 509 ++ .../trunk/boot/after_win/kordldr.win.asm | 921 +++ .../trunk/boot/after_win/kordldr.win.txt | 391 ++ .../sec_loader/trunk/boot/after_win/ntfs.inc | 587 ++ .../sec_loader/trunk/boot/build.bat | 20 + .../sec_loader/trunk/boot/cdfs/bootsect.asm | 1024 +++ .../sec_loader/trunk/boot/cdfs/bootsect.txt | 418 ++ .../sec_loader/trunk/boot/cdfs/build.bat | 2 + .../sec_loader/trunk/boot/fat1x/bootsect.asm | 392 ++ .../sec_loader/trunk/boot/fat1x/bootsect.txt | 360 + .../sec_loader/trunk/boot/fat1x/build.bat | 3 + .../trunk/boot/fat1x/kordldr.f1x.asm | 667 ++ .../sec_loader/trunk/boot/fat32/bootsect.asm | 358 + .../sec_loader/trunk/boot/fat32/bootsect.txt | 333 + .../sec_loader/trunk/boot/fat32/build.bat | 3 + .../trunk/boot/fat32/kordldr.f32.asm | 672 ++ .../sec_loader/trunk/boot/floppy.asc | 49 + .../sec_loader/trunk/boot/mkfloppy.inc | 90 + .../sec_loader/trunk/boot_st.inc | 68 + .../sec_loader/trunk/build_ru.bat | 4 + .../sec_loader/trunk/debug_msg.inc | 77 + .../sec_loader/trunk/kolibri_ldm/ETFONT.FNT | Bin 0 -> 4096 bytes .../sec_loader/trunk/kolibri_ldm/booteng.inc | 98 + .../sec_loader/trunk/kolibri_ldm/bootet.inc | 119 + .../sec_loader/trunk/kolibri_ldm/bootge.inc | 118 + .../sec_loader/trunk/kolibri_ldm/bootru.inc | 87 + .../sec_loader/trunk/kolibri_ldm/bootstr.inc | 55 + .../sec_loader/trunk/kolibri_ldm/bootvesa.inc | 754 +++ .../sec_loader/trunk/kolibri_ldm/build_ru.bat | 89 + .../sec_loader/trunk/kolibri_ldm/et.inc | 14 + .../trunk/kolibri_ldm/kolibri_ldm.asm | 808 +++ .../sec_loader/trunk/kolibri_ldm/macros.inc | 86 + .../sec_loader/trunk/kolibri_ldm/preboot.inc | 36 + .../sec_loader/trunk/kolibri_ldm/rdload.inc | 123 + .../sec_loader/trunk/kolibri_ldm/ru.inc | 100 + .../sec_loader/trunk/kolibri_ldm/shutdown.inc | 207 + .../sec_loader/trunk/listing.inc | 635 ++ .../sec_loader/trunk/loader.asm | 317 + .../sec_loader/trunk/loader.lst | 2147 ++++++ .../kolibri0.7.7.0/sec_loader/trunk/parse.inc | 118 + .../sec_loader/trunk/parse_any.inc | 683 ++ .../sec_loader/trunk/parse_dat.inc | 56 + .../sec_loader/trunk/parse_def_sect.inc | 2094 ++++++ .../sec_loader/trunk/parse_err.inc | 66 + .../sec_loader/trunk/parse_loader.inc | 332 + .../sec_loader/trunk/sl_equ.inc | 98 + .../sec_loader/trunk/sl_proc.inc | 524 ++ .../sec_loader/trunk/startos.ini | 98 + kernel/tags/kolibri0.7.7.0/skin/base.bmp | Bin 0 -> 584 bytes kernel/tags/kolibri0.7.7.0/skin/base_1.bmp | Bin 0 -> 584 bytes kernel/tags/kolibri0.7.7.0/skin/default.asm | 38 + kernel/tags/kolibri0.7.7.0/skin/left.bmp | Bin 0 -> 670 bytes kernel/tags/kolibri0.7.7.0/skin/left_1.bmp | Bin 0 -> 670 bytes kernel/tags/kolibri0.7.7.0/skin/me_skin.inc | 242 + kernel/tags/kolibri0.7.7.0/skin/myblue.dtp | Bin 0 -> 40 bytes kernel/tags/kolibri0.7.7.0/skin/oper.bmp | Bin 0 -> 2694 bytes kernel/tags/kolibri0.7.7.0/skin/oper_1.bmp | Bin 0 -> 2694 bytes kernel/tags/kolibri0.7.7.0/sound/playnote.inc | 164 + kernel/tags/kolibri0.7.7.0/sys.conf | 18 + kernel/tags/kolibri0.7.7.0/unpacker.inc | 527 ++ kernel/tags/kolibri0.7.7.0/video/arrow.cur | Bin 0 -> 766 bytes kernel/tags/kolibri0.7.7.0/video/cursors.inc | 806 +++ kernel/tags/kolibri0.7.7.0/video/vesa12.inc | 1004 +++ kernel/tags/kolibri0.7.7.0/video/vesa20.inc | 1150 ++++ kernel/tags/kolibri0.7.7.0/video/vga.inc | 450 ++ kernel/tags/kolibri0.7.7.0/vmodeint.inc | 58 + kernel/tags/kolibri0.7.7.0/vmodeld.inc | 35 + 200 files changed, 105597 insertions(+) create mode 100644 kernel/tags/kolibri0.7.7.0/COPYING.TXT create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/cd_drv.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/ide_cache.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/rd.inc create mode 100644 kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/ETFONT.FNT create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootcode.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/booteng.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootet.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootge.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootru.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootstr.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/et.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/preboot.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/rdload.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/ru.inc create mode 100644 kernel/tags/kolibri0.7.7.0/boot/shutdown.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/boot_fat12.asm create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/floppy1440.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/floppy1680.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/floppy1743.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/floppy2880.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bootloader/readme create mode 100644 kernel/tags/kolibri0.7.7.0/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc create mode 100644 kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/const.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/conf_lib.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/debug.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/dll.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/export.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/exports.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/ext_lib.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/fpu.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/heap.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/malloc.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/memory.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/peload.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/sched.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/string.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/sync.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/sys32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/syscall.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/taskman.inc create mode 100644 kernel/tags/kolibri0.7.7.0/core/v86.inc create mode 100644 kernel/tags/kolibri0.7.7.0/data16.inc create mode 100644 kernel/tags/kolibri0.7.7.0/data32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/biosdisk.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/biosmem.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/dev_hdcd.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/disks.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/getcache.inc create mode 100644 kernel/tags/kolibri0.7.7.0/detect/sear_par.inc create mode 100644 kernel/tags/kolibri0.7.7.0/docs/apm.txt create mode 100644 kernel/tags/kolibri0.7.7.0/docs/loader_doc.txt create mode 100644 kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt create mode 100644 kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/codec.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/com_mouse.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/ensoniq.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/imports.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/infinity.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/main.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/mix_mmx.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/mix_sse2.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/mixer.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/proc32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sb16/CONFIG.INC create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sb16/README.TXT create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sb16/SB16.INC create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sb16/sb16.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sceletone.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sis.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/sound.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/uart.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/usb/urb.inc create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/usb/usb.asm create mode 100644 kernel/tags/kolibri0.7.7.0/drivers/vmode.asm create mode 100644 kernel/tags/kolibri0.7.7.0/fdo.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/fat12.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/fat32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/fs.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/iso9660.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/ntfs.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/parse_fn.inc create mode 100644 kernel/tags/kolibri0.7.7.0/fs/part_set.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/button.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/event.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/font.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/mouse.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/skincode.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/skindata.inc create mode 100644 kernel/tags/kolibri0.7.7.0/gui/window.inc create mode 100644 kernel/tags/kolibri0.7.7.0/hid/keyboard.inc create mode 100644 kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc create mode 100644 kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc create mode 100644 kernel/tags/kolibri0.7.7.0/imports.inc create mode 100644 kernel/tags/kolibri0.7.7.0/init.inc create mode 100644 kernel/tags/kolibri0.7.7.0/kernel.asm create mode 100644 kernel/tags/kolibri0.7.7.0/kernel32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/kglobals.inc create mode 100644 kernel/tags/kolibri0.7.7.0/macros.inc create mode 100755 kernel/tags/kolibri0.7.7.0/make.sh create mode 100644 kernel/tags/kolibri0.7.7.0/makefile create mode 100644 kernel/tags/kolibri0.7.7.0/memmap.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/arp.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/3c59x.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/forcedeth.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/i8255x.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/pcnet32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8029.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8139.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8169.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/sis900.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/ethernet.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/eth_drv/pci.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/icmp.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/ip.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/queue.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/socket.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/stack.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/tcp.inc create mode 100644 kernel/tags/kolibri0.7.7.0/network/udp.inc create mode 100644 kernel/tags/kolibri0.7.7.0/proc32.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/PrimaryLoader.txt create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/fat.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.txt create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/ntfs.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.txt create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.txt create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.txt create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/build.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/kordldr.f32.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/floppy.asc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/mkfloppy.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot_st.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/build_ru.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/debug_msg.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ETFONT.FNT create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/booteng.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootet.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootge.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootru.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootstr.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootvesa.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/build_ru.bat create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/et.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/macros.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/preboot.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/rdload.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ru.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/shutdown.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/listing.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.asm create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.lst create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_any.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_dat.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_def_sect.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_err.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_loader.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_equ.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_proc.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sec_loader/trunk/startos.ini create mode 100644 kernel/tags/kolibri0.7.7.0/skin/base.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/base_1.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/default.asm create mode 100644 kernel/tags/kolibri0.7.7.0/skin/left.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/left_1.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/me_skin.inc create mode 100644 kernel/tags/kolibri0.7.7.0/skin/myblue.dtp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/oper.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/skin/oper_1.bmp create mode 100644 kernel/tags/kolibri0.7.7.0/sound/playnote.inc create mode 100644 kernel/tags/kolibri0.7.7.0/sys.conf create mode 100644 kernel/tags/kolibri0.7.7.0/unpacker.inc create mode 100644 kernel/tags/kolibri0.7.7.0/video/arrow.cur create mode 100644 kernel/tags/kolibri0.7.7.0/video/cursors.inc create mode 100644 kernel/tags/kolibri0.7.7.0/video/vesa12.inc create mode 100644 kernel/tags/kolibri0.7.7.0/video/vesa20.inc create mode 100644 kernel/tags/kolibri0.7.7.0/video/vga.inc create mode 100644 kernel/tags/kolibri0.7.7.0/vmodeint.inc create mode 100644 kernel/tags/kolibri0.7.7.0/vmodeld.inc diff --git a/kernel/tags/kolibri0.7.7.0/COPYING.TXT b/kernel/tags/kolibri0.7.7.0/COPYING.TXT new file mode 100644 index 000000000..f6213b69c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/COPYING.TXT @@ -0,0 +1,347 @@ + + GNU GENERAL PUBLIC LICENSE + + Version 2, June 1991 + + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + GNU GENERAL PUBLIC LICENSE + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + 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/tags/kolibri0.7.7.0/blkdev/cd_drv.inc b/kernel/tags/kolibri0.7.7.0/blkdev/cd_drv.inc new file mode 100644 index 000000000..38f7c9068 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/cd_drv.inc @@ -0,0 +1,929 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;********************************************************** +; Непосредственная работа с устройством СD (ATAPI) +;********************************************************** +; Автор части исходного текста Кулаков Владимир Геннадьевич +; Адаптация, доработка и разработка Mario79, + +; Максимальное количество повторений операции чтения +MaxRetr equ 10 +; Предельное время ожидания готовности к приему команды +; (в тиках) +BSYWaitTime equ 1000 ;2 +NoTickWaitTime equ 0xfffff +CDBlockSize equ 2048 +;******************************************** +;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * +;* Многократное повторение чтения при сбоях * +;******************************************** +ReadCDWRetr: +;----------------------------------------------------------- +; input : eax = block to read +; ebx = destination +;----------------------------------------------------------- + pushad + mov eax,[CDSectorAddress] + mov ebx,[CDDataBuf_pointer] + call cd_calculate_cache + xor edi,edi + add esi,8 + inc edi +.hdreadcache: +; cmp dword [esi+4],0 ; empty +; je .nohdcache + cmp [esi],eax ; correct sector + je .yeshdcache +.nohdcache: + add esi,8 + inc edi + dec ecx + jnz .hdreadcache + call find_empty_slot_CD_cache ; ret in edi + + push edi + push eax + call cd_calculate_cache_2 + shl edi,11 + add edi,eax + mov [CDDataBuf_pointer],edi + pop eax + pop edi + + call ReadCDWRetr_1 + cmp [DevErrorCode],0 + jne .exit + + mov [CDDataBuf_pointer],ebx + call cd_calculate_cache_1 + lea esi,[edi*8+esi] + mov [esi],eax ; sector number +; mov dword [esi+4],1 ; hd read - mark as same as in hd +.yeshdcache: + mov esi,edi + shl esi,11 ;9 + push eax + call cd_calculate_cache_2 + add esi,eax + pop eax + mov edi,ebx ;[CDDataBuf_pointer] + mov ecx,512 ;/4 + cld + rep movsd ; move data +.exit: + popad + ret + +ReadCDWRetr_1: + pushad + +; Цикл, пока команда не выполнена успешно или не +; исчерпано количество попыток + mov ECX,MaxRetr +@@NextRetr: +; Подать команду +;************************************************* +;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * +;* Считываются данные пользователя, информация * +;* субканала и контрольная информация * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* CDSectorAddress - адрес считываемого сектора. * +;* Данные считывается в массив CDDataBuf. * +;************************************************* +;ReadCD: + push ecx +; pusha +; Задать размер сектора +; mov [CDBlockSize],2048 ;2352 +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать пакетную команду для считывания +; сектора данных +; Задать код команды Read CD + mov [PacketCommand],byte 0x28 ;0xBE +; Задать адрес сектора + mov AX,word [CDSectorAddress+2] + xchg AL,AH + mov word [PacketCommand+2],AX + mov AX,word [CDSectorAddress] + xchg AL,AH + mov word [PacketCommand+4],AX +; mov eax,[CDSectorAddress] +; mov [PacketCommand+2],eax +; Задать количество считываемых секторов + mov [PacketCommand+8],byte 1 +; Задать считывание данных в полном объеме +; mov [PacketCommand+9],byte 0xF8 +; Подать команду + call SendPacketDatCommand + pop ecx +; ret + +; cmp [DevErrorCode],0 + test eax,eax + jz @@End_4 + + or ecx,ecx ;{SPraid.simba} (for cd load) + jz @@End_4 + dec ecx + + cmp [timer_ticks_enable],0 + jne @f + mov eax,NoTickWaitTime +.wait: + dec eax +; test eax,eax + jz @@NextRetr + jmp .wait +@@: +; Задержка на 2,5 секунды +; mov EAX,[timer_ticks] +; add EAX,50 ;250 +;@@Wait: +; call change_task +; cmp EAX,[timer_ticks] +; ja @@Wait + loop @@NextRetr +@@End_4: + mov dword [DevErrorCode],eax + popad + ret + + +; Универсальные процедуры, обеспечивающие выполнение +; пакетных команд в режиме PIO + +; Максимально допустимое время ожидания реакции +; устройства на пакетную команду (в тиках) + +MaxCDWaitTime equ 1000 ;200 ;10 секунд +uglobal +; Область памяти для формирования пакетной команды +PacketCommand: rb 12 ;DB 12 DUP (?) +; Область памяти для приема данных от дисковода +;CDDataBuf DB 4096 DUP (0) +; Размер принимаемого блока данных в байтах +;CDBlockSize DW ? +; Адрес считываемого сектора данных +CDSectorAddress: DD ? +; Время начала очередной операции с диском +TickCounter_1 DD 0 +; Время начала ожидания готовности устройства +WURStartTime DD 0 +; указатель буфера для считывания +CDDataBuf_pointer dd 0 +endg +;**************************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * +;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет; * +;* CDBlockSize - размер принимаемого блока данных. * +; return eax DevErrorCode +;**************************************************** +SendPacketDatCommand: + xor eax,eax +; mov byte [DevErrorCode],al +; Задать режим CHS + mov byte [ATAAddressMode],al +; Послать ATA-команду передачи пакетной команды + mov byte [ATAFeatures],al + mov byte [ATASectorCount],al + mov byte [ATASectorNumber],al + ; Загрузить размер передаваемого блока + mov [ATAHead],al +; mov AX,[CDBlockSize] + mov [ATACylinder],CDBlockSize + mov [ATACommand],0A0h + call SendCommandToHDD_1 + test eax,eax +; cmp [DevErrorCode],0 ;проверить код ошибки + jnz @@End_8 ;закончить, сохранив код ошибки + +; Ожидание готовности дисковода к приему +; пакетной команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h + mov ecx,NoTickWaitTime +@@WaitDevice0: + cmp [timer_ticks_enable],0 + jne @f + dec ecx +; test ecx,ecx + jz @@Err1_1 + jmp .test +@@: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,BSYWaitTime + ja @@Err1_1 ;ошибка тайм-аута + ; Проверить готовность +.test: + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice0 + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice0 + test AL,1 ;состояние сигнала ERR + jnz @@Err6 +; Послать пакетную команду + cli + mov DX,[ATABasePortAddr] + mov AX,[PacketCommand] + out DX,AX + mov AX,[PacketCommand+2] + out DX,AX + mov AX,[PacketCommand+4] + out DX,AX + mov AX,[PacketCommand+6] + out DX,AX + mov AX,[PacketCommand+8] + out DX,AX + mov AX,[PacketCommand+10] + out DX,AX + sti +; Ожидание готовности данных + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h + mov ecx,NoTickWaitTime +@@WaitDevice1: + cmp [timer_ticks_enable],0 + jne @f + dec ecx +; test ecx,ecx + jz @@Err1_1 + jmp .test_1 +@@: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,MaxCDWaitTime + ja @@Err1_1 ;ошибка тайм-аута + ; Проверить готовность +.test_1: + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice1 + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_temp +; Принять блок данных от контроллера + mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf + ; Загрузить адрес регистра данных контроллера + mov DX,[ATABasePortAddr] ;порт 1x0h + ; Загрузить в счетчик размер блока в байтах + xor ecx,ecx + mov CX,CDBlockSize + ; Вычислить размер блока в 16-разрядных словах + shr CX,1 ;разделить размер блока на 2 + ; Принять блок данных + cli + cld + rep insw + sti +; Успешное завершение приема данных +@@End_8: + xor eax,eax + ret + +; Записать код ошибки +@@Err1_1: + xor eax,eax + inc eax + ret +; mov [DevErrorCode],1 +; ret +@@Err6_temp: + mov eax,7 + ret +; mov [DevErrorCode],7 +; ret +@@Err6: + mov eax,6 + ret +; mov [DevErrorCode],6 +;@@End_8: +; ret + + + +;*********************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * +;* Входные параметры передаются через * +;* глобальные перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет. * +;*********************************************** +SendPacketNoDatCommand: + pushad + xor eax,eax +; mov byte [DevErrorCode],al +; Задать режим CHS + mov byte [ATAAddressMode],al +; Послать ATA-команду передачи пакетной команды + mov byte [ATAFeatures],al + mov byte [ATASectorCount],al + mov byte [ATASectorNumber],al + mov word [ATACylinder],ax + mov byte [ATAHead],al + mov [ATACommand],0A0h + call SendCommandToHDD_1 +; cmp [DevErrorCode],0 ;проверить код ошибки + test eax,eax + jnz @@End_9 ;закончить, сохранив код ошибки +; Ожидание готовности дисковода к приему +; пакетной команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice0_1: + call change_task + ; Проверить время ожидания + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,BSYWaitTime + ja @@Err1_3 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice0_1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_1 + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice0_1 +; Послать пакетную команду +; cli + mov DX,[ATABasePortAddr] + mov AX,word [PacketCommand] + out DX,AX + mov AX,word [PacketCommand+2] + out DX,AX + mov AX,word [PacketCommand+4] + out DX,AX + mov AX,word [PacketCommand+6] + out DX,AX + mov AX,word [PacketCommand+8] + out DX,AX + mov AX,word [PacketCommand+10] + out DX,AX +; sti + cmp [ignore_CD_eject_wait],1 + je @@clear_DEC +; Ожидание подтверждения приема команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice1_1: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,MaxCDWaitTime + ja @@Err1_3 ;ошибка тайм-аута + ; Ожидать освобождения устройства + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice1_1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_1 + test AL,40h ;состояние сигнала DRDY + jz @@WaitDevice1_1 +@@clear_DEC: + and [DevErrorCode],0 + popad + ret +; Записать код ошибки +@@Err1_3: + xor eax,eax + inc eax + jmp @@End_9 +@@Err6_1: + mov eax,6 +@@End_9: + mov [DevErrorCode],eax + popad + ret + +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска (0 или 1); * +;* ATAFeatures - "особенности"; * +;* ATASectorCount - количество секторов; * +;* ATASectorNumber - номер начального сектора; * +;* ATACylinder - номер начального цилиндра; * +;* ATAHead - номер начальной головки; * +;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * +;* ATACommand - код команды. * +;* После успешного выполнения функции: * +;* в ATABasePortAddr - базовый адрес HDD; * +;* в DevErrorCode - ноль. * +;* При возникновении ошибки в DevErrorCode будет * +;* возвращен код ошибки в eax * +;**************************************************** +SendCommandToHDD_1: +; pushad +; mov [DevErrorCode],0 not need +; Проверить значение кода режима + cmp [ATAAddressMode],1 + ja @@Err2_4 +; Проверить корректность номера канала + mov BX,[ChannelNumber] + cmp BX,1 + jb @@Err3_4 + cmp BX,2 + ja @@Err3_4 +; Установить базовый адрес + dec BX + shl BX,1 + movzx ebx,bx + mov AX,[ebx+StandardATABases] + mov [ATABasePortAddr],AX +; Ожидание готовности HDD к приему команды + ; Выбрать нужный диск + mov DX,[ATABasePortAddr] + add DX,6 ;адрес регистра головок + mov AL,[DiskNumber] + cmp AL,1 ;проверить номера диска + ja @@Err4_4 + shl AL,4 + or AL,10100000b + out DX,AL + ; Ожидать, пока диск не будет готов + inc DX + mov eax,[timer_ticks] + mov [TickCounter_1],eax + mov ecx,NoTickWaitTime +@@WaitHDReady_2: + cmp [timer_ticks_enable],0 + jne @f + dec ecx +; test ecx,ecx + jz @@Err1_4 + jmp .test +@@: + call change_task + ; Проверить время ожидания + mov eax,[timer_ticks] + sub eax,[TickCounter_1] + cmp eax,BSYWaitTime ;300 ;ожидать 3 сек. + ja @@Err1_4 ;ошибка тайм-аута + ; Прочитать регистр состояния +.test: + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady_2 + ; Проверить состояние сигнала DRQ + test AL,08h + jnz @@WaitHDReady_2 + +; Загрузить команду в регистры контроллера + cli + mov DX,[ATABasePortAddr] + inc DX ;регистр "особенностей" + mov AL,[ATAFeatures] + out DX,AL + inc DX ;счетчик секторов + mov AL,[ATASectorCount] + out DX,AL + inc DX ;регистр номера сектора + mov AL,[ATASectorNumber] + out DX,AL + inc DX ;номер цилиндра (младший байт) + mov AX,[ATACylinder] + out DX,AL + inc DX ;номер цилиндра (старший байт) + mov AL,AH + out DX,AL + inc DX ;номер головки/номер диска + mov AL,[DiskNumber] + shl AL,4 + cmp [ATAHead],0Fh ;проверить номер головки + ja @@Err5_4 + or AL,[ATAHead] + or AL,10100000b + mov AH,[ATAAddressMode] + shl AH,6 + or AL,AH + out DX,AL +; Послать команду + mov AL,[ATACommand] + inc DX ;регистр команд + out DX,AL + sti +; Сбросить признак ошибки +; mov [DevErrorCode],0 +@@End_10: + xor eax,eax + ret +; Записать код ошибки +@@Err1_4: + xor eax,eax + inc eax +; mov [DevErrorCode],1 + ret +@@Err2_4: + mov eax,2 +; mov [DevErrorCode],2 + ret +@@Err3_4: + mov eax,3 +; mov [DevErrorCode],3 + ret +@@Err4_4: + mov eax,4 +; mov [DevErrorCode],4 + ret +@@Err5_4: + mov eax,5 +; mov [DevErrorCode],5 +; Завершение работы программы + ret +; sti +; popad + +;************************************************* +;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +WaitUnitReady: + pusha +; Запомнить время начала операции + mov EAX,[timer_ticks] + mov [WURStartTime],EAX +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду TEST UNIT READY + mov [PacketCommand],word 00h +; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА + mov ecx,NoTickWaitTime +@@SendCommand: + ; Подать команду проверки готовности + call SendPacketNoDatCommand + cmp [timer_ticks_enable],0 + jne @f + cmp [DevErrorCode],0 + je @@End_11 + dec ecx +; cmp ecx,0 + jz .Error + jmp @@SendCommand +@@: + call change_task + ; Проверить код ошибки + cmp [DevErrorCode],0 + je @@End_11 + ; Проверить время ожидания готовности + mov EAX,[timer_ticks] + sub EAX,[WURStartTime] + cmp EAX,MaxCDWaitTime + jb @@SendCommand +.Error: + ; Ошибка тайм-аута + mov [DevErrorCode],1 +@@End_11: + popa + ret + +;************************************************* +;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +prevent_medium_removal: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Задать код команды + mov [PacketCommand],byte 0x1E +; Задать код запрета + mov [PacketCommand+4],byte 11b +; Подать команду + call SendPacketNoDatCommand + mov eax,ATAPI_IDE0_lock + add eax,[cdpos] + dec eax + mov [eax],byte 1 + popa + ret + +;************************************************* +;* РАЗРЕШИТЬ СМЕНУ ДИСКА * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +allow_medium_removal: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Задать код команды + mov [PacketCommand],byte 0x1E +; Задать код запрета + mov [PacketCommand+4],byte 00b +; Подать команду + call SendPacketNoDatCommand + mov eax,ATAPI_IDE0_lock + add eax,[cdpos] + dec eax + mov [eax],byte 0 + popa + ret + +;************************************************* +;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +LoadMedium: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду START/STOP UNIT + ; Задать код команды + mov [PacketCommand],word 1Bh + ; Задать операцию загрузки носителя + mov [PacketCommand+4],word 00000011b +; Подать команду + call SendPacketNoDatCommand + popa + ret + +;************************************************* +;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +EjectMedium: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду START/STOP UNIT + ; Задать код команды + mov [PacketCommand],word 1Bh + ; Задать операцию извлечения носителя + mov [PacketCommand+4],word 00000010b +; Подать команду + call SendPacketNoDatCommand + popa + ret + +;************************************************* +;* Проверить событие нажатия кнопки извлечения * +;* диска * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +align 4 +check_ATAPI_device_event: + pusha + mov eax,[timer_ticks] + sub eax,[timer_ATAPI_check] + cmp eax,100 + jb .end_1 + mov al,[DRIVE_DATA+1] + and al,11b + cmp al,10b + jz .ide3 +.ide2_1: + mov al,[DRIVE_DATA+1] + and al,1100b + cmp al,1000b + jz .ide2 +.ide1_1: + mov al,[DRIVE_DATA+1] + and al,110000b + cmp al,100000b + jz .ide1 +.ide0_1: + mov al,[DRIVE_DATA+1] + and al,11000000b + cmp al,10000000b + jz .ide0 +.end: + + sti + mov eax,[timer_ticks] + mov [timer_ATAPI_check],eax +.end_1: + popa + ret + +.ide3: + cli + cmp [ATAPI_IDE3_lock],1 + jne .ide2_1 + cmp [IDE_Channel_2],0 + jne .ide1_1 + cmp [cd_status],0 + jne .end + mov [IDE_Channel_2],1 + call reserve_ok2 + mov [ChannelNumber],2 + mov [DiskNumber],1 + mov [cdpos],4 + call GetEvent_StatusNotification + cmp [CDDataBuf+4],byte 1 + je .eject_ide3 + call syscall_cdaudio.free + jmp .ide2_1 +.eject_ide3: + call .eject + call syscall_cdaudio.free + jmp .ide2_1 + +.ide2: + cli + cmp [ATAPI_IDE2_lock],1 + jne .ide1_1 + cmp [IDE_Channel_2],0 + jne .ide1_1 + cmp [cd_status],0 + jne .end + mov [IDE_Channel_2],1 + call reserve_ok2 + mov [ChannelNumber],2 + mov [DiskNumber],0 + mov [cdpos],3 + call GetEvent_StatusNotification + cmp [CDDataBuf+4],byte 1 + je .eject_ide2 + call syscall_cdaudio.free + jmp .ide1_1 +.eject_ide2: + call .eject + call syscall_cdaudio.free + jmp .ide1_1 + +.ide1: + cli + cmp [ATAPI_IDE1_lock],1 + jne .ide0_1 + cmp [IDE_Channel_1],0 + jne .end + cmp [cd_status],0 + jne .end + mov [IDE_Channel_1],1 + call reserve_ok2 + mov [ChannelNumber],1 + mov [DiskNumber],1 + mov [cdpos],2 + call GetEvent_StatusNotification + cmp [CDDataBuf+4],byte 1 + je .eject_ide1 + call syscall_cdaudio.free + jmp .ide0_1 +.eject_ide1: + call .eject + call syscall_cdaudio.free + jmp .ide0_1 + +.ide0: + cli + cmp [ATAPI_IDE0_lock],1 + jne .end + cmp [IDE_Channel_1],0 + jne .end + cmp [cd_status],0 + jne .end + mov [IDE_Channel_1],1 + call reserve_ok2 + mov [ChannelNumber],1 + mov [DiskNumber],0 + mov [cdpos],1 + call GetEvent_StatusNotification + cmp [CDDataBuf+4],byte 1 + je .eject_ide0 + call syscall_cdaudio.free + jmp .end +.eject_ide0: + call .eject + call syscall_cdaudio.free + jmp .end + +.eject: + call clear_CD_cache + call allow_medium_removal + mov [ignore_CD_eject_wait],1 + call EjectMedium + mov [ignore_CD_eject_wait],0 + ret +iglobal +timer_ATAPI_check dd 0 +ATAPI_IDE0_lock db 0 +ATAPI_IDE1_lock db 0 +ATAPI_IDE2_lock db 0 +ATAPI_IDE3_lock db 0 +ignore_CD_eject_wait db 0 +endg +;************************************************* +;* Получить сообщение о событии или состоянии * +;* устройства * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +GetEvent_StatusNotification: + pusha + mov [CDDataBuf_pointer],CDDataBuf +; Очистить буфер пакетной команды + call clear_packet_buffer +; Задать код команды + mov [PacketCommand],byte 4Ah + mov [PacketCommand+1],byte 00000001b +; Задать запрос класса сообщений + mov [PacketCommand+4],byte 00010000b +; Размер выделенной области + mov [PacketCommand+7],byte 8h + mov [PacketCommand+8],byte 0h +; Подать команду + call SendPacketDatCommand + popa + ret + +;************************************************* +; прочитать информацию из TOC +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +Read_TOC: + pusha + mov [CDDataBuf_pointer],CDDataBuf +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать пакетную команду для считывания +; сектора данных + mov [PacketCommand],byte 0x43 + ; Задать формат + mov [PacketCommand+2],byte 1 +; Размер выделенной области + mov [PacketCommand+7],byte 0xFF + mov [PacketCommand+8],byte 0h +; Подать команду + call SendPacketDatCommand + popa + ret + +;************************************************* +;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +;ReadCapacity: +; pusha +;; Очистить буфер пакетной команды +; call clear_packet_buffer +;; Задать размер буфера в байтах +; mov [CDBlockSize],8 +;; Сформировать команду READ CAPACITY +; mov [PacketCommand],word 25h +;; Подать команду +; call SendPacketDatCommand +; popa +; ret + +clear_packet_buffer: +; Очистить буфер пакетной команды + and [PacketCommand],dword 0 + and [PacketCommand+4],dword 0 + and [PacketCommand+8],dword 0 + ret diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc b/kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc new file mode 100644 index 000000000..d7a937066 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/cdrom.inc @@ -0,0 +1,271 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +sys_cd_audio: + + cmp word [cdbase],word 0 + jnz @f + mov eax,1 + ret + @@: + + ; eax=1 cdplay at ebx 0x00FFSSMM + ; eax=2 get tracklist size of ecx to [ebx] + ; eax=3 stop/pause playing + + cmp eax,1 + jnz nocdp + call sys_cdplay + ret + nocdp: + + cmp eax,2 + jnz nocdtl + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add ebx,[edi] + call sys_cdtracklist + ret + nocdtl: + + cmp eax,3 + jnz nocdpause + call sys_cdpause + ret + nocdpause: + + mov eax,0xffffff01 + ret + + + +sys_cd_atapi_command: + + pushad + + mov dx,word [cdbase] + add dx,6 + mov ax,word [cdid] + out dx,al + mov esi,10 + call delay_ms + mov dx,word [cdbase] + add dx,7 + in al,dx + and al,0x80 + cmp al,0 + jnz res + jmp cdl6 + res: + mov dx,word [cdbase] + add dx,7 + mov al,0x8 + out dx,al + mov dx,word [cdbase] + add dx,0x206 + mov al,0xe + out dx,al + mov esi,1 + call delay_ms + mov dx,word [cdbase] + add dx,0x206 + mov al,0x8 + out dx,al + mov esi,30 + call delay_ms + xor cx,cx + cdl5: + inc cx + cmp cx,10 + jz cdl6 + mov dx,word [cdbase] + add dx,7 + in al,dx + and al,0x88 + cmp al,0x00 + jz cdl5 + mov esi,100 + call delay_ms + jmp cdl5 + cdl6: + mov dx,word [cdbase] + add dx,4 + mov al,0 + out dx,al + mov dx,word [cdbase] + add dx,5 + mov al,0 + out dx,al + mov dx,word [cdbase] + add dx,7 + mov al,0xec + out dx,al + mov esi,5 + call delay_ms + mov dx,word [cdbase] + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,128 + out dx,al + add dx,2 + mov al,0xa0 + out dx,al + xor cx,cx + mov dx,word [cdbase] + add dx,7 + cdl1: + inc cx + cmp cx,100 + jz cdl2 + in al,dx + and ax,0x88 + cmp al,0x8 + jz cdl2 + mov esi,2 + call delay_ms + jmp cdl1 + cdl2: + + popad + ret + + +sys_cdplay: + + mov ax,5 + push ax + push ebx + cdplay: + call sys_cd_atapi_command + cli + mov dx,word [cdbase] + mov ax,0x0047 + out dx,ax + mov al,1 + mov ah,[esp+0] ; min xx + out dx,ax + mov ax,[esp+1] ; fr sec + out dx,ax + mov ax,256+99 + out dx,ax + mov ax,0x0001 + out dx,ax + mov ax,0x0000 + out dx,ax + mov esi,10 + call delay_ms + sti + add dx,7 + in al,dx + test al,1 + jz cdplayok + mov ax,[esp+4] + dec ax + mov [esp+4],ax + cmp ax,0 + jz cdplayfail + jmp cdplay + cdplayfail: + cdplayok: + pop ebx + pop ax + xor eax, eax + ret + + +sys_cdtracklist: + + push ebx + tcdplay: + call sys_cd_atapi_command + mov dx,word [cdbase] + mov ax,0x43+2*256 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,200 + out dx,ax + mov ax,0x0 + out dx,ax + in al,dx + mov cx,1000 + mov dx,word [cdbase] + add dx,7 + cld + cdtrnwewait: + mov esi,10 + call delay_ms + in al,dx + and al,128 + cmp al,0 + jz cdtrl1 + loop cdtrnwewait + cdtrl1: + ; read the result + mov ecx,[esp+0] + mov dx,word [cdbase] + cdtrread: + add dx,7 + in al,dx + and al,8 + cmp al,8 + jnz cdtrdone + sub dx,7 + in ax,dx + mov [ecx],ax + add ecx,2 + jmp cdtrread + cdtrdone: + pop ecx + xor eax, eax + ret + + +sys_cdpause: + + call sys_cd_atapi_command + + mov dx,word [cdbase] + mov ax,0x004B + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + + mov esi,10 + call delay_ms + add dx,7 + in al,dx + + xor eax, eax + ret + diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc b/kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc new file mode 100644 index 000000000..65f4af940 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/fdc.inc @@ -0,0 +1,71 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +iglobal + ;function pointers. + fdc_irq_func dd fdc_null +endg + +uglobal + dmasize db 0x0 + dmamode db 0x0 +endg + +fdc_init: ;start with clean tracks. + mov edi,OS_BASE+0xD201 + mov al,0 + mov ecx,160 + rep stosb +ret + +fdc_irq: + call [fdc_irq_func] +fdc_null: +ret + +save_image: + call reserve_flp + call restorefatchain + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_save_image + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],1 ; Сектор + mov esi,RAMDISK + call SeekTrack +save_image_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr +; call WriteSector + cmp [FDC_Status],0 + jne unnecessary_save_image + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne save_image_1 + mov [FDD_Sector],1 + inc [FDD_Head] + cmp [FDD_Head],2 + jne save_image_1 + mov [FDD_Head],0 + inc [FDD_Track] + call SeekTrack + cmp [FDD_Track],80 + jne save_image_1 +unnecessary_save_image: + mov [fdc_irq_func],fdc_null + popa + mov [flp_status],0 + ret + diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc b/kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc new file mode 100644 index 000000000..127bfe48e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/flp_drv.inc @@ -0,0 +1,626 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;********************************************************** +; Непосредственная работа с контроллером гибкого диска +;********************************************************** +; Автор исходного текста Кулаков Владимир Геннадьевич. +; Адаптация и доработка Mario79 + +;give_back_application_data: ; переслать приложению +; mov edi,[TASK_BASE] +; mov edi,[edi+TASKDATA.mem_start] +; add edi,ecx +give_back_application_data_1: + mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000 + xor ecx,ecx + mov cx,128 + cld + rep movsd + ret + +;take_data_from_application: ; взять из приложени +; mov esi,[TASK_BASE] +; mov esi,[esi+TASKDATA.mem_start] +; add esi,ecx +take_data_from_application_1: + mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000 + xor ecx,ecx + mov cx,128 + cld + rep movsd + ret + +; Коды завершения операции с контроллером (FDC_Status) +FDC_Normal equ 0 ;нормальное завершение +FDC_TimeOut equ 1 ;ошибка тайм-аута +FDC_DiskNotFound equ 2 ;в дисководе нет диска +FDC_TrackNotFound equ 3 ;дорожка не найдена +FDC_SectorNotFound equ 4 ;сектор не найден + +; Максимальные значения координат сектора (заданные +; значения соответствуют параметрам стандартного +; трехдюймового гибкого диска объемом 1,44 Мб) +MAX_Track equ 79 +MAX_Head equ 1 +MAX_Sector equ 18 + +uglobal +; Счетчик тиков таймера +TickCounter dd ? +; Код завершения операции с контроллером НГМД +FDC_Status DB ? +; Флаг прерывания от НГМД +FDD_IntFlag DB ? +; Момент начала последней операции с НГМД +FDD_Time DD ? +; Номер дисковода +FDD_Type db 0 +; Координаты сектора +FDD_Track DB ? +FDD_Head DB ? +FDD_Sector DB ? + +; Блок результата операции +FDC_ST0 DB ? +FDC_ST1 DB ? +FDC_ST2 DB ? +FDC_C DB ? +FDC_H DB ? +FDC_R DB ? +FDC_N DB ? +; Счетчик повторения операции чтени +ReadRepCounter DB ? +; Счетчик повторения операции рекалибровки +RecalRepCounter DB ? +endg +; Область памяти для хранения прочитанного сектора +;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) +fdd_motor_status db 0 +timer_fdd_motor dd 0 + +;************************************* +;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД * +;************************************* +Init_FDC_DMA: + pushad + mov al,0 + out 0x0c,al ; reset the flip-flop to a known state. + mov al,6 ; mask channel 2 so we can reprogram it. + out 0x0a,al + mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy + out 0x0b,al + mov al,0 + out 0x0c,al ; reset the flip-flop to a known state. + mov eax,0xD000 + out 0x04,al ; set the channel 2 starting address to 0 + shr eax,8 + out 0x04,al + shr eax,8 + out 0x81,al + mov al,0 + out 0x0c, al ; reset flip-flop + mov al, 0xff ;set count (actual size -1) + out 0x5, al + mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) + out 0x5,al + mov al,2 + out 0xa,al + popad + ret + +;*********************************** +;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC * +;* Параметры: * +;* AL - выводимый байт. * +;*********************************** +FDCDataOutput: +; pusha + push eax ecx edx + mov AH,AL ;запомнить байт в AH +; Сбросить переменную состояния контроллера + mov [FDC_Status],FDC_Normal +; Проверить готовность контроллера к приему данных + mov DX,3F4h ;(порт состояния FDC) + mov ecx, 0x10000 ;установить счетчик тайм-аута +@@TestRS: + in AL,DX ;прочитать регистр RS + and AL,0C0h ;выделить разряды 6 и 7 + cmp AL,80h ;проверить разряды 6 и 7 + je @@OutByteToFDC + loop @@TestRS +; Ошибка тайм-аута + mov [FDC_Status],FDC_TimeOut + jmp @@End_5 +; Вывести байт в порт данных +@@OutByteToFDC: + inc DX + mov AL,AH + out DX,AL +@@End_5: +; popa + pop edx ecx eax + ret + +;****************************************** +;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC * +;* Процедура не имеет входных параметров. * +;* Выходные данные: * +;* AL - считанный байт. * +;****************************************** +FDCDataInput: + push ECX + push DX +; Сбросить переменную состояния контроллера + mov [FDC_Status],FDC_Normal +; Проверить готовность контроллера к передаче данных + mov DX,3F4h ;(порт состояния FDC) + xor CX,CX ;установить счетчик тайм-аута +@@TestRS_1: + in AL,DX ;прочитать регистр RS + and AL,0C0h ;выдлить разряды 6 и 7 + cmp AL,0C0h ;проверить разряды 6 и 7 + je @@GetByteFromFDC + loop @@TestRS_1 +; Ошибка тайм-аута + mov [FDC_Status],FDC_TimeOut + jmp @@End_6 +; Ввести байт из порта данных +@@GetByteFromFDC: + inc DX + in AL,DX +@@End_6: pop DX + pop ECX + ret + +;********************************************* +;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * +;********************************************* +FDCInterrupt: +; Установить флаг прерывани + mov [FDD_IntFlag],1 + ret + + +;****************************************** +;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ * +;* НГМД * +;****************************************** +SetUserInterrupts: + mov [fdc_irq_func],FDCInterrupt + ret + +;******************************************* +;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * +;******************************************* +WaitFDCInterrupt: + pusha +; Сбросить байт состояния операции + mov [FDC_Status],FDC_Normal +; Сбросить флаг прерывани + mov [FDD_IntFlag],0 +; Обнулить счетчик тиков + mov eax,[timer_ticks] + mov [TickCounter],eax +; Ожидать установки флага прерывания НГМД +@@TestRS_2: + cmp [FDD_IntFlag],0 + jnz @@End_7 ;прерывание произошло + call change_task + mov eax,[timer_ticks] + sub eax,[TickCounter] + cmp eax,50 ;25 ;5 ;ожидать 5 тиков + jb @@TestRS_2 +; jl @@TestRS_2 +; Ошибка тайм-аута + mov [FDC_Status],FDC_TimeOut +; mov [flp_status],0 +@@End_7: popa + ret + +;********************************* +;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * +;********************************* +FDDMotorON: + pusha +; cmp [fdd_motor_status],1 +; je fdd_motor_on + mov al,[flp_number] + cmp [fdd_motor_status],al + je fdd_motor_on +; Произвести сброс контроллера НГМД + mov DX,3F2h ;порт управления двигателями + mov AL,0 + out DX,AL +; Выбрать и включить мотор дисковода + cmp [flp_number],1 + jne FDDMotorON_B +; call FDDMotorOFF_B + mov AL,1Ch ; Floppy A + jmp FDDMotorON_1 +FDDMotorON_B: +; call FDDMotorOFF_A + mov AL,2Dh ; Floppy B +FDDMotorON_1: + out DX,AL +; Обнулить счетчик тиков + mov eax,[timer_ticks] + mov [TickCounter],eax +; Ожидать 0,5 с +@@dT: + call change_task + mov eax,[timer_ticks] + sub eax,[TickCounter] + cmp eax,50 ;10 + jb @@dT + cmp [flp_number],1 + jne fdd_motor_on_B + mov [fdd_motor_status],1 + jmp fdd_motor_on +fdd_motor_on_B: + mov [fdd_motor_status],2 +fdd_motor_on: + call save_timer_fdd_motor + popa + ret + +;***************************************** +;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * +;***************************************** +save_timer_fdd_motor: + mov eax,[timer_ticks] + mov [timer_fdd_motor],eax + ret + +;***************************************** +;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * +;***************************************** +align 4 +check_fdd_motor_status: + cmp [fdd_motor_status],0 + je end_check_fdd_motor_status_1 + mov eax,[timer_ticks] + sub eax,[timer_fdd_motor] + cmp eax,500 + jb end_check_fdd_motor_status + call FDDMotorOFF + mov [fdd_motor_status],0 +end_check_fdd_motor_status_1: + mov [flp_status],0 +end_check_fdd_motor_status: + ret + +;********************************** +;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * +;********************************** +FDDMotorOFF: + push AX + push DX + cmp [flp_number],1 + jne FDDMotorOFF_1 + call FDDMotorOFF_A + jmp FDDMotorOFF_2 +FDDMotorOFF_1: + call FDDMotorOFF_B +FDDMotorOFF_2: + pop DX + pop AX + ; сброс флагов кеширования в связи с устареванием информации + mov [root_read],0 + mov [flp_fat],0 + ret + +FDDMotorOFF_A: + mov DX,3F2h ;порт управления двигателями + mov AL,0Ch ; Floppy A + out DX,AL + ret + +FDDMotorOFF_B: + mov DX,3F2h ;порт управления двигателями + mov AL,5h ; Floppy B + out DX,AL + ret + +;******************************* +;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" * +;******************************* +RecalibrateFDD: + pusha + call save_timer_fdd_motor +; Подать команду "Рекалибровка" + mov AL,07h + call FDCDataOutput + mov AL,00h + call FDCDataOutput +; Ожидать завершения операции + call WaitFDCInterrupt +; cmp [FDC_Status],0 +; je no_fdc_status_error +; mov [flp_status],0 +;no_fdc_status_error: + call save_timer_fdd_motor + popa + ret + +;***************************************************** +;* ПОИСК ДОРОЖКИ * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1). * +;* Результат операции заносится в FDC_Status. * +;***************************************************** +SeekTrack: + pusha + call save_timer_fdd_motor +; Подать команду "Поиск" + mov AL,0Fh + call FDCDataOutput + ; Передать байт номера головки/накопител + mov AL,[FDD_Head] + shl AL,2 + call FDCDataOutput + ; Передать байт номера дорожки + mov AL,[FDD_Track] + call FDCDataOutput +; Ожидать завершения операции + call WaitFDCInterrupt + cmp [FDC_Status],FDC_Normal + jne @@Exit +; Сохранить результат поиска + mov AL,08h + call FDCDataOutput + call FDCDataInput + mov [FDC_ST0],AL + call FDCDataInput + mov [FDC_C],AL +; Проверить результат поиска + ; Поиск завершен? + test [FDC_ST0],100000b + je @@Err + ; Заданный трек найден? + mov AL,[FDC_C] + cmp AL,[FDD_Track] + jne @@Err + ; Номер головки совпадает с заданным? + mov AL,[FDC_ST0] + and AL,100b + shr AL,2 + cmp AL,[FDD_Head] + jne @@Err + ; Операция завершена успешно + mov [FDC_Status],FDC_Normal + jmp @@Exit +@@Err: ; Трек не найден + mov [FDC_Status],FDC_TrackNotFound +; mov [flp_status],0 +@@Exit: + call save_timer_fdd_motor + popa + ret + +;******************************************************* +;* ЧТЕНИЕ СЕКТОРА ДАННЫХ * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции чтения * +;* содержимое сектора будет занесено в FDD_DataBuffer. * +;******************************************************* +ReadSector: + pushad + call save_timer_fdd_motor +; Установить скорость передачи 500 Кбайт/с + mov AX,0 + mov DX,03F7h + out DX,AL +; Инициализировать канал прямого доступа к памяти + mov [dmamode],0x46 + call Init_FDC_DMA +; Подать команду "Чтение данных" + mov AL,0E6h ;чтение в мультитрековом режиме + call FDCDataOutput + mov AL,[FDD_Head] + shl AL,2 + call FDCDataOutput + mov AL,[FDD_Track] + call FDCDataOutput + mov AL,[FDD_Head] + call FDCDataOutput + mov AL,[FDD_Sector] + call FDCDataOutput + mov AL,2 ;код размера сектора (512 байт) + call FDCDataOutput + mov AL,18 ;+1; 3Fh ;число секторов на дорожке + call FDCDataOutput + mov AL,1Bh ;значение GPL + call FDCDataOutput + mov AL,0FFh ;значение DTL + call FDCDataOutput +; Ожидаем прерывание по завершении операции + call WaitFDCInterrupt + cmp [FDC_Status],FDC_Normal + jne @@Exit_1 +; Считываем статус завершения операции + call GetStatusInfo + test [FDC_ST0],11011000b + jnz @@Err_1 + mov [FDC_Status],FDC_Normal + jmp @@Exit_1 +@@Err_1: mov [FDC_Status],FDC_SectorNotFound +; mov [flp_status],0 +@@Exit_1: + call save_timer_fdd_motor + popad + ret + +;******************************************************* +;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции чтения * +;* содержимое сектора будет занесено в FDD_DataBuffer. * +;******************************************************* +ReadSectWithRetr: + pusha +; Обнулить счетчик повторения операции рекалибровки + mov [RecalRepCounter],0 +@@TryAgain: +; Обнулить счетчик повторения операции чтени + mov [ReadRepCounter],0 +@@ReadSector_1: + call ReadSector + cmp [FDC_Status],0 + je @@Exit_2 + cmp [FDC_Status],1 + je @@Err_3 + ; Троекратное повторение чтени + inc [ReadRepCounter] + cmp [ReadRepCounter],3 + jb @@ReadSector_1 + ; Троекратное повторение рекалибровки + call RecalibrateFDD + call SeekTrack + inc [RecalRepCounter] + cmp [RecalRepCounter],3 + jb @@TryAgain +; mov [flp_status],0 +@@Exit_2: + popa + ret +@@Err_3: + mov [flp_status],0 + popa + ret + +;******************************************************* +;* ЗАПИСЬ СЕКТОРА ДАННЫХ * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции записи * +;* содержимое FDD_DataBuffer будет занесено в сектор. * +;******************************************************* +WriteSector: + pushad + call save_timer_fdd_motor +; Установить скорость передачи 500 Кбайт/с + mov AX,0 + mov DX,03F7h + out DX,AL +; Инициализировать канал прямого доступа к памяти + mov [dmamode],0x4A + call Init_FDC_DMA +; Подать команду "Запись данных" + mov AL,0xC5 ;0x45 ;запись в мультитрековом режиме + call FDCDataOutput + mov AL,[FDD_Head] + shl AL,2 + call FDCDataOutput + mov AL,[FDD_Track] + call FDCDataOutput + mov AL,[FDD_Head] + call FDCDataOutput + mov AL,[FDD_Sector] + call FDCDataOutput + mov AL,2 ;код размера сектора (512 байт) + call FDCDataOutput + mov AL,18; 3Fh ;число секторов на дорожке + call FDCDataOutput + mov AL,1Bh ;значение GPL + call FDCDataOutput + mov AL,0FFh ;значение DTL + call FDCDataOutput +; Ожидаем прерывание по завершении операции + call WaitFDCInterrupt + cmp [FDC_Status],FDC_Normal + jne @@Exit_3 +; Считываем статус завершения операции + call GetStatusInfo + test [FDC_ST0],11000000b ;11011000b + jnz @@Err_2 + mov [FDC_Status],FDC_Normal + jmp @@Exit_3 +@@Err_2: mov [FDC_Status],FDC_SectorNotFound +@@Exit_3: + call save_timer_fdd_motor + popad + ret + +;******************************************************* +;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции записи * +;* содержимое FDD_DataBuffer будет занесено в сектор. * +;******************************************************* +WriteSectWithRetr: + pusha +; Обнулить счетчик повторения операции рекалибровки + mov [RecalRepCounter],0 +@@TryAgain_1: +; Обнулить счетчик повторения операции чтени + mov [ReadRepCounter],0 +@@WriteSector_1: + call WriteSector + cmp [FDC_Status],0 + je @@Exit_4 + cmp [FDC_Status],1 + je @@Err_4 + ; Троекратное повторение чтени + inc [ReadRepCounter] + cmp [ReadRepCounter],3 + jb @@WriteSector_1 + ; Троекратное повторение рекалибровки + call RecalibrateFDD + call SeekTrack + inc [RecalRepCounter] + cmp [RecalRepCounter],3 + jb @@TryAgain_1 +@@Exit_4: + popa + ret +@@Err_4: + mov [flp_status],0 + popa + ret + +;********************************************* +;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * +;********************************************* +GetStatusInfo: + push AX + call FDCDataInput + mov [FDC_ST0],AL + call FDCDataInput + mov [FDC_ST1],AL + call FDCDataInput + mov [FDC_ST2],AL + call FDCDataInput + mov [FDC_C],AL + call FDCDataInput + mov [FDC_H],AL + call FDCDataInput + mov [FDC_R],AL + call FDCDataInput + mov [FDC_N],AL + pop AX + ret + diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc b/kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc new file mode 100644 index 000000000..016f4a216 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/hd_drv.inc @@ -0,0 +1,928 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; Low-level driver for HDD access +; DMA support by Mario79 +; Access through BIOS by diamond + +align 4 +hd_read: +;----------------------------------------------------------- +; input : eax = block to read +; ebx = destination +;----------------------------------------------------------- + and [hd_error], 0 + push ecx esi edi ; scan cache + +; mov ecx,cache_max ; entries in cache +; mov esi,HD_CACHE+8 + call calculate_cache + add esi,8 + + mov edi,1 + + hdreadcache: + + cmp dword [esi+4],0 ; empty + je nohdcache + + cmp [esi],eax ; correct sector + je yeshdcache + + nohdcache: + + add esi,8 + inc edi + dec ecx + jnz hdreadcache + + call find_empty_slot ; ret in edi + cmp [hd_error],0 + jne return_01 +; Read through BIOS? + cmp [hdpos], 0x80 + jae .bios +; DMA read is permitted if [allow_dma_access]=1 or 2 + cmp [allow_dma_access], 2 + ja .nodma + cmp [dma_hdd], 1 + jnz .nodma + call hd_read_dma + jmp @f +.nodma: + call hd_read_pio + jmp @f +.bios: + call bd_read +@@: + cmp [hd_error], 0 + jne return_01 +; lea esi,[edi*8+HD_CACHE] +; push eax + call calculate_cache_1 + lea esi,[edi*8+esi] +; pop eax + + mov [esi],eax ; sector number + mov dword [esi+4],1 ; hd read - mark as same as in hd + + yeshdcache: + + mov esi,edi + shl esi,9 +; add esi,HD_CACHE+65536 + push eax + call calculate_cache_2 + add esi,eax + pop eax + + mov edi,ebx + mov ecx,512/4 + cld + rep movsd ; move data + return_01: + pop edi esi ecx + ret + +align 4 +hd_read_pio: + push eax edx + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_read_error + + cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al ; ATAFeatures ॣЁбва "®б®ЎҐ­­®б⥩" + inc edx + inc eax + out dx,al ; ATASectorCount бзсвзЁЄ ᥪв®а®ў + inc edx + mov eax,[esp+4] + out dx,al ; ATASectorNumber ॣЁбва ­®¬Ґа  ᥪв®а  + shr eax,8 + inc edx + out dx,al ; ATACylinder ­®¬Ґа жЁ«Ё­¤а  (¬« ¤иЁ© Ў ©в) + shr eax,8 + inc edx + out dx,al ; ­®¬Ґа жЁ«Ё­¤а  (бв аиЁ© Ў ©в) + shr eax,8 + inc edx + and al,1+2+4+8 + add al,byte [hdid] + add al,128+64+32 + out dx,al ; ­®¬Ґа Ј®«®ўЄЁ/­®¬Ґа ¤ЁбЄ  + inc edx + mov al,20h + out dx,al ; ATACommand ॣЁбва Є®¬ ­¤ + sti + + call wait_for_sector_buffer + + cmp [hd_error],0 + jne hd_read_error + + cli + push edi + shl edi,9 +; add edi,HD_CACHE+65536 + push eax + call calculate_cache_2 + add edi,eax + pop eax + + mov ecx,256 + mov edx,[hdbase] + cld + rep insw + pop edi + sti + + pop edx eax + ret + +disable_ide_int: +; mov edx,[hdbase] +; add edx,0x206 +; mov al,2 +; out dx,al + cli + ret + +enable_ide_int: +; mov edx,[hdbase] +; add edx,0x206 +; mov al,0 +; out dx,al + sti + ret + +align 4 +hd_write: +;----------------------------------------------------------- +; input : eax = block +; ebx = pointer to memory +;----------------------------------------------------------- + push ecx esi edi + + ; check if the cache already has the sector and overwrite it + +; mov ecx,cache_max +; mov esi,HD_CACHE+8 + call calculate_cache + add esi,8 + + mov edi,1 + + hdwritecache: + + cmp dword [esi+4],0 ; if cache slot is empty + je not_in_cache_write + + cmp [esi],eax ; if the slot has the sector + je yes_in_cache_write + + not_in_cache_write: + + add esi,8 + inc edi + dec ecx + jnz hdwritecache + + ; sector not found in cache + ; write the block to a new location + + call find_empty_slot ; ret in edi + cmp [hd_error],0 + jne hd_write_access_denied + +; lea esi,[edi*8+HD_CACHE] +; push eax + call calculate_cache_1 + lea esi,[edi*8+esi] +; pop eax + + mov [esi],eax ; sector number + + yes_in_cache_write: + + mov dword [esi+4],2 ; write - differs from hd + + shl edi,9 +; add edi,HD_CACHE+65536 + push eax + call calculate_cache_2 + add edi,eax + pop eax + + mov esi,ebx + mov ecx,512/4 + cld + rep movsd ; move data + hd_write_access_denied: + pop edi esi ecx + ret + +align 4 +cache_write_pio: +; call disable_ide_int + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_write_error + + cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al + inc edx + inc eax + out dx,al + inc edx + mov eax,[esi] ; eax = sector to write + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + and al,1+2+4+8 + add al,byte [hdid] + add al,128+64+32 + out dx,al + inc edx + mov al,30h + out dx,al + sti + + call wait_for_sector_buffer + + cmp [hd_error],0 + jne hd_write_error + + push ecx esi + + cli + mov esi,edi + shl esi,9 +; add esi,HD_CACHE+65536 ; esi = from memory position + push eax + call calculate_cache_2 + add esi,eax + pop eax + + mov ecx,256 + mov edx,[hdbase] + cld + rep outsw + sti + +; call enable_ide_int + pop esi ecx + + ret + +save_hd_wait_timeout: + + push eax + mov eax,[timer_ticks] + add eax,300 ; 3 sec timeout + mov [hd_wait_timeout],eax + pop eax + ret + +align 4 +check_hd_wait_timeout: + + push eax + mov eax,[hd_wait_timeout] + cmp [timer_ticks], eax + jg hd_timeout_error + pop eax + mov [hd_error],0 + ret + +;iglobal +; hd_timeout_str db 'K : FS - HD timeout',0 +; hd_read_str db 'K : FS - HD read error',0 +; hd_write_str db 'K : FS - HD write error',0 +; hd_lba_str db 'K : FS - HD LBA error',0 +;endg + +hd_timeout_error: + +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_timeout_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD timeout\n" + + mov [hd_error],1 + pop eax + ret + +hd_read_error: + +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_read_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD read error\n" + pop edx eax + ret + +hd_write_error: + +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_write_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD write error\n" + ret + +hd_write_error_dma: +; call clear_hd_cache +; call clear_application_table_status +; mov esi, hd_write_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD read error\n" + pop esi + ret + +hd_lba_error: +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_lba_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD LBA error\n" + jmp LBA_read_ret + + +align 4 +wait_for_hd_idle: + + push eax edx + + call save_hd_wait_timeout + + mov edx,[hdbase] + add edx,0x7 + + wfhil1: + + call check_hd_wait_timeout + cmp [hd_error],0 + jne @f + + in al,dx + test al,128 + jnz wfhil1 + + @@: + + pop edx eax + ret + + +align 4 +wait_for_sector_buffer: + + push eax edx + + mov edx,[hdbase] + add edx,0x7 + + call save_hd_wait_timeout + + hdwait_sbuf: ; wait for sector buffer to be ready + + call check_hd_wait_timeout + cmp [hd_error],0 + jne @f + + in al,dx + test al,8 + jz hdwait_sbuf + + mov [hd_error],0 + + cmp [hd_setup],1 ; do not mark error for setup request + je buf_wait_ok + + test al,1 ; previous command ended up with an error + jz buf_wait_ok + @@: + mov [hd_error],1 + + buf_wait_ok: + + pop edx eax + ret + +; \begin{Mario79} +align 4 +wait_for_sector_dma_ide0: + push eax + push edx + call save_hd_wait_timeout +.wait: + call change_task + cmp [irq14_func], hdd_irq14 + jnz .done + call check_hd_wait_timeout + cmp [hd_error], 0 + jz .wait + mov [irq14_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + mov al, 0 + out dx, al +.done: + pop edx + pop eax + ret + +align 4 +wait_for_sector_dma_ide1: + push eax + push edx + call save_hd_wait_timeout +.wait: + call change_task + cmp [irq15_func], hdd_irq15 + jnz .done + call check_hd_wait_timeout + cmp [hd_error], 0 + jz .wait + mov [irq15_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + add dx, 8 + mov al, 0 + out dx, al +.done: + pop edx + pop eax + ret + +iglobal +align 4 +; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary +IDE_descriptor_table: + dd IDE_DMA + dw 0x2000 + dw 0x8000 + +dma_cur_sector dd not 40h +dma_hdpos dd 0 +irq14_func dd hdd_irq_null +irq15_func dd hdd_irq_null +endg + +uglobal +; all uglobals are zeroed at boot +dma_process dd 0 +dma_slot_ptr dd 0 +cache_chain_pos dd 0 +cache_chain_ptr dd 0 +cache_chain_size db 0 +cache_chain_started db 0 +dma_task_switched db 0 +dma_hdd db 0 +allow_dma_access db 0 +endg + +align 4 +hdd_irq14: + pushfd + cli + pushad + mov [irq14_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + mov al, 0 + out dx, al +; call update_counters +; mov ebx, [dma_process] +; cmp [CURRENT_TASK], ebx +; jz .noswitch +; mov [dma_task_switched], 1 +; mov edi, [dma_slot_ptr] +; mov eax, [CURRENT_TASK] +; mov [dma_process], eax +; mov eax, [TASK_BASE] +; mov [dma_slot_ptr], eax +; mov [CURRENT_TASK], ebx +; mov [TASK_BASE], edi +; mov byte [DONT_SWITCH], 1 +; call do_change_task +.noswitch: + popad + popfd +align 4 +hdd_irq_null: + ret + +align 4 +hdd_irq15: + pushfd + cli + pushad + mov [irq15_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + add dx, 8 + mov al, 0 + out dx, al +; call update_counters +; mov ebx, [dma_process] +; cmp [CURRENT_TASK], ebx +; jz .noswitch +; mov [dma_task_switched], 1 +; mov edi, [dma_slot_ptr] +; mov eax, [CURRENT_TASK] +; mov [dma_process], eax +; mov eax, [TASK_BASE] +; mov [dma_slot_ptr], eax +; mov [CURRENT_TASK], ebx +; mov [TASK_BASE], edi +; mov byte [DONT_SWITCH], 1 +; call do_change_task +.noswitch: + popad + popfd + ret + +align 4 +hd_read_dma: + push eax + push edx + mov edx,[dma_hdpos] + cmp edx,[hdpos] + jne .notread + mov edx, [dma_cur_sector] + cmp eax, edx + jb .notread + add edx, 15 + cmp [esp+4], edx + ja .notread + mov eax, [esp+4] + sub eax, [dma_cur_sector] + shl eax, 9 + add eax, (OS_BASE+IDE_DMA) + push ecx esi edi + mov esi, eax + shl edi, 9 +; add edi, HD_CACHE+0x10000 + push eax + call calculate_cache_2 + add edi,eax + pop eax + + mov ecx, 512/4 + cld + rep movsd + pop edi esi ecx + pop edx + pop eax + ret +.notread: + mov eax, IDE_descriptor_table + mov dword [eax], IDE_DMA + mov word [eax+4], 0x2000 + sub eax, OS_BASE + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add edx, 8 +@@: + push edx + add edx, 4 + out dx, eax + pop edx + mov al, 0 + out dx, al + add edx, 2 + mov al, 6 + out dx, al + call wait_for_hd_idle + cmp [hd_error], 0 + jnz hd_read_error + call disable_ide_int + xor eax, eax + mov edx, [hdbase] + inc edx + out dx, al + inc edx + mov eax, 10h + out dx, al + inc edx + mov eax, [esp+4] + out dx, al + shr eax, 8 + inc edx + out dx, al + shr eax, 8 + inc edx + out dx, al + shr eax, 8 + inc edx + and al, 0xF + add al, byte [hdid] + add al, 11100000b + out dx, al + inc edx + mov al, 0xC8 + out dx, al + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add dx, 8 +@@: + mov al, 9 + out dx, al + mov eax, [CURRENT_TASK] + mov [dma_process], eax + mov eax, [TASK_BASE] + mov [dma_slot_ptr], eax + cmp [hdbase], 0x1F0 + jnz .ide1 + mov [irq14_func], hdd_irq14 + jmp @f +.ide1: + mov [irq15_func], hdd_irq15 +@@: + call enable_ide_int + cmp [hdbase], 0x1F0 + jnz .wait_ide1 + call wait_for_sector_dma_ide0 + jmp @f +.wait_ide1: + call wait_for_sector_dma_ide1 +@@: + cmp [hd_error], 0 + jnz hd_read_error + mov eax,[hdpos] + mov [dma_hdpos],eax + pop edx + pop eax + mov [dma_cur_sector], eax + jmp hd_read_dma + +align 4 +write_cache_sector: + mov [cache_chain_size],1 + mov [cache_chain_pos],edi +write_cache_chain: + cmp [hdpos], 0x80 + jae bd_write_cache_chain + push esi + mov eax, IDE_descriptor_table + mov edx,eax + pusha + mov esi,[cache_chain_pos] + shl esi, 9 + call calculate_cache_2 + add esi,eax + mov edi, (OS_BASE+IDE_DMA) + mov dword [edx], IDE_DMA + movzx ecx, [cache_chain_size] + shl ecx, 9 + mov word [edx+4], cx + shr ecx,2 + cld + rep movsd + popa + sub eax, OS_BASE + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add edx, 8 +@@: + push edx + add edx, 4 + out dx, eax + pop edx + mov al, 0 + out dx, al + add edx, 2 + mov al, 6 + out dx, al + call wait_for_hd_idle + cmp [hd_error], 0 + jnz hd_write_error_dma + call disable_ide_int + xor eax, eax + mov edx, [hdbase] + inc edx + out dx, al + inc edx + mov al, [cache_chain_size] + out dx, al + inc edx + mov esi, [cache_chain_ptr] + mov eax, [esi] + out dx, al + shr eax, 8 + inc edx + out dx, al + shr eax, 8 + inc edx + out dx, al + shr eax, 8 + inc edx + and al, 0xF + add al, byte [hdid] + add al, 11100000b + out dx, al + inc edx + mov al, 0xCA + out dx, al + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add dx, 8 +@@: + mov al, 1 + out dx, al + mov eax, [CURRENT_TASK] + mov [dma_process], eax + mov eax, [TASK_BASE] + mov [dma_slot_ptr], eax + cmp [hdbase], 0x1F0 + jnz .ide1 + mov [irq14_func], hdd_irq14 + jmp @f +.ide1: + mov [irq15_func], hdd_irq15 +@@: + call enable_ide_int + mov [dma_cur_sector], not 0x40 + cmp [hdbase], 0x1F0 + jnz .wait_ide1 + call wait_for_sector_dma_ide0 + jmp @f +.wait_ide1: + call wait_for_sector_dma_ide1 +@@: + cmp [hd_error], 0 + jnz hd_write_error_dma + pop esi + ret + +uglobal +IDEContrRegsBaseAddr dw ? +endg +; \end{Mario79} + +; \begin{diamond} +uglobal +bios_hdpos dd 0 ; 0 is invalid value for [hdpos] +bios_cur_sector dd ? +bios_read_len dd ? +endg +bd_read: + push eax + push edx + mov edx, [bios_hdpos] + cmp edx, [hdpos] + jne .notread + mov edx, [bios_cur_sector] + cmp eax, edx + jb .notread + add edx, [bios_read_len] + dec edx + cmp eax, edx + ja .notread + sub eax, [bios_cur_sector] + shl eax, 9 + add eax, (OS_BASE+0x9A000) + push ecx esi edi + mov esi, eax + shl edi, 9 +; add edi, HD_CACHE+0x10000 + push eax + call calculate_cache_2 + add edi,eax + pop eax + + mov ecx, 512/4 + cld + rep movsd + pop edi esi ecx + pop edx + pop eax + ret +.notread: + push ecx + mov dl, 42h + mov ecx, 16 + call int13_call + pop ecx + test eax, eax + jnz .v86err + test edx, edx + jz .readerr + mov [bios_read_len], edx + mov edx, [hdpos] + mov [bios_hdpos], edx + pop edx + pop eax + mov [bios_cur_sector], eax + jmp bd_read +.readerr: +.v86err: + mov [hd_error], 1 + jmp hd_read_error + +bd_write_cache_chain: + pusha + mov esi, [cache_chain_pos] + shl esi, 9 + call calculate_cache_2 + add esi, eax + mov edi, OS_BASE + 0x9A000 + movzx ecx, [cache_chain_size] + push ecx + shl ecx, 9-2 + rep movsd + pop ecx + mov dl, 43h + mov eax, [cache_chain_ptr] + mov eax, [eax] + call int13_call + test eax, eax + jnz .v86err + cmp edx, ecx + jnz .writeerr + popa + ret +.v86err: +.writeerr: + popa + mov [hd_error], 1 + jmp hd_write_error + +uglobal +int13_regs_in rb v86_regs.size +int13_regs_out rb v86_regs.size +endg + +int13_call: +; Because this code uses fixed addresses, +; it can not be run simultaniously by many threads. +; In current implementation it is protected by common mutex 'hd1_status' + mov word [BOOT_VAR + 510h], 10h ; packet length + mov word [BOOT_VAR + 512h], cx ; number of sectors + mov dword [BOOT_VAR + 514h], 9A000000h ; buffer 9A00:0000 + mov dword [BOOT_VAR + 518h], eax + and dword [BOOT_VAR + 51Ch], 0 + push ebx ecx esi edi + mov ebx, int13_regs_in + mov edi, ebx + mov ecx, v86_regs.size/4 + xor eax, eax + rep stosd + mov byte [ebx+v86_regs.eax+1], dl + mov eax, [hdpos] + lea eax, [BiosDisksData+(eax-80h)*4] + mov dl, [eax] + mov byte [ebx+v86_regs.edx], dl + movzx edx, byte [eax+1] +; mov dl, 5 + test edx, edx + jnz .hasirq + dec edx + jmp @f +.hasirq: + pushad + stdcall enable_irq, edx + popad +@@: + mov word [ebx+v86_regs.esi], 510h + mov word [ebx+v86_regs.ss], 9000h + mov word [ebx+v86_regs.esp], 0A000h + mov word [ebx+v86_regs.eip], 500h + mov [ebx+v86_regs.eflags], 20200h + mov esi, [sys_v86_machine] + mov ecx, 0x502 + call v86_start + and [bios_hdpos], 0 + pop edi esi ecx ebx + movzx edx, byte [BOOT_VAR + 512h] + test byte [int13_regs_out+v86_regs.eflags], 1 + jnz @f + mov edx, ecx +@@: + ret +; \end{diamond} diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/ide_cache.inc b/kernel/tags/kolibri0.7.7.0/blkdev/ide_cache.inc new file mode 100644 index 000000000..453cbf6a2 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/ide_cache.inc @@ -0,0 +1,922 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;************************************************************************** +; +; [cache_ide[X]_pointer] +; or [cache_ide[X]_data_pointer] first entry in cache list +; +; +0 - lba sector +; +4 - state of cache sector +; 0 = empty +; 1 = used for read ( same as in hd ) +; 2 = used for write ( differs from hd ) +; +; [cache_ide[X]_system_data] +; or [cache_ide[x]_appl_data] - cache entries +; +;************************************************************************** + +$Revision$ + + +align 4 +write_cache: +;----------------------------------------------------------- +; write all changed sectors to disk +;----------------------------------------------------------- + push eax ecx edx esi edi + + ; write difference ( 2 ) from cache to hd + call calculate_cache + add esi,8 + mov edi,1 +write_cache_more: + cmp dword [esi+4],2 ; if cache slot is not different + jne .write_chain + mov dword [esi+4],1 ; same as in hd + mov eax,[esi] ; eax = sector to write + cmp eax,[PARTITION_START] + jb danger + cmp eax,[PARTITION_END] + ja danger + cmp [hdpos], 0x80 + jae @f +; DMA write is permitted only if [allow_dma_access]=1 + cmp [allow_dma_access], 2 + jae .nodma + cmp [dma_hdd], 1 + jnz .nodma +@@: +; ЋЎкҐ¤Ё­пҐ¬ § ЇЁбм 楯®зЄЁ Ї®б«Ґ¤®ў вҐ«м­ле ᥪв®а®ў ў ®¤­® ®Ўа йҐ­ЁҐ Є ¤ЁбЄг + cmp ecx, 1 + jz .nonext + cmp dword [esi+8+4], 2 + jnz .nonext + push eax + inc eax + cmp eax, [esi+8] + pop eax + jnz .nonext + cmp [cache_chain_started], 1 + jz @f + mov [cache_chain_started], 1 + mov [cache_chain_size], 0 + mov [cache_chain_pos], edi + mov [cache_chain_ptr], esi +@@: + inc [cache_chain_size] + cmp [cache_chain_size], 16 + jnz .continue + jmp .write_chain +.nonext: + call flush_cache_chain + mov [cache_chain_size], 1 + mov [cache_chain_ptr], esi + call write_cache_sector + jmp .continue +.nodma: + call cache_write_pio +.write_chain: + call flush_cache_chain +.continue: +danger: + add esi,8 + inc edi + dec ecx + jnz write_cache_more + call flush_cache_chain + return_02: + pop edi esi edx ecx eax + ret + +flush_cache_chain: + cmp [cache_chain_started], 0 + jz @f + call write_cache_chain + mov [cache_chain_started], 0 +@@: + ret +;-------------------------------------------------------------------- +align 4 +find_empty_slot: +;----------------------------------------------------------- +; find empty or read slot, flush cache if next 10% is used by write +; output : edi = cache slot +;----------------------------------------------------------- +; push ecx esi + +search_again: + call calculate_cache_3 + shr ecx,3 +search_for_empty: + inc edi + call calculate_cache_4 + jbe inside_cache + mov edi,1 +inside_cache: + push esi + call calculate_cache_1 + cmp dword [edi*8+esi+4],2 + pop esi + jb found_slot ; it's empty or read + dec ecx + jnz search_for_empty + call write_cache ; no empty slots found, write all + cmp [hd_error],0 + jne found_slot_access_denied + jmp search_again ; and start again +found_slot: + call calculate_cache_5 +found_slot_access_denied: + ret +;-------------------------------------------------------------------- +align 4 +clear_hd_cache: + mov [fat_in_cache],-1 + mov [fat_change],0 + ret +;-------------------------------------------------------------------- +align 4 +calculate_cache: +; mov ecx,cache_max ; entries in cache +; mov esi,HD_CACHE+8 + +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + mov ecx,[cache_ide0_system_sad_size] + mov esi,[cache_ide0_pointer] + ret +.ide0_appl_data: + mov ecx,[cache_ide0_appl_sad_size] + mov esi,[cache_ide0_data_pointer] + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + mov ecx,[cache_ide1_system_sad_size] + mov esi,[cache_ide1_pointer] + ret +.ide1_appl_data: + mov ecx,[cache_ide1_appl_sad_size] + mov esi,[cache_ide1_data_pointer] + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + mov ecx,[cache_ide2_system_sad_size] + mov esi,[cache_ide2_pointer] + ret +.ide2_appl_data: + mov ecx,[cache_ide2_appl_sad_size] + mov esi,[cache_ide2_data_pointer] + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + mov ecx,[cache_ide3_system_sad_size] + mov esi,[cache_ide3_pointer] + ret +.ide3_appl_data: + mov ecx,[cache_ide3_appl_sad_size] + mov esi,[cache_ide3_data_pointer] + ret +.noide: + push eax + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] + mov esi,[cache_ide0_pointer-cache_ide0+eax] + pop eax + ret +.bd_appl_data: + mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] + mov esi,[cache_ide0_data_pointer-cache_ide0+eax] + pop eax + ret +;-------------------------------------------------------------------- +align 4 +calculate_cache_1: +; lea esi,[edi*8+HD_CACHE] +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + mov esi,[cache_ide0_pointer] + ret +.ide0_appl_data: + mov esi,[cache_ide0_data_pointer] + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + mov esi,[cache_ide1_pointer] + ret +.ide1_appl_data: + mov esi,[cache_ide1_data_pointer] + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + mov esi,[cache_ide2_pointer] + ret +.ide2_appl_data: + mov esi,[cache_ide2_data_pointer] + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + mov esi,[cache_ide3_pointer] + ret +.ide3_appl_data: + mov esi,[cache_ide3_data_pointer] + ret +.noide: + push eax + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + mov esi,[cache_ide0_pointer-cache_ide0+eax] + pop eax + ret +.bd_appl_data: + mov esi,[cache_ide0_data_pointer-cache_ide0+eax] + pop eax + ret + +;-------------------------------------------------------------------- +align 4 +calculate_cache_2: +; add esi,HD_CACHE+65536 +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + mov eax,[cache_ide0_system_data] + ret +.ide0_appl_data: + mov eax,[cache_ide0_appl_data] + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + mov eax,[cache_ide1_system_data] + ret +.ide1_appl_data: + mov eax,[cache_ide1_appl_data] + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + mov eax,[cache_ide2_system_data] + ret +.ide2_appl_data: + mov eax,[cache_ide2_appl_data] + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + mov eax,[cache_ide3_system_data] + ret +.ide3_appl_data: + mov eax,[cache_ide3_appl_data] + ret +.noide: + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + mov eax,[cache_ide0_system_data-cache_ide0+eax] + ret +.bd_appl_data: + mov eax,[cache_ide0_appl_data-cache_ide0+eax] + ret +;-------------------------------------------------------------------- +align 4 +calculate_cache_3: +; mov ecx,cache_max*10/100 +; mov edi,[cache_search_start] + +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + mov ecx,[cache_ide0_system_sad_size] + mov edi,[cache_ide0_search_start] + ret +.ide0_appl_data: + mov ecx,[cache_ide0_appl_sad_size] + mov edi,[cache_ide0_appl_search_start] + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + mov ecx,[cache_ide1_system_sad_size] + mov edi,[cache_ide1_search_start] + ret +.ide1_appl_data: + mov ecx,[cache_ide1_appl_sad_size] + mov edi,[cache_ide1_appl_search_start] + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + mov ecx,[cache_ide2_system_sad_size] + mov edi,[cache_ide2_search_start] + ret +.ide2_appl_data: + mov ecx,[cache_ide2_appl_sad_size] + mov edi,[cache_ide2_appl_search_start] + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + mov ecx,[cache_ide3_system_sad_size] + mov edi,[cache_ide3_search_start] + ret +.ide3_appl_data: + mov ecx,[cache_ide3_appl_sad_size] + mov edi,[cache_ide3_appl_search_start] + ret +.noide: + push eax + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] + mov edi,[cache_ide0_search_start-cache_ide0+eax] + pop eax + ret +.bd_appl_data: + mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] + mov edi,[cache_ide0_appl_search_start-cache_ide0+eax] + pop eax + ret +;-------------------------------------------------------------------- +align 4 +calculate_cache_4: +; cmp edi,cache_max +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + cmp edi,[cache_ide0_system_sad_size] + ret +.ide0_appl_data: + cmp edi,[cache_ide0_appl_sad_size] + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + cmp edi,[cache_ide1_system_sad_size] + ret +.ide1_appl_data: + cmp edi,[cache_ide1_appl_sad_size] + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + cmp edi,[cache_ide2_system_sad_size] + ret +.ide2_appl_data: + cmp edi,[cache_ide2_appl_sad_size] + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + cmp edi,[cache_ide3_system_sad_size] + ret +.ide3_appl_data: + cmp edi,[cache_ide3_appl_sad_size] + ret +.noide: + push eax + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax] + pop eax + ret +.bd_appl_data: + cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax] + pop eax + ret + +;-------------------------------------------------------------------- +align 4 +calculate_cache_5: +; mov [cache_search_start],edi +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [hdpos],1 + jne .ide1 + cmp [hdd_appl_data],0 + jne .ide0_appl_data + mov [cache_ide0_search_start],edi + ret +.ide0_appl_data: + mov [cache_ide0_appl_search_start],edi + ret +.ide1: + cmp [hdpos],2 + jne .ide2 + cmp [hdd_appl_data],0 + jne .ide1_appl_data + mov [cache_ide1_search_start],edi + ret +.ide1_appl_data: + mov [cache_ide1_appl_search_start],edi + ret +.ide2: + cmp [hdpos],3 + jne .ide3 + cmp [hdd_appl_data],0 + jne .ide2_appl_data + mov [cache_ide2_search_start],edi + ret +.ide2_appl_data: + mov [cache_ide2_appl_search_start],edi + ret +.ide3: + cmp [hdpos],4 + jne .noide + cmp [hdd_appl_data],0 + jne .ide3_appl_data + mov [cache_ide3_search_start],edi + ret +.ide3_appl_data: + mov [cache_ide3_appl_search_start],edi + ret +.noide: + push eax + mov eax,[hdpos] + sub eax,80h + cmp byte [BiosDisksData+eax*4+2], -1 + jz @f + movzx eax,byte [BiosDisksData+eax*4+2] + imul eax,cache_ide1-cache_ide0 + add eax,cache_ide0 + jmp .get +@@: + imul eax,cache_ide1-cache_ide0 + add eax,BiosDiskCaches +.get: + cmp [hdd_appl_data],0 + jne .bd_appl_data + mov [cache_ide0_search_start-cache_ide0+eax],edi + pop eax + ret +.bd_appl_data: + mov [cache_ide0_appl_search_start-cache_ide0+eax],edi + pop eax + ret + +;-------------------------------------------------------------------- +align 4 +find_empty_slot_CD_cache: +;----------------------------------------------------------- +; find empty or read slot, flush cache if next 10% is used by write +; output : edi = cache slot +;----------------------------------------------------------- +.search_again: + call cd_calculate_cache_3 +.search_for_empty: + inc edi + call cd_calculate_cache_4 + jbe .inside_cache + mov edi,1 +.inside_cache: + call cd_calculate_cache_5 + ret +;-------------------------------------------------------------------- +clear_CD_cache: + pusha +.ide0: + xor eax,eax + cmp [cdpos],1 + jne .ide1 + mov [cache_ide0_search_start],eax + mov ecx,[cache_ide0_system_sad_size] + mov edi,[cache_ide0_pointer] + call .clear + mov [cache_ide0_appl_search_start],eax + mov ecx,[cache_ide0_appl_sad_size] + mov edi,[cache_ide0_data_pointer] + jmp .continue +.ide1: + cmp [cdpos],2 + jne .ide2 + mov [cache_ide1_search_start],eax + mov ecx,[cache_ide1_system_sad_size] + mov edi,[cache_ide1_pointer] + call .clear + mov [cache_ide1_appl_search_start],eax + mov ecx,[cache_ide1_appl_sad_size] + mov edi,[cache_ide1_data_pointer] + jmp .continue +.ide2: + cmp [cdpos],3 + jne .ide3 + mov [cache_ide2_search_start],eax + mov ecx,[cache_ide2_system_sad_size] + mov edi,[cache_ide2_pointer] + call .clear + mov [cache_ide2_appl_search_start],eax + mov ecx,[cache_ide2_appl_sad_size] + mov edi,[cache_ide2_data_pointer] + jmp .continue +.ide3: + mov [cache_ide3_search_start],eax + mov ecx,[cache_ide3_system_sad_size] + mov edi,[cache_ide3_pointer] + call .clear + mov [cache_ide3_appl_search_start],eax + mov ecx,[cache_ide3_appl_sad_size] + mov edi,[cache_ide3_data_pointer] +.continue: + call .clear + popa + ret +.clear: + shl ecx,1 + cld + rep stosd + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache: +; mov ecx,cache_max ; entries in cache +; mov esi,HD_CACHE+8 + +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + mov ecx,[cache_ide0_system_sad_size] + mov esi,[cache_ide0_pointer] + ret +.ide0_appl_data: + mov ecx,[cache_ide0_appl_sad_size] + mov esi,[cache_ide0_data_pointer] + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + mov ecx,[cache_ide1_system_sad_size] + mov esi,[cache_ide1_pointer] + ret +.ide1_appl_data: + mov ecx,[cache_ide1_appl_sad_size] + mov esi,[cache_ide1_data_pointer] + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + mov ecx,[cache_ide2_system_sad_size] + mov esi,[cache_ide2_pointer] + ret +.ide2_appl_data: + mov ecx,[cache_ide2_appl_sad_size] + mov esi,[cache_ide2_data_pointer] + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + mov ecx,[cache_ide3_system_sad_size] + mov esi,[cache_ide3_pointer] + ret +.ide3_appl_data: + mov ecx,[cache_ide3_appl_sad_size] + mov esi,[cache_ide3_data_pointer] + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache_1: +; lea esi,[edi*8+HD_CACHE] +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + mov esi,[cache_ide0_pointer] + ret +.ide0_appl_data: + mov esi,[cache_ide0_data_pointer] + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + mov esi,[cache_ide1_pointer] + ret +.ide1_appl_data: + mov esi,[cache_ide1_data_pointer] + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + mov esi,[cache_ide2_pointer] + ret +.ide2_appl_data: + mov esi,[cache_ide2_data_pointer] + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + mov esi,[cache_ide3_pointer] + ret +.ide3_appl_data: + mov esi,[cache_ide3_data_pointer] + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache_2: +; add esi,HD_CACHE+65536 +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + mov eax,[cache_ide0_system_data] + ret +.ide0_appl_data: + mov eax,[cache_ide0_appl_data] + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + mov eax,[cache_ide1_system_data] + ret +.ide1_appl_data: + mov eax,[cache_ide1_appl_data] + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + mov eax,[cache_ide2_system_data] + ret +.ide2_appl_data: + mov eax,[cache_ide2_appl_data] + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + mov eax,[cache_ide3_system_data] + ret +.ide3_appl_data: + mov eax,[cache_ide3_appl_data] + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache_3: +; mov ecx,cache_max*10/100 +; mov edi,[cache_search_start] + +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + mov edi,[cache_ide0_search_start] + ret +.ide0_appl_data: + mov edi,[cache_ide0_appl_search_start] + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + mov edi,[cache_ide1_search_start] + ret +.ide1_appl_data: + mov edi,[cache_ide1_appl_search_start] + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + mov edi,[cache_ide2_search_start] + ret +.ide2_appl_data: + mov edi,[cache_ide2_appl_search_start] + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + mov edi,[cache_ide3_search_start] + ret +.ide3_appl_data: + mov edi,[cache_ide3_appl_search_start] + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache_4: +; cmp edi,cache_max +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + cmp edi,[cache_ide0_system_sad_size] + ret +.ide0_appl_data: + cmp edi,[cache_ide0_appl_sad_size] + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + cmp edi,[cache_ide1_system_sad_size] + ret +.ide1_appl_data: + cmp edi,[cache_ide1_appl_sad_size] + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + cmp edi,[cache_ide2_system_sad_size] + ret +.ide2_appl_data: + cmp edi,[cache_ide2_appl_sad_size] + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + cmp edi,[cache_ide3_system_sad_size] + ret +.ide3_appl_data: + cmp edi,[cache_ide3_appl_sad_size] + ret +;-------------------------------------------------------------------- +align 4 +cd_calculate_cache_5: +; mov [cache_search_start],edi +; 1 - IDE0 ... 4 - IDE3 +.ide0: + cmp [cdpos],1 + jne .ide1 + cmp [cd_appl_data],0 + jne .ide0_appl_data + mov [cache_ide0_search_start],edi + ret +.ide0_appl_data: + mov [cache_ide0_appl_search_start],edi + ret +.ide1: + cmp [cdpos],2 + jne .ide2 + cmp [cd_appl_data],0 + jne .ide1_appl_data + mov [cache_ide1_search_start],edi + ret +.ide1_appl_data: + mov [cache_ide1_appl_search_start],edi + ret +.ide2: + cmp [cdpos],3 + jne .ide3 + cmp [cd_appl_data],0 + jne .ide2_appl_data + mov [cache_ide2_search_start],edi + ret +.ide2_appl_data: + mov [cache_ide2_appl_search_start],edi + ret +.ide3: + cmp [cd_appl_data],0 + jne .ide3_appl_data + mov [cache_ide3_search_start],edi + ret +.ide3_appl_data: + mov [cache_ide3_appl_search_start],edi + ret +;-------------------------------------------------------------------- +;align 4 +;calculate_linear_to_real: +; shr eax, 12 +; mov eax, [page_tabs+eax*4] +; and eax, 0xFFFFF000 +; ret diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/rd.inc b/kernel/tags/kolibri0.7.7.0/blkdev/rd.inc new file mode 100644 index 000000000..2b6b49d12 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/rd.inc @@ -0,0 +1,2266 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; RAMDISK functions ;; +;; (C) 2004 Ville Turjanmaa, License: GPL ;; +;; Addings by M.Lisovin ;; +;; LFN support by diamond ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; calculate fat chain + +calculatefatchain: + + pushad + + mov esi,RAMDISK+512 + mov edi,RAMDISK_FAT + + fcnew: + mov eax,dword [esi] + mov ebx,dword [esi+4] + mov ecx,dword [esi+8] + mov edx,ecx + shr edx,4 ;8 ok + shr dx,4 ;7 ok + xor ch,ch + shld ecx,ebx,20 ;6 ok + shr cx,4 ;5 ok + shld ebx,eax,12 + and ebx,0x0fffffff ;4 ok + shr bx,4 ;3 ok + shl eax,4 + and eax,0x0fffffff ;2 ok + shr ax,4 ;1 ok + mov dword [edi],eax + mov dword [edi+4],ebx + mov dword [edi+8],ecx + mov dword [edi+12],edx + add edi,16 + add esi,12 + + cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters + jnz fcnew + + popad + ret + + +restorefatchain: ; restore fat chain + + pushad + + mov esi,RAMDISK_FAT + mov edi,RAMDISK+512 + + fcnew2: + mov eax,dword [esi] + mov ebx,dword [esi+4] + shl ax,4 + shl eax,4 + shl bx,4 + shr ebx,4 + shrd eax,ebx,8 + shr ebx,8 + mov dword [edi],eax + mov word [edi+4],bx + add edi,6 + add esi,8 + + cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT + jb fcnew2 + + mov esi,RAMDISK+512 ; duplicate fat chain + mov edi,RAMDISK+512+0x1200 + mov ecx,1069 ;4274/4 + cld + rep movsd + + popad + ret + + +ramdisk_free_space: +;--------------------------------------------- +; +; returns free space in edi +; rewr.by Mihasik +;--------------------------------------------- + + push eax ebx ecx + + mov edi,RAMDISK_FAT ;start of FAT + xor ax,ax ;Free cluster=0x0000 in FAT + xor ebx,ebx ;counter + mov ecx,2849 ;2849 clusters + cld + rdfs1: + repne scasw + jnz rdfs2 ;if last cluster not 0 + inc ebx + test ecx, ecx + jnz rdfs1 + rdfs2: + shl ebx,9 ;free clusters*512 + mov edi,ebx + + pop ecx ebx eax + ret + + +expand_filename: +;--------------------------------------------- +; +; exapand filename with '.' to 11 character +; eax - pointer to filename +;--------------------------------------------- + + push esi edi ebx + + mov edi,esp ; check for '.' in the name + add edi,12+8 + + mov esi,eax + + mov eax,edi + mov [eax+0],dword ' ' + mov [eax+4],dword ' ' + mov [eax+8],dword ' ' + + flr1: + + cmp [esi],byte '.' + jne flr2 + mov edi,eax + add edi,7 + jmp flr3 + + flr2: + + mov bl,[esi] + mov [edi],bl + + flr3: + + inc esi + inc edi + + mov ebx,eax + add ebx,11 + + cmp edi,ebx + jbe flr1 + + pop ebx edi esi + ret + +fileread: +;---------------------------------------------------------------- +; +; fileread - sys floppy +; +; eax points to filename 11 chars +; ebx first wanted block ; 1+ ; if 0 then set to 1 +; ecx number of blocks to read ; 1+ ; if 0 then set to 1 +; edx mem location to return data +; esi length of filename 12*X 0=root +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- + test ebx,ebx ;if ebx=0 - set to 1 + jnz frfl5 + inc ebx + frfl5: + test ecx,ecx ;if ecx=0 - set to 1 + jnz frfl6 + inc ecx + frfl6: + test esi,esi ; return ramdisk root + jnz fr_noroot ;if not root + cmp ebx,14 ;14 clusters=root dir + ja oorr + cmp ecx,14 + ja oorr + jmp fr_do + oorr: + mov eax,5 ;out of root range (fnf) + xor ebx,ebx + dec ebx ;0xffffffff + ret + + fr_do: ;reading rootdir + mov edi,edx + dec ebx + push edx + mov edx,ecx + add edx,ebx + cmp edx,15 ;ebx+ecx=14+1 + pushf + jbe fr_do1 + sub edx,14 + sub ecx,edx + fr_do1: + shl ebx,9 + mov esi,RAMDISK+512*19 + add esi,ebx + shl ecx,7 + cld + rep movsd + popf + pop edx + jae fr_do2 + xor eax,eax ; ok read + xor ebx,ebx + ret + fr_do2: ;if last cluster + mov eax,6 ;end of file + xor ebx,ebx + ret + + fr_noroot: + + sub esp,32 + call expand_filename + + dec ebx + + push eax + + push eax ebx ecx edx esi edi + call rd_findfile + je fifound + add esp,32+28 ;if file not found + ret + + fifound: + + mov ebx,[edi-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + add edi,0xf + movzx eax,word [edi] + mov edi,eax ;edi=cluster + + frnew: + + add eax,31 ;bootsector+2*fat+filenames + shl eax,9 ;*512 + add eax,RAMDISK ;image base + mov ebx,[esp+8] + mov ecx,512 ;[esp+4] + + cmp [esp+16],dword 0 ; wanted cluster ? + jne frfl7 + call memmove + add [esp+8],dword 512 + dec dword [esp+12] ; last wanted cluster ? + je frnoread + jmp frfl8 + frfl7: + dec dword [esp+16] + frfl8: + movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT + mov edi,eax + cmp edi,4095 ;eof - cluster + jz frnoread2 + + cmp [esp+24],dword 512 ;eof - size + jb frnoread + sub [esp+24],dword 512 + + jmp frnew + + frnoread2: + + cmp [esp+16],dword 0 ; eof without read ? + je frnoread + + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + mov eax,6 ; end of file + ret + + frnoread: + + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + xor eax,eax ;read ok + ret + + + + rd_findfile: + ;by Mihasik + ;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx + + mov edi,RAMDISK+512*18+512 ;Point at directory + cld + rd_newsearch: + mov esi,eax + mov ecx,11 + rep cmpsb + je rd_ff + add cl,21 + add edi,ecx + cmp edi,RAMDISK+512*33 + jb rd_newsearch + mov eax,5 ;if file not found - eax=5 + xor ebx,ebx + dec ebx ;ebx=0xffffffff and zf=0 + rd_ff: + ret + +; \begin{diamond} + +uni2ansi_str: +; convert UNICODE zero-terminated string to ASCII-string (codepage 866) +; in: esi->source, edi->buffer (may be esi=edi) +; destroys: eax,esi,edi + lodsw + test ax, ax + jz .done + cmp ax, 0x80 + jb .ascii + cmp ax, 0x401 + jz .yo1 + cmp ax, 0x451 + jz .yo2 + cmp ax, 0x410 + jb .unk + cmp ax, 0x440 + jb .rus1 + cmp ax, 0x450 + jb .rus2 +.unk: + mov al, '_' + jmp .doit +.yo1: + mov al, 'р' + jmp .doit +.yo2: + mov al, 'с' + jmp .doit +.rus1: +; 0x410-0x43F -> 0x80-0xAF + add al, 0x70 + jmp .doit +.rus2: +; 0x440-0x44F -> 0xE0-0xEF + add al, 0xA0 +.ascii: +.doit: + stosb + jmp uni2ansi_str +.done: + mov byte [edi], 0 + ret + +ansi2uni_char: +; convert ANSI character in al to UNICODE character in ax, using cp866 encoding + mov ah, 0 +; 0x00-0x7F - trivial map + cmp al, 0x80 + jb .ret +; 0x80-0xAF -> 0x410-0x43F + cmp al, 0xB0 + jae @f + add ax, 0x410-0x80 +.ret: + ret +@@: +; 0xE0-0xEF -> 0x440-0x44F + cmp al, 0xE0 + jb .unk + cmp al, 0xF0 + jae @f + add ax, 0x440-0xE0 + ret +; 0xF0 -> 0x401 +; 0xF1 -> 0x451 +@@: + cmp al, 'р' + jz .yo1 + cmp al, 'с' + jz .yo2 +.unk: + mov al, '_' ; ah=0 + ret +.yo1: + mov ax, 0x401 + ret +.yo2: + mov ax, 0x451 + ret + +char_toupper: +; convert character to uppercase, using cp866 encoding +; in: al=symbol +; out: al=converted symbol + cmp al, 'a' + jb .ret + cmp al, 'z' + jbe .az + cmp al, ' ' + jb .ret + cmp al, 'а' + jb .rus1 + cmp al, 'п' + ja .ret +; 0xE0-0xEF -> 0x90-0x9F + sub al, 'а'-'ђ' +.ret: + ret +.rus1: +; 0xA0-0xAF -> 0x80-0x8F +.az: + and al, not 0x20 + ret + +fat_get_name: +; in: edi->FAT entry +; out: CF=1 - no valid entry +; else CF=0 and ebp->ASCIIZ-name +; (maximum length of filename is 255 (wide) symbols without trailing 0, +; but implementation requires buffer 261 words) +; destroys eax + cmp byte [edi], 0 + jz .no + cmp byte [edi], 0xE5 + jnz @f +.no: + stc + ret +@@: + cmp byte [edi+11], 0xF + jz .longname + test byte [edi+11], 8 + jnz .no + push ecx + push edi ebp + test byte [ebp-4], 1 + jnz .unicode_short + + mov eax, [edi] + mov ecx, [edi+4] + mov [ebp], eax + mov [ebp+4], ecx + + mov ecx, 8 +@@: + cmp byte [ebp+ecx-1], ' ' + loope @b + + mov eax, [edi+8] + cmp al, ' ' + je .done + shl eax, 8 + mov al, '.' + + lea ebp, [ebp+ecx+1] + mov [ebp], eax + mov ecx, 3 +@@: + rol eax, 8 + cmp al, ' ' + jne .done + loop @b + dec ebp +.done: + and byte [ebp+ecx+1], 0 ; CF=0 + pop ebp edi ecx + ret +.unicode_short: + mov ecx, 8 + push ecx +@@: + mov al, [edi] + inc edi + call ansi2uni_char + mov [ebp], ax + inc ebp + inc ebp + loop @b + pop ecx +@@: + cmp word [ebp-2], ' ' + jnz @f + dec ebp + dec ebp + loop @b +@@: + mov word [ebp], '.' + inc ebp + inc ebp + mov ecx, 3 + push ecx +@@: + mov al, [edi] + inc edi + call ansi2uni_char + mov [ebp], ax + inc ebp + inc ebp + loop @b + pop ecx +@@: + cmp word [ebp-2], ' ' + jnz @f + dec ebp + dec ebp + loop @b + dec ebp + dec ebp +@@: + and word [ebp], 0 ; CF=0 + pop ebp edi ecx + ret +.longname: +; LFN + mov al, byte [edi] + and eax, 0x3F + dec eax + cmp al, 20 + jae .no ; ignore invalid entries + mov word [ebp+260*2], 0 ; force null-terminating for orphans + imul eax, 13*2 + add ebp, eax + test byte [edi], 0x40 + jz @f + mov word [ebp+13*2], 0 +@@: + push eax +; now copy name from edi to ebp ... + mov eax, [edi+1] + mov [ebp], eax ; symbols 1,2 + mov eax, [edi+5] + mov [ebp+4], eax ; 3,4 + mov eax, [edi+9] + mov [ebp+8], ax ; 5 + mov eax, [edi+14] + mov [ebp+10], eax ; 6,7 + mov eax, [edi+18] + mov [ebp+14], eax ; 8,9 + mov eax, [edi+22] + mov [ebp+18], eax ; 10,11 + mov eax, [edi+28] + mov [ebp+22], eax ; 12,13 +; ... done + pop eax + sub ebp, eax + test eax, eax + jz @f +; if this is not first entry, more processing required + stc + ret +@@: +; if this is first entry: + test byte [ebp-4], 1 + jnz .ret +; buffer at ebp contains UNICODE name, convert it to ANSI + push esi edi + mov esi, ebp + mov edi, ebp + call uni2ansi_str + pop edi esi +.ret: + clc + ret + +fat_compare_name: +; compares ASCIIZ-names, case-insensitive (cp866 encoding) +; in: esi->name, ebp->name +; out: if names match: ZF=1 and esi->next component of name +; else: ZF=0, esi is not changed +; destroys eax + push ebp esi +.loop: + mov al, [ebp] + inc ebp + call char_toupper + push eax + lodsb + call char_toupper + cmp al, [esp] + jnz .done + pop eax + test al, al + jnz .loop + dec esi + pop eax + pop ebp + xor eax, eax ; set ZF flag + ret +.done: + cmp al, '/' + jnz @f + cmp byte [esp], 0 + jnz @f + mov [esp+4], esi +@@: + pop eax + pop esi ebp + ret + +fat_time_to_bdfe: +; in: eax=FAT time +; out: eax=BDFE time + push ecx edx + mov ecx, eax + mov edx, eax + shr eax, 11 + shl eax, 16 ; hours + and edx, 0x1F + add edx, edx + mov al, dl ; seconds + shr ecx, 5 + and ecx, 0x3F + mov ah, cl ; minutes + pop edx ecx + ret + +fat_date_to_bdfe: + push ecx edx + mov ecx, eax + mov edx, eax + shr eax, 9 + add ax, 1980 + shl eax, 16 ; year + and edx, 0x1F + mov al, dl ; day + shr ecx, 5 + and ecx, 0xF + mov ah, cl ; month + pop edx ecx + ret + +bdfe_to_fat_time: + push edx + mov edx, eax + shr eax, 16 + and dh, 0x3F + shl eax, 6 + or al, dh + shr dl, 1 + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + +bdfe_to_fat_date: + push edx + mov edx, eax + shr eax, 16 + sub ax, 1980 + and dh, 0xF + shl eax, 4 + or al, dh + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + +fat_entry_to_bdfe: +; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi +; destroys eax + mov eax, [ebp-4] + mov [esi+4], eax ; ASCII/UNICODE name +fat_entry_to_bdfe2: + movzx eax, byte [edi+11] + mov [esi], eax ; attributes + movzx eax, word [edi+14] + call fat_time_to_bdfe + mov [esi+8], eax ; creation time + movzx eax, word [edi+16] + call fat_date_to_bdfe + mov [esi+12], eax ; creation date + and dword [esi+16], 0 ; last access time is not supported on FAT + movzx eax, word [edi+18] + call fat_date_to_bdfe + mov [esi+20], eax ; last access date + movzx eax, word [edi+22] + call fat_time_to_bdfe + mov [esi+24], eax ; last write time + movzx eax, word [edi+24] + call fat_date_to_bdfe + mov [esi+28], eax ; last write date + mov eax, [edi+28] + mov [esi+32], eax ; file size (low dword) + xor eax, eax + mov [esi+36], eax ; file size (high dword) + test ebp, ebp + jz .ret + push ecx edi + lea edi, [esi+40] + mov esi, ebp + test byte [esi-4], 1 + jz .ansi + mov ecx, 260/2 + rep movsd + mov [edi-2], ax +@@: + mov esi, edi + pop edi ecx +.ret: + ret +.ansi: + mov ecx, 264/4 + rep movsd + mov [edi-1], al + jmp @b + +bdfe_to_fat_entry: +; convert BDFE at edx to FAT entry at edi +; destroys eax +; attributes byte + test byte [edi+11], 8 ; volume label? + jnz @f + mov al, [edx] + and al, 0x27 + and byte [edi+11], 0x10 + or byte [edi+11], al +@@: + mov eax, [edx+8] + call bdfe_to_fat_time + mov [edi+14], ax ; creation time + mov eax, [edx+12] + call bdfe_to_fat_date + mov [edi+16], ax ; creation date + mov eax, [edx+20] + call bdfe_to_fat_date + mov [edi+18], ax ; last access date + mov eax, [edx+24] + call bdfe_to_fat_time + mov [edi+22], ax ; last write time + mov eax, [edx+28] + call bdfe_to_fat_date + mov [edi+24], ax ; last write date + ret + +ramdisk_root_first: + mov edi, RAMDISK+512*19 + clc + ret +ramdisk_root_next: + add edi, 0x20 + cmp edi, RAMDISK+512*33 + cmc + ret + +ramdisk_root_extend_dir: + stc + ret + +uglobal +; this is for delete support +rd_prev_sector dd ? +rd_prev_prev_sector dd ? +endg + +ramdisk_notroot_next: + add edi, 0x20 + test edi, 0x1FF + jz ramdisk_notroot_next_sector + ret ; CF=0 +ramdisk_notroot_next_sector: + push ecx + mov ecx, [eax] + push [rd_prev_sector] + pop [rd_prev_prev_sector] + mov [rd_prev_sector], ecx + mov ecx, [ecx*2+RAMDISK_FAT] + and ecx, 0xFFF + cmp ecx, 2849 + jae ramdisk_notroot_first.err2 + mov [eax], ecx + pop ecx +ramdisk_notroot_first: + mov eax, [eax] + cmp eax, 2 + jb .err + cmp eax, 2849 + jae .err + shl eax, 9 + lea edi, [eax+(31 shl 9)+RAMDISK] + clc + ret +.err2: + pop ecx +.err: + stc + ret +ramdisk_notroot_next_write: + test edi, 0x1FF + jz ramdisk_notroot_next_sector +ramdisk_root_next_write: + ret + +ramdisk_notroot_extend_dir: + pusha + xor eax, eax + mov edi, RAMDISK_FAT + mov ecx, 2849 + repnz scasw + jnz .notfound + mov word [edi-2], 0xFFF + sub edi, RAMDISK_FAT + shr edi, 1 + dec edi + mov eax, [esp+28] + mov ecx, [eax] + mov [RAMDISK_FAT+ecx*2], di + mov [eax], edi + shl edi, 9 + add edi, (31 shl 9)+RAMDISK + mov [esp], edi + xor eax, eax + mov ecx, 128 + rep stosd + popa + clc + ret +.notfound: + popa + stc + ret + +rd_find_lfn: +; in: esi+ebp -> name +; out: CF=1 - file not found +; else CF=0 and edi->direntry + push esi edi + push 0 + push ramdisk_root_first + push ramdisk_root_next +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found +.continue: + test byte [edi+11], 10h + jz .notfound + movzx eax, word [edi+26] + mov [esp+8], eax + mov dword [esp+4], ramdisk_notroot_first + mov dword [esp], ramdisk_notroot_next + test eax, eax + jnz .loop + mov dword [esp+4], ramdisk_root_first + mov dword [esp], ramdisk_notroot_next + jmp .loop +.notfound: + add esp, 12 + pop edi esi + stc + ret +.found: + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp + jmp .continue +@@: + mov eax, [esp+8] + add esp, 16 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskRead - LFN variant for reading sys floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskRead: + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 ; EOF +@@: + movzx edi, word [edi+26] ; cluster +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + lea eax, [edi+31] ; bootsector+2*fat+filenames + shl eax, 9 ; *512 + add eax, RAMDISK ; image base +; now eax points to data of cluster + sub ebx, 512 + jae .skip + lea eax, [eax+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx +.skip: + movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT + jmp .new +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder +; +; esi points to filename; only root is folder on ramdisk +; ebx pointer to structure 32-bit number = first wanted block +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskReadFolder: + push edi + cmp byte [esi], 0 + jz .root + call rd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + movzx eax, word [edi+26] + add eax, 31 + push 0 + jmp .doit +.root: + mov eax, 19 + push 14 +.doit: + push esi ecx ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + mov byte [edx], 1 ; version + pop ecx eax + mov esi, edi ; esi points to block of data of folder entry (BDFE) +.main_loop: + mov edi, eax + shl edi, 9 + add edi, RAMDISK + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + test edi, 0x1FF + jnz .do_bdfe + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+RAMDISK_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 +@@: + mov edi, eax + shl edi, 9 + add edi, RAMDISK + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec ebx + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + test edi, 0x1FF + jnz .l1 + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+RAMDISK_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 +@@: + jmp .main_loop +.done: + add esp, 262*2+4 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx esi edi edi + ret + +iglobal +label fat_legal_chars byte +; 0 = not allowed +; 1 = allowed only in long names +; 3 = allowed + times 32 db 0 +; ! " # $ % & ' ( ) * + , - . / + db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 +; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 +; @ A B C D E F G H I J K L M N O + db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 +; P Q R S T U V W X Y Z [ \ ] ^ _ + db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 +; ` a b c d e f g h i j k l m n o + db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 +; p q r s t u v w x y z { | } ~ + db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 +endg + +fat_name_is_legal: +; in: esi->(long) name +; out: CF set <=> legal +; destroys eax + push esi + xor eax, eax +@@: + lodsb + test al, al + jz .done + cmp al, 80h + jae .big + test [fat_legal_chars+eax], 1 + jnz @b +.err: + pop esi + clc + ret +.big: +; 0x80-0xAF, 0xE0-0xEF + cmp al, 0xB0 + jb @b + cmp al, 0xE0 + jb .err + cmp al, 0xF0 + jb @b + jmp .err +.done: + sub esi, [esp] + cmp esi, 257 + pop esi + ret + +fat_next_short_name: +; in: edi->8+3 name +; out: name corrected +; CF=1 <=> error + pushad + mov ecx, 8 + mov al, '~' + std + push edi + add edi, 7 + repnz scasb + pop edi + cld + jz .tilde +; tilde is not found, insert "~1" at end + add edi, 6 + cmp word [edi], ' ' + jnz .insert_tilde +@@: dec edi + cmp byte [edi], ' ' + jz @b + inc edi +.insert_tilde: + mov word [edi], '~1' + popad + clc + ret +.tilde: + push edi + add edi, 7 + xor ecx, ecx +@@: +; after tilde may be only digits and trailing spaces + cmp byte [edi], '~' + jz .break + cmp byte [edi], ' ' + jz .space + cmp byte [edi], '9' + jnz .found + dec edi + jmp @b +.space: + dec edi + inc ecx + jmp @b +.found: + inc byte [edi] + add dword [esp], 8 + jmp .zerorest +.break: + jecxz .noplace + inc edi + mov al, '1' +@@: + xchg al, [edi] + inc edi + cmp al, ' ' + mov al, '0' + jnz @b +.succ: + pop edi + popad + clc + ret +.noplace: + dec edi + cmp edi, [esp] + jz .err + add dword [esp], 8 + mov word [edi], '~1' + inc edi + inc edi +@@: + mov byte [edi], '0' +.zerorest: + inc edi + cmp edi, [esp] + jb @b + pop edi + popad + ;clc ; automatically + ret +.err: + pop edi + popad + stc + ret + +fat_gen_short_name: +; in: esi->long name +; edi->buffer (8+3=11 chars) +; out: buffer filled + pushad + mov eax, ' ' + push edi + stosd + stosd + stosd + pop edi + xor eax, eax + push 8 + pop ebx + lea ecx, [edi+8] +.loop: + lodsb + test al, al + jz .done + call char_toupper + cmp al, ' ' + jz .space + cmp al, 80h + ja .big + test [fat_legal_chars+eax], 2 + jnz .symbol +.inv_symbol: + mov al, '_' + or bh, 1 +.symbol: + cmp al, '.' + jz .dot +.normal_symbol: + dec bl + jns .store + mov bl, 0 +.space: + or bh, 1 + jmp .loop +.store: + stosb + jmp .loop +.big: + cmp al, 0xB0 + jb .normal_symbol + cmp al, 0xE0 + jb .inv_symbol + cmp al, 0xF0 + jb .normal_symbol + jmp .inv_symbol +.dot: + test bh, 2 + jz .firstdot + pop ebx + add ebx, edi + sub ebx, ecx + push ebx + cmp ebx, ecx + jb @f + pop ebx + push ecx +@@: + cmp edi, ecx + jbe .skip +@@: + dec edi + mov al, [edi] + dec ebx + mov [ebx], al + mov byte [edi], ' ' + cmp edi, ecx + ja @b +.skip: + mov bh, 3 + jmp @f +.firstdot: + cmp bl, 8 + jz .space + push edi + or bh, 2 +@@: + mov edi, ecx + mov bl, 3 + jmp .loop +.done: + test bh, 2 + jz @f + pop edi +@@: + lea edi, [ecx-8] + test bh, 1 + jz @f + call fat_next_short_name +@@: + popad + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskRewrite - LFN variant for writing ramdisk +; fs_RamdiskCreateFolder - create folder on ramdisk +; +; esi points to file/folder name +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ (ignored for folders) +; edx mem location to data (ignored for folders) +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +@@: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret + +fs_RamdiskCreateFolder: + mov al, 1 ; create folder + jmp fs_RamdiskRewrite.common + +fs_RamdiskRewrite: + xor eax, eax ; create file +.common: + cmp byte [esi], 0 + jz @b + pushad + xor edi, edi + push esi + test ebp, ebp + jz @f + mov esi, ebp +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea edi, [esi-1] + jmp @b +@@: + pop esi + test edi, edi + jnz .noroot + test ebp, ebp + jnz .hasebp + push ramdisk_root_extend_dir + push ramdisk_root_next_write + push edi + push ramdisk_root_first + push ramdisk_root_next + jmp .common1 +.hasebp: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp], 0 + jz .ret1 + push ebp + xor ebp, ebp + call rd_find_lfn + pop esi + jc .notfound0 + jmp .common0 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [edi+1], 0 + jz .ret1 +; check existence + mov byte [edi], 0 + push edi + call rd_find_lfn + pop esi + mov byte [esi], '/' + jnc @f +.notfound0: + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + inc esi +.common0: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + movzx ebp, word [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 + cmp ebp, 2849 + jae .ret1 + push ramdisk_notroot_extend_dir + push ramdisk_notroot_next_write + push ebp + push ramdisk_notroot_first + push ramdisk_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found + test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 20 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+20+28], 0 + jz @f + add esp, 20 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xchg ax, word [edi+26] ; start cluster + test eax, eax + jz .done1 +@@: + cmp eax, 0xFF8 + jae .done1 + lea edi, [RAMDISK_FAT + eax*2] ; position in FAT + xor eax, eax + xchg ax, [edi] + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 20 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+20 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+12+8+12+8] + mov [eax], ebp + call dword [eax-4] + pop eax +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+12+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + push eax + lea eax, [esp+12+8+12+8] + call dword [eax+8] ; extend directory + pop eax + jnc .scan_dir + add esp, 8+8+12+20 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+8+8+12+8] + mov [esp+4], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+8] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+8] +; edi points to last entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call .read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call .read_symbols + xor eax, eax + stosw + mov cl, 2 + call .read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+4] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + and word [edi+20], 0 ; high word of cluster + and word [edi+26], 0 ; low word of cluster - to be filled + and dword [edi+28], 0 ; file size - to be filled + cmp byte [esp+20+28], 0 + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov ecx, 32*2 + mov edx, edi +.doit: + push edx + push ecx + push edi + add edi, 26 ; edi points to low word of cluster + push edi + jecxz .done + mov ecx, 2849 + mov edi, RAMDISK_FAT +.write_loop: +; allocate new cluster + xor eax, eax + repnz scasw + jnz .disk_full2 + dec edi + dec edi + + ; lea eax, [edi-(RAMDISK_FAT)] + + mov eax, edi + sub eax, RAMDISK_FAT + + shr eax, 1 ; eax = cluster + mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp] + stosw + pop edi + push edi + inc ecx +; write data + cmp byte [esp+16+20+28], 0 + jnz .writedir + shl eax, 9 + add eax, RAMDISK+31*512 +.writefile: + mov ebx, edx + xchg eax, ebx + push ecx + mov ecx, 512 + cmp dword [esp+12], ecx + jae @f + mov ecx, [esp+12] +@@: + call memmove + add edx, ecx + sub [esp+12], ecx + pop ecx + jnz .write_loop +.done: + mov ebx, edx + pop edi edi ecx edx + sub ebx, edx + mov [edi+28], ebx + add esp, 20 + mov [esp+16], ebx + popad + xor eax, eax + ret +.disk_full2: + mov ebx, edx + pop edi edi ecx edx + sub ebx, edx + mov [edi+28], ebx + add esp, 20 + mov [esp+16], ebx + popad + push ERROR_DISK_FULL + pop eax + ret +.writedir: + mov edi, eax + shl edi, 9 + add edi, RAMDISK+31*512 + mov esi, edx + mov ecx, 32/4 + push ecx + rep movsd + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov word [edi-32+26], ax + mov esi, edx + pop ecx + rep movsd + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov eax, [esp+16+8] + mov word [edi-32+26], ax + xor eax, eax + mov ecx, (512-32*2)/4 + rep stosd + pop edi edi ecx edx + add esp, 20 + popad + xor eax, eax + xor ebx, ebx + ret + +.read_symbol: + or ax, -1 + test esi, esi + jz .retFFFF + lodsb + test al, al + jnz ansi2uni_char + xor eax, eax + xor esi, esi +.retFFFF: + ret + +.read_symbols: + call .read_symbol + stosw + loop .read_symbols + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskWrite - LFN variant for writing to sys floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +@@: + push ERROR_ACCESS_DENIED +fs_RamdiskWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_RamdiskWrite: + cmp byte [esi], 0 + jz @b + pushad + call rd_find_lfn + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; must not be directory + test byte [edi+11], 10h + jz @f + popad + push ERROR_ACCESS_DENIED + jmp .ret0 +@@: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + call fat_update_datetime + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push 0 ; return value=0 + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call ramdisk_extend_file + jnc .length_ok +; ramdisk_extend_file can return two error codes: FAT table error or disk full. +; First case is fatal error, in second case we may write some data + mov [esp], eax + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + mov [esp+28], eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + pop eax + mov [esp+28], eax ; eax=return value + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret + movzx edi, word [edi+26] ; starting cluster +.write_loop: + sub ebx, 0x200 + jae .next_cluster + push ecx + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov eax, edi + shl eax, 9 + add eax, RAMDISK+31*512+0x200 + sub eax, ebx + mov ebx, eax + mov eax, edx + call memmove + xor ebx, ebx + add edx, ecx + sub [esp], ecx + pop ecx + jz .ret +.next_cluster: + movzx edi, word [edi*2+RAMDISK_FAT] + jmp .write_loop + +ramdisk_extend_file.zero_size: + xor eax, eax + jmp ramdisk_extend_file.start_extend + +; extends file on ramdisk to given size, new data area is filled by 0 +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) +ramdisk_extend_file: + push ecx +; find the last cluster of file + movzx eax, word [edi+26] ; first cluster + mov ecx, [edi+28] + jecxz .zero_size +@@: + sub ecx, 0x200 + jbe @f + mov eax, [eax*2+RAMDISK_FAT] + and eax, 0xFFF + jz .fat_err + cmp eax, 0xFF8 + jb @b +.fat_err: + pop ecx + push ERROR_FAT_TABLE + pop eax + stc + ret +@@: + push eax + mov eax, [eax*2+RAMDISK_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + pop eax + jb .fat_err +; set length to full number of sectors and make sure that last sector is zero-padded + sub [edi+28], ecx + push eax edi + mov edi, eax + shl edi, 9 + lea edi, [edi+RAMDISK+31*512+0x200+ecx] + neg ecx + xor eax, eax + rep stosb + pop edi eax +.start_extend: + pop ecx +; now do extend + push edx esi + mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2 + mov edx, 2847 ; number of clusters to scan +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new sector + push ecx + mov ecx, edx + push edi + mov edi, esi + jecxz .disk_full + push eax + xor eax, eax + repnz scasw + pop eax + jnz .disk_full + mov word [edi-2], 0xFFF + mov esi, edi + mov edx, ecx + sub edi, RAMDISK_FAT + shr edi, 1 + dec edi ; now edi=new cluster + test eax, eax + jz .first_cluster + mov [RAMDISK_FAT+eax*2], di + jmp @f +.first_cluster: + pop eax ; eax->direntry + push eax + mov [eax+26], di +@@: + push edi + shl edi, 9 + add edi, RAMDISK+31*512 + xor eax, eax + mov ecx, 512/4 + rep stosd + pop eax ; eax=new cluster + pop edi ; edi->direntry + pop ecx ; ecx=required size + add dword [edi+28], 0x200 + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop esi edx + xor eax, eax ; CF=0 + ret +.disk_full: + pop edi ecx + pop esi edx + stc + push ERROR_DISK_FULL + pop eax + ret + +fat_update_datetime: + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskSetFileEnd - set end of file on ramdisk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskSetFileEnd: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop edi + xor eax, eax + ret +.expand: + push ecx + mov ecx, eax + call ramdisk_extend_file + pop ecx + pop edi + ret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [RAMDISK_FAT+ecx*2] + jmp @b +@@: +; zero data at the end of last sector + push ecx + mov edi, ecx + shl edi, 9 + lea edi, [edi+RAMDISK+31*512+eax+0x200] + mov ecx, eax + neg ecx + xor eax, eax + rep stosb + pop ecx +; terminate FAT chain + lea ecx, [RAMDISK_FAT+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [RAMDISK_FAT+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + pop ecx + pop edi + xor eax, eax + ret + +fs_RamdiskGetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn +fs_GetFileInfo_finish: + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push esi ebp + xor ebp, ebp + mov esi, edx + and dword [esi+4], 0 + call fat_entry_to_bdfe2 + pop ebp esi + pop edi + xor eax, eax + ret + +fs_RamdiskSetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + call bdfe_to_fat_entry + pop edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskDelete - delete file or empty folder from ramdisk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskDelete: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED +.pop_ret: + pop eax + ret +@@: + and [rd_prev_sector], 0 + and [rd_prev_prev_sector], 0 + push edi + call rd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + movzx eax, word [edi+26] + push ebx + mov ebx, eax + shl ebx, 9 + add ebx, RAMDISK + 31*0x200 + 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + test ebx, 0x1FF + jnz .checkempty + movzx eax, word [RAMDISK_FAT + eax*2] + test eax, eax + jz .empty + mov ebx, eax + shl ebx, 9 + add ebx, RAMDISK + 31*0x200 + jmp .checkempty +.notempty: + pop ebx +.access_denied2: + pop edi + jmp .access_denied +.empty: + pop ebx +.dodel: + movzx eax, word [edi+26] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + test edi, 0x1FF + jnz @f + cmp [rd_prev_sector], 0 + jz @f + cmp [rd_prev_sector], -1 + jz .lfndone + mov edi, [rd_prev_sector] + push [rd_prev_prev_sector] + pop [rd_prev_sector] + or [rd_prev_prev_sector], -1 + shl edi, 9 + add edi, RAMDISK + 31*0x200 + 0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: +; delete FAT chain + test eax, eax + jz .done + lea eax, [RAMDISK_FAT + eax*2] + push dword [eax] + and word [eax], 0 + pop eax + and eax, 0xFFF + jmp .lfndone +.done: + pop edi + xor eax, eax + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc b/kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc new file mode 100644 index 000000000..2e9396e41 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/blkdev/rdsave.inc @@ -0,0 +1,32 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +iglobal +saverd_fileinfo: + dd 2 ; subfunction: write + dd 0 ; (reserved) + dd 0 ; (reserved) + dd 1440*1024 ; size 1440 Kb + dd RAMDISK + db 0 +.name: + dd ? +endg +sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) + call restorefatchain + mov eax, saverd_fileinfo + mov [saverd_fileinfo.name], ecx + pushad + push eax + call file_system_lfn + pop eax + popad + mov [esp+32], eax + ret diff --git a/kernel/tags/kolibri0.7.7.0/boot/ETFONT.FNT b/kernel/tags/kolibri0.7.7.0/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 + test al,al + jnz @b + popa + ret + +getkey: +; get number in range [bl,bh] (bl,bh in ['0'..'9']) +; in: bx=range +; out: ax=digit (1..9, 10 for 0) + mov ah, 0 + int 16h + cmp al, bl + jb getkey + cmp al, bh + ja getkey + push ax + call putchar + pop ax + and ax, 0Fh + jnz @f + mov al, 10 +@@: + ret + +setcursor: +; in: dl=column, dh=row + mov ah, 2 + mov bh, 0 + int 10h + ret + +macro _setcursor row,column +{ + mov dx, row*256 + column + call setcursor +} + +boot_read_floppy: + push si + xor si, si + mov ah, 2 ; read +@@: + push ax + int 0x13 + pop ax + jnc @f + inc si + cmp si, 10 + jb @b + mov si, badsect +sayerr_plain: + call printplain + jmp $ +@@: + pop si + ret + +; convert abs. sector number (AX) to BIOS T:H:S +; sector number = (abs.sector%BPB_SecPerTrk)+1 +; pre.track number = (abs.sector/BPB_SecPerTrk) +; head number = pre.track number%BPB_NumHeads +; track number = pre.track number/BPB_NumHeads +; Return: cl - sector number +; ch - track number +; dl - drive number (0 = a:) +; dh - head number +conv_abs_to_THS: + push bx + mov bx,word [BPB_SecPerTrk] + xor dx,dx + div bx + inc dx + mov cl, dl ; cl = sector number + mov bx,word [BPB_NumHeads] + xor dx,dx + div bx + ; !!!!!!! ax = track number, dx = head number + mov ch,al ; ch=track number + xchg dh,dl ; dh=head number + mov dl,0 ; dl=0 (drive 0 (a:)) + pop bx + retn +; needed variables +BPB_SecPerTrk dw 0 ; sectors per track +BPB_NumHeads dw 0 ; number of heads +BPB_FATSz16 dw 0 ; size of FAT +BPB_RootEntCnt dw 0 ; count of root dir. entries +BPB_BytsPerSec dw 0 ; bytes per sector +BPB_RsvdSecCnt dw 0 ; number of reserved sectors +BPB_TotSec16 dw 0 ; count of the sectors on the volume +BPB_SecPerClus db 0 ; number of sectors per cluster +BPB_NumFATs db 0 ; number of FAT tables +abs_sector_adj dw 0 ; adjustment to make abs. sector number +end_of_FAT dw 0 ; end of FAT table +FirstDataSector dw 0 ; begin of data + +;========================================================================= +; +; 16 BIT CODE +; +;========================================================================= + +include 'bootvesa.inc' ;Include source for boot vesa + +start_of_code: + cld +; \begin{diamond}[02.12.2005] +; if bootloader sets ax = 'KL', then ds:si points to loader block + cmp ax, 'KL' + jnz @f + mov word [cs:cfgmanager.loader_block], si + mov word [cs:cfgmanager.loader_block+2], ds +@@: +; \end{diamond}[02.12.2005] + +; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk +; (see comment to bx_from_load) + cmp cx, 'HA' + jnz no_hd_load + cmp dx,'RD' + jnz no_hd_load + mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007] +no_hd_load: + +; set up stack + mov ax, 3000h + mov ss, ax + mov sp, 0EC00h +; set up segment registers + push cs + pop ds + push cs + pop es + +; set videomode + mov ax, 3 + int 0x10 + +if lang eq ru + ; Load & set russian VGA font (RU.INC) + mov bp, RU_FNT1 ; RU_FNT1 - First part + mov bx, 1000h ; 768 bytes + mov cx, 30h ; 48 symbols + mov dx, 80h ; 128 - position of first symbol + mov ax, 1100h + int 10h + + mov bp, RU_FNT2 ; RU_FNT2 -Second part + mov bx, 1000h ; 512 bytes + mov cx, 20h ; 32 symbols + mov dx, 0E0h ; 224 - position of first symbol + mov ax, 1100h + int 10h + ; End set VGA russian font +else if lang eq et + mov bp, ET_FNT ; ET_FNT1 + mov bx, 1000h ; + mov cx, 255 ; 256 symbols + xor dx, dx ; 0 - position of first symbol + mov ax, 1100h + int 10h +end if + +; draw frames + push 0xb800 + pop es + xor di, di + mov ah, 1*16+15 + +; draw top + mov si, d80x25_top + mov cx, d80x25_top_num * 80 +@@: + lodsb + stosw + loop @b +; draw spaces + mov si, space_msg + mov dx, 25 - d80x25_top_num - d80x25_bottom_num +dfl1: + push si + mov cx, 80 +@@: + lodsb + stosw + loop @b + pop si + dec dx + jnz dfl1 +; draw bottom + mov si, d80x25_bottom + mov cx, d80x25_bottom_num * 80 +@@: + lodsb + stosw + loop @b + + mov byte [space_msg+80], 0 ; now space_msg is null terminated + + _setcursor d80x25_top_num,0 + + +; TEST FOR 386+ + + mov bx, 0x4000 + pushf + pop ax + mov dx, ax + xor ax, bx + push ax + popf + pushf + pop ax + and ax, bx + and dx, bx + cmp ax, dx + jnz cpugood + mov si, not386 +sayerr: + call print + jmp $ + cpugood: + + push 0 + popf + sti + +; set up esp + movzx esp, sp + + push 0 + pop es + and word [es:0x9031], 0 +; \begin{Mario79} +; find HDD IDE DMA PCI device +; check for PCI BIOS + mov ax, 0xB101 + int 0x1A + jc .nopci + cmp edx, 'PCI ' + jnz .nopci +; find PCI class code +; class 1 = mass storage +; subclass 1 = IDE controller +; a) class 1, subclass 1, programming interface 0x80 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x80 + xor si, si ; device index = 0 + int 0x1A + jnc .found +; b) class 1, subclass 1, programming interface 0x8A + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x8A + xor si, si ; device index = 0 + int 0x1A + jnc .found +; c) class 1, subclass 1, programming interface 0x85 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x85 + xor si, si + int 0x1A + jc .nopci +.found: +; get memory base + mov ax, 0xB10A + mov di, 0x20 ; memory base is config register at 0x20 + int 0x1A + jc .nopci + and cx, 0xFFF0 ; clear address decode type + mov [es:0x9031], cx +.nopci: +; \end{Mario79} + + mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование + out 0x60, al + xor cx, cx +wait_loop: ; variant 2 +; reading state of port of 8042 controller + in al, 64h + and al, 00000010b ; ready flag +; wait until 8042 controller is ready + loopnz wait_loop + +;;;/diamond today 5.02.2008 +; set keyboard typematic rate & delay + mov al, 0xf3 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b + mov al, 0 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; --------------- APM --------------------- + and word [es:0x9044], 0 ; ver = 0.0 (APM not found) + mov ax, 0x5300 + xor bx, bx + int 0x15 + jc apm_end ; APM not found + test cx, 2 + jz apm_end ; APM 32-bit protected-mode interface not supported + mov [es:0x9044], ax ; Save APM Version + mov [es:0x9046], cx ; Save APM flags + + ; Write APM ver ---- + and ax, 0xf0f + add ax, '00' + mov si, msg_apm + mov [si + 5], ah + mov [si + 7], al + _setcursor 0, 3 + call printplain + ; ------------------ + + mov ax, 0x5304 ; Disconnect interface + xor bx, bx + int 0x15 + mov ax, 0x5303 ; Connect 32 bit mode interface + xor bx, bx + int 0x15 + + mov [es:0x9040], ebx + mov [es:0x9050], ax + mov [es:0x9052], cx + mov [es:0x9054], dx + +apm_end: + _setcursor d80x25_top_num, 0 + +;CHECK current of code + cmp [cfgmanager.loader_block], -1 + jz noloaderblock + les bx, [cfgmanager.loader_block] + cmp byte [es:bx], 1 + mov si, loader_block_error + jnz sayerr + push 0 + pop es + +noloaderblock: +; DISPLAY VESA INFORMATION + call print_vesa_info + call calc_vmodes_table + call check_first_parm ;check and enable cursor_pos + +; \begin{diamond}[30.11.2005] +cfgmanager: +; settings: +; a) preboot_graph = graphical mode +; preboot_gprobe = probe this mode? +; b) preboot_dma = use DMA access? +; c) preboot_vrrm = use VRR? +; d) preboot_device = from what boot? + +; determine default settings + mov [.bSettingsChanged], 0 + +;.preboot_gr_end: + mov di, preboot_device +; if image in memory is present and [preboot_device] is uninitialized, +; set it to use this preloaded image + cmp byte [di], 0 + jnz .preboot_device_inited + cmp [.loader_block], -1 + jz @f + les bx, [.loader_block] + test byte [es:bx+1], 1 + jz @f + mov byte [di], 3 + jmp .preboot_device_inited +@@: +; otherwise, set [preboot_device] to 1 (default value - boot from floppy) + mov byte [di], 1 +.preboot_device_inited: +; following 4 lines set variables to 1 if its current value is 0 + cmp byte [di+preboot_dma-preboot_device], 1 + adc byte [di+preboot_dma-preboot_device], 0 + cmp byte [di+preboot_biosdisk-preboot_device], 1 + adc byte [di+preboot_biosdisk-preboot_device], 0 +; default value for VRR is OFF + cmp byte [di+preboot_vrrm-preboot_device], 0 + jnz @f + mov byte [di+preboot_vrrm-preboot_device], 2 +@@: +; notify user + _setcursor 5,2 + + mov si, linef + call printplain + mov si, start_msg + call print + mov si, time_msg + call print +; get start time + call .gettime + mov [.starttime], eax + mov word [.timer], .newtimer + mov word [.timer+2], cs +.printcfg: + + _setcursor 9,0 + mov si, current_cfg_msg + call print + mov si, curvideo_msg + call print + + call draw_current_vmode + + mov si, usebd_msg + cmp [preboot_biosdisk], 1 + call .say_on_off + mov si, vrrm_msg + cmp [preboot_vrrm], 1 + call .say_on_off + mov si, preboot_device_msg + call print + mov al, [preboot_device] + and eax, 7 + mov si, [preboot_device_msgs+eax*2] + call printplain +.show_remarks: +; show remarks in gray color + mov di, ((21-num_remarks)*80 + 2)*2 + push 0xB800 + pop es + mov cx, num_remarks + mov si, remarks +.write_remarks: + lodsw + push si + xchg ax, si + mov ah, 1*16+7 ; background: blue (1), foreground: gray (7) + push di +.write_remark: + lodsb + test al, al + jz @f + stosw + jmp .write_remark +@@: + pop di + pop si + add di, 80*2 + loop .write_remarks +.wait: + _setcursor 25,0 ; out of screen +; set timer interrupt handler + cli + push 0 + pop es + push dword [es:8*4] + pop dword [.oldtimer] + push dword [.timer] + pop dword [es:8*4] +; mov eax, [es:8*4] +; mov [.oldtimer], eax +; mov eax, [.timer] +; mov [es:8*4], eax + sti +; wait for keypressed + xor ax,ax + int 16h + push ax +; restore timer interrupt +; push 0 +; pop es + mov eax, [.oldtimer] + mov [es:8*4], eax + mov [.timer], eax + + _setcursor 7,0 + mov si, space_msg + call printplain +; clear remarks and restore normal attributes + push es + mov di, ((21-num_remarks)*80 + 2)*2 + push 0xB800 + pop es + mov cx, num_remarks + mov ax, ' ' + (1*16 + 15)*100h +@@: + push cx + mov cx, 76 + rep stosw + pop cx + add di, 4*2 + loop @b + pop es + pop ax +; switch on key + cmp al, 13 + jz .continue + or al, 20h + cmp al, 'a' + jz .change_a + cmp al, 'b' + jz .change_b + cmp al, 'c' + jz .change_c + cmp al, 'd' + jnz .show_remarks + _setcursor 15,0 + mov si, bdev + call print + mov bx, '14' + call getkey + mov [preboot_device], al + _setcursor 13,0 +.d: + mov [.bSettingsChanged], 1 + call clear_vmodes_table ;clear vmodes_table + jmp .printcfg +.change_a: +.loops: + call draw_vmodes_table + _setcursor 25,0 ; out of screen + xor ax,ax + int 0x16 +; call clear_table_cursor ;clear current position of cursor + + mov si,word [cursor_pos] + + cmp ah,0x48;x,0x48E0 ; up + jne .down + cmp si,modes_table + jbe .loops + sub word [cursor_pos],size_of_step + jmp .loops + +.down: cmp ah,0x50;x,0x50E0 ; down + jne .pgup + cmp word[es:si+10],-1 + je .loops + add word [cursor_pos],size_of_step + jmp .loops + +.pgup: cmp ah,0x49 ; page up + jne .pgdn + sub si, size_of_step*long_v_table + cmp si, modes_table + jae @f + mov si, modes_table +@@: + mov word [cursor_pos], si + mov si, word [home_cursor] + sub si, size_of_step*long_v_table + cmp si, modes_table + jae @f + mov si, modes_table +@@: + mov word [home_cursor], si + jmp .loops + +.pgdn: cmp ah,0x51 ; page down + jne .enter + mov ax, [end_cursor] + add si, size_of_step*long_v_table + cmp si, ax + jb @f + mov si, ax + sub si, size_of_step +@@: + mov word [cursor_pos], si + mov si, word [home_cursor] + sub ax, size_of_step*long_v_table + add si, size_of_step*long_v_table + cmp si, ax + jb @f + mov si, ax +@@: + mov word [home_cursor], si + jmp .loops + +.enter: cmp al,0x0D;x,0x1C0D ; enter + jne .loops + push word [cursor_pos] + pop bp + push word [es:bp] + pop word [x_save] + push word [es:bp+2] + pop word [y_save] + push word [es:bp+6] + pop word [number_vm] + mov word [preboot_graph],bp ;save choose + + jmp .d + +.change_b: + _setcursor 15,0 +; mov si, ask_dma +; call print +; mov bx, '13' +; call getkey +; mov [preboot_dma], al + mov si, ask_bd + call print + mov bx, '12' + call getkey + mov [preboot_biosdisk], al + _setcursor 11,0 + jmp .d +.change_c: + _setcursor 15,0 + mov si, vrrmprint + call print + mov bx, '12' + call getkey + mov [preboot_vrrm], al + _setcursor 12,0 + jmp .d +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.say_on_off: + pushf + call print + mov si, on_msg + popf + jz @f + mov si, off_msg +@@: jmp printplain +; novesa and vervesa strings are not used at the moment of executing this code +virtual at novesa +.oldtimer dd ? +.starttime dd ? +.bSettingsChanged db ? +.timer dd ? +end virtual +.loader_block dd -1 +.gettime: + mov ah, 0 + int 1Ah + xchg ax, cx + shl eax, 10h + xchg ax, dx + ret +.newtimer: + push ds + push cs + pop ds + pushf + call [.oldtimer] + pushad + call .gettime + sub eax, [.starttime] + sub ax, 18*5 + jae .timergo + neg ax + add ax, 18-1 + mov bx, 18 + xor dx, dx + div bx +if lang eq ru +; Ї®¤®¦¤ЁвҐ 5 ᥪ㭤, 4/3/2 ᥪ㭤л, 1 ᥪ㭤г + cmp al, 5 + mov cl, ' ' + jae @f + cmp al, 1 + mov cl, 'г' + jz @f + mov cl, 'л' +@@: mov [time_str+9], cl +else if lang eq et + cmp al, 1 + ja @f + mov [time_str+9], ' ' + mov [time_str+10],' ' +@@: +else +; wait 5/4/3/2 seconds, 1 second + cmp al, 1 + mov cl, 's' + ja @f + mov cl, ' ' +@@: mov [time_str+9], cl +end if + add al, '0' + mov [time_str+1], al + mov si, time_msg + _setcursor 7,0 + call print + _setcursor 25,0 + popad + pop ds + iret +.timergo: + push 0 + pop es + mov eax, [.oldtimer] + mov [es:8*4], eax + mov sp, 0EC00h +.continue: + sti + _setcursor 6,0 + mov si, space_msg + call printplain + call printplain + _setcursor 6,0 + mov si, loading_msg + call print + _setcursor 15,0 + cmp [.bSettingsChanged], 0 + jz .load + cmp [.loader_block], -1 + jz .load + les bx, [.loader_block] + mov eax, [es:bx+3] + push ds + pop es + test eax, eax + jz .load + push eax + mov si, save_quest + call print +.waityn: + mov ah, 0 + int 16h + or al, 20h + cmp al, 'n' + jz .loadc + cmp al, 'y' + jnz .waityn + call putchar + mov byte [space_msg+80], 186 + + pop eax + push cs + push .cont + push eax + retf ;call back +.loadc: + pop eax +.cont: + push cs + pop ds + mov si, space_msg + mov byte [si+80], 0 + _setcursor 15,0 + call printplain + _setcursor 15,0 +.load: +; \end{diamond}[02.12.2005] + +; ASK GRAPHICS MODE + + call set_vmode + +; GRAPHICS ACCELERATION +; force yes + mov [es:0x901C], byte 1 + +; DMA ACCESS TO HD + + mov al, [preboot_dma] + mov [es:0x901F], al + +; VRR_M USE + + mov al,[preboot_vrrm] + mov [es:0x9030], al + mov [es:0x901E], byte 1 + +; BOOT DEVICE + + mov al, [preboot_device] + dec al + mov [boot_dev], al + +; GET MEMORY MAP +include 'detect/biosmem.inc' + +; READ DISKETTE TO MEMORY + + cmp [boot_dev],0 + jne no_sys_on_floppy + mov si,diskload + call print + xor ax, ax ; reset drive + xor dx, dx + int 0x13 +; do we boot from CD-ROM? + mov ah, 41h + mov bx, 55AAh + xor dx, dx + int 0x13 + jc .nocd + cmp bx, 0AA55h + jnz .nocd + mov ah, 48h + push ds + push es + pop ds + mov si, 0xa000 + mov word [si], 30 + int 0x13 + pop ds + jc .nocd + push ds + lds si, [es:si+26] + test byte [ds:si+10], 40h + pop ds + jz .nocd +; yes - read all floppy by 18 sectors + +; TODO: !!!! read only first sector and set variables !!!!! +; ... +; TODO: !!! then read flippy image track by track + + mov cx, 0x0001 ; startcyl,startsector +.a1: + push cx dx + mov al, 18 + mov bx, 0xa000 + call boot_read_floppy + mov si, movedesc + push es + push ds + pop es + mov cx, 256*18 + mov ah, 0x87 + int 0x15 + pop es + pop dx cx + test ah, ah + jnz sayerr_floppy + add dword [si+8*3+2], 512*18 + inc dh + cmp dh, 2 + jnz .a1 + mov dh, 0 + inc ch + cmp ch, 80 + jae ok_sys_on_floppy + pusha + mov al, ch + shr ch, 2 + add al, ch + aam + xchg al, ah + add ax, '00' + mov si, pros + mov [si], ax + call printplain + popa + jmp .a1 +.nocd: +; no - read only used sectors from floppy +; now load floppy image to memory +; at first load boot sector and first FAT table + +; read only first sector and fill variables + mov cx, 0x0001 ; first logical sector + xor dx, dx ; head = 0, drive = 0 (a:) + mov al, 1 ; read one sector + mov bx, 0xB000 ; es:bx -> data area + call boot_read_floppy +; fill the necessary parameters to work with a floppy + mov ax, word [es:bx+24] + mov word [BPB_SecPerTrk], ax + mov ax, word [es:bx+26] + mov word [BPB_NumHeads], ax + mov ax, word [es:bx+17] + mov word [BPB_RootEntCnt], ax + mov ax, word [es:bx+14] + mov word [BPB_RsvdSecCnt], ax + mov ax, word [es:bx+19] + mov word [BPB_TotSec16], ax + mov al, byte [es:bx+13] + mov byte [BPB_SecPerClus], al + mov al, byte [es:bx+16] + mov byte [BPB_NumFATs], al +; 18.11.2008 + mov ax, word [es:bx+22] + mov word [BPB_FATSz16], ax + mov cx, word [es:bx+11] + mov word [BPB_BytsPerSec], cx + +; count of clusters in FAT12 ((size_of_FAT*2)/3) +; mov ax, word [BPB_FATSz16] +; mov cx, word [BPB_BytsPerSec] +;end 18.11.2008 + xor dx, dx + mul cx + shl ax, 1 + mov cx, 3 + div cx ; now ax - number of clusters in FAT12 + mov word [end_of_FAT], ax + +; load first FAT table + mov cx, 0x0002 ; startcyl,startsector ; TODO!!!!! + xor dx, dx ; starthead,drive + mov al, byte [BPB_FATSz16] ; no of sectors to read + add bx, word [BPB_BytsPerSec] ; es:bx -> data area + call boot_read_floppy + mov bx, 0xB000 + +; and copy them to extended memory + mov si, movedesc + mov [si+8*2+3], bh ; from + + mov ax, word [BPB_BytsPerSec] + shr ax, 1 ; words per sector + mov cx, word [BPB_RsvdSecCnt] + add cx, word [BPB_FATSz16] + mul cx + push ax ; save to stack count of words in boot+FAT + xchg ax, cx + + push es + push ds + pop es + mov ah, 0x87 + int 0x15 + pop es + test ah, ah + jz @f +sayerr_floppy: + mov dx, 0x3f2 + mov al, 0 + out dx, al + mov si, memmovefailed + jmp sayerr_plain +@@: + pop ax ; restore from stack count of words in boot+FAT + shl ax, 1 ; make bytes count from count of words + and eax, 0ffffh + add dword [si+8*3+2], eax + +; copy first FAT to second copy +; TODO: BPB_NumFATs !!!!! + add bx, word [BPB_BytsPerSec] ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!! + mov byte [si+8*2+3], bh ; bx - begin of FAT + + mov ax, word [BPB_BytsPerSec] + shr ax, 1 ; words per sector + mov cx, word [BPB_FATSz16] + mul cx + mov cx, ax ; cx - count of words in FAT + + push es + push ds + pop es + mov ah, 0x87 + int 0x15 + pop es + test ah, ah + jnz sayerr_floppy + + mov ax, cx + shl ax, 1 + and eax, 0ffffh ; ax - count of bytes in FAT + add dword [si+8*3+2], eax + +; reading RootDir +; TODO: BPB_NumFATs + add bx, ax + add bx, 100h + and bx, 0ff00h ; bx - place in buffer to write RootDir + push bx + + mov bx, word [BPB_BytsPerSec] + shr bx, 5 ; divide bx by 32 + mov ax, word [BPB_RootEntCnt] + xor dx, dx + div bx + push ax ; ax - count of RootDir sectors + + mov ax, word [BPB_FATSz16] + xor cx, cx + mov cl, byte [BPB_NumFATs] + mul cx + add ax, word [BPB_RsvdSecCnt] ; ax - first sector of RootDir + + mov word [FirstDataSector], ax + pop bx + push bx + add word [FirstDataSector], bx ; Begin of data region of floppy + +; read RootDir + call conv_abs_to_THS + pop ax + pop bx ; place in buffer to write + push ax + call boot_read_floppy ; read RootDir into buffer +; copy RootDir + mov byte [si+8*2+3], bh ; from buffer + pop ax ; ax = count of RootDir sectors + mov cx, word [BPB_BytsPerSec] + mul cx + shr ax, 1 + mov cx, ax ; count of words to copy + push es + push ds + pop es + mov ah, 0x87 + int 0x15 + pop es + + mov ax, cx + shl ax, 1 + and eax, 0ffffh ; ax - count of bytes in RootDir + add dword [si+8*3+2], eax ; add count of bytes copied + +; Reading data clusters from floppy + mov byte [si+8*2+3], bh + push bx + + mov di, 2 ; First data cluster +.read_loop: + mov bx, di + shr bx, 1 ; bx+di = di*1.5 + jnc .even + test word [es:bx+di+0xB200], 0xFFF0 ; TODO: may not be 0xB200 !!! + jmp @f +.even: + test word [es:bx+di+0xB200], 0xFFF ; TODO: may not be 0xB200 !!! + +@@: + jz .skip +; read cluster di +;.read: + ;conv cluster di to abs. sector ax + ; ax = (N-2) * BPB_SecPerClus + FirstDataSector + mov ax, di + sub ax, 2 + xor bx, bx + mov bl, byte [BPB_SecPerClus] + mul bx + add ax, word [FirstDataSector] + call conv_abs_to_THS + pop bx + push bx + mov al, byte [BPB_SecPerClus] ; number of sectors in cluster + call boot_read_floppy + push es + push ds + pop es + pusha +; + mov ax, word [BPB_BytsPerSec] + xor cx, cx + mov cl, byte [BPB_SecPerClus] + mul cx + shr ax, 1 ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2 + mov cx, ax ; number of words to copy (count words in cluster) +; + mov ah, 0x87 + int 0x15 ; copy data + test ah, ah + popa + pop es + jnz sayerr_floppy +; skip cluster di +.skip: + mov ax, word [BPB_BytsPerSec] + xor cx, cx + mov cl, byte [BPB_SecPerClus] + mul cx + and eax, 0ffffh ; ax - count of bytes in cluster + add dword [si+8*3+2], eax + + mov ax, word [end_of_FAT] ; max cluster number + pusha +; draw percentage +; total clusters: ax +; read clusters: di + xchg ax, di + mov cx, 100 + mul cx + div di + aam + xchg al, ah + add ax, '00' + mov si, pros + cmp [si], ax + jz @f + mov [si], ax + call printplain +@@: + popa + inc di + cmp di, word [end_of_FAT] ; max number of cluster + jnz .read_loop + pop bx ; clear stack + +ok_sys_on_floppy: + mov si, backspace2 + call printplain + mov si, okt + call printplain +no_sys_on_floppy: + xor ax, ax ; reset drive + xor dx, dx + int 0x13 + mov dx, 0x3f2 ; floppy motor off + mov al, 0 + out dx, al + + +; SET GRAPHICS + + xor ax, ax + mov es, ax + + mov ax, [es:0x9008] ; vga & 320x200 + mov bx, ax + cmp ax, 0x13 + je setgr + cmp ax, 0x12 + je setgr + mov ax, 0x4f02 ; Vesa +setgr: + int 0x10 + test ah, ah + mov si, fatalsel + jnz v_mode_error +; set mode 0x12 graphics registers: + cmp bx, 0x12 + jne gmok2 + + mov al, 0x05 + mov dx, 0x03ce + push dx + out dx, al ; select GDC mode register + mov al, 0x02 + inc dx + out dx, al ; set write mode 2 + + mov al, 0x02 + mov dx, 0x03c4 + out dx, al ; select VGA sequencer map mask register + mov al, 0x0f + inc dx + out dx, al ; set mask for all planes 0-3 + + mov al, 0x08 + pop dx + out dx, al ; select GDC bit mask register + ; for writes to 0x03cf +gmok2: + push ds + pop es diff --git a/kernel/tags/kolibri0.7.7.0/boot/booteng.inc b/kernel/tags/kolibri0.7.7.0/boot/booteng.inc new file mode 100644 index 000000000..4c14a2d2e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/booteng.inc @@ -0,0 +1,110 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +$Revision$ + + +d80x25_bottom: + db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +msg_apm db " APM x.x ", 0 +vervesa db "Version of Vesa: Vesa x.x",13,10,0 +novesa db "Display: EGA/CGA",13,10,0 +s_vesa db "Version of VESA: " + .ver db "?.?",13,10,0 + +gr_mode db "Select a videomode: ",13,10,0 +;s_bpp db 13,10,186," ѓ«гЎЁ­  梥в : " +; .bpp dw "??" +; db 13,10,0 + +vrrmprint db "Apply VRR? (picture frequency greater than 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0 + + +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 + +bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-use preloaded ram-image from kernel restart;" + db 13,10,186," " + db "4-create blank image]: ",0 +probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, " + db "2-probe bios (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fatal - Videomode not found.",0 +;modena db "Fatal - VBE 0x112+ required.",0 +not386 db "Fatal - CPU 386+ required.",0 +btns db "Fatal - Can't determine color depth.",0 +fatalsel db "Fatal - Graphics mode not supported by hardware.",0 +pres_key db "Press any key to choose a new videomode.",0 +badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loading diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0 +time_msg db " or wait " +time_str db " 5 seconds" + db " before automatical continuation",13,10,0 +current_cfg_msg db "Current settings:",13,10,0 +curvideo_msg db " [a] Videomode: ",0 + +;modes_msg dw mode4,mode1,mode2,mode3 +;modevesa20 db " with LFB",0 +;modevesa12 db ", VESA 1.2 Bnk",0 +mode0 db "320x200, EGA/CGA 256 colors",13,10,0 +mode9 db "640x480, VGA 16 colors",13,10,0 + +;probeno_msg db " (standard mode)",0 +;probeok_msg db " (check nonstandard modes)",0 +;dma_msg db " [b] Use DMA for HDD access:",0 +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " on",13,10,0 +off_msg db " off",13,10,0 +;readonly_msg db " only for reading",13,10,0 +vrrm_msg db " [c] Use VRR:",0 +preboot_device_msg db " [d] Floppy image: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "real floppy",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "use already loaded image",13,10,0 +pdm4 db "create blank image",13,10,0 +loading_msg db "Loading KolibriOS...",0 +save_quest db "Remember current settings? [y/n]: ",0 +loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 + +_st db 186,' ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї',13,10,0 +_r1 db 186,' і 320x200 EGA/CGA 256 colors і і',13,10,0 +_r2 db 186,' і 640x480 VGA 16 colors і і',13,10,0 +_rs db 186,' і ????x????@?? SVGA VESA і і',13,10,0 +_bt db 186,' АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ',13,10,0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/boot/bootet.inc b/kernel/tags/kolibri0.7.7.0/boot/bootet.inc new file mode 100644 index 000000000..414efdf38 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/bootet.inc @@ -0,0 +1,115 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +$Revision$ + + +d80x25_bottom: + db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Ekraan: EGA/CGA",13,10,0 +vervesa db "Vesa versioon: Vesa x.x",13,10,0 +vervesa_off=20 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 vдrvi: [9] 320x200, " + db "VGA 16 vдrvi: [0] 640x480",13,10 + db 186," Vali reziim: ",0 +bt24 db "Bitti pikseli kohta: 24",13,10,0 +bt32 db "Bitti pikseli kohta: 32",13,10,0 +vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" + db " ainult:",13,10 + db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 +;askmouse db " Hiir:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Vali port [1-3]: ",0 +;no_com1 db 13,10,186, " No COM1 mouse",0 +;no_com2 db 13,10,186, " No COM2 mouse",0 +;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0 +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 +;gr_direct db 186," Use direct LFB writing? " +; db "[1-yes/2-no] ? ",0 +;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Paigalda mдluketas [1-diskett; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-kasuta eellaaditud mдluketast kerneli restardist;" + db 13,10,186," " + db "4-loo tьhi pilt]: ",0 +probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, " + db "2-leia biosist (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 +;modena db "Fataalne - VBE 0x112+ on vajalik.",0 +not386 db "Fataalne - CPU 386+ on vajalik.",0 +btns db "Fataalne - Ei suuda vдrvisьgavust mддratleda.",0 +fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 +badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 +memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaхnnestus.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loen disketti: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jдtkamiseks",13,10,0 +time_msg db " vхi oota " +time_str db " 5 sekundit" + db " automaatseks jдtkamiseks",13,10,0 +current_cfg_msg db "Praegused seaded:",13,10,0 +curvideo_msg db " [a] Videoreziim: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4,mode1,mode2,mode3 +modevesa20 db " koos LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 vдrvi",0 +mode10 db "640x480, VGA 16 vдrvi",0 +probeno_msg db " (standard reziim)",0 +probeok_msg db " (kontrolli ebastandardseid reziime)",0 +;dma_msg db " [b] Kasuta DMA'd HDD juurdepддsuks:",0 +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " sees",13,10,0 +off_msg db " vдljas",13,10,0 +;readonly_msg db " ainult lugemiseks",13,10,0 +vrrm_msg db " [c] Kasuta VRR:",0 +preboot_device_msg db " [d] Disketi kujutis: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "reaalne diskett",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "kasuta juba laaditud kujutist",13,10,0 +pdm4 db "loo tьhi pilt",13,10,0 +loading_msg db "Laadin KolibriOS...",0 +save_quest db "Jдta meelde praegused seaded? [y/n]: ",0 +loader_block_error db "Alglaaduri andmed vigased, ei saa jдtkata. Peatatud.",0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/boot/bootge.inc b/kernel/tags/kolibri0.7.7.0/boot/bootge.inc new file mode 100644 index 000000000..2ea4959f1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/bootge.inc @@ -0,0 +1,120 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +$Revision$ + + +d80x25_bottom: +; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' +; db 'NO WARRANTY ',186 +; db 186,' See file COPYING for details ' +; db ' ',186 + + db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' + db ' Garantie vertrieben ',186 + db 186,' Details stehen in der Datei COPYING ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Anzeige: EGA/CGA ",13,10,0 +vervesa db "Vesa-Version: Vesa ",13,10,0 +vervesa_off=22 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 Farben: [9] 320x200, " + db "VGA 16 Farben: [0] 640x480",13,10 + db 186," Waehle Modus: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",13,10,0 +vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 +;askmouse db " Maus angeschlossen an:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Waehle Port [1-3]: ",0 +;no_com1 db 13,10,186, " Keine COM1 Maus",0 +;no_com2 db 13,10,186, " Keine COM2 Maus",0 +;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0 +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 +;gr_direct db 186," Benutze direct LFB? " +; db "[1-ja/2-nein] ? ",0 +;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-benutze ein bereits geladenes Kernel image;" + db 13,10,186," " + db "4-create blank image]: ",0 +probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, " + db "2-BIOS Test (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fatal - Videomodus nicht gefunden.",0 +;modena db "Fatal - VBE 0x112+ required.",0 +not386 db "Fatal - CPU 386+ benoetigt.",0 +btns db "Fatal - konnte Farbtiefe nicht erkennen.",0 +fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0 +badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Lade Diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0 +time_msg db " oder warte " +time_str db " 5 Sekunden" + db " bis zum automatischen Start",13,10,0 +current_cfg_msg db "Aktuelle Einstellungen:",13,10,0 +curvideo_msg db " [a] Videomodus: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4,mode1,mode2,mode3 +modevesa20 db " mit LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 colors",0 +mode10 db "640x480, VGA 16 colors",0 +probeno_msg db " (Standard Modus)",0 +probeok_msg db " (teste nicht-standard Modi)",0 +;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0 +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " an",13,10,0 +off_msg db " aus",13,10,0 +;readonly_msg db " fur Lesen",13,10,0 +vrrm_msg db " [c] Nutze VRR:",0 +preboot_device_msg db " [d] Diskettenimage: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "Echte Diskette",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "Nutze bereits geladenes Image",13,10,0 +pdm4 db "create blank image",13,10,0 +loading_msg db "Lade KolibriOS...",0 +save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 +loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/boot/bootru.inc b/kernel/tags/kolibri0.7.7.0/boot/bootru.inc new file mode 100644 index 000000000..4e85269a6 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/bootru.inc @@ -0,0 +1,91 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;================================================================= +; +; BOOT DATA +; +;================================================================= + +$Revision$ + + +d80x25_bottom: + db 186,' Kolibri OS ®б­®ў ­  ­  Menuet OS Ё ­Ґ ЇаҐ¤®бв ў«пҐв ' + db '­ЁЄ ЄЁе Ј аa­вЁ©. ',186 + db 186,' Џ®¤а®Ў­ҐҐ ᬮваЁвҐ ў д ©«Ґ COPYING.TXT ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +msg_apm db " APM x.x ", 0 +novesa db "‚Ё¤Ґ®Є ав : EGA/CGA",13,10,0 +s_vesa db "‚ҐабЁп VESA: " + .ver db "?.?",13,10,0 + +gr_mode db "‚лЎҐаЁвҐ ўЁ¤Ґ®аҐ¦Ё¬: ",13,10,0 +vrrmprint db "€бЇ®«м§®ў вм VRR? (з бв®в  Є ¤а®ў ўлиҐ 60 ѓж" + db " в®«мЄ® ¤«п ЇҐаҐе®¤®ў:",13,10 + db 186," 1024*768>800*600 Ё 800*600>640*480) [1-¤ , 2-­Ґв]: ",0 +;ask_dma db "€бЇ®«м§®ў вм DMA ¤«п ¤®бвгЇ  Є HDD? [1-¤ , 2-в®«мЄ® з⥭ЁҐ, 3-­Ґв]: ",0 +ask_bd db "„®Ў ўЁвм ¤ЁбЄЁ, ўЁ¤Ё¬лҐ зҐаҐ§ BIOS ў ०Ё¬Ґ V86? [1-¤ , 2-­Ґв]: ",0 +bdev db "‡ Јаг§Ёвм ®Ўа § Ё§ [1-¤ЁбЄҐв ; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §;" + db 13,10,186," " + db "4-б®§¤ вм зЁбвл© ®Ўа §]: ",0 +prnotfnd db "ЋиЁЎЄ  - ‚Ё¤Ґ®аҐ¦Ё¬ ­Ґ ­ ©¤Ґ­.",0 +not386 db "ЋиЁЎЄ  - ’ॡгҐвбп Їа®жҐбб®а 386+.",0 +fatalsel db "ЋиЁЎЄ  - ‚лЎа ­­л© ўЁ¤Ґ®аҐ¦Ё¬ ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп.",0 +pres_key db "Ќ ¦Ё¬ЁвҐ «оЎго Є« ўЁиг, ¤«п ЇҐаҐе®¤  ў ўлЎ®а ०Ё¬®ў.",0 +badsect db 13,10,186," ЋиЁЎЄ  - „ЁбЄҐв  Ї®ўаҐ¦¤Ґ­ . Џ®Їа®Ўг©вҐ ¤агЈго.",0 +memmovefailed db 13,10,186," ЋиЁЎЄ  - Int 0x15 move failed.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "‡ Јаг§Є  ¤ЁбЄҐвл: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 +start_msg db "Ќ ¦¬ЁвҐ [abcd] ¤«п Ё§¬Ґ­Ґ­Ёп ­ бв஥Є, [Enter] ¤«п Їа®¤®«¦Ґ­Ёп § Јаг§ЄЁ",13,10,0 +time_msg db " Ё«Ё Ї®¤®¦¤ЁвҐ " +time_str db " 5 ᥪ㭤 " + db " ¤®  ўв®¬ вЁзҐбЄ®Ј® Їа®¤®«¦Ґ­Ёп",13,10,0 +current_cfg_msg db "’ҐЄгйЁҐ ­ бва®©ЄЁ:",13,10,0 +curvideo_msg db " [a] ‚Ё¤Ґ®аҐ¦Ё¬: ",0 + + +mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0 +mode9 db "640x480, VGA 16 梥⮢",13,10,0 + +usebd_msg db " [b] „®Ў ўЁвм ¤ЁбЄЁ, ўЁ¤Ё¬лҐ зҐаҐ§ BIOS:",0 +on_msg db " ўЄ«",13,10,0 +off_msg db " ўлЄ«",13,10,0 +readonly_msg db " в®«мЄ® з⥭ЁҐ",13,10,0 +vrrm_msg db " [c] €бЇ®«м§®ў ­ЁҐ VRR:",0 +preboot_device_msg db " [d] ЋЎа § ¤ЁбЄҐвл: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4 +pdm1 db "­ бв®пй п ¤ЁбЄҐв ",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §",13,10,0 +pdm4 db "б®§¤ вм зЁбвл© ®Ўа §",13,10,0 +loading_msg db "€¤св § Јаг§Є  KolibriOS...",0 +save_quest db "‡ Ї®¬­Ёвм ⥪гйЁҐ ­ бва®©ЄЁ? [y/n]: ",0 +loader_block_error db "ЋиЁЎЄ  ў ¤ ­­ле ­ з «м­®Ј® § Јаг§зЁЄ , Їа®¤®«¦Ґ­ЁҐ ­Ґў®§¬®¦­®.",0 + + +_st db 186,' ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї ',13,10,0 +_r1 db 186,' і 320x200 EGA/CGA 256 梥⮢ і і ',13,10,0 +_r2 db 186,' і 640x480 VGA 16 梥⮢ і і ',13,10,0 +_rs db 186,' і ????x????@?? SVGA VESA і і ',13,10,0 +_bt db 186,' АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ ',13,10,0 + + +remark1 db "‡­ зҐ­Ёп Ї® 㬮«з ­Ёо ўлЎа ­л ¤«п 㤮Ўбвў  Ў®«миЁ­бвў , ­® ­Ґ ўбҐе.",0 +remark2 db "…б«Ё г ‚ б ќ‹’-¬®­Ёв®а, ўЄ«озЁвҐ VRR ў Їг­ЄвҐ [c].",0 +remark3 db "…б«Ё г ‚ б ­Ґ Јаг§Ёвбп бЁб⥬ , Ї®Їа®Ўг©вҐ ®вЄ«озЁвм Їг­Єв [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/boot/bootstr.inc b/kernel/tags/kolibri0.7.7.0/boot/bootstr.inc new file mode 100644 index 000000000..bf71fb7a9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/bootstr.inc @@ -0,0 +1,62 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; boot data: common strings (for all languages) +macro line_full_top { + db 201 + times 78 db 205 + db 187 +} +macro line_full_bottom { + db 200 + times 78 db 205 + db 188 +} +macro line_half { + db 186,' ' + times 76 db 0xc4 + db ' ',186 +} +macro line_space { + db 186 + times 78 db 32 + db 186 +} +d80x25_top: + line_full_top +cur_line_pos = 75 + store byte ' ' at d80x25_top+cur_line_pos+1 +rev_var = __REV__ +while rev_var > 0 + store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos + cur_line_pos = cur_line_pos - 1 + rev_var = rev_var / 10 +end while + store byte ' ' at d80x25_top+cur_line_pos + store dword ' SVN' at d80x25_top+cur_line_pos-4 + +space_msg: line_space +verstr: +; line_space +; version string + db 186,32 + repeat 78 + load a byte from version+%-1 + if a = 13 + break + end if + db a + end repeat + repeat 78 - ($-verstr) + db ' ' + end repeat + db 32,186 + line_half +d80x25_top_num = 4 diff --git a/kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc b/kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc new file mode 100644 index 000000000..aaef71888 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/bootvesa.inc @@ -0,0 +1,755 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +struc VBE_VGAInfo { + .VESASignature dd ? ; char + .VESAVersion dw ? ; short + .OemStringPtr dd ? ; char * + .Capabilities dd ? ; ulong + .VideoModePtr dd ? ; ulong + .TotalMemory dw ? ; short + ; VBE 2.0+ + .OemSoftwareRev db ? ; short + .OemVendorNamePtr dw ? ; char * + .OemProductNamePtr dw ? ; char * + .OemProductRevPtr dw ? ; char * + .reserved rb 222 ; char + .OemData rb 256 ; char +} + +struc VBE_ModeInfo { + .ModeAttributes dw ? ; short + .WinAAttributes db ? ; char + .WinBAttributes db ? ; char + .WinGranularity dw ? ; short + .WinSize dw ? ; short + .WinASegment dw ? ; ushort + .WinBSegment dw ? ; ushort + .WinFuncPtr dd ? ; void * + .BytesPerScanLine dw ? ; short + .XRes dw ? ; short + .YRes dw ? ; short + .XCharSize db ? ; char + .YCharSize db ? ; char + .NumberOfPlanes db ? ; char + .BitsPerPixel db ? ; char + .NumberOfBanks db ? ; char + .MemoryModel db ? ; char + .BankSize db ? ; char + .NumberOfImagePages db ? ; char + .res1 db ? ; char + .RedMaskSize db ? ; char + .RedFieldPosition db ? ; char + .GreenMaskSize db ? ; char + .GreenFieldPosition db ? ; char + .BlueMaskSize db ? ; char + .BlueFieldPosition db ? ; char + .RsvedMaskSize db ? ; char + .RsvedFieldPosition db ? ; char + .DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE + ; VBE 2.0+ + .PhysBasePtr dd ? ; ulong + .OffScreenMemOffset dd ? ; ulong + .OffScreenMemSize dw ? ; short + ; VBE 3.0+ + .LinbytesPerScanLine dw ? ; short + .BankNumberOfImagePages db ? ; char + .LinNumberOfImagePages db ? ; char + .LinRedMaskSize db ? ; char + .LinRedFieldPosition db ? ; char + .LingreenMaskSize db ? ; char + .LinGreenFieldPosition db ? ; char + .LinBlueMaskSize db ? ; char + .LinBlueFieldPosition db ? ; char + .LinRsvdMaskSize db ? ; char + .LinRsvdFieldPosition db ? ; char + .MaxPixelClock dd ? ; ulong + .res2 rb 190 ; char +} + +virtual at $A000 + vi VBE_VGAInfo + mi VBE_ModeInfo +modes_table: +end virtual +cursor_pos dw 0 ;временное хранение курсора. +home_cursor dw 0 ;current shows rows a table +end_cursor dw 0 ;end of position current shows rows a table +scroll_start dw 0 ;start position of scroll bar +scroll_end dw 0 ;end position of scroll bar +long_v_table equ 9 ;long of visible video table +size_of_step equ 10 +scroll_area_size equ (long_v_table-2) +int2str: + dec bl + jz @f + xor edx,edx + div ecx + push edx + call int2str + pop eax + @@: or al,0x30 + mov [ds:di],al + inc di + ret + +int2strnz: + cmp eax,ecx + jb @f + xor edx,edx + div ecx + push edx + call int2strnz + pop eax + @@: or al,0x30 + mov [es:di],al + inc di + ret + +;------------------------------------------------------- +;Write message about incorrect v_mode and write message about jmp on swith v_mode +v_mode_error: + _setcursor 19,2 + mov si, fatalsel + call printplain + _setcursor 20,2 + mov si,pres_key + call printplain + xor eax,eax + int 16h + jmp cfgmanager.d +;------------------------------------------------------- +; + + + +;------------------------------------------------------- +print_vesa_info: + _setcursor 5,2 + + mov [es:vi.VESASignature],'VBE2' + mov ax,0x4F00 + mov di,vi ;0xa000 + int 0x10 + or ah,ah + jz @f + mov [es:vi.VESASignature],'VESA' + mov ax,$4F00 + mov di,vi + int 0x10 + or ah,ah + jnz .exit + @@: + cmp [es:vi.VESASignature],'VESA' + jne .exit + cmp [es:vi.VESAVersion],0x0100 + jb .exit + jmp .vesaok2 + + .exit: + mov si,novesa + call printplain + ret + + .vesaok2: + mov ax,[es:vi.VESAVersion] + add ax,'00' + + mov [s_vesa.ver], ah + mov [s_vesa.ver+2], al + mov si,s_vesa + call printplain + + _setcursor 4,2 + mov si,word[es:vi.OemStringPtr] + mov di,si + + push ds + mov ds,word[es:vi.OemStringPtr+2] + call printplain + pop ds + + ret +;----------------------------------------------------------------------------- + +calc_vmodes_table: + pushad + +; push 0 +; pop es + + lfs si, [es:vi.VideoModePtr] + + mov bx,modes_table +;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢ + mov word [es:bx],640 + mov word [es:bx+2],480 + mov word [es:bx+6],0x13 + + mov word [es:bx+10],640 + mov word [es:bx+12],480 + mov word [es:bx+16],0x12 + add bx,20 + .next_mode: + mov cx,word [fs:si] ; mode number + cmp cx,-1 + je .modes_ok.2 + + mov ax,0x4F01 + mov di,mi + int 0x10 + + or ah,ah + jnz .modes_ok.2;vesa_info.exit + + test [es:mi.ModeAttributes],00000001b ;videomode support ? + jz @f + test [es:mi.ModeAttributes],00010000b ;picture ? + jz @f + test [es:mi.ModeAttributes],10000000b ;LFB ? + jz @f + + cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp + jb @f + +; cmp [es:mi.BitsPerPixel],16 +; jne .l0 +; cmp [es:mi.GreenMaskSize],5 +; jne .l0 +; mov [es:mi.BitsPerPixel],15 + + +.l0: + cmp [es:mi.XRes],640 + jb @f + cmp [es:mi.YRes],480 + jb @f +; cmp [es:mi.BitsPerPixel],8 +; jb @f + + mov ax,[es:mi.XRes] + mov [es:bx+0],ax ; +0[2] : resolution X + mov ax,[es:mi.YRes] + mov [es:bx+2],ax ; +2[2] : resolution Y + mov ax,[es:mi.ModeAttributes] + mov [es:bx+4],ax ; +4[2] : attributes + + cmp [s_vesa.ver],'2' + jb .lp1 + + or cx,0x4000 ; use LFB +.lp1: mov [es:bx+6],cx ; +6 : mode number + movzx ax,byte [es:mi.BitsPerPixel] + mov word [es:bx+8],ax ; +8 : bits per pixel + add bx,size_of_step ; size of record + + @@: + add si,2 + jmp .next_mode + + .modes_ok.2: + + mov word[es:bx],-1 ;end video table + mov word[end_cursor],bx ;save end cursor position +;;;;;;;;;;;;;;;;;; +;Sort array +; mov si,modes_table +;.new_mode: +; mov ax,word [es:si] +; cmp ax,-1 +; je .exxit +; add ax,word [es:si+2] +; add ax,word [es:si+8] +; mov bp,si +;.again: +; add bp,12 +; mov bx,word [es:bp] +; cmp bx,-1 +; je .exit +; add bx,word [es:bp+2] +; add bx,word [es:bp+8] +; +; cmp ax,bx +; ja .loops +; jmp .again +;.loops: +; push dword [es:si] +; push dword [es:si+4] +; push dword [es:si+8] +; push dword [es:bp] +; push dword [es:bp+4] +; push dword [es:bp+8] +; +; pop dword [es:si+8] +; pop dword [es:si+4] +; pop dword [es:si] +; pop dword [es:bp+8] +; pop dword [es:bp+4] +; pop dword [es:bp] +; jmp .new_mode +; +;.exit: add si,12 +; jmp .new_mode +;.exxit: + popad + ret + +;----------------------------------------------------------------------------- + +draw_current_vmode: + push 0 + pop es + + mov si,word [cursor_pos] + + cmp word [es:si+6],0x12 + je .no_vesa_0x12 + + cmp word [es:si+6],0x13 + je .no_vesa_0x13 + + mov di,loader_block_error + movzx eax,word[es:si+0] + mov ecx,10 + call int2strnz + mov byte[es:di],'x' + inc di + movzx eax,word[es:si+2] + call int2strnz + mov byte[es:di],'x' + inc di + movzx eax,word[es:si+8] + call int2strnz + mov dword[es:di],0x00000d0a + mov si,loader_block_error + push ds + push es + pop ds + call printplain + pop ds + ret +.no_vesa_0x13: + mov si,mode0 + jmp .print +.no_vesa_0x12: + mov si,mode9 +.print: + call printplain + ret +;----------------------------------------------------------------------------- +check_first_parm: + mov si,word [preboot_graph] + test si,si + jnz .no_zero ;if no zero +.zerro: +; mov ax,modes_table +; mov word [cursor_pos],ax +; mov word [home_cursor],ax +; mov word [preboot_graph],ax +;SET default video of mode first probe will fined a move of work 1024x768@32 + + mov ax,1024 + mov bx,768 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + mov ax,800 + mov bx,600 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + mov ax,640 + mov bx,480 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + + mov si,modes_table + jmp .ok_found_mode + + + +.no_zero: + mov bp,word [number_vm] + cmp bp,word [es:si+6] + jz .ok_found_mode + mov ax,word [x_save] + mov bx,word [y_save] + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + + mov si,modes_table +; cmp ax,modes_table +; jb .zerro ;check on correct if bellow +; cmp ax,word [end_cursor] +; ja .zerro ;check on correct if anymore + +.ok_found_mode: + mov word [home_cursor],si +; mov word [cursor_pos],si + mov word [preboot_graph],si + mov ax,si + + mov ecx,long_v_table + +.loop: add ax,size_of_step + cmp ax,word [end_cursor] + jae .next_step + loop .loop +.next_step: + sub ax,size_of_step*long_v_table + cmp ax,modes_table + jae @f + mov ax,modes_table +@@: + + mov word [home_cursor],ax + mov si,[preboot_graph] + mov word [cursor_pos],si + + push word [es:si] + pop word [x_save] + push word [es:si+2] + pop word [y_save] + push word [es:si+6] + pop word [number_vm] + + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;; +.loops: + cmp ax,word [es:si] + jne .next + cmp bx,word [es:si+2] + jne .next + cmp word [es:si+8],32 + je .ok + cmp word [es:si+8],24 + je .ok +.next: add si,size_of_step + cmp word [es:si],-1 + je .exit + jmp .loops +.ok: xor ax,ax + ret +.exit: or ax,-1 + ret + + +;----------------------------------------------------------------------------- + +;default_vmode: + +;----------------------------------------------------------------------------- +draw_vmodes_table: + _setcursor 9, 2 + mov si,gr_mode + call printplain + + mov si,_st + call printplain + + push word [cursor_pos] + pop ax + push word [home_cursor] + pop si + mov cx,si + + cmp ax,si + je .ok + jb .low + + + add cx,size_of_step*long_v_table + + cmp ax,cx + jb .ok + + sub cx,size_of_step*long_v_table + add cx,size_of_step + cmp cx,word[end_cursor] + jae .ok + add si,size_of_step + push si + pop word [home_cursor] + jmp .ok + + +.low: sub cx,size_of_step + cmp cx,modes_table + jb .ok + push cx + push cx + pop word [home_cursor] + pop si + + +.ok: +; calculate scroll position + push si + mov ax, [end_cursor] + sub ax, modes_table + mov bx, size_of_step + cwd + div bx + mov si, ax ; si = size of list + mov ax, [home_cursor] + sub ax, modes_table + cwd + div bx + mov di, ax + mov ax, scroll_area_size*long_v_table + cwd + div si + test ax, ax + jnz @f + inc ax +@@: + cmp al, scroll_area_size + jb @f + mov al, scroll_area_size +@@: + mov cx, ax +; cx = scroll height +; calculate scroll pos + xor bx, bx ; initialize scroll pos + sub al, scroll_area_size+1 + neg al + sub si, long_v_table-1 + jbe @f + mul di + div si + mov bx, ax +@@: + inc bx + imul ax, bx, size_of_step + add ax, [home_cursor] + mov [scroll_start], ax + imul cx, size_of_step + add ax, cx + mov [scroll_end], ax + pop si + mov bp,long_v_table ;show rows +.@@_next_bit: +;clear cursor + mov ax,' ' + mov word[ds:_r1+21],ax + mov word[ds:_r1+50],ax + + mov word[ds:_r2+21],ax + mov word[ds:_r2+45],ax + + mov word[ds:_rs+21],ax + mov word[ds:_rs+46],ax +; draw string + cmp word [es:si+6],0x12 + je .show_0x12 + cmp word [es:si+6],0x13 + je .show_0x13 + + movzx eax,word[es:si] + cmp ax,-1 + je .@@_end + mov di,_rs+23 + mov ecx,10 + mov bl,4 + call int2str + movzx eax,word[es:si+2] + inc di + mov bl,4 + call int2str + + movzx eax,word[es:si+8] + inc di + mov bl,2 + call int2str + + cmp si, word [cursor_pos] + jne .next +;draw cursor + mov word[ds:_rs+21],'>>' + mov word[ds:_rs+46],'<<' + + + +.next: + push si + mov si,_rs +.@@_sh: +; add to the string pseudographics for scrollbar + pop bx + push bx + mov byte [si+53], ' ' + cmp bx, [scroll_start] + jb @f + cmp bx, [scroll_end] + jae @f + mov byte [si+53], 0xDB ; filled bar +@@: + push bx + add bx, size_of_step + cmp bx, [end_cursor] + jnz @f + mov byte [si+53], 31 ; 'down arrow' symbol +@@: + sub bx, [home_cursor] + cmp bx, size_of_step*long_v_table + jnz @f + mov byte [si+53], 31 ; 'down arrow' symbol +@@: + pop bx + cmp bx, [home_cursor] + jnz @f + mov byte [si+53], 30 ; 'up arrow' symbol +@@: + call printplain + pop si + add si,size_of_step + + dec bp + jnz .@@_next_bit + +.@@_end: + mov si,_bt + call printplain + ret +.show_0x13: + push si + + cmp si, word [cursor_pos] + jne @f + mov word[ds:_r1+21],'>>' + mov word[ds:_r1+50],'<<' +@@: + mov si,_r1 + jmp .@@_sh +.show_0x12: + push si + cmp si, word [cursor_pos] + jne @f + + mov word[ds:_r2+21],'>>' + mov word[ds:_r2+45],'<<' +@@: + mov si,_r2 + jmp .@@_sh + +;----------------------------------------------------------------------------- +;Clear arrea of current video page (0xb800) +clear_vmodes_table: + pusha + ; draw frames + push es + push 0xb800 + pop es + mov di,1444 + xor ax,ax + mov ah, 1*16+15 + mov cx,70 + mov bp,12 +.loop_start: + rep stosw + mov cx,70 + add di,20 + dec bp + jns .loop_start + pop es + popa + ret + +;----------------------------------------------------------------------------- + +set_vmode: + push 0 ;0;x1000 + pop es + + mov si,word [preboot_graph] ;[preboot_graph] + mov cx,word [es:si+6] ; number of mode + + + mov ax,word [es:si+0] ; resolution X + mov bx,word [es:si+2] ; resolution Y + + + mov word [es:0x900A],ax ; resolution X + mov word [es:0x900C],bx ; resolution Y + mov word [es:0x9008],cx ; number of mode + + cmp cx,0x12 + je .mode0x12_0x13 + cmp cx,0x13 + je .mode0x12_0x13 + + + cmp byte [s_vesa.ver],'2' + jb .vesa12 + +; VESA 2 and Vesa 3 + + mov ax,0x4f01 + and cx,0xfff + mov di,mi;0xa000 + int 0x10 + ; LFB + mov eax,[es:mi.PhysBasePtr];di+0x28] + mov [es:0x9018],eax + ; ---- vbe voodoo + BytesPerLine equ 0x10 + mov ax, [es:di+BytesPerLine] + mov [es:0x9001], ax + ; BPP + cmp [es:mi.BitsPerPixel],16 + jne .l0 + cmp [es:mi.GreenMaskSize],5 + jne .l0 + mov [es:mi.BitsPerPixel],15 +.l0: + mov al, byte [es:di+0x19] + mov [es:0x9000], al + jmp .exit + +.mode0x12_0x13: + mov byte [es:0x9000], 32 + or dword [es:0x9018], 0xFFFFFFFF; 0x800000 + + +; VESA 1.2 PM BANK SWITCH ADDRESS + +.vesa12: + + + mov ax,0x4f0A + xor bx,bx + int 0x10 + xor eax,eax + xor ebx,ebx + mov ax,es + shl eax,4 + mov bx,di + add eax,ebx + movzx ebx,word[es:di] + add eax,ebx + push 0x0000 + pop es + mov [es:0x9014],eax + .exit: + ret + + +; mov dword[es:0x9018],0x000A0000 +; ret + +;============================================================================= +;============================================================================= +;============================================================================= + diff --git a/kernel/tags/kolibri0.7.7.0/boot/et.inc b/kernel/tags/kolibri0.7.7.0/boot/et.inc new file mode 100644 index 000000000..83fc44f2b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/et.inc @@ -0,0 +1,16 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; Full ASCII code font +; only х and д added +; Kaitz +ET_FNT: + fontfile file "ETFONT.FNT" + diff --git a/kernel/tags/kolibri0.7.7.0/boot/preboot.inc b/kernel/tags/kolibri0.7.7.0/boot/preboot.inc new file mode 100644 index 000000000..036ba51c1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/preboot.inc @@ -0,0 +1,38 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +display_modechg db 0 ; display mode change for text, yes/no (0 or 2) + ; + ; !! Important note !! + ; + ; Must be set to 2, to avoid two screenmode + ; changes within a very short period of time. + +display_atboot db 0 ; show boot screen messages ( 2-no ) + +preboot_graph dw 0 ; graph mode +x_save dw 0 ; x +y_save dw 0 ; y +number_vm dw 0 ; +;pixel_save dw 0 ; per to pixel +preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes) +preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no) +preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never) +preboot_device db 0 ; boot device + ; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk) + ;!!!! 0 - autodetect !!!! +preboot_blogesc = 0 ; start immediately after bootlog +preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no) + + if $>0x200 +ERROR: prebooting parameters must fit in first sector!!! + end if +hdsysimage db 'KOLIBRI IMG' ; load from +image_save db 'KOLIBRI IMG' ; save to diff --git a/kernel/tags/kolibri0.7.7.0/boot/rdload.inc b/kernel/tags/kolibri0.7.7.0/boot/rdload.inc new file mode 100644 index 000000000..b9c9c9656 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/rdload.inc @@ -0,0 +1,125 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; READ RAMDISK IMAGE FROM HD + + cmp [boot_dev+OS_BASE+0x10000],1 + jne no_sys_on_hd + + test [DRIVE_DATA+1],byte 0x40 + jz position_2 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + mov [fat32part],0 + position_1_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+2] + cmp [fat32part],eax + jle position_1_1 + position_2: + test [DRIVE_DATA+1],byte 0x10 + jz position_3 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + mov [fat32part],0 + position_2_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+3] + cmp eax,[fat32part] + jle position_2_1 + position_3: + test [DRIVE_DATA+1],byte 0x4 + jz position_4 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + mov [fat32part],0 + position_3_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+4] + cmp eax,[fat32part] + jle position_3_1 + position_4: + test [DRIVE_DATA+1],byte 0x1 + jz no_sys_on_hd + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 + mov [fat32part],0 + position_4_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+5] + cmp eax,[fat32part] + jle position_4_1 + jmp yes_sys_on_hd + + search_and_read_image: + call set_FAT32_variables + mov edx, bootpath + call read_image + test eax, eax + jz image_present + mov edx, bootpath2 + call read_image + test eax, eax + jz image_present + ret + image_present: + mov [image_retrieved],1 + ret + +read_image: + mov eax, hdsysimage+OS_BASE+0x10000 + mov ebx, 1474560/512 + mov ecx, RAMDISK + mov esi, 0 + mov edi, 12 + call file_read + ret + +image_retrieved db 0 +counter_of_partitions db 0 +no_sys_on_hd: + ; test_to_format_ram_disk (need if not using ram disk) + cmp [boot_dev+OS_BASE+0x10000],3 + jne not_format_ram_disk + ; format_ram_disk + mov edi, RAMDISK + mov ecx, 0x1080 + xor eax,eax +@@: + stosd + loop @b + + mov ecx, 0x58F7F + mov eax,0xF6F6F6F6 +@@: + stosd + loop @b + + mov [RAMDISK+0x200],dword 0xFFFFF0 ; fat table + mov [RAMDISK+0x4200],dword 0xFFFFF0 + +not_format_ram_disk: +yes_sys_on_hd: diff --git a/kernel/tags/kolibri0.7.7.0/boot/ru.inc b/kernel/tags/kolibri0.7.7.0/boot/ru.inc new file mode 100644 index 000000000..aa59d6f6a --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/ru.inc @@ -0,0 +1,102 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; Generated by RUFNT.EXE +; By BadBugsKiller (C) +; Modifyed by BadBugsKiller 12.01.2004 17:45 +; Шрифт уменьшен в размере и теперь состоит из 2-ух частей, +; содержащих только символы русского алфавита. +; символы в кодировке ASCII (ДОС'овская), кодовая страница 866. +RU_FNT1: + db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + +RU_FNT2: + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/kernel/tags/kolibri0.7.7.0/boot/shutdown.inc b/kernel/tags/kolibri0.7.7.0/boot/shutdown.inc new file mode 100644 index 000000000..3e3679caf --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/boot/shutdown.inc @@ -0,0 +1,209 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Shutdown for Menuet ;; +;; ;; +;; Distributed under General Public License ;; +;; See file COPYING for details. ;; +;; Copyright 2003 Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +align 4 +pr_mode_exit: + +; setup stack + mov ax, 0x3000 + mov ss, ax + mov esp, 0x0EC00 +; setup ds + push cs + pop ds + + lidt [old_ints_h] +;remap IRQs + mov al,0x11 + out 0x20,al + call rdelay + out 0xA0,al + call rdelay + + mov al,0x08 + out 0x21,al + call rdelay + mov al,0x70 + out 0xA1,al + call rdelay + + mov al,0x04 + out 0x21,al + call rdelay + mov al,0x02 + out 0xA1,al + call rdelay + + mov al,0x01 + out 0x21,al + call rdelay + out 0xA1,al + call rdelay + + mov al,0xB8 + out 0x21,al + call rdelay + mov al,0xBD + out 0xA1,al + sti + +temp_3456: + xor ax,ax + mov es,ax + mov al,byte [es:0x9030] + cmp al,1 + jl nbw + cmp al,4 + jle nbw32 + +nbw: + in al,0x60 + cmp al,6 + jae nbw + mov bl,al +nbw2: + in al,0x60 + cmp al,bl + je nbw2 + cmp al,240 ;ax,240 + jne nbw31 + mov al,bl + dec ax + jmp nbw32 +nbw31: + add bl,128 + cmp al,bl + jne nbw + sub al,129 + +nbw32: + + dec ax + dec ax ; 2 = power off + jnz no_apm_off + call APM_PowerOff + jmp $ +no_apm_off: + + dec ax ; 3 = reboot + jnz restart_kernel ; 4 = restart kernel + push 0x40 + pop ds + mov word[0x0072],0x1234 + jmp 0xF000:0xFFF0 + + +rdelay: + ret + +APM_PowerOff: + mov ax, 5304h + xor bx, bx + int 15h +;!!!!!!!!!!!!!!!!!!!!!!!! + mov ax,0x5300 + xor bx,bx + int 0x15 + push ax + + mov ax,0x5301 + xor bx,bx + int 0x15 + + mov ax,0x5308 + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x530E + xor bx,bx + pop cx + int 0x15 + + mov ax,0x530D + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x530F + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x5307 + mov bx,1 + mov cx,3 + int 0x15 +;!!!!!!!!!!!!!!!!!!!!!!!! + ret + +restart_kernel: + + mov ax,0x0003 ; set text mode for screen + int 0x10 + jmp 0x4000:0000 + +restart_kernel_4000: + cli + + push ds + pop es + mov cx, 0x8000 + push cx + push 0x7000 + pop ds + xor si, si + xor di, di + rep movsw + pop cx + mov ds, cx + push 0x2000 + pop es + rep movsw + push 0x9000 + pop ds + push 0x3000 + pop es + mov cx, 0xE000/2 + rep movsw + + wbinvd ; write and invalidate cache + + mov al, 00110100b + out 43h, al + jcxz $+2 + mov al, 0xFF + out 40h, al + jcxz $+2 + out 40h, al + jcxz $+2 + sti + +; (hint by Black_mirror) +; We must read data from keyboard port, +; because there may be situation when previous keyboard interrupt is lost +; (due to return to real mode and IRQ reprogramming) +; and next interrupt will not be generated (as keyboard waits for handling) + in al, 0x60 + +; bootloader interface + push 0x1000 + pop ds + mov si, kernel_restart_bootblock + mov ax, 'KL' + jmp 0x1000:0000 + + diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/boot_fat12.asm b/kernel/tags/kolibri0.7.7.0/bootloader/boot_fat12.asm new file mode 100644 index 000000000..1c01e8e97 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/boot_fat12.asm @@ -0,0 +1,287 @@ +; FAT12 boot sector for Kolibri OS +; +; Copyright (C) Alex Nogueira Teixeira +; Copyright (C) Diamond +; Copyright (C) Dmitry Kartashov aka shurf +; +; Distributed under GPL, see file COPYING for details +; +; Version 1.0 + +lf equ 0ah +cr equ 0dh + +pos_read_tmp equ 0700h ;position for temporary read +boot_program equ 07c00h ;position for boot code +seg_read_kernel equ 01000h ;segment to kernel read + + jmp start_program + nop + +; Boot Sector and BPB Structure +include 'floppy1440.inc' +;include 'floppy2880.inc' +;include 'floppy1680.inc' +;include 'floppy1743.inc' + +start_program: + + xor ax,ax + mov ss,ax + mov sp,boot_program + push ss + pop ds + + ; print loading string + mov si,loading+boot_program +loop_loading: + lodsb + or al,al + jz read_root_directory + mov ah,0eh + mov bx,7 + int 10h + jmp loop_loading + +read_root_directory: + push ss + pop es + + ; calculate some disk parameters + ; - beginning sector of RootDir + mov ax,word [BPB_FATSz16+boot_program] + xor cx,cx + mov cl,byte [BPB_NumFATs+boot_program] + mul cx + add ax,word [BPB_RsvdSecCnt+boot_program] + mov word [FirstRootDirSecNum+boot_program],ax ; 19 + mov si,ax + + ; - count of sectors in RootDir + mov bx,word [BPB_BytsPerSec+boot_program] + mov cl,5 ; divide ax by 32 + shr bx,cl ; bx = directory entries per sector + mov ax,word [BPB_RootEntCnt+boot_program] + xor dx,dx + div bx + mov word [RootDirSecs+boot_program],ax ; 14 + + ; - data start + add si,ax ; add beginning sector of RootDir and count sectors in RootDir + mov word [data_start+boot_program],si ; 33 + ; reading root directory + ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! + mov ah,2 ; read + push ax + + mov ax,word [FirstRootDirSecNum+boot_program] + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) + pop ax + mov bx,pos_read_tmp ; es:bx read buffer + call read_sector + + mov si,bx ; read buffer address: es:si + mov ax,[RootDirSecs+boot_program] + mul word [BPB_BytsPerSec+boot_program] + add ax,si ; AX = end of root dir. in buffer pos_read_tmp + + ; find kernel file in root directory +loop_find_dir_entry: + push si + mov cx,11 + mov di,kernel_name+boot_program + rep cmpsb ; compare es:si and es:di, cx bytes long + pop si + je found_kernel_file + add si,32 ; next dir. entry + cmp si,ax ; end of directory + jb loop_find_dir_entry + +file_error_message: + mov si,error_message+boot_program + +loop_error_message: + lodsb + or al,al + jz freeze_pc + mov ah,0eh + mov bx,7 + int 10h + jmp loop_error_message + +freeze_pc: + jmp $ ; endless loop + + ; === KERNEL FOUND. LOADING... === + +found_kernel_file: + mov bp,[si+01ah] ; first cluster of kernel file + ; + mov [cluster1st+boot_program],bp ; starting cluster of kernel file + ; <\diamond> + + ; reading first FAT table + mov ax,word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) + mov bx,pos_read_tmp ; es:bx read position + mov ah,2 ; ah=2 (read) + mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) + call read_sector + jc file_error_message ; read error + + mov ax,seg_read_kernel + mov es,ax + xor bx,bx ; es:bx = 1000h:0000h + + + ; reading kernel file +loop_obtains_kernel_data: + ; read one cluster of file + call obtain_cluster + jc file_error_message ; read error + + ; add one cluster length to segment:offset + push bx + mov bx,es + mov ax,word [BPB_BytsPerSec+boot_program] ;\ + movsx cx,byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! + mul cx ; | out this from loop !!! + shr ax,4 ;/ + add bx,ax + mov es,bx + pop bx + + mov di,bp + shr di,1 + pushf + add di,bp ; di = bp * 1.5 + add di,pos_read_tmp + mov ax,[di] ; read next entry from FAT-chain + popf + jc move_4_right + and ax,0fffh + jmp verify_end_sector +move_4_right: + mov cl,4 + shr ax,cl +verify_end_sector: + cmp ax,0ff8h ; last cluster + jae execute_kernel + mov bp,ax + jmp loop_obtains_kernel_data + +execute_kernel: + ; + mov ax,'KL' + push 0 + pop ds + mov si,loader_block+boot_program + ; + push word seg_read_kernel + push word 0 + retf ; jmp far 1000:0000 + + +;------------------------------------------ + ; loading cluster from file to es:bx +obtain_cluster: + ; bp - cluster number to read + ; carry = 0 -> read OK + ; carry = 1 -> read ERROR + + ; print one dot + push bx + mov ax,0e2eh ; ah=0eh (teletype), al='.' + xor bh,bh + int 10h + + ; convert cluster number to sector number + mov ax,bp ; data cluster to read + sub ax,2 + xor bx,bx + mov bl,byte [BPB_SecPerClus+boot_program] + mul bx + add ax,word [data_start+boot_program] + pop bx + +writesec: + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) +patchhere: + mov ah,2 ; ah=2 (read) + mov al,byte [BPB_SecPerClus+boot_program] ; al=(one cluster) + call read_sector + retn +;------------------------------------------ + +;------------------------------------------ + ; read sector from disk +read_sector: + push bp + mov bp,20 ; try 20 times +newread: + dec bp + jz file_error_message + push ax bx cx dx + int 13h + pop dx cx bx ax + jc newread + pop bp + retn +;------------------------------------------ + ; convert abs. sector number (AX) to BIOS T:H:S + ; sector number = (abs.sector%BPB_SecPerTrk)+1 + ; pre.track number = (abs.sector/BPB_SecPerTrk) + ; head number = pre.track number%BPB_NumHeads + ; track number = pre.track number/BPB_NumHeads + ; Return: cl - sector number + ; ch - track number + ; dl - drive number (0 = a:) + ; dh - head number +conv_abs_to_THS: + push bx + mov bx,word [BPB_SecPerTrk+boot_program] + xor dx,dx + div bx + inc dx + mov cl, dl ; cl = sector number + mov bx,word [BPB_NumHeads+boot_program] + xor dx,dx + div bx + ; !!!!!!! ax = track number, dx = head number + mov ch,al ; ch=track number + xchg dh,dl ; dh=head number + mov dl,0 ; dl=0 (drive 0 (a:)) + pop bx + retn +;------------------------------------------ + +loading db cr,lf,'Starting system ',00h +error_message db 13,10 +kernel_name db 'KERNEL MNT ?',cr,lf,00h +FirstRootDirSecNum dw ? +RootDirSecs dw ? +data_start dw ? + +; +write1st: + push cs + pop ds + mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 + mov ax,[cluster1st+boot_program] + push 1000h + pop es + xor bx,bx + call writesec + mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 + retf +cluster1st dw ? +loader_block: + db 1 + dw 0 + dw write1st+boot_program + dw 0 +; <\diamond> + +times 0x1fe-$ db 00h + + db 55h,0aah ;boot signature diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/floppy1440.inc b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1440.inc new file mode 100644 index 000000000..678e2d35f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1440.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) + BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 18 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/floppy1680.inc b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1680.inc new file mode 100644 index 000000000..ef754de8d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1680.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors) + BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 21 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/floppy1743.inc b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1743.inc new file mode 100644 index 000000000..bd777301f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/floppy1743.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) + BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 21 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/floppy2880.inc b/kernel/tags/kolibri0.7.7.0/bootloader/floppy2880.inc new file mode 100644 index 000000000..8a52c059c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/floppy2880.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 2 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors) + BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 36 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/tags/kolibri0.7.7.0/bootloader/readme b/kernel/tags/kolibri0.7.7.0/bootloader/readme new file mode 100644 index 000000000..bbcc50f2e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bootloader/readme @@ -0,0 +1,43 @@ +‡ Јаг§®з­л© ᥪв®а ¤«п Ћ‘ Љ®«ЁЎаЁ (FAT12, ¤ЁбЄҐв ) + +- ЋЇЁб ­ЁҐ + Џ®§ў®«пҐв § Јаг¦ вм KERNEL.MNT б ¤ЁбЄҐв/®Ўа §®ў + ®Ўкс¬®¬ 1.44M, 1.68M, 1.72M Ё 2.88M + „«п ўлЎ®а  ®Ўкс¬  ¤ЁбЄ , ¤«п Є®в®а®Ј® ­ ¤® б®Ўа вм + § Јаг§®з­л© ᥪв®а, ­Ґ®Ўе®¤Ё¬® ў д ©«Ґ boot_fat12.asm + а бЄ®¬¬Ґ­вЁа®ў вм бва®Єг ўЁ¤ : + include 'floppy????.inc' + ¤«п ­Ґ®Ўе®¤Ё¬®Ј® ®Ўкс¬  ¤ЁбЄ . „®бвгЇ­лҐ ў аЁ ­вл: + floppy1440.inc, + floppy1680.inc, + floppy1743.inc Ё floppy2880.inc + +- ‘Ў®аЄ  + fasm boot_fat12.asm + +- „«п § ЇЁбЁ § Јаг§®з­®Ј® ᥪв®а  ­  ¤ЁбЄ/®Ўа § Ї®¤ Linux + ¬®¦­® ў®бЇ®«м§®ў вмбп б«Ґ¤го饩 Є®¬ ­¤®©: + dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc + +--------------------------------------------------------------------- + +Floppy FAT12 boot sector for KolibriOS. + +- Description + Allows booting KERNEL.MNT floppies/images + with volumes of 1.44M, 1.68M, 1.72M and 2.88M + To select the volume of the disk, which should gather + boot sector, it was necessary in file boot_fat12.asm + uncomment line: + include 'floppy????. inc' + for the necessary disk volume. Available options is: + floppy1440.inc, + floppy1680.inc, + floppy1743.inc and floppy2880.inc + +- Compile + fasm boot_fat12.asm + +- To write boot sector to the floppy/image under Linux + you can use the following command: + dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc diff --git a/kernel/tags/kolibri0.7.7.0/build.bat b/kernel/tags/kolibri0.7.7.0/build.bat new file mode 100644 index 000000000..e322d1e19 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/build.bat @@ -0,0 +1,142 @@ +@echo off +cls +set languages=en ru ge et +set drivers=sound sis infinity ensoniq ps2mouse com_mouse uart ati2d vmode +set targets=all kernel drivers skins clean + +call :Check_Target %1 +for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 +call :Target_%target% + +if ERRORLEVEL 0 goto Exit_OK + +echo There was an error executing script. +echo For any help, please send a report. +pause +goto :eof + + + + +:Check_Lang + set res=%1 + :Check_Lang_loop + for %%a in (%languages%) do if %%a==%res% set lang=%res% + if defined lang goto :eof + + echo Language '%res%' is incorrect + echo Enter valid language [ %languages% ]: + + set /P res="> + goto Check_Lang_loop +goto :eof + +:Check_Target + set res=%1 + :Check_Target_loop + for %%a in (%targets%) do if %%a==%res% set target=%res% + if defined target goto :eof + + echo Target '%res%' is incorrect + echo Enter valid target [ %targets% ]: + + set /P res="> + goto Check_Target_loop +goto :eof + + +:Target_kernel + echo *** building kernel with language '%lang%' ... + + if not exist bin mkdir bin + echo lang fix %lang% > lang.inc + fasm -m 65536 kernel.asm bin\kernel.mnt + if not %errorlevel%==0 goto :Error_FasmFailed + erase lang.inc +goto :eof + + +:Target_all + call :Target_kernel + call :Target_drivers + call :Target_skins +goto :eof + + +:Target_drivers + echo *** building drivers ... + + if not exist bin\drivers mkdir bin\drivers + cd drivers + for %%a in (%drivers%) do ( + fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj + if not %errorlevel%==0 goto :Error_FasmFailed + ) + cd .. + move bin\drivers\vmode.obj bin\drivers\vmode.mdr + + +kpack >nul 2>&1 + +if %errorlevel%==9009 goto :Error_KpackFailed + +echo * +echo ############################################## +echo * +echo Kpack KolibriOS drivers? +echo * + +set /P res=[y/n]? + +if "%res%"=="y" ( + + echo * + echo Compressing system + + echo * + for %%a in (bin\drivers\*.obj) do ( + echo ================== kpack %%a + kpack %%a + if not %errorlevel%==0 goto :Error_KpackFailed + ) + +) +goto :eof + + +:Target_skins + echo *** building skins ... + + if not exist bin\skins mkdir bin\skins + cd skin + fasm -m 65536 default.asm ..\bin\skins\default.skn + if not %errorlevel%==0 goto :Error_FasmFailed + cd .. +goto :eof + +:Target_clean + echo *** cleaning ... + rmdir /S /Q bin +goto :Exit_OK + + +:Error_FasmFailed +echo error: fasm execution failed +erase lang.inc >nul 2>&1 +echo. +pause +exit 1 + +:Error_KpackFailed +echo *** NOTICE *** +echo If you want to pack all applications you may +echo place "kpack" in accessible directory or system %PATH%. +echo You can get this tool from KolibriOS distribution kit. +pause +exit 1 + +:Exit_OK +echo. +echo all operations have been done +pause +exit 0 diff --git a/kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc b/kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc new file mode 100644 index 000000000..211fabf2f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bus/pci/pci16.inc @@ -0,0 +1,51 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; PCI16.INC ;; +;; ;; +;; 16 bit PCI driver code ;; +;; ;; +;; Version 0.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +init_pci_16: + + pushad + + xor ax,ax + mov es,ax + mov byte [es:0x9020],1 ;default mechanism:1 + mov ax,0xb101 + int 0x1a + or ah,ah + jnz pci16skip + + mov [es:0x9021],cl ;last PCI bus in system + mov [es:0x9022],bx + mov [es:0x9024],edi + +; we have a PCI BIOS, so check which configuration mechanism(s) +; it supports +; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) + test al,1 + jnz pci16skip + test al,2 + jz pci16skip + mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 + +pci16skip: + + mov ax,0x1000 + mov es,ax + + popad diff --git a/kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc b/kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc new file mode 100644 index 000000000..e9752b2d1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/bus/pci/pci32.inc @@ -0,0 +1,483 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; PCI32.INC ;; +;; ;; +;; 32 bit PCI driver code ;; +;; ;; +;; Version 0.3 April 9, 2007 ;; +;; Version 0.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; Mihailov Ilia, ghost.nsk@gmail.com ;; +;; Credits: ;; +;; Ralf Brown ;; +;; Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +;*************************************************************************** +; Function +; pci_api: +; +; Description +; entry point for system PCI calls +;*************************************************************************** + +align 4 + +pci_api: + + cmp [pci_access_enabled],1 + jne no_pci_access_for_applications + + or al,al + jnz pci_fn_1 + ; PCI function 0: get pci version (AH.AL) + movzx eax,word [BOOT_VAR+0x9022] + ret + +pci_fn_1: + cmp al,1 + jnz pci_fn_2 + + ; PCI function 1: get last bus in AL + mov al,[BOOT_VAR+0x9021] + ret + +pci_fn_2: + cmp al,2 + jne pci_fn_3 + ; PCI function 2: get pci access mechanism + mov al,[BOOT_VAR+0x9020] + ret +pci_fn_3: + + cmp al,4 + jz pci_read_reg ;byte + cmp al,5 + jz pci_read_reg ;word + cmp al,6 + jz pci_read_reg ;dword + + cmp al,8 + jz pci_write_reg ;byte + cmp al,9 + jz pci_write_reg ;word + cmp al,10 + jz pci_write_reg ;dword + + no_pci_access_for_applications: + + mov eax,-1 + + ret + +;*************************************************************************** +; Function +; pci_make_config_cmd +; +; Description +; creates a command dword for use with the PCI bus +; bus # in ah +; device+func in bh (dddddfff) +; register in bl +; +; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) +;*************************************************************************** + +align 4 + +pci_make_config_cmd: + shl eax,8 ; move bus to bits 16-23 + mov ax,bx ; combine all + and eax,0xffffff + or eax,0x80000000 + ret + +;*************************************************************************** +; Function +; pci_read_reg: +; +; Description +; read a register from the PCI config space into EAX/AX/AL +; IN: ah=bus,device+func=bh,register address=bl +; number of bytes to read (1,2,4) coded into AL, bits 0-1 +; (0 - byte, 1 - word, 2 - dword) +;*************************************************************************** + +align 4 + +pci_read_reg: + cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? + je pci_read_reg_2 + + ; mechanism 1 + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + call pci_make_config_cmd + mov ebx,eax + ; get current state + mov dx,0xcf8 + in eax, dx + push eax + ; set up addressing to config data + mov eax,ebx + and al,0xfc ; make address dword-aligned + out dx,eax + ; get requested DWORD of config data + mov dl,0xfc + and bl,3 + or dl,bl ; add to port address first 2 bits of register address + + or esi,esi + jz pci_read_byte1 + cmp esi,1 + jz pci_read_word1 + cmp esi,2 + jz pci_read_dword1 + jmp pci_fin_read1 + +pci_read_byte1: + in al,dx + jmp pci_fin_read1 +pci_read_word1: + in ax,dx + jmp pci_fin_read1 +pci_read_dword1: + in eax,dx + jmp pci_fin_read1 +pci_fin_read1: + ; restore configuration control + xchg eax,[esp] + mov dx,0xcf8 + out dx,eax + + pop eax + pop esi + ret +pci_read_reg_2: + + test bh,128 ;mech#2 only supports 16 devices per bus + jnz pci_read_reg_err + + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + push eax + ;store current state of config space + mov dx,0xcf8 + in al,dx + mov ah,al + mov dl,0xfa + in al,dx + + xchg eax,[esp] + ; out 0xcfa,bus + mov al,ah + out dx,al + ; out 0xcf8,0x80 + mov dl,0xf8 + mov al,0x80 + out dx,al + ; compute addr + shr bh,3 ; func is ignored in mechanism 2 + or bh,0xc0 + mov dx,bx + + or esi,esi + jz pci_read_byte2 + cmp esi,1 + jz pci_read_word2 + cmp esi,2 + jz pci_read_dword2 + jmp pci_fin_read2 + +pci_read_byte2: + in al,dx + jmp pci_fin_read2 +pci_read_word2: + in ax,dx + jmp pci_fin_read2 +pci_read_dword2: + in eax,dx +; jmp pci_fin_read2 +pci_fin_read2: + + ; restore configuration space + xchg eax,[esp] + mov dx,0xcfa + out dx,al + mov dl,0xf8 + mov al,ah + out dx,al + + pop eax + pop esi + ret + +pci_read_reg_err: + xor eax,eax + dec eax + ret + + +;*************************************************************************** +; Function +; pci_write_reg: +; +; Description +; write a register from ECX/CX/CL into the PCI config space +; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, +; value to write in ecx +; number of bytes to write (1,2,4) coded into AL, bits 0-1 +; (0 - byte, 1 - word, 2 - dword) +;*************************************************************************** + +align 4 + +pci_write_reg: + cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? + je pci_write_reg_2 + + ; mechanism 1 + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + call pci_make_config_cmd + mov ebx,eax + ; get current state into ecx + mov dx,0xcf8 + in eax, dx + push eax + ; set up addressing to config data + mov eax,ebx + and al,0xfc ; make address dword-aligned + out dx,eax + ; write DWORD of config data + mov dl,0xfc + and bl,3 + or dl,bl + mov eax,ecx + + or esi,esi + jz pci_write_byte1 + cmp esi,1 + jz pci_write_word1 + cmp esi,2 + jz pci_write_dword1 + jmp pci_fin_write1 + +pci_write_byte1: + out dx,al + jmp pci_fin_write1 +pci_write_word1: + out dx,ax + jmp pci_fin_write1 +pci_write_dword1: + out dx,eax + jmp pci_fin_write1 +pci_fin_write1: + + ; restore configuration control + pop eax + mov dl,0xf8 + out dx,eax + + xor eax,eax + pop esi + + ret +pci_write_reg_2: + + test bh,128 ;mech#2 only supports 16 devices per bus + jnz pci_write_reg_err + + + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + push eax + ;store current state of config space + mov dx,0xcf8 + in al,dx + mov ah,al + mov dl,0xfa + in al,dx + xchg eax,[esp] + ; out 0xcfa,bus + mov al,ah + out dx,al + ; out 0xcf8,0x80 + mov dl,0xf8 + mov al,0x80 + out dx,al + ; compute addr + shr bh,3 ; func is ignored in mechanism 2 + or bh,0xc0 + mov dx,bx + ; write register + mov eax,ecx + + or esi,esi + jz pci_write_byte2 + cmp esi,1 + jz pci_write_word2 + cmp esi,2 + jz pci_write_dword2 + jmp pci_fin_write2 + +pci_write_byte2: + out dx,al + jmp pci_fin_write2 +pci_write_word2: + out dx,ax + jmp pci_fin_write2 +pci_write_dword2: + out dx,eax + jmp pci_fin_write2 +pci_fin_write2: + ; restore configuration space + pop eax + mov dx,0xcfa + out dx,al + mov dl,0xf8 + mov al,ah + out dx,al + + xor eax,eax + pop esi + ret + +pci_write_reg_err: + xor eax,eax + dec eax + ret + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) +pci_emu_dat: times 30*10 db 0 + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +align 4 +sys_pcibios: + xchg ebx, eax + xchg ecx, eax + xchg edx, eax + xchg esi, eax + xchg edi, eax + cmp [pci_access_enabled], 1 + jne .unsupported_func + cmp [pci_bios_entry], 0 + jz .emulate_bios + + push ds + mov ax, pci_data_sel + mov ds, ax + mov eax, ebp + mov ah, 0B1h + call pword [cs:pci_bios_entry] + pop ds + + jmp .return + ;-=-=-=-=-=-=-=-= +.emulate_bios: + cmp ebp, 1 ; PCI_FUNCTION_ID + jnz .not_PCI_BIOS_PRESENT + mov edx, 'PCI ' + mov al, [OS_BASE+0x2F0000 + 0x9020] + mov bx, [OS_BASE+0x2F0000 + 0x9022] + mov cl, [OS_BASE+0x2F0000 + 0x9021] + xor ah, ah + jmp .return_abcd + +.not_PCI_BIOS_PRESENT: + cmp ebp, 2 ; FIND_PCI_DEVICE + jne .not_FIND_PCI_DEVICE + mov ebx, pci_emu_dat +..nxt: cmp [ebx], dx + jne ..no + cmp [ebx + 2], cx + jne ..no + dec si + jns ..no + mov bx, [ebx + 4] + xor ah, ah + jmp .return_ab +..no: cmp word[ebx], 0 + je ..dev_not_found + add ebx, 10 + jmp ..nxt +..dev_not_found: + mov ah, 0x86 ; DEVICE_NOT_FOUND + jmp .return_a + +.not_FIND_PCI_DEVICE: + cmp ebp, 3 ; FIND_PCI_CLASS_CODE + jne .not_FIND_PCI_CLASS_CODE + mov esi, pci_emu_dat + shl ecx, 8 +..nxt2: cmp [esi], ecx + jne ..no2 + mov bx, [esi] + xor ah, ah + jmp .return_ab +..no2: cmp dword[esi], 0 + je ..dev_not_found + add esi, 10 + jmp ..nxt2 + +.not_FIND_PCI_CLASS_CODE: + cmp ebp, 8 ; READ_CONFIG_* + jb .not_READ_CONFIG + cmp ebp, 0x0A + ja .not_READ_CONFIG + mov eax, ebp + mov ah, bh + mov edx, edi + mov bh, bl + mov bl, dl + call pci_read_reg + mov ecx, eax + xor ah, ah ; SUCCESSFUL + jmp .return_abc +.not_READ_CONFIG: + cmp ebp, 0x0B ; WRITE_CONFIG_* + jb .not_WRITE_CONFIG + cmp ebp, 0x0D + ja .not_WRITE_CONFIG + lea eax, [ebp+1] + mov ah, bh + mov edx, edi + mov bh, bl + mov bl, dl + call pci_write_reg + xor ah, ah ; SUCCESSFUL + jmp .return_abc +.not_WRITE_CONFIG: +.unsupported_func: + mov ah, 0x81 ; FUNC_NOT_SUPPORTED +.return:mov dword[esp + 8 ], edi + mov dword[esp + 12], esi +.return_abcd: + mov dword[esp + 28], edx +.return_abc: + mov dword[esp + 32], ecx +.return_ab: + mov dword[esp + 24], ebx +.return_a: + mov dword[esp + 36], eax + ret diff --git a/kernel/tags/kolibri0.7.7.0/const.inc b/kernel/tags/kolibri0.7.7.0/const.inc new file mode 100644 index 000000000..ae3b8bd8c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/const.inc @@ -0,0 +1,767 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +dpl0 equ 10010000b ; data read dpl0 +drw0 equ 10010010b ; data read/write dpl0 +drw3 equ 11110010b ; data read/write dpl3 +cpl0 equ 10011010b ; code read dpl0 +cpl3 equ 11111010b ; code read dpl3 + +D32 equ 01000000b ; 32bit segment +G32 equ 10000000b ; page gran + + +;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; + +CPU_386 equ 3 +CPU_486 equ 4 +CPU_PENTIUM equ 5 +CPU_P6 equ 6 +CPU_PENTIUM4 equ 0x0F + +CAPS_FPU equ 00 ;on-chip x87 floating point unit +CAPS_VME equ 01 ;virtual-mode enhancements +CAPS_DE equ 02 ;debugging extensions +CAPS_PSE equ 03 ;page-size extensions +CAPS_TSC equ 04 ;time stamp counter +CAPS_MSR equ 05 ;model-specific registers +CAPS_PAE equ 06 ;physical-address extensions +CAPS_MCE equ 07 ;machine check exception +CAPS_CX8 equ 08 ;CMPXCHG8B instruction +CAPS_APIC equ 09 ;on-chip advanced programmable + ; interrupt controller +; 10 ;unused +CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions +CAPS_MTRR equ 12 ;memory-type range registers +CAPS_PGE equ 13 ;page global extension +CAPS_MCA equ 14 ;machine check architecture +CAPS_CMOV equ 15 ;conditional move instructions +CAPS_PAT equ 16 ;page attribute table + +CAPS_PSE36 equ 17 ;page-size extensions +CAPS_PSN equ 18 ;processor serial number +CAPS_CLFLUSH equ 19 ;CLFUSH instruction + +CAPS_DS equ 21 ;debug store +CAPS_ACPI equ 22 ;thermal monitor and software + ;controlled clock supported +CAPS_MMX equ 23 ;MMX instructions +CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions +CAPS_SSE equ 25 ;SSE instructions +CAPS_SSE2 equ 26 ;SSE2 instructions +CAPS_SS equ 27 ;self-snoop +CAPS_HTT equ 28 ;hyper-threading technology +CAPS_TM equ 29 ;thermal monitor supported +CAPS_IA64 equ 30 ;IA64 capabilities +CAPS_PBE equ 31 ;pending break enable + +;ecx +CAPS_SSE3 equ 32 ;SSE3 instructions +; 33 +; 34 +CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions +CAPS_DS_CPL equ 36 ; +CAPS_VMX equ 37 ;virtual mode extensions +; 38 ; +CAPS_EST equ 39 ;enhansed speed step +CAPS_TM2 equ 40 ;thermal monitor2 supported +; 41 +CAPS_CID equ 42 ; +; 43 +; 44 +CAPS_CX16 equ 45 ;CMPXCHG16B instruction +CAPS_xTPR equ 46 ; +; +;reserved +; +;ext edx /ecx +CAPS_SYSCAL equ 64 ; +CAPS_XD equ 65 ;execution disable +CAPS_FFXSR equ 66 ; +CAPS_RDTSCP equ 67 ; +CAPS_X64 equ 68 ; +CAPS_3DNOW equ 69 ; +CAPS_3DNOWEXT equ 70 ; +CAPS_LAHF equ 71 ; +CAPS_CMP_LEG equ 72 ; +CAPS_SVM equ 73 ;secure virual machine +CAPS_ALTMOVCR8 equ 74 ; + +; CPU MSR names +MSR_SYSENTER_CS equ 0x174 +MSR_SYSENTER_ESP equ 0x175 +MSR_SYSENTER_EIP equ 0x176 +MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register +MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register + +CR0_PE equ 0x00000001 ;protected mode +CR0_MP equ 0x00000002 ;monitor fpu +CR0_EM equ 0x00000004 ;fpu emulation +CR0_TS equ 0x00000008 ;task switch +CR0_ET equ 0x00000010 ;extension type hardcoded to 1 +CR0_NE equ 0x00000020 ;numeric error +CR0_WP equ 0x00010000 ;write protect +CR0_AM equ 0x00040000 ;alignment check +CR0_NW equ 0x20000000 ;not write-through +CR0_CD equ 0x40000000 ;cache disable +CR0_PG equ 0x80000000 ;paging + + +CR4_VME equ 0x0001 +CR4_PVI equ 0x0002 +CR4_TSD equ 0x0004 +CR4_DE equ 0x0008 +CR4_PSE equ 0x0010 +CR4_PAE equ 0x0020 +CR4_MCE equ 0x0040 +CR4_PGE equ 0x0080 +CR4_PCE equ 0x0100 +CR4_OSFXSR equ 0x0200 +CR4_OSXMMEXPT equ 0x0400 + +SSE_IE equ 0x0001 +SSE_DE equ 0x0002 +SSE_ZE equ 0x0004 +SSE_OE equ 0x0008 +SSE_UE equ 0x0010 +SSE_PE equ 0x0020 +SSE_DAZ equ 0x0040 +SSE_IM equ 0x0080 +SSE_DM equ 0x0100 +SSE_ZM equ 0x0200 +SSE_OM equ 0x0400 +SSE_UM equ 0x0800 +SSE_PM equ 0x1000 +SSE_FZ equ 0x8000 + +SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) + + +struc TSS +{ + ._back rw 2 + ._esp0 rd 1 + ._ss0 rw 2 + ._esp1 rd 1 + ._ss1 rw 2 + ._esp2 rd 1 + ._ss2 rw 2 + ._cr3 rd 1 + ._eip rd 1 + ._eflags rd 1 + ._eax rd 1 + ._ecx rd 1 + ._edx rd 1 + ._ebx rd 1 + ._esp rd 1 + ._ebp rd 1 + ._esi rd 1 + ._edi rd 1 + ._es rw 2 + ._cs rw 2 + ._ss rw 2 + ._ds rw 2 + ._fs rw 2 + ._gs rw 2 + ._ldt rw 2 + ._trap rw 1 + ._io rw 1 + rb 24 + ._io_map_0 rb 4096 + ._io_map_1 rb 4096 +} + +virtual at 0 + TSS TSS +end virtual + +TSS_SIZE equ (128+8192) + +OS_BASE equ 0x80000000 + +window_data equ (OS_BASE+0x0001000) + +CURRENT_TASK equ (OS_BASE+0x0003000) +TASK_COUNT equ (OS_BASE+0x0003004) +TASK_BASE equ (OS_BASE+0x0003010) +TASK_DATA equ (OS_BASE+0x0003020) +TASK_EVENT equ (OS_BASE+0x0003020) + +mouseunder equ (OS_BASE+0x0006900) +CDDataBuf equ (OS_BASE+0x0007000) +FLOPPY_BUFF equ (OS_BASE+0x0008000) +ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused +idts equ (OS_BASE+0x000B100) +WIN_STACK equ (OS_BASE+0x000C000) +WIN_POS equ (OS_BASE+0x000C400) +FDD_BUFF equ (OS_BASE+0x000D000) + +;unused ? only one reference +ENABLE_TASKSWITCH equ (OS_BASE+0x000E000) + +PUTPIXEL equ (OS_BASE+0x000E020) +GETPIXEL equ (OS_BASE+0x000E024) + +;unused ? only one reference +BANK_SWITCH equ (OS_BASE+0x000E030) + +;unused ? store mousepointer +MOUSE_PICTURE equ (OS_BASE+0x000F200) + +MOUSE_VISIBLE equ (OS_BASE+0x000F204) +WIN_TEMP_XY equ (OS_BASE+0x000F300) +KEY_COUNT equ (OS_BASE+0x000F400) +KEY_BUFF equ (OS_BASE+0x000F401) + +BTN_COUNT equ (OS_BASE+0x000F500) +BTN_BUFF equ (OS_BASE+0x000F501) + +CPU_FREQ equ (OS_BASE+0x000F600) + +;unused ? no active references +MOUSE_PORT equ (OS_BASE+0x000F604) + +;unused +PS2_CHUNK equ (OS_BASE+0x000FB00) + +MOUSE_SCROLL_H equ (OS_BASE+0x000FB08) +MOUSE_X equ (OS_BASE+0x000FB0A) +MOUSE_Y equ (OS_BASE+0x000FB0C) +MOUSE_SCROLL_V equ (OS_BASE+0x000FB0E) + +MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10) +COLOR_TEMP equ (OS_BASE+0x000FB30) +BTN_DOWN equ (OS_BASE+0x000FB40) +MOUSE_DOWN equ (OS_BASE+0x000FB44) +X_UNDER equ (OS_BASE+0x000FB4A) +Y_UNDER equ (OS_BASE+0x000FB4C) +ScreenBPP equ (OS_BASE+0x000FBF1) + +;unused ? only one reference +MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) + +LFBAddress equ (OS_BASE+0x000FE80) +MEM_AMOUNT equ (OS_BASE+0x000FE8C) + +Screen_Max_X equ (OS_BASE+0x000FE00) +Screen_Max_Y equ (OS_BASE+0x000FE04) +BytesPerScanLine equ (OS_BASE+0x000FE08) +SCR_MODE equ (OS_BASE+0x000FE0C) + +BTN_ADDR equ (OS_BASE+0x000FE88) +SYS_SHUTDOWN equ (OS_BASE+0x000FF00) +TASK_ACTIVATE equ (OS_BASE+0x000FF01) + +REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0) +BANK_RW equ (OS_BASE+0x000FFF2) +MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) +DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) +DONT_SWITCH equ (OS_BASE+0x000FFFF) + +TMP_STACK_TOP equ 0x006CC00 + +FONT_II equ (OS_BASE+0x006DC00) +FONT_I equ (OS_BASE+0x006E600) + +sys_pgdir equ (OS_BASE+0x006F000) + +DRIVE_DATA equ (OS_BASE+0x0070000) + +SLOT_BASE equ (OS_BASE+0x0080000) + +;unused +TMP_BUFF equ (OS_BASE+0x0090000) + +VGABasePtr equ (OS_BASE+0x00A0000) + +RAMDISK equ (OS_BASE+0x0100000) +RAMDISK_FAT equ (OS_BASE+0x0280000) +FLOPPY_FAT equ (OS_BASE+0x0282000) + +IDE_DMA equ 0x284000 + +BgrAuxTable equ (OS_BASE+0x0298000) +; unused? +SB16Buffer equ (OS_BASE+0x2A0000) +SB16_Status equ (OS_BASE+0x02B0000) + +BUTTON_INFO equ (OS_BASE+0x02C0000) +RESERVED_PORTS equ (OS_BASE+0x02D0000) +IRQ_SAVE equ (OS_BASE+0x02E0000) +BOOT_VAR equ (OS_BASE+0x02f0000) + +stack_data_start equ (OS_BASE+0x0300000) +eth_data_start equ (OS_BASE+0x0300000) +stack_data equ (OS_BASE+0x0304000) +stack_data_end equ (OS_BASE+0x031ffff) +resendQ equ (OS_BASE+0x0320000) +VMODE_BASE equ (OS_BASE+0x0328000) +skin_data equ (OS_BASE+0x0330000) +draw_data equ (OS_BASE+0x0338000); + +BgrDrawMode equ (OS_BASE+0x033BFF4) +BgrDataWidth equ (OS_BASE+0x033BFF8) +BgrDataHeight equ (OS_BASE+0x033BFFC) + +sys_pgmap equ (OS_BASE+0x033C000) + +virtual at (OS_BASE+0x05FFF80) + tss TSS +end virtual + +HEAP_BASE equ (OS_BASE+0x0800000) +HEAP_MIN_SIZE equ 0x01000000 + +page_tabs equ 0xFDC00000 +app_page_tabs equ 0xFDC00000 +kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000 +master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000 + +LFB_BASE equ 0xFE000000 + + +new_app_base equ 0; + +twdw equ 0x2000 ;(CURRENT_TASK-window_data) + +std_application_base_address equ new_app_base +RING0_STACK_SIZE equ (0x2000 - 512) ;512 байт для контекста FPU + +REG_SS equ (RING0_STACK_SIZE-4) +REG_APP_ESP equ (RING0_STACK_SIZE-8) +REG_EFLAGS equ (RING0_STACK_SIZE-12) +REG_CS equ (RING0_STACK_SIZE-16) +REG_EIP equ (RING0_STACK_SIZE-20) +REG_EAX equ (RING0_STACK_SIZE-24) +REG_ECX equ (RING0_STACK_SIZE-28) +REG_EDX equ (RING0_STACK_SIZE-32) +REG_EBX equ (RING0_STACK_SIZE-36) +REG_ESP equ (RING0_STACK_SIZE-40) ;RING0_STACK_SIZE-20 +REG_EBP equ (RING0_STACK_SIZE-44) +REG_ESI equ (RING0_STACK_SIZE-48) +REG_EDI equ (RING0_STACK_SIZE-52) +REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return + + +PG_UNMAP equ 0x000 +PG_MAP equ 0x001 +PG_WRITE equ 0x002 +PG_SW equ 0x003 +PG_USER equ 0x005 +PG_UW equ 0x007 +PG_NOCACHE equ 0x018 +PG_LARGE equ 0x080 +PG_GLOBAL equ 0x100 + +PG_SHARED equ 0x200 + +;;;;;;;;;;;boot time variables + +;BOOT_BPP equ 0x9000 ;byte bits per pixel +BOOT_SCANLINE equ 0x9001 ;word scanline length +BOOT_VESA_MODE equ 0x9008 ;word vesa video mode +;;BOOT_X_RES equ 0x900A ;word X res +;;BOOT_Y_RES equ 0x900C ;word Y res +;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used +BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch +BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address +BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration +BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) +BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled +BOOT_PCI_DATA equ 0x9020 ;8bytes pci data +BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no +BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr +BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount + +TMP_FILE_NAME equ 0 +TMP_CMD_LINE equ 1024 +TMP_ICON_OFFS equ 1280 + + +EVENT_REDRAW equ 0x00000001 +EVENT_KEY equ 0x00000002 +EVENT_BUTTON equ 0x00000004 +EVENT_BACKGROUND equ 0x00000010 +EVENT_MOUSE equ 0x00000020 +EVENT_IPC equ 0x00000040 +EVENT_NETWORK equ 0x00000080 +EVENT_DEBUG equ 0x00000100 +EVENT_EXTENDED equ 0x00000200 + +EV_INTR equ 1 + +struc THR_DATA +{ + rb (8192-512) + .pl0_stack: + .fpu_state rb 512 + .tls_page rb 4096 + .pdbr rb 4096 +} + +THR_DATA_SIZE equ 4096*4 + +virtual at (OS_BASE-THR_DATA_SIZE) + thr_data THR_DATA +end virtual + +struc SYS_VARS +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? +} + +struc APPOBJ ;common object header +{ + .magic dd ? ; + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id +}; + +virtual at 0 + APPOBJ APPOBJ +end virtual + +APP_OBJ_OFFSET equ 48 +APP_EV_OFFSET equ 40 + +struc CURSOR +{ +;common object header + .magic dd ? ;'CURS' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + ;cursor data + .base dd ? ;allocated memory + .hot_x dd ? ;hotspot coords + .hot_y dd ? + + .list_next dd ? ;next cursor in cursor list + .list_prev dd ? ;prev cursor in cursor list + .dev_obj dd ? ;device depended data + + .sizeof: +} +virtual at 0 + CURSOR CURSOR +end virtual + + +struc EVENT +{ + .magic dd ? ;'EVNT' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .id dd ? ;event uid + .state dd ? ;internal flags + .code dd ? + rd 5 + .size = $ - .magic + .codesize = $ - .code +} + +virtual at 0 + EVENT EVENT +end virtual + + +struc SMEM +{ + .bk dd ? + .fd dd ? ;+4 + .base dd ? ;+8 + .size dd ? ;+12 + .access dd ? ;+16 + .refcount dd ? ;+20 + .name rb 32 ;+24 + .sizeof: +} + +struc SMAP +{ + .magic dd ? ; SMAP + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .base dd ? ;mapped base + .parent dd ? ;SMEM + .sizeof: +} + +virtual at 0 + SMEM SMEM +end virtual + +virtual at 0 + SMAP SMAP +end virtual + +struc DLLDESCR +{ + .bk dd ? + .fd dd ? ;+4 + .data dd ? ;+8 + .size dd ? ;+12 + .timestamp dq ? + .refcount dd ? + .defaultbase dd ? + .coff_hdr dd ? + .symbols_ptr dd ? + .symbols_num dd ? + .symbols_lim dd ? + .exports dd ? ;export table + .name: + .sizeof: +} + +struc HDLL +{ + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .base dd ? ;mapped base + .size dd ? ;mapped size + .refcount dd ? ;reference counter for this process and this lib + .parent dd ? ;DLLDESCR + .sizeof: +} + +virtual at 0 + DLLDESCR DLLDESCR +end virtual + +virtual at 0 + HDLL HDLL +end virtual + +struc display_t +{ + .x dd ? + .y dd ? + .width dd ? + .height dd ? + .bpp dd ? + .vrefresh dd ? + .pitch dd ? + .lfb dd ? + + .modes dd ? + .ddev dd ? + .connector dd ? + .crtc dd ? + + .cr_list.next dd ? + .cr_list.prev dd ? + + .cursor dd ? + + .init_cursor dd ? + .select_cursor dd ? + .show_cursor dd ? + .move_cursor dd ? + .restore_cursor dd ? + .disable_mouse dd ? +} + +virtual at 0 + display_t display_t +end virtual + +struc HEAP_DATA +{ + .mutex rd 1 + .refcount rd 1 + .heap_base rd 1 + .heap_top rd 1 + .app_mem rd 1 +} + +HEAP_DATA_SIZE equ 20 +virtual at 0 + HEAP_DATA HEAP_DATA +end virtual + +struc BOOT_DATA +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .mouse_port dd ? + .bank_switch dd ? + .lfb dd ? + .vesa_mem dd ? + .log dd ? + .direct_lfb dd ? + .pci_data dd ? +; dd ? + .vrr dd ? + .ide_base dd ? + .mem_amount dd ? + .pages_count dd ? + .pagemap_size dd ? + .kernel_max dd ? + .kernel_pages dd ? + .kernel_tables dd ? + + .cpu_vendor dd ? + dd ? + dd ? + .cpu_sign dd ? + .cpu_info dd ? + .cpu_caps dd ? + dd ? + dd ? +} + +virtual at 0 + BOOT_DATA BOOT_DATA +end virtual + +struc MEM_STATE +{ .mutex rd 1 + .smallmap rd 1 + .treemap rd 1 + .topsize rd 1 + .top rd 1 + .smallbins rd 4*32 + .treebins rd 32 +} + +struc PG_DATA +{ .mem_amount dd ? + .vesa_mem dd ? + .pages_count dd ? + .pages_free dd ? + .pages_faults dd ? + .pagemap_size dd ? + .kernel_pages dd ? + .kernel_tables dd ? + .sys_page_dir dd ? + .pg_mutex dd ? +} + +;struc LIB +;{ .lib_name rb 16 +; .lib_base dd ? +; .lib_start dd ? +; .export dd ? +; .import dd ? +;} + +struc SRV +{ + .srv_name rb 16 ;ASCIIZ string + .magic dd ? ;+0x10 ;'SRV ' + .size dd ? ;+0x14 ;size of structure SRV + .fd dd ? ;+0x18 ;next SRV descriptor + .bk dd ? ;+0x1C ;prev SRV descriptor + .base dd ? ;+0x20 ;service base address + .entry dd ? ;+0x24 ;service START function + .srv_proc dd ? ;+0x28 ;user mode service handler + .srv_proc_ex dd ? ;+0x2C ;kernel mode service handler + .sizeof: +} + +SRV_FD_OFFSET equ 0x18 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 + +struc COFF_HEADER +{ .machine dw ? + .nSections dw ? + .DataTime dd ? + .pSymTable dd ? + .nSymbols dd ? + .optHeader dw ? + .flags dw ? +}; + + +struc COFF_SECTION +{ .Name rb 8 + .VirtualSize dd ? + .VirtualAddress dd ? + .SizeOfRawData dd ? + .PtrRawData dd ? + .PtrReloc dd ? + .PtrLinenumbers dd ? + .NumReloc dw ? + .NumLinenum dw ? + .Characteristics dd ? +} +COFF_SECTION_SIZE equ 40 + +struc COFF_RELOC +{ .VirtualAddress dd ? + .SymIndex dd ? + .Type dw ? +} + +struc COFF_SYM +{ .Name rb 8 + .Value dd ? + .SectionNumber dw ? + .Type dw ? + .StorageClass db ? + .NumAuxSymbols db ? +} +CSYM_SIZE equ 18 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +;virtual at 0 +; LIB LIB +;end virtual + +virtual at 0 + SRV SRV +end virtual + +virtual at 0 + CFH COFF_HEADER +end virtual + +virtual at 0 + CFS COFF_SECTION +end virtual + +virtual at 0 + CRELOC COFF_RELOC +end virtual + +virtual at 0 + CSYM COFF_SYM +end virtual diff --git a/kernel/tags/kolibri0.7.7.0/core/conf_lib.inc b/kernel/tags/kolibri0.7.7.0/core/conf_lib.inc new file mode 100644 index 000000000..1fbe6de68 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/conf_lib.inc @@ -0,0 +1,297 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;------------------------------------------------------------------------- +;Loading configuration from ini file +; {SPraid.simba} +;------------------------------------------------------------------------- + +$Revision$ + +iglobal +conf_path_sect: db 'path',0 + +conf_fname db '/sys/sys.conf',0 +endg +; set soke kernel configuration +proc set_kernel_conf + locals + par db 30 dup(?) + endl + + pushad +;[gui] +;mouse_speed + + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed,\ + eax,30, ugui_mouse_speed_def + pop eax + stdcall strtoint,eax + mov [mouse_speed_factor], ax + +;mouse_delay + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay,\ + eax,30, ugui_mouse_delay_def + pop eax + stdcall strtoint,eax + mov [mouse_delay], eax + + +;midibase + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def + pop eax + stdcall strtoint,eax + + cmp eax, 0x100 + jb @f + cmp eax, 0x10000 + jae @f + mov [midi_base], ax + mov [mididp], eax + inc eax + mov [midisp], eax +@@: + popad + ret +endp +iglobal +ugui db 'gui',0 +ugui_mouse_speed db 'mouse_speed',0 +ugui_mouse_speed_def db '2',0 +ugui_mouse_delay db 'mouse_delay',0 +ugui_mouse_delay_def db '0x00A',0 + +udev db 'dev',0 +udev_midibase db 'midibase',0 +udev_midibase_def db '0x320',0 +endg +;set up netvork configuration +proc set_network_conf +locals + par db 30 dup(?) +endl + pushad + + ;[net] + ;active + lea eax,[par] + invoke ini.get_int,conf_fname, unet, unet_active, 0 + or eax,eax + jz .do_not_set_net + mov eax, [stack_config] + and eax, 0xFFFFFF80 + add eax, 3 + mov [stack_config], eax + call ash_eth_enable + + ;addr + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def + pop eax + stdcall do_inet_adr,eax + mov [stack_ip], eax + + ;mask + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def + pop eax + stdcall do_inet_adr,eax + mov [subnet_mask], eax + + ;gate + lea eax,[par] + push eax + invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def + pop eax + stdcall do_inet_adr,eax + mov [gateway_ip], eax +.do_not_set_net: + popad + ret + + +endp +iglobal +unet db 'net',0 +unet_active db 'active',0 +unet_addr db 'addr',0 +unet_mask db 'mask',0 +unet_gate db 'gate',0 +unet_def db 0 +endg +; convert string to DWord +proc strtoint stdcall,strs + pushad + + mov eax,[strs] + inc eax + mov bl,[eax] + cmp bl,'x' + je .hex + cmp bl,'X' + je .hex + jmp .dec +.hex: + inc eax + stdcall strtoint_hex,eax + jmp .exit +.dec: + dec eax + stdcall strtoint_dec,eax +.exit: + mov [esp+28],eax + popad + ret +endp + +; convert string to DWord for decimal value +proc strtoint_dec stdcall,strs + pushad + xor edx,edx + ; Ї®ЁбЄ Є®­ж  + mov esi,[strs] +@@: + lodsb + or al,al + jnz @b + mov ebx,esi + mov esi,[strs] + dec ebx + sub ebx,esi + mov ecx,1 + +@@: + dec ebx + or ebx,ebx + jz @f + imul ecx,ecx,10 ; Ї®а冷Є + jmp @b +@@: + + xchg ebx,ecx + + + xor ecx,ecx + + +@@: + xor eax,eax + lodsb + cmp al,0 + je .eend + + sub al,30h + imul ebx + add ecx,eax + push ecx + xchg eax,ebx + mov ecx,10 + div ecx + xchg eax,ebx + pop ecx + jmp @b + +.eend: + mov [esp+28],ecx + popad + ret +endp + +;convert string to DWord for hex value +proc strtoint_hex stdcall,strs + pushad + xor edx,edx + + mov esi,[strs] + mov ebx,1 + add esi,1 + +@@: + lodsb + or al,al + jz @f + shl ebx,4 + jmp @b +@@: + xor ecx,ecx + mov esi,[strs] + +@@: + xor eax,eax + lodsb + cmp al,0 + je .eend + + cmp al,'a' + jae .bm + cmp al,'A' + jae .bb + jmp .cc +.bm: ; 57h + sub al,57h + jmp .do + +.bb: ; 37h + sub al,37h + jmp .do + +.cc: ; 30h + sub al,30h + +.do: + imul ebx + add ecx,eax + shr ebx,4 + + jmp @b + +.eend: + mov [esp+28],ecx + popad + ret +endp + + +; convert string to DWord for IP addres +proc do_inet_adr stdcall,strs + pushad + + mov esi,[strs] + mov ebx,0 +.next: + push esi +@@: + lodsb + or al,al + jz @f + cmp al,'.' + jz @f + jmp @b +@@: + mov cl, al + mov [esi-1],byte 0 + ;pop eax + call strtoint_dec + rol eax,24 + ror ebx,8 + add ebx,eax + or cl,cl + jz @f + jmp .next +@@: + mov [esp+28],ebx + popad + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/core/debug.inc b/kernel/tags/kolibri0.7.7.0/core/debug.inc new file mode 100644 index 000000000..15d0b9c17 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/debug.inc @@ -0,0 +1,416 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; diamond, 2006 +sys_debug_services: + cmp eax, 9 + ja @f + jmp dword [sys_debug_services_table+eax*4] +@@: ret +sys_debug_services_table: + dd debug_set_event_data + dd debug_getcontext + dd debug_setcontext + dd debug_detach + dd debug_suspend + dd debug_resume + dd debug_read_process_memory + dd debug_write_process_memory + dd debug_terminate + dd debug_set_drx + +debug_set_event_data: +; in: ebx = pointer +; destroys eax + mov eax, [current_slot] + mov [eax+APPDATA.dbg_event_mem], ebx + ret + +get_debuggee_slot: +; in: ebx=PID +; out: CF=1 if error +; CF=0 and eax=slot*0x20 if ok +; out: interrupts disabled + cli + mov eax, ebx + call pid_to_slot + test eax, eax + jz .ret_bad + shl eax, 5 + push ebx + mov ebx, [CURRENT_TASK] + cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx + pop ebx + jnz .ret_bad +; clc ; automatically + ret +.ret_bad: + stc + ret + +debug_detach: +; in: ebx=pid +; destroys eax,ebx + call get_debuggee_slot + jc .ret + and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 + call do_resume +.ret: + sti + ret + +debug_terminate: +; in: ebx=pid + call get_debuggee_slot + jc debug_detach.ret + mov ecx, eax + shr ecx, 5 + push 2 + pop ebx + jmp sys_system + +debug_suspend: +; in: ebx=pid +; destroys eax,ebx + cli + mov eax, ebx + call pid_to_slot + shl eax, 5 + jz .ret + mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state + test bl, bl + jz .1 + cmp bl, 5 + jnz .ret + mov bl, 2 +.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl +.ret: + sti + ret +.1: + inc ebx + jmp .2 + +do_resume: + mov bl, [CURRENT_TASK+eax+TASKDATA.state] + cmp bl, 1 + jz .1 + cmp bl, 2 + jnz .ret + mov bl, 5 +.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl +.ret: ret +.1: dec ebx + jmp .2 + +debug_resume: +; in: ebx=pid +; destroys eax,ebx + cli + mov eax, ebx + call pid_to_slot + shl eax, 5 + jz .ret + call do_resume +.ret: sti + ret + +debug_getcontext: +; in: +; ebx=pid +; ecx=sizeof(CONTEXT) +; edx->CONTEXT +; destroys eax,ecx,edx,esi,edi + cmp ecx, 28h + jnz .ret + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .ret + mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] + lea esi, [eax+RING0_STACK_SIZE] + mov edi, edx +.ring0: +; note that following code assumes that all interrupt/exception handlers +; saves ring-3 context by pushad in this order +; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad + sub esi, 8+12+20h + lodsd ;edi + mov [edi+24h], eax + lodsd ;esi + mov [edi+20h], eax + lodsd ; ebp + mov [edi+1Ch], eax + lodsd ;esp + lodsd ;ebx + mov [edi+14h], eax + lodsd ;edx + mov [edi+10h], eax + lodsd ;ecx + mov [edi+0Ch], eax + lodsd ;eax + mov [edi+8], eax + lodsd ;eip + mov [edi], eax + lodsd ;cs + lodsd ;eflags + mov [edi+4], eax + lodsd ;esp + mov [edi+18h], eax +.ret: + sti + ret + +debug_setcontext: +; in: +; ebx=pid +; ecx=sizeof(CONTEXT) +; edx->CONTEXT +; destroys eax,ecx,edx,esi,edi + cmp ecx, 28h + jnz .ret + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .stiret + mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] + lea edi, [eax+RING0_STACK_SIZE] + mov esi, edx +.ring0: + sub edi, 8+12+20h + mov eax, [esi+24h] ;edi + stosd + mov eax, [esi+20h] ;esi + stosd + mov eax, [esi+1Ch] ;ebp + stosd + scasd + mov eax, [esi+14h] ;ebx + stosd + mov eax, [esi+10h] ;edx + stosd + mov eax, [esi+0Ch] ;ecx + stosd + mov eax, [esi+8] ;eax + stosd + mov eax, [esi] ;eip + stosd + scasd + mov eax, [esi+4] ;eflags + stosd + mov eax, [esi+18h] ;esp + stosd +.stiret: + sti +.ret: + ret + +debug_set_drx: + call get_debuggee_slot + jc .errret + mov ebp, eax + lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] +; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 +; [eax+10]=dr7 + cmp edx, OS_BASE + jae .errret + cmp cl, 3 + ja .errret + mov ebx, dr7 + shr ebx, cl + shr ebx, cl + test ebx, 2 ; bit 1+2*index = G0..G3, global break enable + jnz .errret2 + test ch, ch + jns .new +; clear breakpoint + movzx ecx, cl + add ecx, ecx + and dword [eax+ecx*2], 0 ; clear DR + btr dword [eax+10h], ecx ; clear L bit + test byte [eax+10h], 55h + jnz .okret +; imul eax, ebp, tss_step/32 +; and byte [eax + tss_data + TSS._trap], not 1 + and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1 +.okret: + and dword [esp+36], 0 + sti + ret +.errret: + sti + mov dword [esp+36], 1 + ret +.errret2: + sti + mov dword [esp+36], 2 + ret +.new: +; add new breakpoint +; cl=index; ch=flags; edx=address + test ch, 0xF0 + jnz .errret + mov bl, ch + and bl, 3 + cmp bl, 2 + jz .errret + mov bl, ch + shr bl, 2 + cmp bl, 2 + jz .errret + test dl, bl + jnz .errret + or byte [eax+10h+1], 3 ; set GE and LE flags + movzx ebx, ch + movzx ecx, cl + add ecx, ecx + bts dword [eax+10h], ecx ; set L flag + add ecx, ecx + mov [eax+ecx], edx ; set DR + shl ebx, cl + mov edx, 0xF + shl edx, cl + not edx + and [eax+10h+2], dx + or [eax+10h+2], bx ; set R/W and LEN fields +; imul eax, ebp, tss_step/32 +; or byte [eax + tss_data + TSS._trap], 1 + or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1 + jmp .okret + +debug_read_process_memory: +; in: +; ebx=pid +; ecx=length +; esi->buffer in debugger +; edx=address in debuggee +; out: [esp+36]=sizeof(read) +; destroys all + push ebx + mov ebx, esi + call check_region + pop ebx + dec eax + jnz .err + call get_debuggee_slot + jc .err + shr eax, 5 + mov ebx, esi + call read_process_memory + sti + mov dword [esp+36], eax + ret +.err: + or dword [esp+36], -1 + ret + +debug_write_process_memory: +; in: +; ebx=pid +; ecx=length +; esi->buffer in debugger +; edx=address in debuggee +; out: [esp+36]=sizeof(write) +; destroys all + push ebx + mov ebx, esi + call check_region + pop ebx + dec eax + jnz debug_read_process_memory.err + call get_debuggee_slot + jc debug_read_process_memory.err + shr eax, 5 + mov ebx, esi + call write_process_memory + sti + mov [esp+36], eax + ret + +debugger_notify: +; in: eax=debugger slot +; ecx=size of debug message +; [esp+4]..[esp+4+ecx]=message +; interrupts must be disabled! +; destroys all general registers +; interrupts remain disabled + xchg ebp, eax + mov edi, [timer_ticks] + add edi, 500 ; 5 sec timeout +.1: + mov eax, ebp + shl eax, 8 + mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] + test edx, edx + jz .ret +; read buffer header + push ecx + push eax + push eax + mov eax, ebp + mov ebx, esp + mov ecx, 8 + call read_process_memory + cmp eax, ecx + jz @f + add esp, 12 + jmp .ret +@@: + cmp dword [ebx], 0 + jg @f +.2: + pop ecx + pop ecx + pop ecx + cmp dword [CURRENT_TASK], 1 + jnz .notos + cmp [timer_ticks], edi + jae .ret +.notos: + sti + call change_task + cli + jmp .1 +@@: + mov ecx, [ebx+8] + add ecx, [ebx+4] + cmp ecx, [ebx] + ja .2 +; advance buffer position + push ecx + mov ecx, 4 + sub ebx, ecx + mov eax, ebp + add edx, ecx + call write_process_memory + pop eax +; write message + mov eax, ebp + add edx, ecx + add edx, [ebx+8] + add ebx, 20 + pop ecx + pop ecx + pop ecx + call write_process_memory +; new debug event + mov eax, ebp + shl eax, 8 + or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h +.ret: + ret diff --git a/kernel/tags/kolibri0.7.7.0/core/dll.inc b/kernel/tags/kolibri0.7.7.0/core/dll.inc new file mode 100644 index 000000000..9dcef5934 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/dll.inc @@ -0,0 +1,1689 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +DRV_COMPAT equ 5 ;minimal required drivers version +DRV_CURRENT equ 5 ;current drivers model version + +DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT +PID_KERNEL equ 1 ;os_idle thread + +align 4 +proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword + + push ebx + + mov ebx, [irq] ;irq num + test ebx, ebx + jz .err + cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's + ja .err + mov eax, [handler] + test eax, eax + jz .err + cmp [irq_owner + 4 * ebx], 0 + je @f + + mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden + test ecx, ecx + jnz .err + +@@: + mov [irq_tab+ebx*4], eax + + mov eax, [access_rights] + mov [irq_rights + 4 * ebx], eax + + mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel + + stdcall enable_irq, [irq] + pop ebx + mov eax, 1 + ret +.err: + pop ebx + xor eax, eax + ret +endp + +uglobal + + irq_rights rd 16 + +endg + +proc get_int_handler stdcall, irq:dword + + mov eax, [irq] + + cmp [irq_rights + 4 * eax], dword 1 + ja .err + + mov eax, [irq_tab + 4 * eax] + ret + + .err: + xor eax, eax + ret + +endp + +align 4 +proc detach_int_handler + + ret +endp + +align 4 +proc enable_irq stdcall, irq_line:dword + mov ebx, [irq_line] + mov edx, 0x21 + cmp ebx, 8 + jb @F + mov edx, 0xA1 + sub ebx,8 +@@: + in al,dx + btr eax, ebx + out dx, al + ret +endp + +align 16 +;; proc irq_serv + +irq_serv: + +.irq_1: + push 1 + jmp .main +align 4 +.irq_2: + push 2 + jmp .main +align 4 +.irq_3: + push 3 + jmp .main +align 4 +.irq_4: + push 4 + jmp .main +align 4 +.irq_5: + push 5 + jmp .main +; align 4 +; .irq_6: +; push 6 +; jmp .main +align 4 +.irq_7: + push 7 + jmp .main +align 4 +.irq_8: + push 8 + jmp .main +align 4 +.irq_9: + push 9 + jmp .main +align 4 +.irq_10: + push 10 + jmp .main +align 4 +.irq_11: + push 11 + jmp .main +align 4 +.irq_12: + push 12 + jmp .main +; align 4 +; .irq_13: +; push 13 +; jmp .main +; align 4 +; .irq_14: +; push 14 +; jmp .main +; align 4 +; .irq_15: +; push 15 +; jmp .main + +align 16 +.main: + save_ring3_context + mov eax, [esp + 32] + mov bx, app_data ;os_data + mov ds, bx + mov es, bx + + cmp [v86_irqhooks+eax*8], 0 + jnz v86_irq + + mov ebx, [irq_tab+eax*4] + test ebx, ebx + jz .exit + + call ebx + mov [check_idle_semaphore],5 + +.exit: + + cmp dword [esp + 32], 8 + mov al, 0x20 + jb @f + out 0xa0, al +@@: + out 0x20, al + + restore_ring3_context + add esp, 4 + + iret + +align 4 +proc get_notify stdcall, p_ev:dword + +.wait: + mov ebx,[current_slot] + test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY + jz @f + and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY + mov edi, [p_ev] + mov dword [edi], EV_INTR + mov eax, [ebx+APPDATA.event] + mov dword [edi+4], eax + ret +@@: + call change_task + jmp .wait +endp + +align 4 +proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 6 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + pop ebx + ret +endp + +align 4 +proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 5 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + pop ebx + ret +endp + +align 4 +proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 4 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + pop ebx + ret +endp + +align 4 +proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 8 + mov bh, byte [devfn] + mov bl, byte [reg] + mov ecx, [val] + call pci_write_reg + pop ebx + ret +endp + +align 4 +proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 9 + mov bh, byte [devfn] + mov bl, byte [reg] + mov ecx, [val] + call pci_write_reg + pop ebx + ret +endp + +align 4 +proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + push ebx + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 10 + mov bh, byte [devfn] + mov bl, byte [reg] + mov ecx, [val] + call pci_write_reg + pop ebx + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + + +align 4 +proc srv_handler stdcall, ioctl:dword + mov esi, [ioctl] + test esi, esi + jz .err + + mov edi, [esi+handle] + cmp [edi+SRV.magic], ' SRV' + jne .fail + + cmp [edi+SRV.size], SRV.sizeof + jne .fail + + stdcall [edi+SRV.srv_proc], esi + ret +.fail: + xor eax, eax + not eax + mov [esi+output], eax + mov [esi+out_size], 4 + ret +.err: + xor eax, eax + not eax + ret +endp + +; param +; ebx= io_control +; +; retval +; eax= error code + +align 4 +srv_handlerEx: + cmp ebx, OS_BASE + jae .fail + + mov eax, [ebx+handle] + cmp [eax+SRV.magic], ' SRV' + jne .fail + + cmp [eax+SRV.size], SRV.sizeof + jne .fail + + stdcall [eax+SRV.srv_proc], ebx + ret +.fail: + or eax, -1 + ret + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc get_service stdcall, sz_name:dword + mov eax, [sz_name] + test eax, eax + jnz @F + ret +@@: + mov edx, [srv.fd] +@@: + cmp edx, srv.fd-SRV_FD_OFFSET + je .not_load + + stdcall strncmp, edx, [sz_name], 16 + test eax, eax + je .ok + + mov edx, [edx+SRV.fd] + jmp @B +.not_load: + pop ebp + jmp load_driver +.ok: + mov eax, edx + ret +endp + +align 4 +proc reg_service stdcall, name:dword, handler:dword + + push ebx + + xor eax, eax + + cmp [name], eax + je .fail + + cmp [handler], eax + je .fail + + mov eax, SRV.sizeof + call malloc + test eax, eax + jz .fail + + push esi + push edi + mov edi, eax + mov esi, [name] + movsd + movsd + movsd + movsd + pop edi + pop esi + + mov [eax+SRV.magic], ' SRV' + mov [eax+SRV.size], SRV.sizeof + + mov ebx, srv.fd-SRV_FD_OFFSET + mov edx, [ebx+SRV.fd] + mov [eax+SRV.fd], edx + mov [eax+SRV.bk], ebx + mov [ebx+SRV.fd], eax + mov [edx+SRV.bk], eax + + mov ecx, [handler] + mov [eax+SRV.srv_proc], ecx + pop ebx + ret +.fail: + xor eax, eax + pop ebx + ret +endp + +align 4 +proc get_proc stdcall, exp:dword, sz_name:dword + + mov edx, [exp] +.next: + mov eax, [edx] + test eax, eax + jz .end + + push edx + stdcall strncmp, eax, [sz_name], 16 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.ok: + mov eax, [edx+4] +.end: + ret +endp + +align 4 +proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword + +@@: + stdcall strncmp, [pSym], [sz_sym], 8 + test eax,eax + jz .ok + add [pSym], 18 + dec [count] + jnz @b + xor eax, eax + ret +.ok: + mov eax, [pSym] + mov eax, [eax+8] + ret +endp + +align 4 +proc get_curr_task + mov eax,[CURRENT_TASK] + shl eax, 8 + ret +endp + +align 4 +proc get_fileinfo stdcall, file_name:dword, info:dword + locals + cmd dd ? + offset dd ? + dd ? + count dd ? + buff dd ? + db ? + name dd ? + endl + + xor eax, eax + mov ebx, [file_name] + mov ecx, [info] + + mov [cmd], 5 + mov [offset], eax + mov [offset+4], eax + mov [count], eax + mov [buff], ecx + mov byte [buff+4], al + mov [name], ebx + + mov eax, 70 + lea ebx, [cmd] + int 0x40 + ret +endp + +align 4 +proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ + bytes:dword + locals + cmd dd ? + offset dd ? + dd ? + count dd ? + buff dd ? + db ? + name dd ? + endl + + xor eax, eax + mov ebx, [file_name] + mov ecx, [off] + mov edx, [bytes] + mov esi, [buffer] + + mov [cmd], eax + mov [offset], ecx + mov [offset+4], eax + mov [count], edx + mov [buff], esi + mov byte [buff+4], al + mov [name], ebx + + pushad + push eax + lea eax, [cmd] + call file_system_lfn + pop eax + popad + ret +endp + +; description +; allocate kernel memory and loads the specified file +; +; param +; file_name= full path to file +; +; retval +; eax= file image in kernel memory +; ebx= size of file +; +; warging +; You mast call kernel_free() to delete each file +; loaded by the load_file() function + +align 4 +proc load_file stdcall, file_name:dword + locals + attr dd ? + flags dd ? + cr_time dd ? + cr_date dd ? + acc_time dd ? + acc_date dd ? + mod_time dd ? + mod_date dd ? + file_size dd ? + + file dd ? + file2 dd ? + endl + + push esi + push edi + + lea eax, [attr] + stdcall get_fileinfo, [file_name], eax + test eax, eax + jnz .fail + + mov eax, [file_size] + cmp eax, 1024*1024*16 + ja .fail + + stdcall kernel_alloc, [file_size] + mov [file], eax + + stdcall read_file, [file_name], eax, dword 0, [file_size] + cmp ebx, [file_size] + jne .cleanup + + mov eax, [file] + cmp dword [eax], 0x4B43504B + jne .exit + mov ebx, [eax+4] + mov [file_size], ebx + stdcall kernel_alloc, ebx + + test eax, eax + jz .cleanup + + mov [file2], eax + pushfd + cli + stdcall unpack, [file], eax + popfd + stdcall kernel_free, [file] + mov eax, [file2] + mov ebx, [file_size] +.exit: + push eax + lea edi, [eax+ebx] ;cleanup remain space + mov ecx, 4096 ;from file end + and ebx, 4095 + jz @f + sub ecx, ebx + xor eax, eax + cld + rep stosb +@@: + mov ebx, [file_size] + pop eax + pop edi + pop esi + ret +.cleanup: + stdcall kernel_free, [file] +.fail: + xor eax, eax + xor ebx, ebx + pop edi + pop esi + ret +endp + +align 4 +proc get_proc_ex stdcall, proc_name:dword, imports:dword + +.look_up: + mov edx, [imports] + test edx, edx + jz .end + mov edx, [edx] + test edx, edx + jz .end +.next: + mov eax, [edx] + test eax, eax + jz .next_table + + push edx + stdcall strncmp, eax, [proc_name], 256 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.next_table: + add [imports], 4 + jmp .look_up +.ok: + mov eax, [edx+4] + ret +.end: + xor eax, eax + ret +endp + +align 4 +proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\ + sym_count:dword, strings:dword, imports:dword + locals + retval dd ? + endl + + mov edi, [symbols] + mov [retval], 1 +.fix: + movzx ebx, [edi+CSYM.SectionNumber] + test ebx, ebx + jnz .internal + mov eax, dword [edi+CSYM.Name] + test eax, eax + jnz @F + + mov edi, [edi+4] + add edi, [strings] +@@: + push edi + stdcall get_proc_ex, edi,[imports] + pop edi + + xor ebx, ebx + test eax, eax + jnz @F + + mov esi, msg_unresolved + call sys_msg_board_str + mov esi, edi + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str + + mov [retval],0 +@@: + mov edi, [symbols] + mov [edi+CSYM.Value], eax + jmp .next +.internal: + cmp bx, -1 + je .next + cmp bx, -2 + je .next + + dec ebx + shl ebx, 3 + lea ebx, [ebx+ebx*4] + add ebx, [sec] + + mov eax, [ebx+CFS.VirtualAddress] + add [edi+CSYM.Value], eax +.next: + add edi, CSYM_SIZE + mov [symbols], edi + dec [sym_count] + jnz .fix + mov eax, [retval] + ret +endp + +align 4 +proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \ + delta:dword + locals + n_sec dd ? + endl + + mov eax, [coff] + movzx ebx, [eax+CFH.nSections] + mov [n_sec], ebx + lea esi, [eax+20] +.fix_sec: + mov edi, [esi+CFS.PtrReloc] + add edi, [coff] + + movzx ecx, [esi+CFS.NumReloc] + test ecx, ecx + jz .next +.reloc_loop: + mov ebx, [edi+CRELOC.SymIndex] + add ebx,ebx + lea ebx,[ebx+ebx*8] + add ebx, [sym] + + mov edx, [ebx+CSYM.Value] + + cmp [edi+CRELOC.Type], 6 + je .dir_32 + + cmp [edi+CRELOC.Type], 20 + jne .next_reloc +.rel_32: + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [esi+CFS.VirtualAddress] + sub edx, eax + sub edx, 4 + jmp .fix +.dir_32: + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [esi+CFS.VirtualAddress] +.fix: + add eax, [delta] + add [eax], edx +.next_reloc: + add edi, 10 + dec ecx + jnz .reloc_loop +.next: + add esi, COFF_SECTION_SIZE + dec [n_sec] + jnz .fix_sec +.exit: + ret +endp + +proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \ + delta:dword + locals + n_sec dd ? + endl + + mov eax, [coff] + movzx ebx, [eax+CFH.nSections] + mov [n_sec], ebx + lea esi, [eax+20] + mov edx, [delta] +.fix_sec: + mov edi, [esi+CFS.PtrReloc] + add edi, [coff] + + movzx ecx, [esi+CFS.NumReloc] + test ecx, ecx + jz .next +.reloc_loop: + cmp [edi+CRELOC.Type], 6 + jne .next_reloc +.dir_32: + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [esi+CFS.VirtualAddress] + add [eax+edx], edx +.next_reloc: + add edi, 10 + dec ecx + jnz .reloc_loop +.next: + add esi, COFF_SECTION_SIZE + dec [n_sec] + jnz .fix_sec +.exit: + ret +endp + +align 4 +proc load_driver stdcall, driver_name:dword + locals + coff dd ? + sym dd ? + strings dd ? + img_size dd ? + img_base dd ? + start dd ? + + exports dd ? ;fake exports table + dd ? + file_name rb 13+16+4+1 ; '/sys/drivers/.obj' + endl + + lea edx, [file_name] + mov dword [edx], '/sys' + mov dword [edx+4], '/dri' + mov dword [edx+8], 'vers' + mov byte [edx+12], '/' + mov esi, [driver_name] +.redo: + lea edx, [file_name] + lea edi, [edx+13] + mov ecx, 16 +@@: + lodsb + test al, al + jz @f + stosb + loop @b +@@: + mov dword [edi], '.obj' + mov byte [edi+4], 0 + stdcall load_file, edx + + test eax, eax + jz .exit + + mov [coff], eax + + movzx ecx, [eax+CFH.nSections] + xor ebx, ebx + + lea edx, [eax+20] +@@: + add ebx, [edx+CFS.SizeOfRawData] + add ebx, 15 + and ebx, not 15 + add edx, COFF_SECTION_SIZE + dec ecx + jnz @B + mov [img_size], ebx + + stdcall kernel_alloc, ebx + test eax, eax + jz .fail + mov [img_base], eax + + mov edi, eax + xor eax, eax + mov ecx, [img_size] + add ecx, 4095 + and ecx, not 4095 + shr ecx, 2 + cld + rep stosd + + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, [img_base] + lea eax, [edx+20] +@@: + mov [eax+CFS.VirtualAddress], edi + mov esi, [eax+CFS.PtrRawData] + test esi, esi + jnz .copy + add edi, [eax+CFS.SizeOfRawData] + jmp .next +.copy: + add esi, edx + mov ecx, [eax+CFS.SizeOfRawData] + cld + rep movsb +.next: + add edi, 15 + and edi, not 15 + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + mov ebx, [edx+CFH.pSymTable] + add ebx, edx + mov [sym], ebx + mov ecx, [edx+CFH.nSymbols] + add ecx,ecx + lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE + add ecx, [sym] + mov [strings], ecx + + lea ebx, [exports] + mov dword [ebx], kernel_export + mov dword [ebx+4], 0 + lea eax, [edx+20] + + stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ + [strings], ebx + test eax, eax + jz .link_fail + + mov ebx, [coff] + stdcall fix_coff_relocs, ebx, [sym], 0 + + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion + test eax, eax + jz .link_fail + + mov eax, [eax] + shr eax, 16 + cmp eax, DRV_COMPAT + jb .ver_fail + + cmp eax, DRV_CURRENT + ja .ver_fail + + mov ebx, [coff] + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART + mov [start], eax + + stdcall kernel_free, [coff] + + mov ebx, [start] + stdcall ebx, DRV_ENTRY + test eax, eax + jnz .ok + + stdcall kernel_free, [img_base] + cmp dword [file_name+13], 'SOUN' + jnz @f + cmp dword [file_name+17], 'D.ob' + jnz @f + cmp word [file_name+21], 'j' + jnz @f + mov esi, aSis + jmp .redo +@@: + xor eax, eax + ret +.ok: + mov ebx, [img_base] + mov [eax+SRV.base], ebx + mov ecx, [start] + mov [eax+SRV.entry], ecx + ret + +.ver_fail: + mov esi, msg_CR + call sys_msg_board_str + mov esi, [driver_name] + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str + mov esi, msg_version + call sys_msg_board_str + mov esi, msg_www + call sys_msg_board_str + jmp .cleanup + +.link_fail: + mov esi, msg_module + call sys_msg_board_str + mov esi, [driver_name] + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str +.cleanup: + stdcall kernel_free,[img_base] +.fail: + stdcall kernel_free, [coff] +.exit: + xor eax, eax + ret +endp + +; in: edx -> COFF_SECTION struct +; out: eax = alignment as mask for bits to drop +coff_get_align: +; Rules: +; - if alignment is not given, use default = 4K; +; - if alignment is given and is no more than 4K, use it; +; - if alignment is more than 4K, revert to 4K. + push ecx + mov cl, byte [edx+CFS.Characteristics+2] + mov eax, 1 + shr cl, 4 + dec cl + js .default + cmp cl, 12 + jbe @f +.default: + mov cl, 12 +@@: + shl eax, cl + pop ecx + dec eax + ret + +align 4 +proc load_library stdcall, file_name:dword + locals + fullname rb 260 + fileinfo rb 40 + coff dd ? + img_base dd ? + endl + + cli + +; resolve file name + mov ebx, [file_name] + lea edi, [fullname+1] + mov byte [edi-1], '/' + stdcall get_full_file_name, edi, 259 + test al, al + jz .fail + +; scan for required DLL in list of already loaded for this process, +; ignore timestamp + mov esi, [CURRENT_TASK] + shl esi, 8 + lea edi, [fullname] + mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr] + test ebx, ebx + jz .not_in_process + mov esi, [ebx+HDLL.fd] +.scan_in_process: + cmp esi, ebx + jz .not_in_process + mov eax, [esi+HDLL.parent] + add eax, DLLDESCR.name + stdcall strncmp, eax, edi, -1 + test eax, eax + jnz .next_in_process +; simple variant: load DLL which is already loaded in this process +; just increment reference counters and return address of exports table + inc [esi+HDLL.refcount] + mov ecx, [esi+HDLL.parent] + inc [ecx+DLLDESCR.refcount] + mov eax, [ecx+DLLDESCR.exports] + sub eax, [ecx+DLLDESCR.defaultbase] + add eax, [esi+HDLL.base] + ret +.next_in_process: + mov esi, [esi+HDLL.fd] + jmp .scan_in_process +.not_in_process: + +; scan in full list, compare timestamp + lea eax, [fileinfo] + stdcall get_fileinfo, edi, eax + test eax, eax + jnz .fail + mov esi, [dll_list.fd] +.scan_for_dlls: + cmp esi, dll_list + jz .load_new + lea eax, [esi+DLLDESCR.name] + stdcall strncmp, eax, edi, -1 + test eax, eax + jnz .continue_scan +.test_prev_dll: + mov eax, dword [fileinfo+24] ; last modified time + mov edx, dword [fileinfo+28] ; last modified date + cmp dword [esi+DLLDESCR.timestamp], eax + jnz .continue_scan + cmp dword [esi+DLLDESCR.timestamp+4], edx + jz .dll_already_loaded +.continue_scan: + mov esi, [esi+DLLDESCR.fd] + jmp .scan_for_dlls + +; new DLL +.load_new: +; load file + stdcall load_file, edi + test eax, eax + jz .fail + mov [coff], eax + mov dword [fileinfo+32], ebx + +; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name + mov esi, edi + mov ecx, -1 + xor eax, eax + repnz scasb + not ecx + lea eax, [ecx+DLLDESCR.sizeof] + push ecx + call malloc + pop ecx + test eax, eax + jz .fail_and_free_coff +; save timestamp + lea edi, [eax+DLLDESCR.name] + rep movsb + mov esi, eax + mov eax, dword [fileinfo+24] + mov dword [esi+DLLDESCR.timestamp], eax + mov eax, dword [fileinfo+28] + mov dword [esi+DLLDESCR.timestamp+4], eax +; initialize DLLDESCR struct + and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented + mov [esi+DLLDESCR.fd], dll_list + mov eax, [dll_list.bk] + mov [dll_list.bk], esi + mov [esi+DLLDESCR.bk], eax + mov [eax+DLLDESCR.fd], esi + +; calculate size of loaded DLL + mov edx, [coff] + movzx ecx, [edx+CFH.nSections] + xor ebx, ebx + + add edx, 20 +@@: + call coff_get_align + add ebx, eax + not eax + and ebx, eax + add ebx, [edx+CFS.SizeOfRawData] + add edx, COFF_SECTION_SIZE + dec ecx + jnz @B +; it must be nonzero and not too big + mov [esi+DLLDESCR.size], ebx + test ebx, ebx + jz .fail_and_free_dll + cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR + ja .fail_and_free_dll +; allocate memory for kernel-side image + stdcall kernel_alloc, ebx + test eax, eax + jz .fail_and_free_dll + mov [esi+DLLDESCR.data], eax +; calculate preferred base address + add ebx, 0x1FFF + and ebx, not 0xFFF + mov ecx, [dll_cur_addr] + lea edx, [ecx+ebx] + cmp edx, MAX_DEFAULT_DLL_ADDR + jb @f + mov ecx, MIN_DEFAULT_DLL_ADDR + lea edx, [ecx+ebx] +@@: + mov [esi+DLLDESCR.defaultbase], ecx + mov [dll_cur_addr], edx + +; copy sections and set correct values for VirtualAddress'es in headers + push esi + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, eax + add edx, 20 + cld +@@: + call coff_get_align + add ecx, eax + add edi, eax + not eax + and ecx, eax + and edi, eax + mov [edx+CFS.VirtualAddress], ecx + add ecx, [edx+CFS.SizeOfRawData] + mov esi, [edx+CFS.PtrRawData] + push ecx + mov ecx, [edx+CFS.SizeOfRawData] + test esi, esi + jnz .copy + xor eax, eax + rep stosb + jmp .next +.copy: + add esi, [coff] + rep movsb +.next: + pop ecx + add edx, COFF_SECTION_SIZE + dec ebx + jnz @B + pop esi + +; save some additional data from COFF file +; later we will use COFF header, headers for sections and symbol table +; and also relocations table for all sections + mov edx, [coff] + mov ebx, [edx+CFH.pSymTable] + mov edi, dword [fileinfo+32] + sub edi, ebx + jc .fail_and_free_data + mov [esi+DLLDESCR.symbols_lim], edi + add ebx, edx + movzx ecx, [edx+CFH.nSections] + lea ecx, [ecx*5] + lea edi, [edi+ecx*8+20] + add edx, 20 +@@: + movzx eax, [edx+CFS.NumReloc] + lea eax, [eax*5] + lea edi, [edi+eax*2] + add edx, COFF_SECTION_SIZE + sub ecx, 5 + jnz @b + stdcall kernel_alloc, edi + test eax, eax + jz .fail_and_free_data + mov edx, [coff] + movzx ecx, [edx+CFH.nSections] + lea ecx, [ecx*5] + lea ecx, [ecx*2+5] + mov [esi+DLLDESCR.coff_hdr], eax + push esi + mov esi, edx + mov edi, eax + rep movsd + pop esi + mov [esi+DLLDESCR.symbols_ptr], edi + push esi + mov ecx, [edx+CFH.nSymbols] + mov [esi+DLLDESCR.symbols_num], ecx + mov ecx, [esi+DLLDESCR.symbols_lim] + mov esi, ebx + rep movsb + pop esi + mov ebx, [esi+DLLDESCR.coff_hdr] + push esi + movzx eax, [edx+CFH.nSections] + lea edx, [ebx+20] +@@: + movzx ecx, [edx+CFS.NumReloc] + lea ecx, [ecx*5] + mov esi, [edx+CFS.PtrReloc] + mov [edx+CFS.PtrReloc], edi + sub [edx+CFS.PtrReloc], ebx + add esi, [coff] + shr ecx, 1 + rep movsd + adc ecx, ecx + rep movsw + add edx, COFF_SECTION_SIZE + dec eax + jnz @b + pop esi + +; fixup symbols + mov edx, ebx + mov eax, [ebx+CFH.nSymbols] + add edx, 20 + mov ecx, [esi+DLLDESCR.symbols_num] + lea ecx, [ecx*9] + add ecx, ecx + add ecx, [esi+DLLDESCR.symbols_ptr] + + stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\ + ecx, 0 +; test eax, eax +; jnz @F +; +;@@: + + stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS + test eax, eax + jnz @F + + stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS +@@: + mov [esi+DLLDESCR.exports], eax + +; fix relocs in the hidden copy in kernel memory to default address +; it is first fix; usually this will be enough, but second fix +; can be necessary if real load address will not equal assumption + mov eax, [esi+DLLDESCR.data] + sub eax, [esi+DLLDESCR.defaultbase] + stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax + + stdcall kernel_free, [coff] + +.dll_already_loaded: + inc [esi+DLLDESCR.refcount] + push esi + call init_heap + pop esi + + mov edi, [esi+DLLDESCR.size] + stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi + test eax, eax + jnz @f + stdcall user_alloc, edi + test eax, eax + jz .fail_and_dereference +@@: + mov [img_base], eax + mov eax, HDLL.sizeof + call malloc + test eax, eax + jz .fail_and_free_user + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov edx, [CURRENT_TASK+ebx+TASKDATA.pid] + mov [eax+HDLL.pid], edx + push eax + call init_dlls_in_thread + pop ebx + test eax, eax + jz .fail_and_free_user + mov edx, [eax+HDLL.fd] + mov [ebx+HDLL.fd], edx + mov [ebx+HDLL.bk], eax + mov [eax+HDLL.fd], ebx + mov [edx+HDLL.bk], ebx + mov eax, ebx + mov ebx, [img_base] + mov [eax+HDLL.base], ebx + mov [eax+HDLL.size], edi + mov [eax+HDLL.refcount], 1 + mov [eax+HDLL.parent], esi + mov edx, ebx + shr edx, 12 + or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK +; copy entries of page table from kernel-side image to usermode +; use copy-on-write for user-mode image, so map as readonly + xor edi, edi + mov ecx, [esi+DLLDESCR.data] + shr ecx, 12 +.map_pages_loop: + mov eax, [page_tabs+ecx*4] + and eax, not 0xFFF + or al, PG_USER + xchg eax, [page_tabs+edx*4] + test al, 1 + jz @f + call free_page +@@: + invlpg [ebx+edi] + inc ecx + inc edx + add edi, 0x1000 + cmp edi, [esi+DLLDESCR.size] + jb .map_pages_loop + +; if real user-mode base is not equal to preferred base, relocate image + sub ebx, [esi+DLLDESCR.defaultbase] + jz @f + stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx +@@: + + mov eax, [esi+DLLDESCR.exports] + sub eax, [esi+DLLDESCR.defaultbase] + add eax, [img_base] + ret +.fail_and_free_data: + stdcall kernel_free, [esi+DLLDESCR.data] +.fail_and_free_dll: + mov eax, esi + call free +.fail_and_free_coff: + stdcall kernel_free, [coff] +.fail: + xor eax, eax + ret +.fail_and_free_user: + stdcall user_free, [img_base] +.fail_and_dereference: + mov eax, 1 ; delete 1 reference + call dereference_dll + xor eax, eax + ret +endp + +; initialize [APPDATA.dlls_list_ptr] for given thread +; DLL is per-process object, so APPDATA.dlls_list_ptr must be +; kept in sync for all threads of one process. +; out: eax = APPDATA.dlls_list_ptr if all is OK, +; NULL if memory allocation failed +init_dlls_in_thread: + mov ebx, [current_slot] + mov eax, [ebx+APPDATA.dlls_list_ptr] + test eax, eax + jnz .ret + push [ebx+APPDATA.dir_table] + mov eax, 8 + call malloc + pop edx + test eax, eax + jz .ret + mov [eax], eax + mov [eax+4], eax + mov ecx, [TASK_COUNT] + mov ebx, SLOT_BASE+256 +.set: + cmp [ebx+APPDATA.dir_table], edx + jnz @f + mov [ebx+APPDATA.dlls_list_ptr], eax +@@: + add ebx, 256 + dec ecx + jnz .set +.ret: + ret + +; in: eax = number of references to delete, esi -> DLLDESCR struc +dereference_dll: + sub [esi+DLLDESCR.refcount], eax + jnz .ret + mov eax, [esi+DLLDESCR.fd] + mov edx, [esi+DLLDESCR.bk] + mov [eax+DLLDESCR.bk], edx + mov [edx+DLLDESCR.fd], eax + stdcall kernel_free, [esi+DLLDESCR.coff_hdr] + stdcall kernel_free, [esi+DLLDESCR.data] + mov eax, esi + call free +.ret: + ret + +destroy_hdll: + push ebx ecx esi edi + push eax + mov ebx, [eax+HDLL.base] + mov esi, [eax+HDLL.parent] + mov edx, [esi+DLLDESCR.size] +; The following actions require the context of application where HDLL is mapped. +; However, destroy_hdll can be called in the context of OS thread when +; cleaning up objects created by the application which is destroyed. +; So remember current cr3 and set it to page table of target. + mov eax, [ecx+APPDATA.dir_table] +; Because we cheat with cr3, disable interrupts: task switch would restore +; page table from APPDATA of current thread. +; Also set [current_slot] because it is used by user_free. + pushf + cli + push [current_slot] + mov [current_slot], ecx + mov ecx, cr3 + push ecx + mov cr3, eax + push ebx ; argument for user_free + mov eax, ebx + shr ebx, 12 + push ebx + mov esi, [esi+DLLDESCR.data] + shr esi, 12 +.unmap_loop: + push eax + mov eax, 2 + xchg eax, [page_tabs+ebx*4] + mov ecx, [page_tabs+esi*4] + and eax, not 0xFFF + and ecx, not 0xFFF + cmp eax, ecx + jz @f + call free_page +@@: + pop eax + invlpg [eax] + add eax, 0x1000 + inc ebx + inc esi + sub edx, 0x1000 + ja .unmap_loop + pop ebx + and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK + call user_free +; Restore context. + pop eax + mov cr3, eax + pop [current_slot] + popf +; Ok, cheating is done. + pop eax + push eax + mov esi, [eax+HDLL.parent] + mov eax, [eax+HDLL.refcount] + call dereference_dll + pop eax + mov edx, [eax+HDLL.bk] + mov ebx, [eax+HDLL.fd] + mov [ebx+HDLL.bk], edx + mov [edx+HDLL.fd], ebx + call free + pop edi esi ecx ebx + ret + +; ecx -> APPDATA for slot, esi = dlls_list_ptr +destroy_all_hdlls: + test esi, esi + jz .ret +.loop: + mov eax, [esi+HDLL.fd] + cmp eax, esi + jz free + call destroy_hdll + jmp .loop +.ret: + ret + +align 4 +stop_all_services: + push ebp + mov edx, [srv.fd] +.next: + cmp edx, srv.fd-SRV_FD_OFFSET + je .done + cmp [edx+SRV.magic], ' SRV' + jne .next + cmp [edx+SRV.size], SRV.sizeof + jne .next + + mov ebx, [edx+SRV.entry] + mov edx, [edx+SRV.fd] + test ebx, ebx + jz .next + + push edx + mov ebp, esp + push 0 + push -1 + call ebx + mov esp, ebp + pop edx + jmp .next +.done: + pop ebp + ret + +; param +; eax= size +; ebx= pid + +align 4 +create_kernel_object: + + push ebx + call malloc + pop ebx + test eax, eax + jz .fail + + mov ecx,[current_slot] + add ecx, APP_OBJ_OFFSET + + pushfd + cli + mov edx, [ecx+APPOBJ.fd] + mov [eax+APPOBJ.fd], edx + mov [eax+APPOBJ.bk], ecx + mov [eax+APPOBJ.pid], ebx + + mov [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + popfd +.fail: + ret + +; param +; eax= object + +align 4 +destroy_kernel_object: + + pushfd + cli + mov ebx, [eax+APPOBJ.fd] + mov ecx, [eax+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx + popfd + + xor edx, edx ;clear common header + mov [eax], edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax+16], edx + + call free ;release object memory + ret + + + +if 0 + +irq: + +.irq0: + pusfd + pushad + push IRQ_0 + jmp .master +.irq_1: + pusfd + pushad + push IRQ_1 + jmp .master + +.master: + mov ax, app_data + mov ds, eax + mov es, eax + mov ebx, [esp+4] ;IRQ_xx + mov eax, [irq_handlers+ebx+4] + call intr_handler + mov ecx, [esp+4] + cmp [irq_actids+ecx*4], 0 + je @F + in al, 0x21 + bts eax, ecx + out 0x21, al + mov al, 0x20 + out 0x20, al + jmp .restart + +.slave: + mov ax, app_data + mov ds, eax + mov es, eax + mov ebx, [esp+4] ;IRQ_xx + mov eax, [irq_handlers+ebx+4] + call intr_handler + mov ecx, [esp+4] + sub ecx, 8 + cmp [irq_actids+ecx*4], 0 + je @F + in al, 0xA1 + bts eax, ecx + out 0xA1, al + mov al, 0x20 + out 0xA0, al + out 0x20, al +.restart: + mov ebx, [next_slot] + test ebx, ebx + jz @F + mov [next_task],0 + mov esi, [prev_slot] + call do_change_task + add esp, 4 + iretd + +end if + + + + diff --git a/kernel/tags/kolibri0.7.7.0/core/export.inc b/kernel/tags/kolibri0.7.7.0/core/export.inc new file mode 100644 index 000000000..edb5c373b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/export.inc @@ -0,0 +1,39 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +; Macroinstruction for making export section + + +macro export dllname,[label,string] + { common + local module,addresses,names,ordinal,count + count = 0 + forward + count = count+1 + common + dd 0,0,0, (module-OS_BASE) , 1 + dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE) + addresses: + forward + dd (label-OS_BASE) + common + names: + forward + local name + dd (name-OS_BASE) + common + ordinal: count = 0 + forward + dw count + count = count+1 + common + module db dllname,0 + forward + name db string,0 + } diff --git a/kernel/tags/kolibri0.7.7.0/core/exports.inc b/kernel/tags/kolibri0.7.7.0/core/exports.inc new file mode 100644 index 000000000..7b64cb4ae --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/exports.inc @@ -0,0 +1,153 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +iglobal + szKernel db 'KERNEL', 0 + szVersion db 'version',0 + + szRegService db 'RegService',0 + szGetService db 'GetService',0 + szServiceHandler db 'ServiceHandler',0 + szAttachIntHandler db 'AttachIntHandler',0 + szGetIntHandler db 'GetIntHandler', 0 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 + szReservePortArea db 'ReservePortArea',0 + szBoot_Log db 'Boot_Log',0 + + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead16 db 'PciRead16', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',0 + szPciWrite16 db 'PciWrite16',0 + szPciWrite32 db 'PciWrite32',0 + + szAllocPage db 'AllocPage',0 + szAllocPages db 'AllocPages',0 + szFreePage db 'FreePage',0 + szGetPgAddr db 'GetPgAddr',0 + szMapPage db 'MapPage',0 + szMapSpace db 'MapSpace',0 + szMapIoMem db 'MapIoMem',0 + szCommitPages db 'CommitPages',0 + szReleasePages db 'ReleasePages',0 + + szAllocKernelSpace db 'AllocKernelSpace',0 + szFreeKernelSpace db 'FreeKernelSpace',0 + szKernelAlloc db 'KernelAlloc',0 + szKernelFree db 'KernelFree',0 + szUserAlloc db 'UserAlloc',0 + szUserFree db 'UserFree',0 + szKmalloc db 'Kmalloc',0 + szKfree db 'Kfree',0 + szCreateRingBuffer db 'CreateRingBuffer',0 + + szGetPid db 'GetPid',0 + szCreateObject db 'CreateObject',0 + szDestroyObject db 'DestroyObject',0 + szCreateEvent db 'CreateEvent',0 + szRaiseEvent db 'RaiseEvent',0 + szWaitEvent db 'WaitEvent',0 + szDestroyEvent db 'DestroyEvent',0 + szClearEvent db 'ClearEvent',0 + + szLoadCursor db 'LoadCursor',0 + + szSysMsgBoardStr db 'SysMsgBoardStr', 0 + szSysMsgBoardChar db 'SysMsgBoardChar', 0 + szGetCurrentTask db 'GetCurrentTask',0 + szLFBAddress db 'LFBAddress',0 + szLoadFile db 'LoadFile',0 + szSendEvent db 'SendEvent',0 + szSetMouseData db 'SetMouseData',0 + szSleep db 'Sleep',0 + szGetTimerTicks db 'GetTimerTicks',0 + + szStrncat db 'strncat',0 + szStrncpy db 'strncpy',0 + szstrncmp db 'strncmp',0 + szStrnlen db 'strnlen',0 + szStrchr db 'strchr',0 + szStrrchr db 'strrchr',0 + + +align 16 +kernel_export: + dd szRegService , reg_service + dd szGetService , get_service + dd szServiceHandler , srv_handler + dd szAttachIntHandler, attach_int_handler + dd szGetIntHandler , get_int_handler + dd szFpuSave , fpu_save + dd szFpuRestore , fpu_restore + dd szReservePortArea , r_f_port_area + dd szBoot_Log , boot_log + + dd szPciApi , pci_api + dd szPciRead32 , pci_read32 + dd szPciRead16 , pci_read16 + dd szPciRead8 , pci_read8 + dd szPciWrite8 , pci_write8 + dd szPciWrite16 , pci_write16 + dd szPciWrite32 , pci_write32 + + dd szAllocPage , alloc_page ;stdcall + dd szAllocPages , alloc_pages ;stdcall + dd szFreePage , free_page + dd szMapPage , map_page ;stdcall + dd szMapSpace , map_space + dd szMapIoMem , map_io_mem ;stdcall + dd szGetPgAddr , get_pg_addr + dd szCommitPages , commit_pages ;not implemented + dd szReleasePages , release_pages + + dd szAllocKernelSpace, alloc_kernel_space ;stdcall + dd szFreeKernelSpace , free_kernel_space ;stdcall + dd szKernelAlloc , kernel_alloc ;stdcall + dd szKernelFree , kernel_free ;stdcall + dd szUserAlloc , user_alloc ;stdcall + dd szUserFree , user_free ;stdcall + dd szKmalloc , malloc + dd szKfree , free + dd szCreateRingBuffer, create_ring_buffer ;stdcall + + dd szGetPid , get_pid + dd szCreateObject , create_kernel_object + dd szDestroyObject , destroy_kernel_object + dd szCreateEvent , create_event ;see EVENT.inc for specification + dd szRaiseEvent , raise_event ;see EVENT.inc for specification + dd szWaitEvent , wait_event ;see EVENT.inc for specification + dd szDestroyEvent , destroy_event ;see EVENT.inc for specification + dd szClearEvent , clear_event ;see EVENT.inc for specification + + dd szLoadCursor , load_cursor ;stdcall + + dd szSysMsgBoardStr , sys_msg_board_str + dd szSysMsgBoardChar , sys_msg_board + dd szGetCurrentTask , get_curr_task + dd szLoadFile , load_file ;retval eax, ebx + dd szSendEvent , send_event ;see EVENT.inc for specification + dd szSetMouseData , set_mouse_data ;stdcall + dd szSleep , delay_ms + dd szGetTimerTicks , get_timer_ticks + + dd szStrncat , strncat + dd szStrncpy , strncpy + dd szstrncmp , strncmp + dd szStrnlen , strnlen + dd szStrchr , strchr + dd szStrrchr , strrchr + +exp_lfb: + dd szLFBAddress , 0 + dd 0 ;terminator, must be zero + +endg diff --git a/kernel/tags/kolibri0.7.7.0/core/ext_lib.inc b/kernel/tags/kolibri0.7.7.0/core/ext_lib.inc new file mode 100644 index 000000000..db53e6326 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/ext_lib.inc @@ -0,0 +1,320 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;============================================================================ +; +; External kernel dependencies (libraries) loading +; +;============================================================================ + +$Revision$ + +if 0 +; The code currently does not work. Kill "if 0/end if" only after correcting +; to current kernel (dll.inc). +macro library [name,fname] +{ + forward + dd __#name#_library_table__,__#name#_library_name__ + common + dd 0 + forward + __#name#_library_name__ db fname,0 +} + +macro import lname,[name,sname] +{ + common + align 4 + __#lname#_library_table__: + forward + name dd __#name#_import_name__ + common + dd 0 + forward + __#name#_import_name__ db sname,0 +} + +macro export [name,sname] +{ +align 4 + forward + dd __#name#_export_name__,name + common + dd 0 + forward + __#name#_export_name__ db sname,0 +} + + + +align 4 ; loading library (use kernel functions) +proc load_k_library stdcall, file_name:dword + locals + coff dd ? + sym dd ? + strings dd ? + img_size dd ? + img_base dd ? + exports dd ? + endl + + cli + + stdcall load_file, [file_name] + test eax, eax + jz .fail + + mov [coff], eax + movzx ecx, [eax+CFH.nSections] + xor ebx, ebx + + lea edx, [eax+20] +@@: + add ebx, [edx+CFS.SizeOfRawData] + add ebx, 15 + and ebx, not 15 + add edx, COFF_SECTION_SIZE + dec ecx + jnz @B + mov [img_size], ebx + + stdcall kernel_alloc, [img_size] + + test eax, eax + jz .fail + mov [img_base], eax + + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, [img_base] + lea eax, [edx+20] +@@: + mov [eax+CFS.VirtualAddress], edi + mov esi, [eax+CFS.PtrRawData] + test esi, esi + jnz .copy + add edi, [eax+CFS.SizeOfRawData] + jmp .next +.copy: + add esi, edx + mov ecx, [eax+CFS.SizeOfRawData] + cld + rep movsb +.next: + add edi, 15 + and edi, not 15 + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + mov ebx, [edx+CFH.pSymTable] + add ebx, edx + mov [sym], ebx + mov ecx, [edx+CFH.nSymbols] + add ecx,ecx + lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE + add ecx, [sym] + mov [strings], ecx + + lea eax, [edx+20] + + stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ + [strings], dword 0 + test eax, eax + jnz @F + +@@: + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, 0 + lea eax, [edx+20] +@@: + add [eax+CFS.VirtualAddress], edi ;patch user space offset + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + add edx, 20 + stdcall fix_coff_relocs, [coff], edx, [sym] + + mov ebx, [coff] + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS + mov [exports], eax + + stdcall kernel_free, [coff] + + mov eax, [exports] + ret +.fail: + xor eax, eax + ret +endp + + +proc dll.Load, import_table:dword + mov esi,[import_table] + .next_lib: mov edx,[esi] + or edx,edx + jz .exit + push esi + + mov edi,s_libname + + mov al, '/' + stosb + mov esi,sysdir_path + @@: lodsb + stosb + or al,al + jnz @b + dec edi + mov [edi], dword '/lib' + mov [edi+4],byte '/' + add edi,5 + pop esi + push esi + mov esi,[esi+4] + @@: lodsb + stosb + or al,al + jnz @b + + pushad + stdcall load_k_library,s_libname + mov [esp+28],eax + popad + or eax,eax + jz .fail + stdcall dll.Link,eax,edx + stdcall dll.Init,[eax+4] + pop esi + add esi,8 + jmp .next_lib + .exit: xor eax,eax + ret + .fail: add esp,4 + xor eax,eax + inc eax + ret +endp + +proc dll.Link, exp:dword,imp:dword + push eax + mov esi,[imp] + test esi,esi + jz .done + .next: lodsd + test eax,eax + jz .done + stdcall dll.GetProcAddress,[exp],eax + or eax,eax + jz @f + mov [esi-4],eax + jmp .next + @@: mov dword[esp],0 + .done: pop eax + ret +endp + +proc dll.Init, dllentry:dword + pushad + mov eax,mem.Alloc + mov ebx,mem.Free + mov ecx,mem.ReAlloc + mov edx,dll.Load + stdcall [dllentry] + popad + ret +endp + +proc dll.GetProcAddress, exp:dword,sz_name:dword + mov edx,[exp] + .next: test edx,edx + jz .end + stdcall strncmp,[edx],[sz_name], dword -1 + test eax,eax + jz .ok + add edx,8 + jmp .next + .ok: mov eax,[edx+4] + .end: ret +endp + +;----------------------------------------------------------------------------- +proc mem.Alloc size ;///////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx +; mov eax,[size] +; lea ecx,[eax+4+4095] +; and ecx,not 4095 +; stdcall kernel_alloc, ecx +; add ecx,-4 +; mov [eax],ecx +; add eax,4 + + stdcall kernel_alloc, [size] + + pop ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx esi edi eax + mov eax,[mptr] + mov ebx,[size] + or eax,eax + jz @f + lea ecx,[ebx+4+4095] + and ecx,not 4095 + add ecx,-4 + cmp ecx,[eax-4] + je .exit + @@: mov eax,ebx + call mem.Alloc + xchg eax,[esp] + or eax,eax + jz .exit + mov esi,eax + xchg eax,[esp] + mov edi,eax + mov ecx,[esi-4] + cmp ecx,[edi-4] + jbe @f + mov ecx,[edi-4] + @@: add ecx,3 + shr ecx,2 + cld + rep movsd + xchg eax,[esp] + call mem.Free + .exit: + pop eax edi esi ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.Free mptr ;////////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- +; mov eax,[mptr] +; or eax,eax +; jz @f +; push ebx ecx +; lea ecx,[eax-4] +; stdcall kernel_free, ecx +; pop ecx ebx +; @@: ret + stdcall kernel_free, [mptr] + ret +endp + +uglobal +s_libname db 64 dup (0) +endg +end if diff --git a/kernel/tags/kolibri0.7.7.0/core/fpu.inc b/kernel/tags/kolibri0.7.7.0/core/fpu.inc new file mode 100644 index 000000000..5b11e0aa8 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/fpu.inc @@ -0,0 +1,183 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +init_fpu: + clts + fninit + + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + mov ebx, cr4 + mov ecx, cr0 + or ebx, CR4_OSFXSR+CR4_OSXMMEXPT + mov cr4, ebx + + and ecx, not (CR0_MP+CR0_EM) + or ecx, CR0_NE + mov cr0, ecx + + mov dword [esp-4], SSE_INIT + ldmxcsr [esp-4] + + xorps xmm0, xmm0 + xorps xmm1, xmm1 + xorps xmm2, xmm2 + xorps xmm3, xmm3 + xorps xmm4, xmm4 + xorps xmm5, xmm5 + xorps xmm6, xmm6 + xorps xmm7, xmm7 + fxsave [fpu_data] ;[eax] + ret +.no_SSE: + mov ecx, cr0 + and ecx, not CR0_EM + or ecx, CR0_MP+CR0_NE + mov cr0, ecx + fnsave [fpu_data] + ret + +; param +; eax= 512 bytes memory area + +align 4 +fpu_save: + push ecx + push esi + push edi + + pushfd + cli + + clts + mov edi, eax + + mov ecx, [fpu_owner] + mov esi, [CURRENT_TASK] + cmp ecx, esi + jne .save + + call save_context + jmp .exit +.save: + mov [fpu_owner], esi + + shl ecx, 8 + mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] + + call save_context + + shl esi, 8 + mov esi, [esi+SLOT_BASE+APPDATA.fpu_state] + mov ecx, 512/4 + cld + rep movsd + fninit +.exit: + popfd + pop edi + pop esi + pop ecx + ret + +align 4 +save_context: + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxsave [eax] + ret +.no_SSE: + fnsave [eax] + ret + +align 4 +fpu_restore: + push ecx + push esi + + mov esi, eax + + pushfd + cli + + mov ecx, [fpu_owner] + mov eax, [CURRENT_TASK] + cmp ecx, eax + jne .copy + + clts + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxrstor [esi] + popfd + pop esi + pop ecx + ret +.no_SSE: + fnclex ;fix possible problems + frstor [esi] + popfd + pop esi + pop ecx + ret +.copy: + shl eax, 8 + mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] + mov ecx, 512/4 + cld + rep movsd + popfd + pop esi + pop ecx + ret + +align 4 +except_7: ;#NM exception handler + save_ring3_context + clts + mov ax, app_data ; + mov ds, ax + mov es, ax + + mov ebx, [fpu_owner] + cmp ebx, [CURRENT_TASK] + je .exit + + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + fxrstor [eax] +.exit: + restore_ring3_context + iret + +.no_SSE: + fnsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + frstor [eax] + restore_ring3_context + iret + +iglobal + fpu_owner dd 0 +endg diff --git a/kernel/tags/kolibri0.7.7.0/core/heap.inc b/kernel/tags/kolibri0.7.7.0/core/heap.inc new file mode 100644 index 000000000..2aee238a5 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/heap.inc @@ -0,0 +1,1538 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +struc MEM_BLOCK +{ .next_block dd ? + .prev_block dd ? ;+4 + .list_fd dd ? ;+8 + .list_bk dd ? ;+12 + .base dd ? ;+16 + .size dd ? ;+20 + .flags dd ? ;+24 + .handle dd ? ;+28 +} + +MEM_LIST_OFFSET equ 8 +FREE_BLOCK equ 4 +USED_BLOCK equ 8 +DONT_FREE_BLOCK equ 10h + +virtual at 0 + MEM_BLOCK MEM_BLOCK +end virtual + +MEM_BLOCK_SIZE equ 8*4 + +block_next equ MEM_BLOCK.next_block +block_prev equ MEM_BLOCK.prev_block +list_fd equ MEM_BLOCK.list_fd +list_bk equ MEM_BLOCK.list_bk +block_base equ MEM_BLOCK.base +block_size equ MEM_BLOCK.size +block_flags equ MEM_BLOCK.flags + +macro calc_index op +{ shr op, 12 + dec op + cmp op, 63 + jna @f + mov op, 63 +@@: +} + +macro remove_from_list op +{ mov edx, [op+list_fd] + mov ecx, [op+list_bk] + test edx, edx + jz @f + mov [edx+list_bk], ecx +@@: + test ecx, ecx + jz @f + mov [ecx+list_fd], edx +@@: + mov [op+list_fd],0 + mov [op+list_bk],0 +} + +macro remove_from_free op +{ + remove_from_list op + + mov eax, [op+block_size] + calc_index eax + cmp [mem_block_list+eax*4], op + jne @f + mov [mem_block_list+eax*4], edx +@@: + cmp [mem_block_list+eax*4], 0 + jne @f + btr [mem_block_mask], eax +@@: +} + +macro remove_from_used op +{ + mov edx, [op+list_fd] + mov ecx, [op+list_bk] + mov [edx+list_bk], ecx + mov [ecx+list_fd], edx + mov [op+list_fd], 0 + mov [op+list_bk], 0 +} + +align 4 +proc init_kernel_heap + + mov ecx, 64 + mov edi, mem_block_list + xor eax, eax + cld + rep stosd + + mov ecx, 512/4 + mov edi, mem_block_map + not eax + rep stosd + + mov [mem_block_start], mem_block_map + mov [mem_block_end], mem_block_map+512 + mov [mem_block_arr], HEAP_BASE + + mov eax, mem_used.fd-MEM_LIST_OFFSET + mov [mem_used.fd], eax + mov [mem_used.bk], eax + + stdcall alloc_pages, dword 32 + mov ecx, 32 + mov edx, eax + mov edi, HEAP_BASE +.l1: + stdcall map_page,edi,edx,PG_SW + add edi, 0x1000 + add edx, 0x1000 + dec ecx + jnz .l1 + + mov edi, HEAP_BASE + mov ebx, HEAP_BASE+MEM_BLOCK_SIZE + xor eax, eax + mov [edi+block_next], ebx + mov [edi+block_prev], eax + mov [edi+list_fd], eax + mov [edi+list_bk], eax + mov [edi+block_base], HEAP_BASE + mov [edi+block_size], 4096*MEM_BLOCK_SIZE + mov [edi+block_flags], USED_BLOCK + + mov [ebx+block_next], eax + mov [ebx+block_prev], eax + mov [ebx+list_fd], eax + mov [ebx+list_bk], eax + mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE + + mov ecx, [pg_data.kernel_pages] + shl ecx, 12 + sub ecx, HEAP_BASE+4096*MEM_BLOCK_SIZE + mov [heap_size], ecx + mov [heap_free], ecx + mov [ebx+block_size], ecx + mov [ebx+block_flags], FREE_BLOCK + + mov [mem_block_mask], eax + mov [mem_block_mask+4],0x80000000 + + mov [mem_block_list+63*4], ebx + mov byte [mem_block_map], 0xFC + and [heap_mutex], 0 + mov [heap_blocks], 4095 + mov [free_blocks], 4094 + ret +endp + +; param +; eax= required size +; +; retval +; edi= memory block descriptor +; ebx= descriptor index + +align 4 +get_small_block: + mov ecx, eax + shr ecx, 12 + dec ecx + cmp ecx, 63 + jle .get_index + mov ecx, 63 +.get_index: + lea esi, [mem_block_mask] + xor ebx, ebx + or edx, -1 + + cmp ecx, 32 + jb .bit_test + + sub ecx, 32 + add ebx, 32 + add esi, 4 +.bit_test: + shl edx, cl + and edx, [esi] +.find: + bsf edi, edx + jz .high_mask + add ebx, edi + mov edi, [mem_block_list+ebx*4] +.check_size: + cmp eax, [edi+block_size] + ja .next + ret + +.high_mask: + add esi, 4 + cmp esi, mem_block_mask+8 + jae .err + add ebx, 32 + mov edx, [esi] + jmp .find +.next: + mov edi, [edi+list_fd] + test edi, edi + jnz .check_size +.err: + xor edi, edi + ret + +align 4 +alloc_mem_block: + + mov ebx, [mem_block_start] + mov ecx, [mem_block_end] +.l1: + bsf eax,[ebx]; + jnz found + add ebx,4 + cmp ebx, ecx + jb .l1 + xor eax,eax + ret + +found: + btr [ebx], eax + mov [mem_block_start],ebx + sub ebx, mem_block_map + lea eax,[eax+ebx*8] + shl eax, 5 + add eax, [mem_block_arr] + dec [free_blocks] + ret +align 4 +free_mem_block: + mov dword [eax], 0 + mov dword [eax+4], 0 + mov dword [eax+8], 0 + mov dword [eax+12], 0 + mov dword [eax+16], 0 +; mov dword [eax+20], 0 + mov dword [eax+24], 0 + mov dword [eax+28], 0 + + sub eax, [mem_block_arr] + shr eax, 5 + + mov ebx, mem_block_map + bts [ebx], eax + inc [free_blocks] + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [mem_block_start], eax + ja @f + ret +@@: + mov [mem_block_start], eax + ret +.err: + xor eax, eax + ret + +align 4 +proc alloc_kernel_space stdcall, size:dword + local block_ind:DWORD + + push ebx + push esi + push edi + + mov eax, [size] + add eax, 4095 + and eax, not 4095 + mov [size], eax + + mov ebx, heap_mutex + call wait_mutex ;ebx + + cmp eax, [heap_free] + ja .error + + call get_small_block ; eax + test edi, edi + jz .error + + cmp [edi+block_flags], FREE_BLOCK + jne .error + + mov [block_ind], ebx ;index of allocated block + + mov eax, [edi+block_size] + cmp eax, [size] + je .m_eq_size + + call alloc_mem_block + and eax, eax + jz .error + + mov esi, eax ;esi - splitted block + + mov [esi+block_next], edi + mov eax, [edi+block_prev] + mov [esi+block_prev], eax + mov [edi+block_prev], esi + mov [esi+list_fd], 0 + mov [esi+list_bk], 0 + and eax, eax + jz @f + mov [eax+block_next], esi +@@: + mov ebx, [edi+block_base] + mov [esi+block_base], ebx + mov edx, [size] + mov [esi+block_size], edx + add [edi+block_base], edx + sub [edi+block_size], edx + + mov eax, [edi+block_size] + shr eax, 12 + sub eax, 1 + cmp eax, 63 + jna @f + mov eax, 63 +@@: + cmp eax, [block_ind] + je .m_eq_ind + + remove_from_list edi + + mov ecx, [block_ind] + mov [mem_block_list+ecx*4], edx + + test edx, edx + jnz @f + btr [mem_block_mask], ecx +@@: + mov edx, [mem_block_list+eax*4] + mov [edi+list_fd], edx + test edx, edx + jz @f + mov [edx+list_bk], edi +@@: + mov [mem_block_list+eax*4], edi + bts [mem_block_mask], eax +.m_eq_ind: + mov ecx, mem_used.fd-MEM_LIST_OFFSET + mov edx, [ecx+list_fd] + mov [esi+list_fd], edx + mov [esi+list_bk], ecx + mov [ecx+list_fd], esi + mov [edx+list_bk], esi + + mov [esi+block_flags], USED_BLOCK + mov eax, [esi+block_base] + mov ebx, [size] + sub [heap_free], ebx + and [heap_mutex], 0 + pop edi + pop esi + pop ebx + ret +.m_eq_size: + remove_from_list edi + mov [mem_block_list+ebx*4], edx + and edx, edx + jnz @f + btr [mem_block_mask], ebx +@@: + mov ecx, mem_used.fd-MEM_LIST_OFFSET + mov edx, [ecx+list_fd] + mov [edi+list_fd], edx + mov [edi+list_bk], ecx + mov [ecx+list_fd], edi + mov [edx+list_bk], edi + + mov [edi+block_flags], USED_BLOCK + mov eax, [edi+block_base] + mov ebx, [size] + sub [heap_free], ebx + and [heap_mutex], 0 + pop edi + pop esi + pop ebx + ret +.error: + xor eax, eax + mov [heap_mutex], eax + pop edi + pop esi + pop ebx + ret +endp + +align 4 +proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword + push ebx + push esi + push edi + mov ebx, heap_mutex + call wait_mutex ;ebx + + mov eax, [base] + mov esi, [mem_used.fd] +@@: + cmp esi, mem_used.fd-MEM_LIST_OFFSET + je .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_fd] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + mov eax, [esi+block_size] + add [heap_free], eax + + mov edi, [esi+block_next] + test edi, edi + jz .prev + + cmp [edi+block_flags], FREE_BLOCK + jne .prev + + remove_from_free edi + + mov edx, [edi+block_next] + mov [esi+block_next], edx + test edx, edx + jz @f + + mov [edx+block_prev], esi +@@: + mov ecx, [edi+block_size] + add [esi+block_size], ecx + + mov eax, edi + call free_mem_block +.prev: + mov edi, [esi+block_prev] + test edi, edi + jz .insert + + cmp [edi+block_flags], FREE_BLOCK + jne .insert + + remove_from_used esi + + mov edx, [esi+block_next] + mov [edi+block_next], edx + test edx, edx + jz @f + mov [edx+block_prev], edi +@@: + mov eax, esi + call free_mem_block + + mov ecx, [edi+block_size] + mov eax, [esi+block_size] + add eax, ecx + mov [edi+block_size], eax + + calc_index eax + calc_index ecx + cmp eax, ecx + je .m_eq + + push ecx + remove_from_list edi + pop ecx + + cmp [mem_block_list+ecx*4], edi + jne @f + mov [mem_block_list+ecx*4], edx +@@: + cmp [mem_block_list+ecx*4], 0 + jne @f + btr [mem_block_mask], ecx +@@: + mov esi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], edi + mov [edi+list_fd], esi + test esi, esi + jz @f + mov [esi+list_bk], edi +@@: + bts [mem_block_mask], eax +.m_eq: + xor eax, eax + mov [heap_mutex], eax + dec eax + pop edi + pop esi + pop ebx + ret +.insert: + remove_from_used esi + + mov eax, [esi+block_size] + calc_index eax + + mov edi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], esi + mov [esi+list_fd], edi + test edi, edi + jz @f + mov [edi+list_bk], esi +@@: + bts [mem_block_mask], eax + mov [esi+block_flags],FREE_BLOCK + xor eax, eax + mov [heap_mutex], eax + dec eax + pop edi + pop esi + pop ebx + ret +.fail: + xor eax, eax + mov [heap_mutex], eax + pop edi + pop esi + pop ebx + ret +endp + +align 4 +proc kernel_alloc stdcall, size:dword + locals + lin_addr dd ? + pages_count dd ? + endl + + push ebx + push edi + + mov eax, [size] + add eax, 4095 + and eax, not 4095; + mov [size], eax + and eax, eax + jz .err + mov ebx, eax + shr ebx, 12 + mov [pages_count], ebx + + stdcall alloc_kernel_space, eax + test eax, eax + jz .err + mov [lin_addr], eax + + mov ecx, [pages_count] + mov edx, eax + mov ebx, ecx + + shr ecx, 3 + jz .next + + and ebx, not 7 + push ebx + stdcall alloc_pages, ebx + pop ecx ; yes ecx!!! + and eax, eax + jz .err + + mov edi, eax + mov edx, [lin_addr] +@@: + stdcall map_page,edx,edi,dword PG_SW + add edx, 0x1000 + add edi, 0x1000 + dec ecx + jnz @B +.next: + mov ecx, [pages_count] + and ecx, 7 + jz .end +@@: + push ecx + call alloc_page + pop ecx + test eax, eax + jz .err + + stdcall map_page,edx,eax,dword PG_SW + add edx, 0x1000 + dec ecx + jnz @B +.end: + mov eax, [lin_addr] + pop edi + pop ebx + ret +.err: + xor eax, eax + pop edi + pop ebx + ret +endp + +align 4 +proc kernel_free stdcall, base:dword + push ebx esi + + mov ebx, heap_mutex + call wait_mutex ;ebx + + mov eax, [base] + mov esi, [mem_used.fd] +@@: + cmp esi, mem_used.fd-MEM_LIST_OFFSET + je .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_fd] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + and [heap_mutex], 0 + + push ecx + mov ecx, [esi+block_size]; + shr ecx, 12 + call release_pages ;eax, ecx + pop ecx + stdcall free_kernel_space, [base] + pop esi ebx + ret +.fail: + and [heap_mutex], 0 + pop esi ebx + ret +endp + +restore block_next +restore block_prev +restore block_list +restore block_base +restore block_size +restore block_flags + +;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; + +HEAP_TOP equ 0x5FC00000 + +align 4 +proc init_heap + + mov ebx,[current_slot] + mov eax, [ebx+APPDATA.heap_top] + test eax, eax + jz @F + sub eax,[ebx+APPDATA.heap_base] + sub eax, 4096 + ret +@@: + mov esi, [ebx+APPDATA.mem_size] + add esi, 4095 + and esi, not 4095 + mov [ebx+APPDATA.mem_size], esi + mov eax, HEAP_TOP + mov [ebx+APPDATA.heap_base], esi + mov [ebx+APPDATA.heap_top], eax + + sub eax, esi + shr esi, 10 + mov ecx, eax + sub eax, 4096 + or ecx, FREE_BLOCK + mov [page_tabs+esi], ecx + ret +endp + +align 4 +proc user_alloc stdcall, alloc_size:dword + + push ebx + push esi + push edi + + mov ecx, [alloc_size] + add ecx, (4095+4096) + and ecx, not 4095 + + mov ebx, [current_slot] + mov esi, dword [ebx+APPDATA.heap_base] ; heap_base + mov edi, dword [ebx+APPDATA.heap_top] ; heap_top +l_0: + cmp esi, edi + jae m_exit + + mov ebx, esi + shr ebx, 12 + mov eax, [page_tabs+ebx*4] + test al, FREE_BLOCK + jz test_used + and eax, 0xFFFFF000 + cmp eax, ecx ;alloc_size + jb m_next + jz @f + + lea edx, [esi+ecx] + sub eax, ecx + or al, FREE_BLOCK + shr edx, 12 + mov [page_tabs+edx*4], eax +@@: + or ecx, USED_BLOCK + mov [page_tabs+ebx*4], ecx + shr ecx, 12 + inc ebx + dec ecx + jz .no +@@: + mov dword [page_tabs+ebx*4], 2 + inc ebx + dec ecx + jnz @B +.no: + + mov edx, [current_slot] + mov ebx, [alloc_size] + add ebx, 0xFFF + and ebx, not 0xFFF + add ebx, [edx+APPDATA.mem_size] + call update_mem_size + + lea eax, [esi+4096] + + pop edi + pop esi + pop ebx + ret +test_used: + test al, USED_BLOCK + jz m_exit + + and eax, 0xFFFFF000 +m_next: + add esi, eax + jmp l_0 +m_exit: + xor eax, eax + pop edi + pop esi + pop ebx + ret +endp + +align 4 +proc user_alloc_at stdcall, address:dword, alloc_size:dword + + push ebx + push esi + push edi + + mov ebx, [current_slot] + mov edx, [address] + and edx, not 0xFFF + mov [address], edx + sub edx, 0x1000 + jb .error + mov esi, [ebx+APPDATA.heap_base] + mov edi, [ebx+APPDATA.heap_top] + cmp edx, esi + jb .error +.scan: + cmp esi, edi + jae .error + mov ebx, esi + shr ebx, 12 + mov eax, [page_tabs+ebx*4] + mov ecx, eax + and ecx, 0xFFFFF000 + add ecx, esi + cmp edx, ecx + jb .found + mov esi, ecx + jmp .scan +.error: + xor eax, eax + pop edi + pop esi + pop ebx + ret +.found: + test al, FREE_BLOCK + jz .error + mov eax, ecx + sub eax, edx + sub eax, 0x1000 + cmp eax, [alloc_size] + jb .error + +; Here we have 1 big free block which includes requested area. +; In general, 3 other blocks must be created instead: +; free at [esi, edx); +; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000)); +; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx) +; First or third block (or both) may be absent. + mov eax, edx + sub eax, esi + jz .nofirst + or al, FREE_BLOCK + mov [page_tabs+ebx*4], eax +.nofirst: + mov eax, [alloc_size] + add eax, 0x1FFF + and eax, not 0xFFF + mov ebx, edx + add edx, eax + shr ebx, 12 + or al, USED_BLOCK + mov [page_tabs+ebx*4], eax + shr eax, 12 + dec eax + jz .second_nofill + inc ebx +.fill: + mov dword [page_tabs+ebx*4], 2 + inc ebx + dec eax + jnz .fill +.second_nofill: + sub ecx, edx + jz .nothird + or cl, FREE_BLOCK + mov [page_tabs+ebx*4], ecx +.nothird: + + mov edx, [current_slot] + mov ebx, [alloc_size] + add ebx, 0xFFF + and ebx, not 0xFFF + add ebx, [edx+APPDATA.mem_size] + call update_mem_size + + mov eax, [address] + + pop edi + pop esi + pop ebx + ret +endp + +align 4 +proc user_free stdcall, base:dword + + push esi + + mov esi, [base] + test esi, esi + jz .exit + + push ebx + + xor ebx, ebx + shr esi, 12 + mov eax, [page_tabs+(esi-1)*4] + test al, USED_BLOCK + jz .cantfree + test al, DONT_FREE_BLOCK + jnz .cantfree + + and eax, not 4095 + mov ecx, eax + or al, FREE_BLOCK + mov [page_tabs+(esi-1)*4], eax + sub ecx, 4096 + mov ebx, ecx + shr ecx, 12 + jz .released +.release: + xor eax, eax + xchg eax, [page_tabs+esi*4] + test al, 1 + jz @F + test eax, PG_SHARED + jnz @F + call free_page + mov eax, esi + shl eax, 12 + invlpg [eax] +@@: + inc esi + dec ecx + jnz .release +.released: + push edi + + mov edx, [current_slot] + mov esi, dword [edx+APPDATA.heap_base] + mov edi, dword [edx+APPDATA.heap_top] + sub ebx, [edx+APPDATA.mem_size] + neg ebx + call update_mem_size + call user_normalize + pop edi + pop ebx + pop esi + ret +.exit: + xor eax, eax + inc eax + pop esi + ret +.cantfree: + xor eax, eax + pop ebx + pop esi + ret +endp + +user_normalize: +; in: esi=heap_base, edi=heap_top +; out: eax=0 <=> OK +; destroys: ebx,edx,esi,edi + shr esi, 12 + shr edi, 12 +@@: + mov eax, [page_tabs+esi*4] + test al, USED_BLOCK + jz .test_free + shr eax, 12 + add esi, eax + jmp @B +.test_free: + test al, FREE_BLOCK + jz .err + mov edx, eax + shr edx, 12 + add edx, esi + cmp edx, edi + jae .exit + + mov ebx, [page_tabs+edx*4] + test bl, USED_BLOCK + jz .next_free + + shr ebx, 12 + add edx, ebx + mov esi, edx + jmp @B +.next_free: + test bl, FREE_BLOCK + jz .err + and dword [page_tabs+edx*4], 0 + add eax, ebx + and eax, not 4095 + or eax, FREE_BLOCK + mov [page_tabs+esi*4], eax + jmp @B +.exit: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret + +user_realloc: +; in: eax = pointer, ebx = new size +; out: eax = new pointer or NULL + test eax, eax + jnz @f +; realloc(NULL,sz) - same as malloc(sz) + push ebx + call user_alloc + ret +@@: + push ecx edx + lea ecx, [eax - 0x1000] + shr ecx, 12 + mov edx, [page_tabs+ecx*4] + test dl, USED_BLOCK + jnz @f +; attempt to realloc invalid pointer +.ret0: + pop edx ecx + xor eax, eax + ret +@@: + test dl, DONT_FREE_BLOCK + jnz .ret0 + add ebx, 0x1FFF + shr edx, 12 + shr ebx, 12 +; edx = allocated size, ebx = new size + add edx, ecx + add ebx, ecx + cmp edx, ebx + jb .realloc_add +; release part of allocated memory +.loop: + cmp edx, ebx + jz .release_done + dec edx + xor eax, eax + xchg eax, [page_tabs+edx*4] + test al, 1 + jz .loop + call free_page + mov eax, edx + shl eax, 12 + invlpg [eax] + jmp .loop +.release_done: + sub ebx, ecx + cmp ebx, 1 + jnz .nofreeall + mov eax, [page_tabs+ecx*4] + and eax, not 0xFFF + mov edx, [current_slot] + mov ebx, [APPDATA.mem_size+edx] + sub ebx, eax + add ebx, 0x1000 + or al, FREE_BLOCK + mov [page_tabs+ecx*4], eax + push esi edi + mov esi, [APPDATA.heap_base+edx] + mov edi, [APPDATA.heap_top+edx] + call update_mem_size + call user_normalize + pop edi esi + jmp .ret0 ; all freed +.nofreeall: + sub edx, ecx + shl ebx, 12 + or ebx, USED_BLOCK + xchg [page_tabs+ecx*4], ebx + shr ebx, 12 + sub ebx, edx + push ebx ecx edx + mov edx, [current_slot] + shl ebx, 12 + sub ebx, [APPDATA.mem_size+edx] + neg ebx + call update_mem_size + pop edx ecx ebx + lea eax, [ecx+1] + shl eax, 12 + push eax + add ecx, edx + lea edx, [ecx+ebx] + shl ebx, 12 + jz .ret + push esi + mov esi, [current_slot] + mov esi, [APPDATA.heap_top+esi] + shr esi, 12 +@@: + cmp edx, esi + jae .merge_done + mov eax, [page_tabs+edx*4] + test al, USED_BLOCK + jnz .merge_done + and dword [page_tabs+edx*4], 0 + shr eax, 12 + add edx, eax + shl eax, 12 + add ebx, eax + jmp @b +.merge_done: + pop esi + or ebx, FREE_BLOCK + mov [page_tabs+ecx*4], ebx +.ret: + pop eax edx ecx + ret +.realloc_add: +; get some additional memory + mov eax, [current_slot] + mov eax, [APPDATA.heap_top+eax] + shr eax, 12 + cmp edx, eax + jae .cant_inplace + mov eax, [page_tabs+edx*4] + test al, FREE_BLOCK + jz .cant_inplace + shr eax, 12 + add eax, edx + sub eax, ebx + jb .cant_inplace + jz @f + shl eax, 12 + or al, FREE_BLOCK + mov [page_tabs+ebx*4], eax +@@: + mov eax, ebx + sub eax, ecx + shl eax, 12 + or al, USED_BLOCK + mov [page_tabs+ecx*4], eax + lea eax, [ecx+1] + shl eax, 12 + push eax + push edi + lea edi, [page_tabs+edx*4] + mov eax, 2 + sub ebx, edx + mov ecx, ebx + cld + rep stosd + pop edi + mov edx, [current_slot] + shl ebx, 12 + add ebx, [APPDATA.mem_size+edx] + call update_mem_size + pop eax edx ecx + ret +.cant_inplace: + push esi edi + mov eax, [current_slot] + mov esi, [APPDATA.heap_base+eax] + mov edi, [APPDATA.heap_top+eax] + shr esi, 12 + shr edi, 12 + sub ebx, ecx +.find_place: + cmp esi, edi + jae .place_not_found + mov eax, [page_tabs+esi*4] + test al, FREE_BLOCK + jz .next_place + shr eax, 12 + cmp eax, ebx + jae .place_found + add esi, eax + jmp .find_place +.next_place: + shr eax, 12 + add esi, eax + jmp .find_place +.place_not_found: + pop edi esi + jmp .ret0 +.place_found: + sub eax, ebx + jz @f + push esi + add esi, ebx + shl eax, 12 + or al, FREE_BLOCK + mov [page_tabs+esi*4], eax + pop esi +@@: + mov eax, ebx + shl eax, 12 + or al, USED_BLOCK + mov [page_tabs+esi*4], eax + inc esi + mov eax, esi + shl eax, 12 + push eax + mov eax, [page_tabs+ecx*4] + and eax, not 0xFFF + or al, FREE_BLOCK + sub edx, ecx + mov [page_tabs+ecx*4], eax + inc ecx + dec ebx + dec edx + jz .no +@@: + xor eax, eax + xchg eax, [page_tabs+ecx*4] + mov [page_tabs+esi*4], eax + mov eax, ecx + shl eax, 12 + invlpg [eax] + inc esi + inc ecx + dec ebx + dec edx + jnz @b +.no: + push ebx + mov edx, [current_slot] + shl ebx, 12 + add ebx, [APPDATA.mem_size+edx] + call update_mem_size + pop ebx +@@: + mov dword [page_tabs+esi*4], 2 + inc esi + dec ebx + jnz @b + pop eax edi esi edx ecx + ret + +if 0 +align 4 +proc alloc_dll + pushf + cli + bsf eax, [dll_map] + jnz .find + popf + xor eax, eax + ret +.find: + btr [dll_map], eax + popf + shl eax, 5 + add eax, dll_tab + ret +endp + +align 4 +proc alloc_service + pushf + cli + bsf eax, [srv_map] + jnz .find + popf + xor eax, eax + ret +.find: + btr [srv_map], eax + popf + shl eax,0x02 + lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 + ret +endp + +end if + + +;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;; + + +; param +; eax= shm_map object + +align 4 +destroy_smap: + + pushfd + cli + + push esi + push edi + + mov edi, eax + mov esi, [eax+SMAP.parent] + test esi, esi + jz .done + + lock dec [esi+SMEM.refcount] + jnz .done + + mov ecx, [esi+SMEM.bk] + mov edx, [esi+SMEM.fd] + + mov [ecx+SMEM.fd], edx + mov [edx+SMEM.bk], ecx + + stdcall kernel_free, [esi+SMEM.base] + mov eax, esi + call free +.done: + mov eax, edi + call destroy_kernel_object + + pop edi + pop esi + popfd + + ret + +E_NOTFOUND equ 5 +E_ACCESS equ 10 +E_NOMEM equ 30 +E_PARAM equ 33 + +SHM_READ equ 0 +SHM_WRITE equ 1 + +SHM_ACCESS_MASK equ 3 + +SHM_OPEN equ (0 shl 2) +SHM_OPEN_ALWAYS equ (1 shl 2) +SHM_CREATE equ (2 shl 2) + +SHM_OPEN_MASK equ (3 shl 2) + +align 4 +proc shmem_open stdcall name:dword, size:dword, access:dword + locals + action dd ? + owner_access dd ? + mapped dd ? + endl + + push ebx + push esi + push edi + + mov [mapped], 0 + mov [owner_access], 0 + + pushfd ;mutex required + cli + + mov eax, [access] + and eax, SHM_OPEN_MASK + mov [action], eax + + mov ebx, [name] + test ebx, ebx + mov edx, E_PARAM + jz .fail + + mov esi, [shmem_list.fd] +align 4 +@@: + cmp esi, shmem_list + je .not_found + + lea edx, [esi+SMEM.name] ; link , base, size + stdcall strncmp, edx, ebx, 32 + test eax, eax + je .found + + mov esi, [esi+SMEM.fd] + jmp @B + +.not_found: + mov eax, [action] + + cmp eax, SHM_OPEN + mov edx, E_NOTFOUND + je .fail + + cmp eax, SHM_CREATE + mov edx, E_PARAM + je .create_shm + + cmp eax, SHM_OPEN_ALWAYS + jne .fail + +.create_shm: + + mov ecx, [size] + test ecx, ecx + jz .fail + + add ecx, 4095 + and ecx, -4096 + mov [size], ecx + + mov eax, SMEM.sizeof + call malloc + test eax, eax + mov esi, eax + mov edx, E_NOMEM + jz .fail + + stdcall kernel_alloc, [size] + test eax, eax + mov [mapped], eax + mov edx, E_NOMEM + jz .cleanup + + mov ecx, [size] + mov edx, [access] + and edx, SHM_ACCESS_MASK + + mov [esi+SMEM.base], eax + mov [esi+SMEM.size], ecx + mov [esi+SMEM.access], edx + mov [esi+SMEM.refcount], 0 + mov [esi+SMEM.name+28], 0 + + lea eax, [esi+SMEM.name] + stdcall strncpy, eax, [name], 31 + + mov eax, [shmem_list.fd] + mov [esi+SMEM.bk], shmem_list + mov [esi+SMEM.fd], eax + + mov [eax+SMEM.bk], esi + mov [shmem_list.fd], esi + + mov [action], SHM_OPEN + mov [owner_access], SHM_WRITE + +.found: + mov eax, [action] + + cmp eax, SHM_CREATE + mov edx, E_ACCESS + je .exit + + cmp eax, SHM_OPEN + mov edx, E_PARAM + je .create_map + + cmp eax, SHM_OPEN_ALWAYS + jne .fail + +.create_map: + + mov eax, [access] + and eax, SHM_ACCESS_MASK + cmp eax, [esi+SMEM.access] + mov [access], eax + mov edx, E_ACCESS + ja .fail + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov ebx, [CURRENT_TASK+ebx+4] + mov eax, SMAP.sizeof + + call create_kernel_object + test eax, eax + mov edi, eax + mov edx, E_NOMEM + jz .fail + + inc [esi+SMEM.refcount] + + mov [edi+SMAP.magic], 'SMAP' + mov [edi+SMAP.destroy], destroy_smap + mov [edi+SMAP.parent], esi + mov [edi+SMAP.base], 0 + + stdcall user_alloc, [esi+SMEM.size] + test eax, eax + mov [mapped], eax + mov edx, E_NOMEM + jz .cleanup2 + + mov [edi+SMAP.base], eax + + mov ecx, [esi+SMEM.size] + mov [size], ecx + + shr ecx, 12 + shr eax, 10 + + mov esi, [esi+SMEM.base] + shr esi, 10 + lea edi, [page_tabs+eax] + add esi, page_tabs + + mov edx, [access] + or edx, [owner_access] + shl edx, 1 + or edx, PG_USER+PG_SHARED +@@: + lodsd + and eax, 0xFFFFF000 + or eax, edx + stosd + loop @B + + xor edx, edx + + cmp [owner_access], 0 + jne .fail +.exit: + mov edx, [size] +.fail: + mov eax, [mapped] + + popfd + pop edi + pop esi + pop ebx + ret +.cleanup: + mov [size], edx + mov eax, esi + call free + jmp .exit + +.cleanup2: + mov [size], edx + mov eax, edi + call destroy_smap + jmp .exit +endp + +align 4 +proc shmem_close stdcall, name:dword + + mov eax, [name] + test eax, eax + jz .fail + + push esi + push edi + pushfd + cli + + mov esi, [current_slot] + add esi, APP_OBJ_OFFSET +.next: + mov eax, [esi+APPOBJ.fd] + test eax, eax + jz @F + + cmp eax, esi + mov esi, eax + je @F + + cmp [eax+SMAP.magic], 'SMAP' + jne .next + + mov edi, [eax+SMAP.parent] + test edi, edi + jz .next + + lea eax, [edi+SMEM.name] + stdcall strncmp, [name], edi, 32 + test eax, eax + jne .next + + stdcall user_free, [esi+SMAP.base] + + call [esi+APPOBJ.destroy] +@@: + popfd + pop edi + pop esi +.fail: + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/core/malloc.inc b/kernel/tags/kolibri0.7.7.0/core/malloc.inc new file mode 100644 index 000000000..d6f531306 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/malloc.inc @@ -0,0 +1,1025 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; Small heap based on malloc/free/realloc written by Doug Lea +; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) +; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c +; License http://creativecommons.org/licenses/publicdomain. + + +; eax= size + +; temp +; esi= nb +; ebx= idx +; +align 16 +malloc: + push esi + +; nb = ((size+7)&~7)+8; + + mov esi, eax ;size + add esi, 7 + and esi, -8 + add esi, 8 + + mov ebx, mst.mutex + call wait_mutex ;ebx + + cmp esi, 256 + jae .large + + mov ecx, esi + shr ecx, 3 + or eax, -1 + shl eax, cl + and eax, [mst.smallmap] + jz .small + + push ebp + push edi + + bsf eax, eax + mov ebx, eax + +; psize= idx<<3; +; B = &ms.smallbins[idx]; +; p = B->fd; +; F = p->fd; +; rsize= psize-nb; + + lea ebp, [eax*8] ;ebp= psize + shl eax, 4 + lea edi, [mst.smallbins+eax] ;edi= B + mov edx, [edi+8] ;edx= p + mov eax, [edx+8] ;eax= F + mov ecx, ebp + sub ecx, esi ;ecx= rsize + +; if (B == F) + cmp edi, eax + jne @F + + btr [mst.smallmap], ebx +@@: + +; B->fd = F; +; F->bk = B; +; if(rsize<16) + + cmp ecx, 16 + mov [edi+8], eax + mov [eax+12], edi + jae .split + +; p->head = psize|PINUSE_BIT|CINUSE_BIT; +; (p + psize)->head |= PINUSE_BIT; + + lea eax, [edx+8] + or dword [edx+ebp+4], 1 + + or ebp, 3 + mov [edx+4], ebp + + pop edi + pop ebp +.done: + pop esi + mov [mst.mutex], 0 + ret +.split: + lea ebx, [edx+8] ;ebx=mem + +; r = chunk_plus_offset(p, nb); +; p->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; + + lea eax, [edx+esi] ;eax= r + or esi, 3 + mov [edx+4], esi + + mov edx, ecx + or edx, 1 + mov [eax+4], edx + +; (r + rsize)->prev_foot = rsize; + + mov [eax+ecx], ecx + +; I = rsize>>3; + + shr ecx, 3 + +; ms.smallmap |= 1<< I; + bts [mst.smallmap], ecx + +; B = &ms.smallbins[I]; + + shl ecx, 4 + pop edi + pop ebp + add ecx, mst.smallbins ;ecx= B + + mov edx, [ecx+8] ; F = B->fd; + mov [ecx+8], eax ; B->fd = r; + mov [edx+12], eax ; F->bk = r; + mov [eax+8], edx ; r->fd = F; + mov [eax+12], ecx ; r->bk = B; + mov eax, ebx + pop esi + mov [mst.mutex], 0 + ret +.small: + +; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) +;;;;;;;;;;; start a change + mov eax,[mst.treemap] + test eax,eax +;;;;;;;;;;; end the change +; cmp [mst.treemap], 0 + jz .from_top + mov eax, esi + call malloc_small + test eax, eax + jz .from_top + pop esi + and [mst.mutex], 0 + ret +.large: + +; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) + + cmp [mst.treemap], 0 + je .from_top + + call malloc_large ;esi= nb + test eax, eax + jne .done +.from_top: + +; if (nb < ms.topsize) + + mov eax, [mst.topsize] + cmp esi, eax + jae .fail + +; rsize = ms.topsize -= nb; +; p = ms.top; + + mov ecx, [mst.top] + sub eax, esi + mov [mst.topsize], eax + +; r = ms.top = chunk_plus_offset(p, nb); +; r->head = rsize | PINUSE_BIT; +; p->head = nb |PINUSE_BIT|CINUSE_BIT; + + lea edx, [ecx+esi] + or eax, 1 + mov [mst.top], edx + or esi, 3 + mov [edx+4], eax + mov [ecx+4], esi + lea eax, [ecx+8] + pop esi + and [mst.mutex], 0 + ret +.fail: + xor eax, eax + pop esi + and [mst.mutex], 0 + ret + +; param +; eax= mem + +free: + push edi + mov edi, eax + add edi, -8 + +; if(p->head & CINUSE_BIT) + + test byte [edi+4], 2 + je .fail + + mov ebx, mst.mutex + call wait_mutex ;ebx + +; psize = p->head & (~3); + + mov eax, [edi+4] + push esi + mov esi, eax + and esi, -4 + +; next = chunk_plus_offset(p, psize); +; if(!(p->head & PINUSE_BIT)) + + test al, 1 + lea ebx, [esi+edi] + jne .next + +; prevsize = p->prev_foot; +; prev=p - prevsize; +; psize += prevsize; +; p = prev; + + mov ecx, [edi] ;ecx= prevsize + add esi, ecx ;esi= psize + sub edi, ecx ;edi= p + +; if (prevsize < 256) + + cmp ecx, 256 + jae .unlink_large + + mov eax, [edi+8] ;F = p->fd; + mov edx, [edi+12] ;B = p->bk; + +; if (F == B) +; ms.smallmap &= ~(1<< I); + shr ecx, 3 + cmp eax, edx + jne @F + and [mst.smallmap], ecx +@@: + mov [eax+12], edx ;F->bk = B; + mov [edx+8], eax ;B->fd = F + jmp .next +.unlink_large: + mov edx, edi + call unlink_large_chunk +.next: + +; if(next->head & PINUSE_BIT) + + mov eax, [ebx+4] + test al, 1 + jz .fail2 + +; if (! (next->head & CINUSE_BIT)) + + test al, 2 + jnz .fix_next + +; if (next == ms.top) + + cmp ebx, [mst.top] + jne @F + +; tsize = ms.topsize += psize; + + mov eax, [mst.topsize] + add eax, esi + mov [mst.topsize], eax + +; ms.top = p; +; p->head = tsize | PINUSE_BIT; + + or eax, 1 + mov [mst.top], edi + mov [edi+4], eax +.fail2: + and [mst.mutex], 0 + pop esi +.fail: + pop edi + ret +@@: + +; nsize = next->head & ~INUSE_BITS; + + and eax, -4 + add esi, eax ;psize += nsize; + +; if (nsize < 256) + + cmp eax, 256 + jae .unl_large + + mov edx, [ebx+8] ;F = next->fd + mov ebx, [ebx+12] ;B = next->bk + +; if (F == B) + + cmp edx, ebx + jne @F + mov ecx, eax + shr ecx, 3 + btr [mst.smallmap], ecx +@@: + mov [edx+12], ebx ;F->bk = B + +; p->head = psize|PINUSE_BIT; + + mov ecx, esi + mov [ebx+8], edx + or ecx, 1 + mov [edi+4], ecx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi + +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk +.unl_large: + +; unlink_large_chunk((tchunkptr)next); + + mov edx, ebx + call unlink_large_chunk +; p->head = psize|PINUSE_BIT; + + mov ecx, esi + or ecx, 1 + mov [edi+4], ecx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi + +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk +.fix_next: + +; (p+psize)->prev_foot = psize; +; next->head &= ~PINUSE_BIT; +; p->head = psize|PINUSE_BIT; + + and eax, -2 + mov edx, esi + mov [ebx+4], eax + or edx, 1 + mov [edi+4], edx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk + +; param +; ecx = chunk +; eax = size + +insert_chunk: + + cmp eax, 256 + push esi + mov esi, ecx + jae .large + +; I = S>>3; +; ms.smallmap |= 1<< I; + + shr eax, 3 + bts [mst.smallmap], eax + +; B = &ms.smallbins[I]; + + shl eax, 4 + add eax, mst.smallbins + mov edx, [eax+8] ;F = B->fd + mov [eax+8], esi ;B->fd = P + mov [edx+12], esi ;F->bk = P + mov [esi+8], edx ;P->fd = F + mov [esi+12], eax ;P->bk = B + pop esi + and [mst.mutex], 0 + ret +.large: + mov ebx, eax + call insert_large_chunk + pop esi + and [mst.mutex], 0 + ret + + +; param +; esi= chunk +; ebx= size + +insert_large_chunk: + +; I = compute_tree_index(S); + + mov edx, ebx + shr edx, 8 + bsr eax, edx + lea ecx, [eax+7] + mov edx, ebx + shr edx, cl + and edx, 1 + lea ecx, [edx+eax*2] + +; X->index = I; + mov dword [esi+28], ecx + +; X->child[0] = X->child[1] = 0; + and dword [esi+20], 0 + and dword [esi+16], 0 + +; H = &ms.treebins[I]; + + mov eax, ecx + lea edx, [mst.treebins+eax*4] + +; if (!(ms.treemap & 1<child[(K >> 31) & 1]); + mov ecx, eax + shr ecx, 31 + lea ecx, [edx+ecx*4+16] + +; K <<= 1; +; if (*C != 0) + mov edi, [ecx] + add eax, eax + test edi, edi + jz .insert_child + +; T = *C; + mov edx, edi +.loop: + +; for (;;) +; if ((T->head & ~INUSE_BITS) != S) + + mov ecx, [edx+4] + and ecx, not 3 + cmp ecx, ebx + jne .not_eq_size + +; F = T->fd; + mov eax, [edx+8] + +; T->fd = F->bk = X; + mov [eax+12], esi + mov [edx+8], esi + +; X->fd = F; +; X->bk = T; +; X->parent = 0; + + and dword [esi+24], 0 + mov [esi+8], eax + mov [esi+12], edx + ret +.insert_child: + +; *C = X; + mov [ecx], esi +.done: + +; X->parent = T; + mov [esi+24], edx + +; X->fd = X->bk = X; + mov [esi+12], esi + mov [esi+8], esi + ret + + +; param +; edx= chunk + +unlink_large_chunk: + + mov eax, [edx+12] + cmp eax, edx + push edi + mov edi, [edx+24] + je @F + + mov ecx, [edx+8] ;F = X->fd + mov [ecx+12], eax ;F->bk = R; + mov [eax+8], ecx ;R->fd = F + jmp .parent +@@: + mov eax, [edx+20] + test eax, eax + push esi + lea esi, [edx+20] + jne .loop + + mov eax, [edx+16] + test eax, eax + lea esi, [edx+16] + je .l2 +.loop: + cmp dword [eax+20], 0 + lea ecx, [eax+20] + jne @F + + cmp dword [eax+16], 0 + lea ecx, [eax+16] + je .l1 +@@: + mov eax, [ecx] + mov esi, ecx + jmp .loop +.l1: + mov dword [esi], 0 +.l2: + pop esi +.parent: + test edi, edi + je .done + + mov ecx, [edx+28] + cmp edx, [mst.treebins+ecx*4] + lea ecx, [mst.treebins+ecx*4] + jne .l3 + + test eax, eax + mov [ecx], eax + jne .l5 + + mov ecx, [edx+28] + btr [mst.treemap], ecx + pop edi + ret + +.l3: + cmp [edi+16], edx + jne @F + + mov [edi+16], eax + jmp .l4 + +@@: + mov [edi+20], eax + +.l4: + test eax, eax + je .done + +.l5: + mov [eax+24], edi + mov ecx, [edx+16] + test ecx, ecx + je .l6 + + mov [eax+16], ecx + mov [ecx+24], eax + +.l6: + mov edx, [edx+20] + test edx, edx + je .done + + mov [eax+20], edx + mov [edx+24], eax + +.done: + pop edi + ret + +; param +; esi= nb + +malloc_small: + push ebp + mov ebp, esi + + push edi + + bsf eax,[mst.treemap] + mov ecx, [mst.treebins+eax*4] + +; rsize = (t->head & ~INUSE_BITS) - nb; + + mov edi, [ecx+4] + and edi, -4 + sub edi, esi + +.loop: + mov ebx, ecx + +.loop_1: + +; while ((t = leftmost_child(t)) != 0) + + mov eax, [ecx+16] + test eax, eax + jz @F + mov ecx, eax + jmp .l1 + +@@: + mov ecx, [ecx+20] + +.l1: + test ecx, ecx + jz .unlink + +; trem = (t->head & ~INUSE_BITS) - nb; + + mov eax, [ecx+4] + and eax, -4 + sub eax, ebp + +; if (trem < rsize) + + cmp eax, edi + jae .loop_1 + +; rsize = trem; + + mov edi, eax + jmp .loop +.unlink: + + +; r = chunk_plus_offset((mchunkptr)v, nb); +; unlink_large_chunk(v); + + mov edx, ebx + lea esi, [ebx+ebp] + call unlink_large_chunk + +; if (rsize < 16) + + cmp edi, 16 + jae .split + +; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; + + lea ecx, [edi+ebp] + +; (v+rsize + nb)->head |= PINUSE_BIT; + + add edi, ebx + lea eax, [edi+ebp+4] + pop edi + or ecx, 3 + mov [ebx+4], ecx + or dword [eax], 1 + pop ebp + + lea eax, [ebx+8] + ret + +.split: + +; v->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; +; (r+rsize)->prev_foot = rsize; + + or ebp, 3 + mov edx, edi + or edx, 1 + + cmp edi, 256 + mov [ebx+4], ebp + mov [esi+4], edx + mov [esi+edi], edi + jae .large + + shr edi, 3 + bts [mst.smallmap], edi + + mov eax, edi + shl eax, 4 + add eax, mst.smallbins + + mov edx, [eax+8] + mov [eax+8], esi + mov [edx+12], esi + pop edi + mov [esi+12], eax + mov [esi+8], edx + pop ebp + lea eax, [ebx+8] + ret + +.large: + lea eax, [ebx+8] + push eax + mov ebx, edi + call insert_large_chunk + pop eax + pop edi + pop ebp + ret + + +; param +; esi= nb + +malloc_large: +.idx equ esp+4 +.rst equ esp + + push ebp + push edi + sub esp, 8 +; v = 0; +; rsize = -nb; + + mov edi, esi + mov ebx, esi + xor ebp, ebp + neg edi + +; idx = compute_tree_index(nb); + + mov edx, esi + shr edx, 8 + bsr eax, edx + lea ecx, [eax+7] + shr esi, cl + and esi, 1 + lea ecx, [esi+eax*2] + mov [.idx], ecx + +; if ((t = ms.treebins[idx]) != 0) + + mov eax, [mst.treebins+ecx*4] + test eax, eax + jz .l3 + +; sizebits = nb << leftshift_for_tree_index(idx); + + cmp ecx, 31 + jne @F + xor ecx, ecx + jmp .l1 + +@@: + mov edx, ecx + shr edx, 1 + mov ecx, 37 + sub ecx, edx + +.l1: + mov edx, ebx + shl edx, cl + +; rst = 0; + mov [.rst], ebp + +.loop: + +; trem = (t->head & ~INUSE_BITS) - nb; + + mov ecx, [eax+4] + and ecx, -4 + sub ecx, ebx + +; if (trem < rsize) + + cmp ecx, edi + jae @F +; v = t; +; if ((rsize = trem) == 0) + + test ecx, ecx + mov ebp, eax + mov edi, ecx + je .l2 + +@@: + +; rt = t->child[1]; + + mov ecx, [eax+20] + +; t = t->child[(sizebits >> 31) & 1]; + + mov esi, edx + shr esi, 31 + +; if (rt != 0 && rt != t) + + test ecx, ecx + mov eax, [eax+esi*4+16] + jz @F + cmp ecx, eax + jz @F + +; rst = rt; + mov [.rst], ecx + +@@: +; if (t == 0) + + test eax, eax + jz @F + +; sizebits <<= 1; + + add edx, edx + jmp .loop + +@@: +; t = rst; + mov eax, [.rst] + +.l2: +; if (t == 0 && v == 0) + + test eax, eax + jne .l4 + test ebp, ebp + jne .l7 + mov ecx, [.idx] + +.l3: + +; leftbits = (-1<head & ~INUSE_BITS) - nb; + + mov ecx, [eax+4] + and ecx, -4 + sub ecx, ebx + +; if (trem < rsize) + + cmp ecx, edi + jae @F +; rsize = trem; + + mov edi, ecx +; v = t; + mov ebp, eax + +@@: + +; t = leftmost_child(t); + + mov ecx, [eax+16] + test ecx, ecx + je @F + mov eax, ecx + jmp .l6 + +@@: + mov eax, [eax+20] + +.l6: + +; while (t != 0) + + test eax, eax + jne .l4 + +.l5: + +; if (v != 0) + + test ebp, ebp + jz .done + +.l7: + +; r = chunk_plus_offset((mchunkptr)v, nb); +; unlink_large_chunk(v); + + mov edx, ebp + lea esi, [ebx+ebp] + call unlink_large_chunk + +; if (rsize < 16) + + cmp edi, 16 + jae .large + +; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; + + lea ecx, [edi+ebx] + +; (v+rsize + nb)->head |= PINUSE_BIT; + + add edi, ebp + lea eax, [edi+ebx+4] + or ecx, 3 + mov [ebp+4], ecx + or dword [eax], 1 + lea eax, [ebp+8] + add esp, 8 + pop edi + pop ebp + ret + +.large: + +; v->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; + + mov edx, edi + or ebx, 3 + mov [ebp+4], ebx + or edx, 1 + mov [esi+4], edx + +; (r+rsize)->prev_foot = rsize; +; insert_large_chunk((tchunkptr)r, rsize); + + mov [esi+edi], edi + mov eax, edi + mov ecx, esi + call insert_chunk + + lea eax, [ebp+8] + add esp, 8 + pop edi + pop ebp + ret + +.done: + add esp, 8 + pop edi + pop ebp + xor eax, eax + ret + +init_malloc: + + stdcall kernel_alloc, 0x40000 + + mov [mst.top], eax + mov [mst.topsize], 128*1024 + mov dword [eax+4], (128*1024) or 1 + mov eax, mst.smallbins + +@@: + mov [eax+8], eax + mov [eax+12], eax + add eax, 16 + cmp eax, mst.smallbins+512 + jb @B + + ret + diff --git a/kernel/tags/kolibri0.7.7.0/core/memory.inc b/kernel/tags/kolibri0.7.7.0/core/memory.inc new file mode 100644 index 000000000..64133c122 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/memory.inc @@ -0,0 +1,1465 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +align 4 +proc alloc_page + + pushfd + cli + push ebx + mov ebx, [page_start] + mov ecx, [page_end] +.l1: + bsf eax,[ebx]; + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + pop ebx + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + mov [page_start],ebx + sub ebx, sys_pgmap + lea eax, [eax+ebx*8] + shl eax, 12 + dec [pg_data.pages_free] + pop ebx + popfd + ret +endp + +align 4 +proc alloc_pages stdcall, count:dword + pushfd + push ebx + push edi + cli + mov eax, [count] + add eax, 7 + shr eax, 3 + mov [count], eax + cmp eax, [pg_data.pages_free] + ja .fail + + mov ecx, [page_start] + mov ebx, [page_end] +.find: + mov edx, [count] + mov edi, ecx +.match: + cmp byte [ecx], 0xFF + jne .next + dec edx + jz .ok + inc ecx + cmp ecx,ebx + jb .match +.fail: + xor eax, eax + pop edi + pop ebx + popfd + ret +.next: + inc ecx + cmp ecx, ebx + jb .find + pop edi + pop ebx + popfd + xor eax, eax + ret +.ok: + sub ecx, edi + inc ecx + push esi + mov esi, edi + xor eax, eax + rep stosb + sub esi, sys_pgmap + shl esi, 3+12 + mov eax, esi + mov ebx, [count] + shl ebx, 3 + sub [pg_data.pages_free], ebx + pop esi + pop edi + pop ebx + popfd + ret +endp + +align 4 +proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword + push ebx + mov eax, [phis_addr] + and eax, not 0xFFF + or eax, [flags] + mov ebx, [lin_addr] + shr ebx, 12 + mov [page_tabs+ebx*4], eax + mov eax, [lin_addr] + invlpg [eax] + pop ebx + ret +endp + +align 4 +map_space: ;not implemented + + + ret + + +align 4 +proc free_page +;arg: eax page address + pushfd + cli + shr eax, 12 ;page index + bts dword [sys_pgmap], eax ;that's all! + cmc + adc [pg_data.pages_free], 0 + shr eax, 3 + and eax, not 3 ;dword offset from page_map + add eax, sys_pgmap + cmp [page_start], eax + ja @f + popfd + ret +@@: + mov [page_start], eax + popfd + ret +endp + +proc map_io_mem stdcall, base:dword, size:dword, flags:dword + + push ebx + push edi + mov eax, [size] + add eax, 4095 + and eax, -4096 + mov [size], eax + stdcall alloc_kernel_space, eax + test eax, eax + jz .fail + push eax + + mov edi, 0x1000 + mov ebx, eax + mov ecx,[size] + mov edx, [base] + shr eax, 12 + shr ecx, 12 + and edx, -4096 + or edx, [flags] +@@: + mov [page_tabs+eax*4], edx + ; push eax + invlpg [ebx] + ; pop eax + inc eax + add ebx, edi + add edx, edi + loop @B + + pop eax + mov edx, [base] + and edx, 4095 + add eax, edx +.fail: + pop edi + pop ebx + ret +endp + +; param +; eax= page base + page flags +; ebx= linear address +; ecx= count + +align 4 +commit_pages: + push edi + test ecx, ecx + jz .fail + + mov edi, ebx + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + mov edx, 0x1000 + mov ebx, edi + shr ebx, 12 +@@: + mov [page_tabs+ebx*4], eax + ; push eax + invlpg [edi] + ; pop eax + add edi, edx + add eax, edx + inc ebx + dec ecx + jnz @B + mov [pg_data.pg_mutex],ecx +.fail: + pop edi + ret + + +; param +; eax= base +; ecx= count + +align 4 +release_pages: + + pushad + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + mov esi, eax + mov edi, eax + + shr esi, 10 + add esi, page_tabs + + mov ebp, [pg_data.pages_free] + mov ebx, [page_start] + mov edx, sys_pgmap +@@: + xor eax, eax + xchg eax, [esi] + push eax + invlpg [edi] + pop eax + + test eax, 1 + jz .next + + shr eax, 12 + bts [edx], eax + cmc + adc ebp, 0 + shr eax, 3 + and eax, -4 + add eax, edx + cmp eax, ebx + jae .next + + mov ebx, eax +.next: + add edi, 0x1000 + add esi, 4 + dec ecx + jnz @B + mov [pg_data.pages_free], ebp + and [pg_data.pg_mutex],0 + popad + ret + +; param +; eax= base +; ecx= count + +align 4 +unmap_pages: + + push edi + + mov edi, eax + mov edx, eax + + shr edi, 10 + add edi, page_tabs + + xor eax, eax +@@: + stosd + invlpg [edx] + add edx, 0x1000 + loop @b + + pop edi + ret + + +align 4 +proc map_page_table stdcall, lin_addr:dword, phis_addr:dword + push ebx + mov ebx, [lin_addr] + shr ebx, 22 + mov eax, [phis_addr] + and eax, not 0xFFF + or eax, PG_UW ;+PG_NOCACHE + mov dword [master_tab+ebx*4], eax + mov eax, [lin_addr] + shr eax, 10 + add eax, page_tabs + invlpg [eax] + pop ebx + ret +endp + +align 4 +proc init_LFB + locals + pg_count dd ? + endl + + cmp dword [LFBAddress], -1 + jne @f + mov [BOOT_VAR+0x901c],byte 2 + stdcall alloc_pages, (0x280000 / 4096) + + push eax + call alloc_page + stdcall map_page_table, LFB_BASE, eax + pop eax + or eax, PG_UW + mov ebx, LFB_BASE + mov ecx, 0x280000 / 4096 + call commit_pages + mov [LFBAddress], dword LFB_BASE + ret +@@: + test [SCR_MODE],word 0100000000000000b + jnz @f + mov [BOOT_VAR+0x901c],byte 2 + ret +@@: + call init_mtrr + + mov edx, LFB_BASE + mov esi, [LFBAddress] + mov edi, 0x00C00000 + mov dword [exp_lfb+4], edx + + shr edi, 12 + mov [pg_count], edi + shr edi, 10 + + bt [cpu_caps], CAPS_PSE + jnc .map_page_tables + or esi, PG_LARGE+PG_UW + mov edx, sys_pgdir+(LFB_BASE shr 20) +@@: + mov [edx], esi + add edx, 4 + add esi, 0x00400000 + dec edi + jnz @B + + bt [cpu_caps], CAPS_PGE + jnc @F + or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL +@@: + mov dword [LFBAddress], LFB_BASE + mov eax, cr3 ;flush TLB + mov cr3, eax + ret + +.map_page_tables: + +@@: + call alloc_page + stdcall map_page_table, edx, eax + add edx, 0x00400000 + dec edi + jnz @B + + mov eax, [LFBAddress] + mov edi, page_tabs + (LFB_BASE shr 10) + or eax, PG_UW + mov ecx, [pg_count] + cld +@@: + stosd + add eax, 0x1000 + dec ecx + jnz @B + + mov dword [LFBAddress], LFB_BASE + mov eax, cr3 ;flush TLB + mov cr3, eax + + ret +endp + +align 4 +proc new_mem_resize stdcall, new_size:dword + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + mov edi, [new_size] + add edi,4095 + and edi,not 4095 + mov [new_size], edi + + mov edx,[current_slot] + cmp [edx+APPDATA.heap_base],0 + jne .exit + + mov esi, [edx+APPDATA.mem_size] + add esi, 4095 + and esi, not 4095 + + cmp edi, esi + jae .expand + + shr edi, 12 + shr esi, 12 +@@: + mov eax, [app_page_tabs+edi*4] + test eax, 1 + jz .next + mov dword [app_page_tabs+edi*4], 2 + mov ebx, edi + shl ebx, 12 + push eax + invlpg [ebx] + pop eax + call free_page + +.next: add edi, 1 + cmp edi, esi + jb @B + +.update_size: + mov ebx, [new_size] + call update_mem_size + + xor eax, eax + dec [pg_data.pg_mutex] + ret +.expand: + + push esi + push edi + + add edi, 0x3FFFFF + and edi, not(0x3FFFFF) + add esi, 0x3FFFFF + and esi, not(0x3FFFFF) + + cmp esi, edi + jae .grow + + xchg esi, edi + +@@: + call alloc_page + test eax, eax + jz .exit_pop + + stdcall map_page_table, edi, eax + + push edi + shr edi, 10 + add edi, page_tabs + mov ecx, 1024 + xor eax, eax + cld + rep stosd + pop edi + + add edi, 0x00400000 + cmp edi, esi + jb @B +.grow: + pop edi + pop esi +@@: + call alloc_page + test eax, eax + jz .exit + stdcall map_page,esi,eax,dword PG_UW + + push edi + mov edi, esi + xor eax, eax + mov ecx, 1024 + cld + rep stosd + pop edi + + add esi, 0x1000 + cmp esi, edi + jb @B + + jmp .update_size +.exit_pop: + pop edi + pop esi +.exit: + xor eax, eax + inc eax + dec [pg_data.pg_mutex] + ret +endp + +update_mem_size: +; in: edx = slot base +; ebx = new memory size +; destroys eax,ecx,edx + + mov [APPDATA.mem_size+edx],ebx +;search threads and update +;application memory size infomation + mov ecx,[APPDATA.dir_table+edx] + mov eax,2 + +.search_threads: +;eax = current slot +;ebx = new memory size +;ecx = page directory + cmp eax,[TASK_COUNT] + jg .search_threads_end + mov edx,eax + shl edx,5 + cmp word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty? + jz .search_threads_next + shl edx,3 + cmp [SLOT_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread? + jnz .search_threads_next + mov [SLOT_BASE+edx+APPDATA.mem_size],ebx ;update memory size +.search_threads_next: + inc eax + jmp .search_threads +.search_threads_end: + ret + +; param +; eax= linear address +; +; retval +; eax= phisical page address + +align 4 +get_pg_addr: + shr eax, 12 + mov eax, [page_tabs+eax*4] + and eax, 0xFFFFF000 + ret + + +align 4 +; Now it is called from core/sys32::exc_c (see stack frame there) +proc page_fault_handler + + .err_addr equ ebp-4 + + push ebx ;save exception number (#PF) + mov ebp, esp + mov ebx, cr2 + push ebx ;that is locals: .err_addr = cr2 + inc [pg_data.pages_faults] + + mov eax, [pf_err_code] + + cmp ebx, OS_BASE ;ebx == .err_addr + jb .user_space ;страница в памяти приложения ; + + cmp ebx, page_tabs + jb .kernel_space ;страница в памяти ядра + + cmp ebx, kernel_tabs + jb .alloc;.app_tabs ;таблицы страниц приложения ; + ;просто создадим одну +if 0 ;пока это просто лишнее + cmp ebx, LFB_BASE + jb .core_tabs ;таблицы страниц ядра + ;Ошибка + .lfb: + ;область LFB + ;Ошибка + jmp .fail +end if +.core_tabs: +.fail: ;simply return to caller + mov esp, ebp + pop ebx ;restore exception number (#PF) + ret + +; xchg bx, bx +; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller +; restore_ring3_context +; iretd + +.user_space: + test eax, PG_MAP + jnz .err_access ;Страница присутствует + ;Ошибка доступа ? + + shr ebx, 12 + mov ecx, ebx + shr ecx, 10 + mov edx, [master_tab+ecx*4] + test edx, PG_MAP + jz .fail ;таблица страниц не создана + ;неверный адрес в программе + + mov eax, [page_tabs+ebx*4] + test eax, 2 + jz .fail ;адрес не зарезервирован для ; + ;использования. Ошибка +.alloc: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page,[.err_addr],eax,PG_UW + + mov edi, [.err_addr] + and edi, 0xFFFFF000 + mov ecx, 1024 + xor eax, eax + ;cld ;caller is duty for this + rep stosd +.exit: ;iret with repeat fault instruction + add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller + restore_ring3_context + iretd + +.err_access: +; access denied? this may be a result of copy-on-write protection for DLL +; check list of HDLLs + and ebx, not 0xFFF + mov eax, [CURRENT_TASK] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr] + test eax, eax + jz .fail + mov esi, [eax+HDLL.fd] +.scan_hdll: + cmp esi, eax + jz .fail + mov edx, ebx + sub edx, [esi+HDLL.base] + cmp edx, [esi+HDLL.size] + jb .fault_in_hdll +.scan_hdll.next: + mov esi, [esi+HDLL.fd] + jmp .scan_hdll +.fault_in_hdll: +; allocate new page, map it as rw and copy data + call alloc_page + test eax, eax + jz .fail + stdcall map_page,ebx,eax,PG_UW + mov edi, ebx + mov ecx, 1024 + sub ebx, [esi+HDLL.base] + mov esi, [esi+HDLL.parent] + mov esi, [esi+DLLDESCR.data] + add esi, ebx + rep movsd + jmp .exit + +.kernel_space: + test eax, PG_MAP + jz .fail ;страница не присутствует + + test eax,12 ;U/S (+below) + jnz .fail ;приложение обратилось к памяти + ;ядра + ;test eax, 8 + ;jnz .fail ;установлен зарезервированный бит + ;в таблицах страниц. добавлено в P4/Xeon + +;попытка записи в защищённую страницу ядра + + cmp ebx, tss._io_map_0 + jb .fail + + cmp ebx, tss._io_map_0+8192 + jae .fail + +; io permission map +; copy-on-write protection + + call alloc_page + test eax, eax + jz .fail + + push eax + stdcall map_page,[.err_addr],eax,dword PG_SW + pop eax + mov edi, [.err_addr] + and edi, -4096 + lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 + + mov ebx, esi + shr ebx, 12 + mov edx, [current_slot] + or eax, PG_SW + mov [edx+APPDATA.io_map+ebx*4], eax + + add esi, [default_io_map] + mov ecx, 4096/4 + ;cld ;caller is duty for this + rep movsd + jmp .exit +endp + +; returns number of mapped bytes +proc map_mem stdcall, lin_addr:dword,slot:dword,\ + ofs:dword,buf_size:dword,req_access:dword + push 0 ; initialize number of mapped bytes + + cmp [buf_size], 0 + jz .exit + + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dir_table] + and eax, 0xFFFFF000 + + stdcall map_page,[ipc_pdir],eax,PG_UW + mov ebx, [ofs] + shr ebx, 22 + mov esi, [ipc_pdir] + mov edi, [ipc_ptab] + mov eax, [esi+ebx*4] + and eax, 0xFFFFF000 + jz .exit + stdcall map_page,edi,eax,PG_UW +; inc ebx +; add edi, 0x1000 +; mov eax, [esi+ebx*4] +; test eax, eax +; jz @f +; and eax, 0xFFFFF000 +; stdcall map_page, edi, eax + +@@: mov edi, [lin_addr] + and edi, 0xFFFFF000 + mov ecx, [buf_size] + add ecx, 4095 + shr ecx, 12 + inc ecx + + mov edx, [ofs] + shr edx, 12 + and edx, 0x3FF + mov esi, [ipc_ptab] + +.map: + stdcall safe_map_page,[slot],[req_access],[ofs] + jnc .exit + add dword [ebp-4], 4096 + add [ofs], 4096 + dec ecx + jz .exit + add edi, 0x1000 + inc edx + cmp edx, 0x400 + jnz .map + inc ebx + mov eax, [ipc_pdir] + mov eax, [eax+ebx*4] + and eax, 0xFFFFF000 + jz .exit + stdcall map_page,esi,eax,PG_UW + xor edx, edx + jmp .map + +.exit: + pop eax + ret +endp + +proc map_memEx stdcall, lin_addr:dword,slot:dword,\ + ofs:dword,buf_size:dword,req_access:dword + push 0 ; initialize number of mapped bytes + + cmp [buf_size], 0 + jz .exit + + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dir_table] + and eax, 0xFFFFF000 + + stdcall map_page,[proc_mem_pdir],eax,PG_UW + mov ebx, [ofs] + shr ebx, 22 + mov esi, [proc_mem_pdir] + mov edi, [proc_mem_tab] + mov eax, [esi+ebx*4] + and eax, 0xFFFFF000 + test eax, eax + jz .exit + stdcall map_page,edi,eax,PG_UW + +@@: mov edi, [lin_addr] + and edi, 0xFFFFF000 + mov ecx, [buf_size] + add ecx, 4095 + shr ecx, 12 + inc ecx + + mov edx, [ofs] + shr edx, 12 + and edx, 0x3FF + mov esi, [proc_mem_tab] + +.map: + stdcall safe_map_page,[slot],[req_access],[ofs] + jnc .exit + add dword [ebp-4], 0x1000 + add edi, 0x1000 + add [ofs], 0x1000 + inc edx + dec ecx + jnz .map +.exit: + pop eax + ret +endp + +; in: esi+edx*4 = pointer to page table entry +; in: [slot], [req_access], [ofs] on the stack +; in: edi = linear address to map +; out: CF cleared <=> failed +; destroys: only eax +proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword + mov eax, [esi+edx*4] + test al, PG_MAP + jz .not_present + test al, PG_WRITE + jz .resolve_readonly +; normal case: writable page, just map with requested access +.map: + stdcall map_page, edi, eax, [req_access] + stc +.fail: + ret +.not_present: +; check for alloc-on-demand page + test al, 2 + jz .fail +; allocate new page, save it to source page table + push ecx + call alloc_page + pop ecx + test eax, eax + jz .fail + or al, PG_UW + mov [esi+edx*4], eax + jmp .map +.resolve_readonly: +; readonly page, probably copy-on-write +; check: readonly request of readonly page is ok + test [req_access], PG_WRITE + jz .map +; find control structure for this page + pushf + cli + cld + push ebx ecx + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr] + test eax, eax + jz .no_hdll + mov ecx, [eax+HDLL.fd] +.scan_hdll: + cmp ecx, eax + jz .no_hdll + mov ebx, [ofs] + and ebx, not 0xFFF + sub ebx, [ecx+HDLL.base] + cmp ebx, [ecx+HDLL.size] + jb .hdll_found + mov ecx, [ecx+HDLL.fd] + jmp .scan_hdll +.no_hdll: + pop ecx ebx + popf + clc + ret +.hdll_found: +; allocate page, save it in page table, map it, copy contents from base + mov eax, [ecx+HDLL.parent] + add ebx, [eax+DLLDESCR.data] + call alloc_page + test eax, eax + jz .no_hdll + or al, PG_UW + mov [esi+edx*4], eax + stdcall map_page, edi, eax, [req_access] + push esi edi + mov esi, ebx + mov ecx, 4096/4 + rep movsd + pop edi esi + pop ecx ebx + popf + stc + ret +endp + +sys_IPC: +;input: +; eax=1 - set ipc buffer area +; ebx=address of buffer +; ecx=size of buffer +; eax=2 - send message +; ebx=PID +; ecx=address of message +; edx=size of message + + cmp eax,1 + jne @f + call set_ipc_buff + mov [esp+36], eax + ret +@@: + cmp eax, 2 + jne @f + stdcall sys_ipc_send, ebx, ecx, edx + mov [esp+36], eax + ret +@@: + xor eax, eax + not eax + mov [esp+36], eax + ret + +align 4 +proc set_ipc_buff + + mov eax,[current_slot] + pushf + cli + mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area + mov [eax+APPDATA.ipc_size],ecx + + add ecx, ebx + add ecx, 4095 + and ecx, not 4095 + +.touch: mov eax, [ebx] + add ebx, 0x1000 + cmp ebx, ecx + jb .touch + + popf + xor eax, eax + ret +endp + +proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword + locals + dst_slot dd ? + dst_offset dd ? + buf_size dd ? + used_buf dd ? + endl + + pushf + cli + + mov eax, [PID] + call pid_to_slot + test eax,eax + jz .no_pid + + mov [dst_slot], eax + shl eax,8 + mov edi,[eax+SLOT_BASE+0xa0] ;is ipc area defined? + test edi,edi + jz .no_ipc_area + + mov ebx, edi + and ebx, 0xFFF + mov [dst_offset], ebx + + mov esi, [eax+SLOT_BASE+0xa4] + mov [buf_size], esi + + mov ecx, [ipc_tmp] + cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page + jbe @f + push esi edi + add esi,0x1000 + stdcall alloc_kernel_space,esi + mov ecx, eax + pop edi esi +@@: + mov [used_buf], ecx + stdcall map_mem, ecx, [dst_slot],\ + edi, esi, PG_SW + + mov edi, [dst_offset] + add edi, [used_buf] + cmp dword [edi], 0 + jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now + + mov edx, dword [edi+4] + lea ebx, [edx+8] + add ebx, [msg_size] + cmp ebx, [buf_size] + ja .buffer_overflow ;esi<0 - not enough memory in buffer + + mov dword [edi+4], ebx + mov eax,[TASK_BASE] + mov eax, [eax+0x04] ;eax - our PID + add edi, edx + mov [edi], eax + mov ecx, [msg_size] + + mov [edi+4], ecx + add edi, 8 + mov esi, [msg_addr] + ; add esi, new_app_base + cld + rep movsb + + mov ebx, [ipc_tmp] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_pdir] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_ptab] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov eax, [dst_slot] + shl eax, 8 + or [eax+SLOT_BASE+0xA8],dword 0x40 + cmp dword [check_idle_semaphore],20 + jge .ipc_no_cis + + mov dword [check_idle_semaphore],5 +.ipc_no_cis: + push 0 + jmp .ret +.no_pid: + popf + mov eax, 4 + ret +.no_ipc_area: + popf + xor eax, eax + inc eax + ret +.ipc_blocked: + push 2 + jmp .ret +.buffer_overflow: + push 3 +.ret: + mov eax, [used_buf] + cmp eax, [ipc_tmp] + jz @f + stdcall free_kernel_space,eax +@@: + pop eax + popf + ret +endp + +align 4 +sysfn_meminfo: + + ; add ecx, new_app_base + cmp ecx, OS_BASE + jae .fail + + mov eax, [pg_data.pages_count] + mov [ecx], eax + shl eax, 12 + mov [esp+32], eax + mov eax, [pg_data.pages_free] + mov [ecx+4], eax + mov eax, [pg_data.pages_faults] + mov [ecx+8], eax + mov eax, [heap_size] + mov [ecx+12], eax + mov eax, [heap_free] + mov [ecx+16], eax + mov eax, [heap_blocks] + mov [ecx+20], eax + mov eax, [free_blocks] + mov [ecx+24], eax + ret +.fail: + or dword [esp+32], -1 + ret +iglobal +align 4 +f68call: + dd f68.11 ; init_heap + dd f68.12 ; user_alloc + dd f68.13 ; user_free + dd f68.14 ; get_event_ex + dd f68.fail ;moved to f68.24 + dd f68.16 ; get_service + dd f68.17 ; call_service + dd f68.fail ;moved to f68.25 + dd f68.19 ; load_dll + dd f68.20 ; user_realloc + dd f68.21 ; load_driver + dd f68.22 ; shmem_open + dd f68.23 ; shmem_close + dd f68.24 + dd f68.25 +endg +align 4 +f68: + cmp eax,4 + jle sys_sheduler + + cmp eax, 11 + jb .fail + + cmp eax, 25 + ja .fail + + jmp dword [f68call+eax*4-11*4] +.11: + call init_heap + mov [esp+36], eax + ret +.12: + stdcall user_alloc, ebx + mov [esp+36], eax + ret +.13: + stdcall user_free, ebx + mov [esp+36], eax + ret +.14: + cmp ebx, OS_BASE + jae .fail + mov edi,ebx + call get_event_ex + mov [esp+36], eax + ret +.16: + test ebx, ebx + jz .fail + cmp ebx, OS_BASE + jae .fail + stdcall get_service, ebx + mov [esp+36], eax + ret +.17: + call srv_handlerEx ;ebx + mov [esp+36], eax + ret +.19: + cmp ebx, OS_BASE + jae .fail + stdcall load_library, ebx + mov [esp+36], eax + ret +.20: + mov eax, ecx + call user_realloc + mov [esp+36], eax + ret +.21: + cmp ebx, OS_BASE + jae .fail + + cmp ecx, OS_BASE + jae .fail + + mov edi, ecx + stdcall load_PE, ebx + mov esi, eax + test eax, eax + jz @F + + push edi + push DRV_ENTRY + call eax + add esp, 8 + test eax, eax + jz @F + + mov [eax+SRV.entry], esi + +@@: + mov [esp+36], eax + ret +.22: + cmp ebx, OS_BASE + jae .fail + + stdcall shmem_open, ebx, ecx, edx + mov [esp+28], edx + mov [esp+36], eax + ret + +.23: + cmp ebx, OS_BASE + jae .fail + + stdcall shmem_close, ebx + mov [esp+36], eax + ret +.24: + mov eax, [current_slot] + xchg ebx, [eax+APPDATA.exc_handler] + xchg ecx, [eax+APPDATA.except_mask] + mov [esp+36], ebx ; reg_eax+8 + mov [esp+24], ecx ; reg_ebx+8 + ret +.25: + cmp ebx,32 + jae .fail + mov eax, [current_slot] + btr [eax+APPDATA.except_mask],ebx + setc byte[esp+36] + jecxz @f + bts [eax+APPDATA.except_mask],ebx +@@: + ret + +.fail: + xor eax, eax + mov [esp+36], eax + ret + +align 4 +proc load_pe_driver stdcall, file:dword + + stdcall load_PE, [file] + test eax, eax + jz .fail + + mov esi, eax + stdcall eax, DRV_ENTRY + test eax, eax + jz .fail + + mov [eax+SRV.entry], esi + ret + +.fail: + xor eax, eax + ret +endp + + +align 4 +proc init_mtrr + + cmp [BOOT_VAR+0x901c],byte 2 + je .exit + + bt [cpu_caps], CAPS_MTRR + jnc .exit + + mov eax, cr0 + or eax, 0x60000000 ;disable caching + mov cr0, eax + wbinvd ;invalidate cache + + mov ecx, 0x2FF + rdmsr ; +; has BIOS already initialized MTRRs? + test ah, 8 + jnz .skip_init +; rarely needed, so mainly placeholder +; main memory - cached + push eax + + mov eax, [MEM_AMOUNT] +; round eax up to next power of 2 + dec eax + bsr ecx, eax + mov ebx, 2 + shl ebx, cl + dec ebx +; base of memory range = 0, type of memory range = MEM_WB + xor edx, edx + mov eax, MEM_WB + mov ecx, 0x200 + wrmsr +; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1 + mov eax, 0xFFFFFFFF + mov edx, 0x0000000F + sub eax, ebx + sbb edx, 0 + or eax, 0x800 + inc ecx + wrmsr +; clear unused MTRRs + xor eax, eax + xor edx, edx +@@: + wrmsr + inc ecx + cmp ecx, 0x210 + jb @b +; enable MTRRs + pop eax + or ah, 8 + and al, 0xF0 ; default memtype = UC + mov ecx, 0x2FF + wrmsr +.skip_init: + stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC + + wbinvd ;again invalidate + + mov eax, cr0 + and eax, not 0x60000000 + mov cr0, eax ; enable caching +.exit: + ret +endp + +align 4 +proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword +; find unused register + mov ecx, 0x201 +@@: + rdmsr + dec ecx + test ah, 8 + jz .found + rdmsr + mov al, 0 ; clear memory type field + cmp eax, [base] + jz .ret + add ecx, 3 + cmp ecx, 0x210 + jb @b +; no free registers, ignore the call +.ret: + ret +.found: +; found, write values + xor edx, edx + mov eax, [base] + or eax, [mem_type] + wrmsr + + mov ebx, [size] + dec ebx + mov eax, 0xFFFFFFFF + mov edx, 0x0000000F + sub eax, ebx + sbb edx, 0 + or eax, 0x800 + inc ecx + wrmsr + ret +endp + +align 4 +proc stall stdcall, delay:dword + push ecx + push edx + push ebx + push eax + + mov eax, [delay] + mul [stall_mcs] + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + jb @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +align 4 +proc create_ring_buffer stdcall, size:dword, flags:dword + locals + buf_ptr dd ? + endl + + mov eax, [size] + test eax, eax + jz .fail + + add eax, eax + stdcall alloc_kernel_space, eax + test eax, eax + jz .fail + + push ebx + + mov [buf_ptr], eax + + mov ebx, [size] + shr ebx, 12 + push ebx + + stdcall alloc_pages, ebx + pop ecx + + test eax, eax + jz .mm_fail + + push edi + + or eax, [flags] + mov edi, [buf_ptr] + mov ebx, [buf_ptr] + mov edx, ecx + shl edx, 2 + shr edi, 10 +@@: + mov [page_tabs+edi], eax + mov [page_tabs+edi+edx], eax + invlpg [ebx] + invlpg [ebx+0x10000] + add eax, 0x1000 + add ebx, 0x1000 + add edi, 4 + dec ecx + jnz @B + + mov eax, [buf_ptr] + pop edi + pop ebx + ret +.mm_fail: + stdcall free_kernel_space, [buf_ptr] + xor eax, eax + pop ebx +.fail: + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/core/peload.inc b/kernel/tags/kolibri0.7.7.0/core/peload.inc new file mode 100644 index 000000000..d85ec4d88 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/peload.inc @@ -0,0 +1,318 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +include 'export.inc' + +align 4 + +proc load_PE stdcall, file_name:dword + locals + image dd ? + entry dd ? + base dd ? + endl + + stdcall load_file, [file_name] + test eax, eax + jz .fail + + mov [image], eax + + mov edx, [eax+60] + + stdcall kernel_alloc, [eax+80+edx] + test eax, eax + jz .cleanup + + mov [base], eax + + stdcall map_PE, eax, [image] + + mov [entry], eax + test eax, eax + jnz .cleanup + + stdcall kernel_free, [base] +.cleanup: + stdcall kernel_free, [image] + mov eax, [entry] + ret +.fail: + xor eax, eax + ret +endp + +DWORD equ dword +PTR equ + +align 4 +map_PE: ;stdcall base:dword, image:dword + cld + push ebp + push edi + push esi + push ebx + sub esp, 60 + mov ebx, DWORD PTR [esp+84] + mov ebp, DWORD PTR [esp+80] + mov edx, ebx + mov esi, ebx + add edx, DWORD PTR [ebx+60] + mov edi, ebp + mov DWORD PTR [esp+32], edx + mov ecx, DWORD PTR [edx+84] + + shr ecx, 2 + rep movsd + + movzx eax, WORD PTR [edx+6] + mov DWORD PTR [esp+36], 0 + mov DWORD PTR [esp+16], eax + jmp L2 +L3: + mov eax, DWORD PTR [edx+264] + test eax, eax + je L4 + mov esi, ebx + mov edi, ebp + add esi, DWORD PTR [edx+268] + mov ecx, eax + add edi, DWORD PTR [edx+260] + + shr ecx, 2 + rep movsd + +L4: + mov ecx, DWORD PTR [edx+256] + add ecx, 4095 + and ecx, -4096 + cmp ecx, eax + jbe L6 + sub ecx, eax + add eax, DWORD PTR [edx+260] + lea edi, [eax+ebp] + + xor eax, eax + rep stosb + +L6: + inc DWORD PTR [esp+36] + add edx, 40 +L2: + mov esi, DWORD PTR [esp+16] + cmp DWORD PTR [esp+36], esi + jne L3 + mov edi, DWORD PTR [esp+32] + cmp DWORD PTR [edi+164], 0 + je L9 + mov esi, ebp + mov ecx, ebp + sub esi, DWORD PTR [edi+52] + add ecx, DWORD PTR [edi+160] + mov eax, esi + shr eax, 16 + mov DWORD PTR [esp+12], eax + jmp L11 +L12: + lea ebx, [eax-8] + xor edi, edi + shr ebx,1 + jmp L13 +L14: + movzx eax, WORD PTR [ecx+8+edi*2] + mov edx, eax + shr eax, 12 + and edx, 4095 + add edx, DWORD PTR [ecx] + cmp ax, 2 + je L17 + cmp ax, 3 + je L18 + dec ax + jne L15 + mov eax, DWORD PTR [esp+12] + add WORD PTR [edx+ebp], ax +L17: + add WORD PTR [edx+ebp], si +L18: + add DWORD PTR [edx+ebp], esi +L15: + inc edi +L13: + cmp edi, ebx + jne L14 + add ecx, DWORD PTR [ecx+4] +L11: + mov eax, DWORD PTR [ecx+4] + test eax, eax + jne L12 +L9: + mov edx, DWORD PTR [esp+32] + cmp DWORD PTR [edx+132], 0 + je L20 + mov eax, ebp + add eax, DWORD PTR [edx+128] + mov DWORD PTR [esp+40], 0 + add eax, 20 + mov DWORD PTR [esp+56], eax +L22: + mov ecx, DWORD PTR [esp+56] + cmp DWORD PTR [ecx-16], 0 + jne L23 + cmp DWORD PTR [ecx-8], 0 + je L25 +L23: + mov edi, DWORD PTR [__exports+32] + mov esi, DWORD PTR [__exports+28] + mov eax, DWORD PTR [esp+56] + mov DWORD PTR [esp+20], edi + add edi, OS_BASE + add esi, OS_BASE + mov DWORD PTR [esp+44], esi + mov ecx, DWORD PTR [eax-4] + mov DWORD PTR [esp+48], edi + mov edx, DWORD PTR [eax-20] + mov DWORD PTR [esp+52], 0 + add ecx, ebp + add edx, ebp + mov DWORD PTR [esp+24], edx + mov DWORD PTR [esp+28], ecx +L26: + mov esi, DWORD PTR [esp+52] + mov edi, DWORD PTR [esp+24] + mov eax, DWORD PTR [edi+esi*4] + test eax, eax + je L27 + test eax, eax + js L27 + lea edi, [ebp+eax] + mov eax, DWORD PTR [esp+28] + mov DWORD PTR [eax+esi*4], 0 + lea esi, [edi+2] + push eax + push 32 + movzx eax, WORD PTR [edi] + mov edx, DWORD PTR [esp+56] + mov eax, DWORD PTR [edx+eax*4] + add eax, OS_BASE + push eax + push esi + call strncmp + pop ebx + xor ebx, ebx + test eax, eax + jne L32 + jmp L30 +L33: + push ecx + push 32 + mov ecx, DWORD PTR [esp+28] + mov eax, DWORD PTR [ecx+OS_BASE+ebx*4] + add eax, OS_BASE + push eax + push esi + call strncmp + pop edx + test eax, eax + jne L34 + mov esi, DWORD PTR [esp+44] + mov edx, DWORD PTR [esp+52] + mov ecx, DWORD PTR [esp+28] + mov eax, DWORD PTR [esi+ebx*4] + add eax, OS_BASE + mov DWORD PTR [ecx+edx*4], eax + jmp L36 +L34: + inc ebx +L32: + cmp ebx, DWORD PTR [__exports+24] + jb L33 +L36: + cmp ebx, DWORD PTR [__exports+24] + jne L37 + + mov esi, msg_unresolved + call sys_msg_board_str + lea esi, [edi+2] + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str + + mov DWORD PTR [esp+40], 1 + jmp L37 +L30: + movzx eax, WORD PTR [edi] + mov esi, DWORD PTR [esp+44] + mov edi, DWORD PTR [esp+52] + mov edx, DWORD PTR [esp+28] + mov eax, DWORD PTR [esi+eax*4] + add eax, OS_BASE + mov DWORD PTR [edx+edi*4], eax +L37: + inc DWORD PTR [esp+52] + jmp L26 +L27: + add DWORD PTR [esp+56], 20 + jmp L22 +L25: + xor eax, eax + cmp DWORD PTR [esp+40], 0 + jne L40 +L20: + mov ecx, DWORD PTR [esp+32] + mov eax, ebp + add eax, DWORD PTR [ecx+40] +L40: + add esp, 60 + pop ebx + pop esi + pop edi + pop ebp + ret 8 + + align 16 +__exports: + export 'KERNEL', \ + alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall + alloc_page, 'AllocPage', \ ; gcc ABI + alloc_pages, 'AllocPages', \ ; stdcall + commit_pages, 'CommitPages', \ ; eax, ebx, ecx + create_kernel_object, 'CreateObject', \ + create_ring_buffer, 'CreateRingBuffer', \ ; stdcall + destroy_kernel_object, 'DestroyObject', \ + free_kernel_space, 'FreeKernelSpace', \ ; stdcall + kernel_alloc, 'KernelAlloc', \ ; stdcall + kernel_free, 'KernelFree', \ ; stdcall + malloc, 'Kmalloc', \ + free, 'Kfree', \ + map_io_mem, 'MapIoMem', \ ; stdcall + get_pg_addr, 'GetPgAddr', \ ; eax +\ + get_display, 'GetDisplay', \ + set_screen, 'SetScreen', \ + pci_api, 'PciApi', \ + pci_read8, 'PciRead8', \ ; stdcall + pci_read16, 'PciRead16', \ ; stdcall + pci_read32, 'PciRead32', \ ; stdcall + pci_write8, 'PciWrite8', \ ; stdcall + pci_write16, 'PciWrite16', \ ; stdcall + pci_write32, 'PciWrite32', \ ; stdcall +\ + get_service, 'GetService', \ ; + reg_service, 'RegService', \ ; stdcall + attach_int_handler, 'AttachIntHandler', \ ; stdcall + user_alloc, 'UserAlloc', \ ; stdcall + user_free, 'UserFree', \ ; stdcall + unmap_pages, 'UnmapPages', \ ; eax, ecx + sys_msg_board_str, 'SysMsgBoardStr', \ + delay_hs, 'Delay', \ ; ebx + set_mouse_data, 'SetMouseData' + + + diff --git a/kernel/tags/kolibri0.7.7.0/core/sched.inc b/kernel/tags/kolibri0.7.7.0/core/sched.inc new file mode 100644 index 000000000..c77f7e1b1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/sched.inc @@ -0,0 +1,311 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; IRQ0 HANDLER (TIMER INTERRUPT) ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +align 32 +irq0: + pushad + Mov ds, ax, app_data + mov es, ax + inc [timer_ticks] + mov eax, [timer_ticks] + call playNote ; <<<--- Speaker driver + sub eax,[next_usage_update] + cmp eax,100 + jb .nocounter + add [next_usage_update],100 + call updatecputimes + .nocounter: + mov al,0x20 ; send End Of Interrupt signal + out 0x20,al + btr dword[DONT_SWITCH], 0 + jc .return + call find_next_task + jz .return ; if there is only one running process + call do_change_task + .return: + popad + iretd + +align 4 +change_task: + pushfd + cli + pushad +if 0 +; \begin{Mario79} ; <- must be refractoried, if used... + cmp [dma_task_switched], 1 + jne .find_next_task + mov [dma_task_switched], 0 + mov ebx, [dma_process] + cmp [CURRENT_TASK], ebx + je .return + mov edi, [dma_slot_ptr] + mov [CURRENT_TASK], ebx + mov [TASK_BASE], edi + jmp @f +.find_next_task: +; \end{Mario79} +end if + call find_next_task + jz .return ; the same task -> skip switch + @@: mov byte[DONT_SWITCH], 1 + call do_change_task + .return: + popad + popfd + ret + +uglobal +align 4 +; far_jump: +; .offs dd ? +; .sel dw ? + context_counter dd 0 ;noname & halyavin + next_usage_update dd 0 + timer_ticks dd 0 +; prev_slot dd ? +; event_sched dd ? +endg + +align 4 +update_counters: + mov edi, [TASK_BASE] + rdtsc + sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add + add [edi+TASKDATA.counter_sum], eax ; counter sum + ret +align 4 +updatecputimes: + xor eax,eax + xchg eax,[idleuse] + mov [idleusesec],eax + mov ecx, [TASK_COUNT] + mov edi, TASK_DATA + .newupdate: + xor eax,eax + xchg eax,[edi+TASKDATA.counter_sum] + mov [edi+TASKDATA.cpu_usage],eax + add edi,0x20 + loop .newupdate + ret + +align 4 +find_next_task: +;info: +; Find next task to execute +;retval: +; ebx = address of the APPDATA for the selected task (slot-base) +; esi = previous slot-base ([current_slot] at the begin) +; edi = address of the TASKDATA for the selected task +; ZF = 1 if the task is the same +;warning: +; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result +; [current_slot] is not set to new value (ebx)!!! +;scratched: eax,ecx + call update_counters ; edi := [TASK_BASE] + Mov esi, ebx, [current_slot] + .loop: + cmp bh,[TASK_COUNT] + jb @f + xor bh, bh + mov edi,CURRENT_TASK + @@: inc bh ; ebx += APPDATA.size + add edi,0x20 ; edi += TASKDATA.size + mov al, [edi+TASKDATA.state] + test al, al + jz .found ; state == 0 + cmp al, 5 + jne .loop ; state == 1,2,3,4,9 + ; state == 5 + pushad ; more freedom for [APPDATA.wait_test] + call [ebx+APPDATA.wait_test] + mov [esp+28],eax + popad + or eax,eax + jnz @f + ; testing for timeout + mov ecx, [timer_ticks] + sub ecx, [ebx+APPDATA.wait_begin] + cmp ecx, [ebx+APPDATA.wait_timeout] + jb .loop + @@: mov [ebx+APPDATA.wait_param], eax ; retval for wait + mov [edi+TASKDATA.state], 0 + .found: + mov [CURRENT_TASK],bh + mov [TASK_BASE],edi + rdtsc ;call _rdtsc + mov [edi+TASKDATA.counter_add],eax ; for next using update_counters + cmp ebx, esi ;esi - previous slot-base + ret +;TODO: Надо бы убрать использование do_change_task из V86... +; и после этого перенести обработку TASKDATA.counter_add/sum в do_change_task + +align 4 +do_change_task: +;param: +; ebx = address of the APPDATA for incoming task (new) +;warning: +; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task) +; [current_slot] is the outcoming (old), and set here to a new value (ebx) +;scratched: eax,ecx,esi + mov esi,ebx + xchg esi,[current_slot] +; set new stack after saving old + mov [esi+APPDATA.saved_esp], esp + mov esp, [ebx+APPDATA.saved_esp] +; set new thread io-map + Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map] + Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4] +; set new thread memory-map + mov ecx, APPDATA.dir_table + mov eax, [ebx+ecx] ;offset>0x7F + cmp eax, [esi+ecx] ;offset>0x7F + je @f + mov cr3, eax +@@: +; set tss.esp0 + + Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0] + + mov edx, [ebx+APPDATA.tls_base] + cmp edx, [esi+APPDATA.tls_base] + je @f + + mov [tls_data_l+2],dx + shr edx,16 + mov [tls_data_l+4],dl + mov [tls_data_l+7],dh + + mov dx, app_tls + mov fs, dx +@@: +; set gs selector unconditionally + Mov gs,ax,graph_data + ; set CR0.TS + cmp bh, byte[fpu_owner] ;bh == incoming task (new) + clts ;clear a task switch flag + je @f + mov eax, cr0 ;and set it again if the owner + or eax, CR0_TS ;of a fpu has changed + mov cr0, eax + @@: ; set context_counter (only for user pleasure ???) + inc [context_counter] ;noname & halyavin + ; set debug-registers, if it's necessary + test byte[ebx+APPDATA.dbg_state], 1 + jz @f + xor eax, eax + mov dr6, eax + lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F + cld + macro lodsReg [reg] { + lodsd + mov reg,eax + } lodsReg dr0, dr1, dr2, dr3, dr7 + purge lodsReg + @@: ret +;end. + +if 0 +struc TIMER +{ + .next dd ? + .exp_time dd ? + .func dd ? + .arg dd ? +} + + +MAX_PROIRITY 0 ; highest, used for kernel tasks +MAX_USER_PRIORITY 0 ; highest priority for user processes +USER_PRIORITY 7 ; default (should correspond to nice 0) +MIN_USER_PRIORITY 14 ; minimum priority for user processes +IDLE_PRIORITY 15 ; lowest, only IDLE process goes here +NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 + +uglobal +rdy_head rd 16 +endg + +align 4 +pick_task: + + xor eax, eax + .pick: + mov ebx, [rdy_head+eax*4] + test ebx, ebx + jz .next + + mov [next_task], ebx + test [ebx+flags.billable] + jz @F + mov [bill_task], ebx + @@: + ret + .next: + inc eax + jmp .pick + +; param +; eax= task +; +; retval +; eax= task +; ebx= queue +; ecx= front if 1 or back if 0 +align 4 +shed: + cmp [eax+.tics_left], 0 ;signed compare + mov ebx, [eax+.priority] + setg ecx + jg @F + + mov edx, [eax+.tics_quantum] + mov [eax+.ticks_left], edx + cmp ebx, (IDLE_PRIORITY-1) + je @F + inc ebx + @@: + ret + +; param +; eax= task +align 4 +enqueue: + call shed ;eax + cmp [rdy_head+ebx*4],0 + jnz @F + + mov [rdy_head+ebx*4], eax + mov [rdy_tail+ebx*4], eax + mov [eax+.next_ready], 0 + jmp .pick + @@: + test ecx, ecx + jz .back + + mov ecx, [rdy_head+ebx*4] + mov [eax+.next_ready], ecx + mov [rdy_head+ebx*4], eax + jmp .pick + .back: + mov ecx, [rdy_tail+ebx*4] + mov [ecx+.next_ready], eax + mov [rdy_tail+ebx*4], eax + mov [eax+.next_ready], 0 + .pick: + call pick_proc ;select next task + ret + +end if diff --git a/kernel/tags/kolibri0.7.7.0/core/string.inc b/kernel/tags/kolibri0.7.7.0/core/string.inc new file mode 100644 index 000000000..fc6e35473 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/string.inc @@ -0,0 +1,188 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; Author: Kees J. Bot 1 Jan 1994 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; size_t strncat(char *s1, const char *s2, size_t n) +; Append string s2 to s1. + +; char *strchr(const char *s, int c) + + +; int strncmp(const char *s1, const char *s2, size_t n) +; Compare two strings. + +; char *strncpy(char *s1, const char *s2, size_t n) +; Copy string s2 to s1. + +; size_t strnlen(const char *s, size_t n) +; Return the length of a string. + +; proc strrchr stdcall, s:dword, c:dword +; Look for the last occurrence a character in a string. + +proc strncat stdcall, s1:dword, s2:dword, n:dword + push esi + push edi + mov edi, [s1] ; String s1 + mov edx, [n] ; Maximum length + + mov ecx, -1 + xor al, al ; Null byte + cld + repne scasb ; Look for the zero byte in s1 + dec edi ; Back one up (and clear 'Z' flag) + push edi ; Save end of s1 + mov edi, [s2] ; edi = string s2 + mov ecx, edx ; Maximum count + repne scasb ; Look for the end of s2 + jne @F + inc ecx ; Exclude null byte +@@: + sub edx, ecx ; Number of bytes in s2 + mov ecx, edx + mov esi, [s2] ; esi = string s2 + pop edi ; edi = end of string s1 + rep movsb ; Copy bytes + stosb ; Add a terminating null + mov eax, [s1] ; Return s1 + pop edi + pop esi + ret +endp + +align 4 +proc strncmp stdcall, s1:dword, s2:dword, n:dword + + push esi + push edi + mov ecx, [n] + test ecx, ecx ; Max length is zero? + je .done + + mov esi, [s1] ; esi = string s1 + mov edi, [s2] ; edi = string s2 + cld +.compare: + cmpsb ; Compare two bytes + jne .done + cmp byte [esi-1], 0 ; End of string? + je .done + dec ecx ; Length limit reached? + jne .compare +.done: + seta al ; al = (s1 > s2) + setb ah ; ah = (s1 < s2) + sub al, ah + movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 + pop edi + pop esi + ret +endp + +align 4 +proc strncpy stdcall, s1:dword, s2:dword, n:dword + + push esi + push edi + + mov ecx, [n] ; Maximum length + mov edi, [s2] ; edi = string s2 + xor al, al ; Look for a zero byte + mov edx, ecx ; Save maximum count + cld + repne scasb ; Look for end of s2 + sub edx, ecx ; Number of bytes in s2 including null + xchg ecx, edx + mov esi, [s2] ; esi = string s2 + mov edi, [s1] ; edi = string s1 + rep movsb ; Copy bytes + + mov ecx, edx ; Number of bytes not copied + rep stosb ; strncpy always copies n bytes by null padding + mov eax, [s1] ; Return s1 + pop edi + pop esi + ret +endp + +align 4 +proc strnlen stdcall, s:dword, n:dword + + push edi + mov edi, [s] ; edi = string + xor al, al ; Look for a zero byte + mov edx, ecx ; Save maximum count + cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 + cld + repne scasb ; Look for zero + jne @F + inc ecx ; Don't count zero byte +@@: + mov eax, edx + sub eax, ecx ; Compute bytes scanned + pop edi + ret +endp + +align 4 +proc strchr stdcall, s:dword, c:dword + push edi + cld + mov edi, [s] ; edi = string + mov edx, 16 ; Look at small chunks of the string +.next: + shl edx, 1 ; Chunks become bigger each time + mov ecx, edx + xor al, al ; Look for the zero at the end + repne scasb + pushf ; Remember the flags + sub ecx, edx + neg ecx ; Some or all of the chunk + sub edi, ecx ; Step back + mov eax, [c] ; The character to look for + repne scasb + je .found + popf ; Did we find the end of string earlier? + jne .next ; No, try again + xor eax, eax ; Return NULL + pop edi + ret +.found: + pop eax ; Get rid of those flags + lea eax, [edi-1] ; Address of byte found + pop edi + ret + +endp + + +proc strrchr stdcall, s:dword, c:dword + push edi + mov edi, [s] ; edi = string + mov ecx, -1 + xor al, al + cld + repne scasb ; Look for the end of the string + not ecx ; -1 - ecx = Length of the string + null + dec edi ; Put edi back on the zero byte + mov eax, [c] ; The character to look for + std ; Downwards search + repne scasb + cld ; Direction bit back to default + jne .fail + lea eax, [edi+1] ; Found it + pop edi + ret +.fail: + xor eax, eax ; Not there + pop edi + ret +endp + + diff --git a/kernel/tags/kolibri0.7.7.0/core/sync.inc b/kernel/tags/kolibri0.7.7.0/core/sync.inc new file mode 100644 index 000000000..03873ade1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/sync.inc @@ -0,0 +1,119 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Synhronization for MenuetOS. ;; +;; Author: Halyavin Andrey, halyavin@land.ru ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +if ~defined sync_inc +sync_inc_fix: +sync_inc fix sync_inc_fix + +;simplest mutex. +macro SimpleMutex name +{ +; iglobal + name dd 0 + name#.type = 1 +; endg +} +macro WaitSimpleMutex name +{ + local start_wait,ok +start_wait=$ + cli + cmp [name],dword 0 + jz ok + sti + call change_task + jmp start_wait +ok=$ + push eax + mov eax,dword [TASK_BASE+second_base_address] + mov eax,[eax+TASKDATA.pid] + mov [name],eax + pop eax + sti +} +macro ReleaseSimpleMutex name +{ + mov [name],dword 0 +} +macro TryWaitSimpleMutex name ;result in eax and in flags +{ + local ok,try_end + cmp [name],dword 0 + jz ok + xor eax,eax + jmp try_end +ok=$ + xor eax,eax + inc eax +try_end=$ +} +macro SimpleCriticalSection name +{ +; iglobal + name dd 0 + dd 0 + name#.type=2 +; endg +} +macro WaitSimpleCriticalSection name +{ + local start_wait,first_wait,inc_counter,end_wait + push eax + mov eax,[TASK_BASE+second_base_address] + mov eax,[eax+TASKDATA.pid] +start_wait=$ + cli + cmp [name],dword 0 + jz first_wait + cmp [name],eax + jz inc_counter + sti + call change_task + jmp start_wait +first_wait=$ + mov [name],eax + mov [name+4],dword 1 + jmp end_wait +inc_counter=$ + inc dword [name+4] +end_wait=$ + sti + pop eax +} +macro ReleaseSimpleCriticalSection name +{ + local release_end + dec dword [name+4] + jnz release_end + mov [name],dword 0 +release_end=$ +} +macro TryWaitSimpleCriticalSection name ;result in eax and in flags +{ + local ok,try_end + mov eax,[CURRENT_TASK+second_base_address] + mov eax,[eax+TASKDATA.pid] + cmp [name],eax + jz ok + cmp [name],0 + jz ok + xor eax,eax + jmp try_end +ok=$ + xor eax,eax + inc eax +try_end=$ +} +_cli equ call MEM_HeapLock +_sti equ call MEM_HeapUnLock +end if + diff --git a/kernel/tags/kolibri0.7.7.0/core/sys32.inc b/kernel/tags/kolibri0.7.7.0/core/sys32.inc new file mode 100644 index 000000000..70bfea382 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/sys32.inc @@ -0,0 +1,844 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; MenuetOS process management, protected ring3 ;; +;; ;; +;; Distributed under GPL. See file COPYING for details. ;; +;; Copyright 2003 Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +align 4 ;3A08 +build_interrupt_table: + mov edi, idts + mov esi, sys_int + mov ecx, 0x40 + mov eax, (10001110b shl 24) + os_code + @@: movsw ;low word of code-entry + stosd ;interrupt gate type : os_code selector + movsw ;high word of code-entry + loop @b + movsd ;copy low dword of trap gate for int 0x40 + movsd ;copy high dword of trap gate for int 0x40 + lidt [esi] + ret + +iglobal + align 4 + sys_int: + ;exception handlers addresses (for interrupt gate construction) + dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc + dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 + dd e16, e17,e18, e19 + times 12 dd unknown_interrupt ;int_20..int_31 + + ;interrupt handlers addresses (for interrupt gate construction) + dd irq0, irq_serv.irq_1, irq_serv.irq_2 + if USE_COM_IRQ + dd irq_serv.irq_3, irq_serv.irq_4 + else + dd p_irq3, p_irq4 ;??? нестыковка + end if + dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 + dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 + dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15 + times 16 dd unknown_interrupt ;int_0x30..int_0x3F + + ;int_0x40 gate trap (for directly copied) + dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 + + idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) + dw 2*($-sys_int-4)-1 + dd idts ;0x8000B100 + dw 0 ;просто выравнивание + + msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b + dd msg_exc_c,msg_exc_d,msg_exc_e + + msg_exc_8 db "Double fault", 0 + msg_exc_u db "Undefined Exception", 0 + msg_exc_a db "Invalid TSS", 0 + msg_exc_b db "Segment not present", 0 + msg_exc_c db "Stack fault", 0 + msg_exc_d db "General protection fault", 0 + msg_exc_e db "Page fault", 0 + + msg_sel_ker db "kernel", 0 + msg_sel_app db "application", 0 + +endg + +macro save_ring3_context { + pushad +} +macro restore_ring3_context { + popad +} +macro exc_wo_code [num] { + e#num : + save_ring3_context + mov bl, num + jmp exc_c +} exc_wo_code 0,1,2,3,4,5,6,15,16,19 + +macro exc_w_code [num] { + e#num : + add esp, 4 + save_ring3_context + mov bl, num + jmp exc_c +} exc_w_code 8,9,10,11,12,13,17,18 + + +uglobal + pf_err_code dd ? +endg + +page_fault_exc: ; дуракоусточивость: селекторы испорчены... + pop [ss:pf_err_code]; действительно до следующего #PF + save_ring3_context + mov bl,14 + +exc_c: ; исключения (все, кроме 7-го - #NM) +; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь) + reg_ss equ esp+0x30 + reg_esp3 equ esp+0x2C + reg_eflags equ esp+0x28 + reg_cs3 equ esp+0x24 + reg_eip equ esp+0x20 + ; это фрэйм от pushad + reg_eax equ esp+0x1C + reg_ecx equ esp+0x18 + reg_edx equ esp+0x14 + reg_ebx equ esp+0x10 + reg_esp0 equ esp+0x0C + reg_ebp equ esp+0x08 + reg_esi equ esp+0x04 + reg_edi equ esp+0x00 + + Mov ds,ax,app_data ; загрузим правильные значения + mov es,ax ; в сегментные регистры + cld ; и приводим DF к стандарту + movzx ebx,bl +; redirect to V86 manager? (EFLAGS & 0x20000) != 0? + test byte[reg_eflags+2],2 + jnz v86_exc_c + cmp bl,14 ; #PF + jne @f + call page_fault_handler ; SEE: core/memory.inc + @@: mov esi, [current_slot] + btr [esi+APPDATA.except_mask], ebx + jnc @f + mov eax,[esi+APPDATA.exc_handler] + test eax, eax + jnz IRetToUserHook + @@: cli + mov eax, [esi+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + call show_error_parameters ;; only ONE using, inline ??? + ;mov edx, [TASK_BASE] + mov [edx + TASKDATA.state], byte 4 ; terminate + jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc +.debug: +; we are debugged process, notify debugger and suspend ourself +; eax=debugger PID + mov ecx,1 ; debug_message code=other_exception + cmp bl,1 ; #DB + jne .notify ; notify debugger and suspend ourself + mov ebx, dr6 ; debug_message data=DR6_image + xor edx, edx + mov dr6, edx + mov edx, dr7 + mov cl, not 8 + .l1: shl dl,2 + jc @f + and bl, cl + @@: sar cl,1 + jc .l1 + mov cl, 3 ; debug_message code=debug_exception +.notify: + push ebx ; debug_message data + mov ebx, [TASK_BASE] + push [ebx+TASKDATA.pid] ; PID + push ecx ; debug_message code ((here: ecx==1/3)) + mov cl, 12 ; debug_message size + call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc + add esp,12 + mov edx, [TASK_BASE] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task ; SEE: core/shed.inc + restore_ring3_context + iretd + +IRetToUserHook: + xchg eax, [reg_eip] + sub dword[reg_esp3], 8 + mov edi, [reg_esp3] + stosd + mov [edi], ebx + restore_ring3_context +unknown_interrupt: + iretd + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +show_error_parameters: + mov edx,[TASK_BASE] ;not scratched below + DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] + cmp bl, 0x08 + jb .l0 + cmp bl, 0x0e + jbe .l1 + .l0: mov bl, 0x09 + .l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4] + DEBUGF 1, "K : %s\n", eax + mov eax, [reg_cs3+4] + mov edi, msg_sel_app + mov ebx, [reg_esp3+4] + cmp eax, app_code + je @f + mov edi, msg_sel_ker + mov ebx, [reg_esp0+4] + @@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] + DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] + DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx + DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi + ret +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + restore reg_ss + restore reg_esp3 + restore reg_eflags + restore reg_cs + restore reg_eip + restore reg_eax + restore reg_ecx + restore reg_edx + restore reg_ebx + restore reg_esp0 + restore reg_ebp + restore reg_esi + restore reg_edi + +; irq1 -> hid/keyboard.inc +macro irqh [num] { + p_irq#num : + mov edi, num + jmp irqhandler +} + + + +p_irq6: + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 6 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 + call fdc_irq + call ready_for_next_irq + restore_ring3_context + iret + + +p_irq14: + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 14 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 +; mov byte [BOOT_VAR + 0x48E], 0xFF + call [irq14_func] + call ready_for_next_irq_1 + restore_ring3_context + iret +p_irq15: + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 15 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 +; mov byte [BOOT_VAR + 0x48E], 0xFF + call [irq15_func] + call ready_for_next_irq_1 + restore_ring3_context + iret + +ready_for_next_irq: + mov eax,5 + mov [check_idle_semaphore],eax +; mov al, 0x20 + add eax,(0x20-0x5) + + out 0x20, al + ret +;destroy eax +ready_for_next_irq_1: + mov eax,5 + mov [check_idle_semaphore],eax +; mov al, 0x20 + add eax,(0x20-0x5) + out 0xa0,al + out 0x20, al + ret + +irqD: + push eax + xor eax,eax + out 0xf0,al + mov al,0x20 + out 0xa0,al + out 0x20,al + pop eax + iret + + +irqh 2,3,4,5,7,8,9,10,11 + +irqhandler: + + mov esi,edi ; 1 + shl esi,6 ; 1 + add esi,irq00read ; 1 + shl edi,12 ; 1 + add edi,IRQ_SAVE + mov ecx,16 + + irqnewread: + dec ecx + js irqover + + movzx edx, word [esi] ; 2+ + + test edx, edx ; 1 + jz irqover + + + mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size + mov eax, 4000 ; + 0x4 dword - data begin offset + cmp ebx, eax + je irqfull + add ebx, [edi + 0x4] ; add data size to data begin offset + cmp ebx, eax ; if end of buffer, begin cycle again + jb @f + + xor ebx, ebx + + @@: + add ebx, edi + movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word + dec eax + jz irqbyte + dec eax + jnz noirqword + + in ax,dx + cmp ebx, 3999 ; check for address odd in the end of buffer + jne .odd + mov [ebx + 0x10], ax + jmp .add_size + .odd: + mov [ebx + 0x10], al ; I could make mistake here :) + mov [edi + 0x10], ah + .add_size: + add dword [edi], 2 + jmp nextport + + + irqbyte: + in al,dx + mov [ebx + 0x10],al + inc dword [edi] + nextport: + add esi,4 + jmp irqnewread + + + noirqword: + irqfull: + irqover: + + ret + + + +set_application_table_status: + push eax + + mov eax,[CURRENT_TASK] + shl eax, 5 + add eax,CURRENT_TASK+TASKDATA.pid + mov eax,[eax] + + mov [application_table_status],eax + + pop eax + + ret + + +clear_application_table_status: + push eax + + mov eax,[CURRENT_TASK] + shl eax, 5 + add eax,CURRENT_TASK+TASKDATA.pid + mov eax,[eax] + + cmp eax,[application_table_status] + jne apptsl1 + xor eax,eax + mov [application_table_status],eax + apptsl1: + + pop eax + + ret + +; * eax = 64 - номер функции +; * ebx = 1 - единственная подфункция +; * ecx = новый размер памяти +;Возвращаемое значение: +; * eax = 0 - успешно +; * eax = 1 - недостаточно памяти + +sys_resize_app_memory: + ; ebx = 1 - resize + ; ecx = new amount of memory + +; cmp eax,1 + dec ebx + jnz .no_application_mem_resize + stdcall new_mem_resize, ecx + mov [esp+32], eax +.no_application_mem_resize: + ret + +sys_threads: + +; eax=1 create thread +; +; ebx=thread start +; ecx=thread stack value +; +; on return : eax = pid +jmp new_sys_threads + +iglobal +; process_terminating db 'K : Process - terminating',13,10,0 +; process_terminated db 'K : Process - done',13,10,0 + msg_obj_destroy db 'K : destroy app object',13,10,0 +endg + +; param +; esi= slot + +terminate: ; terminate application + + .slot equ esp ;locals + + push esi ;save .slot + + shl esi, 8 + cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 + jne @F + pop esi + shl esi, 5 + mov [CURRENT_TASK+esi+TASKDATA.state], 9 + ret +@@: + ;mov esi,process_terminating + ;call sys_msg_board_str +@@: + cli + cmp [application_table_status],0 + je term9 + sti + call change_task + jmp @b +term9: + call set_application_table_status + +; if the process is in V86 mode... + mov eax, [.slot] + shl eax, 8 + mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack] + add esi, RING0_STACK_SIZE + cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi + jz .nov86 +; ...it has page directory for V86 mode + mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] + mov ecx, [esi+4] + mov [eax+SLOT_BASE+APPDATA.dir_table], ecx +; ...and I/O permission map for V86 mode + mov ecx, [esi+12] + mov [eax+SLOT_BASE+APPDATA.io_map], ecx + mov ecx, [esi+8] + mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx +.nov86: + + mov esi, [.slot] + shl esi,8 + add esi, SLOT_BASE+APP_OBJ_OFFSET +@@: + mov eax, [esi+APPOBJ.fd] + test eax, eax + jz @F + + cmp eax, esi + je @F + + push esi + call [eax+APPOBJ.destroy] + DEBUGF 1,"%s",msg_obj_destroy + pop esi + jmp @B +@@: + + mov eax, [.slot] + shl eax, 8 + stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr] + + mov esi, [.slot] + cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 + jne @F + + mov [fpu_owner],1 + mov eax, [256+SLOT_BASE+APPDATA.fpu_state] + clts + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + fxrstor [eax] + jmp @F +.no_SSE: + fnclex + frstor [eax] +@@: + + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer + + +; remove defined hotkeys + mov eax, hotkey_list +.loop: + cmp [eax+8], esi + jnz .cont + mov ecx, [eax] + jecxz @f + push dword [eax+12] + pop dword [ecx+12] +@@: + mov ecx, [eax+12] + push dword [eax] + pop dword [ecx] + xor ecx, ecx + mov [eax], ecx + mov [eax+4], ecx + mov [eax+8], ecx + mov [eax+12], ecx +.cont: + add eax, 16 + cmp eax, hotkey_list+256*16 + jb .loop +; remove hotkeys in buffer + mov eax, hotkey_buffer +.loop2: + cmp [eax], esi + jnz .cont2 + and dword [eax+4], 0 + and dword [eax], 0 +.cont2: + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb .loop2 + + mov ecx,esi ; remove buttons + bnewba2: + mov edi,[BTN_ADDR] + mov eax,edi + cld + movzx ebx,word [edi] + inc bx + bnewba: + dec bx + jz bnmba + add eax,0x10 + cmp cx,[eax] + jnz bnewba + pusha + mov ecx,ebx + inc ecx + shl ecx,4 + mov ebx,eax + add eax,0x10 + call memmove + dec dword [edi] + popa + jmp bnewba2 + bnmba: + + pusha ; save window coordinates for window restoring + cld + shl esi,5 + add esi,window_data + mov eax,[esi+WDATA.box.left] + mov [dlx],eax + add eax,[esi+WDATA.box.width] + mov [dlxe],eax + mov eax,[esi+WDATA.box.top] + mov [dly],eax + add eax,[esi+WDATA.box.height] + mov [dlye],eax + + xor eax, eax + mov [esi+WDATA.box.left],eax + mov [esi+WDATA.box.width],eax + mov [esi+WDATA.box.top],eax + mov [esi+WDATA.box.height],eax + mov [esi+WDATA.cl_workarea],eax + mov [esi+WDATA.cl_titlebar],eax + mov [esi+WDATA.cl_frames],eax + mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn + lea edi, [esi-window_data+draw_data] + mov ecx,32/4 + rep stosd + popa + +; debuggee test + pushad + mov edi, esi + shl edi, 5 + mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot] + test eax, eax + jz .nodebug + push 8 + pop ecx + push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID + push 2 + call debugger_notify + pop ecx + pop ecx +.nodebug: + popad + + mov ebx, [.slot] + shl ebx, 8 + push ebx + mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] + + stdcall kernel_free, ebx + + pop ebx + mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir] + stdcall kernel_free, ebx + + mov edi, [.slot] + shl edi,8 + add edi,SLOT_BASE + + mov eax, [edi+APPDATA.io_map] + cmp eax, [SLOT_BASE+256+APPDATA.io_map] + je @F + call free_page +@@: + mov eax, [edi+APPDATA.io_map+4] + cmp eax, [SLOT_BASE+256+APPDATA.io_map+4] + je @F + call free_page +@@: + mov eax, 0x20202020 + stosd + stosd + stosd + mov ecx,244/4 + xor eax, eax + rep stosd + + ; activate window + movzx eax, word [WIN_STACK + esi*2] + cmp eax, [TASK_COUNT] + jne .dont_activate + pushad + .check_next_window: + dec eax + cmp eax, 1 + jbe .nothing_to_activate + lea esi, [WIN_POS+eax*2] + movzx edi, word [esi] ; edi = process + shl edi, 5 + cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots + je .check_next_window + add edi, window_data +; \begin{diamond}[19.09.2006] +; skip minimized windows + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .check_next_window +; \end{diamond} + call waredraw + .nothing_to_activate: + popad + .dont_activate: + + push esi ; remove hd1 & cd & flp reservation + shl esi, 5 + mov esi, [esi+CURRENT_TASK+TASKDATA.pid] + cmp [hd1_status], esi + jnz @f + call free_hd_channel + and [hd1_status], 0 +@@: + cmp [cd_status], esi + jnz @f + call free_cd_channel + and [cd_status], 0 +@@: + cmp [flp_status], esi + jnz @f + and [flp_status], 0 +@@: + pop esi + cmp [bgrlockpid], esi + jnz @f + and [bgrlockpid], 0 + and [bgrlock], 0 +@@: + + pusha ; remove all irq reservations + mov eax,esi + shl eax, 5 + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] + mov edi,irq_owner + xor ebx, ebx + xor edx, edx + newirqfree: + cmp [edi + 4 * ebx], eax + jne nofreeirq + mov [edi + 4 * ebx], edx ; remove irq reservation + mov [irq_tab + 4 * ebx], edx ; remove irq handler + mov [irq_rights + 4 * ebx], edx ; set access rights to full access + nofreeirq: + inc ebx + cmp ebx, 16 + jb newirqfree + popa + + pusha ; remove all port reservations + mov edx,esi + shl edx, 5 + add edx,CURRENT_TASK + mov edx,[edx+TASKDATA.pid] + + rmpr0: + + mov esi,[RESERVED_PORTS] + + test esi,esi + jz rmpr9 + + rmpr3: + + mov edi,esi + shl edi,4 + add edi,RESERVED_PORTS + + cmp edx,[edi] + je rmpr4 + + dec esi + jnz rmpr3 + + jmp rmpr9 + + rmpr4: + + mov ecx,256 + sub ecx,esi + shl ecx,4 + + mov esi,edi + add esi,16 + cld + rep movsb + + dec dword [RESERVED_PORTS] + + jmp rmpr0 + + rmpr9: + + popa + mov edi,esi ; do not run this process slot + shl edi, 5 + mov [edi+CURRENT_TASK + TASKDATA.state],byte 9 +; debugger test - terminate all debuggees + mov eax, 2 + mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot +.xd0: + cmp eax, [TASK_COUNT] + ja .xd1 + cmp dword [ecx], esi + jnz @f + and dword [ecx], 0 + pushad + xchg eax, ecx + mov ebx, 2 + call sys_system + popad +@@: + inc eax + add ecx, 0x100 + jmp .xd0 +.xd1: +; call systest + sti ; .. and life goes on + + mov eax, [dlx] + mov ebx, [dly] + mov ecx, [dlxe] + mov edx, [dlye] + call calculatescreen + xor eax, eax + xor esi, esi + call redrawscreen + + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse + + and [application_table_status],0 + ;mov esi,process_terminated + ;call sys_msg_board_str + add esp, 4 + ret +restore .slot + +iglobal + boot_sched_1 db 'Building gdt tss pointer',0 + boot_sched_2 db 'Building IDT table',0 +endg + + +build_scheduler: + + mov esi,boot_sched_1 + call boot_log + ; call build_process_gdt_tss_pointer + + ; mov esi,boot_sched_2 + ; call boot_log + + ret diff --git a/kernel/tags/kolibri0.7.7.0/core/syscall.inc b/kernel/tags/kolibri0.7.7.0/core/syscall.inc new file mode 100644 index 000000000..cd0cbbf45 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/syscall.inc @@ -0,0 +1,261 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +; Old style system call converter +align 16 +cross_order: + ; load all registers in crossed order + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + movzx edi, byte[esp+28 + 4] + call dword [servetable+edi*4] + ret + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSENTER ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 32 +sysenter_entry: + ; Настраиваем стек + mov esp, [ss:tss._esp0] + sti + push ebp ; save app esp + 4 + mov ebp, [ebp] ; ebp - original ebp + ;------------------ + pushad + cld + + movzx eax, al + call dword [servetable2 + eax * 4] + + popad + ;------------------ + xchg ecx, [ss:esp] ; в вершин стека - app ecx, ecx - app esp + 4 + sub ecx, 4 + xchg edx, [ecx] ; edx - return point, & save original edx + push edx + mov edx, [ss:esp + 4] + mov [ecx + 4], edx ; save original ecx + pop edx + sysexit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSTEM CALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +i40: + pushad + cld + movzx eax, al + call dword [servetable2 + eax * 4] + popad + iretd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSCALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +syscall_entry: + ; cli syscall clear IF + xchg esp, [ss:tss._esp0] + push ecx + lea ecx, [esp+4] + xchg ecx, [ss:tss._esp0] + sti + push ecx + mov ecx, [ecx] + ;------------------ + pushad + cld + + movzx eax, al + call dword [servetable2 + eax * 4] + + popad + ;------------------ + mov ecx, [ss:esp+4] + pop esp + sysret + +iglobal + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; SYSTEM FUNCTIONS TABLE ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + servetable: + + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd 0 ; 25 + dd 0 ; 26 + dd 0 + dd 0 ; + dd 0 + dd 0 ; 30-Get/SetCurrentDirectory + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 ; 37-GetMousePosition_ScreenRelative,. + dd 0 ; 38-DrawLine + dd 0 ; 39-GetBackgroundSize,ReadBgrData,. + dd 0 + dd 0 + dd 0 + dd 0 ; 43-SendDeviceData + dd 0 + dd 0 + dd 0 ; 46-ReservePortArea and FreePortArea + dd display_number ; 47-WriteNum + dd display_settings ; 48-SetRedrawType and SetButtonType + dd sys_apm ; 49-Advanced Power Management (APM) + dd random_shaped_window ; 50-Window shape & scale + dd syscall_threads ; 51-Threads + dd stack_driver_stat ; 52-Stack driver status + dd socket ; 53-Socket interface + dd 0 + dd sound_interface ; 55-Sound interface + dd 0 + dd sys_pcibios ; 57-PCI BIOS32 + dd file_system ; 58-Common file system interface + dd 0 + dd sys_IPC ; 60-Inter Process Communication + dd sys_gs ; 61-Direct graphics access + dd sys_pci ; 62-PCI functions + dd sys_msg_board ; 63-System message board + dd 0 ; 64-Resize application memory usage + dd syscall_putimage_palette; 65-PutImagePalette + dd sys_process_def ; 66-Process definitions - keyboard + dd sys_window_move ; 67-Window move or resize + dd f68 ; 68-Some internal services + dd sys_debug_services ; 69-Debug + dd file_system_lfn ; 70-Common file system interface, version 2 + dd syscall_windowsettings ; 71-Window settings + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; NEW SYSTEM FUNCTIONS TABLE ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + align 4 + servetable2: + + dd sys_drawwindow ; 0-DrawWindow + dd syscall_setpixel ; 1-SetPixel + dd sys_getkey ; 2-GetKey + dd sys_clock ; 3-GetTime + dd syscall_writetext ; 4-WriteText + dd delay_hs ; 5-DelayHs + dd syscall_openramdiskfile ; 6-OpenRamdiskFile + dd syscall_putimage ; 7-PutImage + dd sys_button ; 8-DefineButton + dd sys_cpuusage ; 9-GetProcessInfo + dd sys_waitforevent ; 10-WaitForEvent + dd sys_getevent ; 11-CheckForEvent + dd sys_redrawstat ; 12-BeginDraw and EndDraw + dd syscall_drawrect ; 13-DrawRect + dd syscall_getscreensize ; 14-GetScreenSize + dd sys_background ; 15-bgr + dd sys_cachetodiskette ; 16-FlushFloppyCache + dd sys_getbutton ; 17-GetButton + dd sys_system ; 18-System Services + dd paleholder ; 19-reserved + dd sys_midi ; 20-ResetMidi and OutputMidi + dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. + dd sys_settime ; 22-setting date,time,clock and alarm-clock + dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent + dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd undefined_syscall ; 25-reserved + dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. + dd undefined_syscall ; 27-reserved + dd undefined_syscall ; 28-reserved + dd sys_date ; 29-GetDate + dd sys_current_directory ; 30-Get/SetCurrentDirectory + dd undefined_syscall ; 31-reserved + dd undefined_syscall ; 32-reserved + dd undefined_syscall ; 33-reserved + dd undefined_syscall ; 34-reserved + dd syscall_getpixel ; 35-GetPixel + dd syscall_getarea ; 36-GetArea + dd readmousepos ; 37-GetMousePosition_ScreenRelative,. + dd syscall_drawline ; 38-DrawLine + dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. + dd set_app_param ; 40-WantEvents + dd syscall_getirqowner ; 41-GetIrqOwner + dd get_irq_data ; 42-ReadIrqData + dd sys_outport ; 43-SendDeviceData + dd sys_programirq ; 44-ProgramIrqs + dd reserve_free_irq ; 45-ReserveIrq and FreeIrq + dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea + dd cross_order ; 47-WriteNum + dd cross_order ; 48-SetRedrawType and SetButtonType + dd cross_order ; 49-Advanced Power Management (APM) + dd cross_order ; 50-Window shape & scale + dd cross_order ; 51-Threads + dd cross_order ; 52-Stack driver status + dd cross_order ; 53-Socket interface + dd undefined_syscall ; 54-reserved + dd cross_order ; 55-Sound interface + dd undefined_syscall ; 56-reserved + dd cross_order ; 57-PCI BIOS32 + dd cross_order ; 58-Common file system interface + dd undefined_syscall ; 59-reserved + dd cross_order ; 60-Inter Process Communication + dd cross_order ; 61-Direct graphics access + dd cross_order ; 62-PCI functions + dd cross_order ; 63-System message board + dd sys_resize_app_memory ; 64-Resize application memory usage + dd cross_order ; 65-PutImagePalette + dd cross_order ; 66-Process definitions - keyboard + dd cross_order ; 67-Window move or resize + dd cross_order ; 68-Some internal services + dd cross_order ; 69-Debug + dd cross_order ; 70-Common file system interface, version 2 + dd cross_order ; 71-Window settings + dd sys_sendwindowmsg ; 72-Send window message + times 255 - ( ($-servetable2) /4 ) dd undefined_syscall + dd sys_end ; -1-end application + +endg diff --git a/kernel/tags/kolibri0.7.7.0/core/taskman.inc b/kernel/tags/kolibri0.7.7.0/core/taskman.inc new file mode 100644 index 000000000..79e5a64a8 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/taskman.inc @@ -0,0 +1,1168 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +GREEDY_KERNEL equ 0 + +struc APP_HEADER_00 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .i_param dd ? ;+24 +} + +struc APP_HEADER_01 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .stack_top dd ? ;+24 + .i_param dd ? ;+28 + .i_icon dd ? ;+32 +} + + +struc APP_PARAMS +{ .app_cmdline ;0x00 + .app_path ;0x04 + .app_eip ;0x08 + .app_esp ;0x0C + .app_mem ;0x10 +} + +macro _clear_ op +{ mov ecx, op/4 + xor eax, eax + cld + rep stosd +} + +fs_execute_from_sysdir: + xor ebx, ebx + xor edx, edx + mov esi, sysdir_path + +align 4 +proc fs_execute + +;fn_read:dword, file_size:dword, cluster:dword + +; ebx - cmdline +; edx - flags +; ebp - full filename +; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it + + locals + cmdline rd 64 ;256/4 + filename rd 256 ;1024/4 + flags dd ? + + save_cr3 dd ? + slot dd ? + slot_base dd ? + file_base dd ? + file_size dd ? + ;app header data + hdr_cmdline dd ? ;0x00 + hdr_path dd ? ;0x04 + hdr_eip dd ? ;0x08 + hdr_esp dd ? ;0x0C + hdr_mem dd ? ;0x10 + hdr_i_end dd ? ;0x14 + endl + + pushad + + mov [flags], edx + +; [ebp] pointer to filename + + lea edi, [filename] + lea ecx, [edi+1024] + mov al, '/' + stosb +@@: + cmp edi, ecx + jae .bigfilename + lodsb + stosb + test al, al + jnz @b + mov esi, [ebp] + test esi, esi + jz .namecopied + mov byte [edi-1], '/' +@@: + cmp edi, ecx + jae .bigfilename + lodsb + stosb + test al, al + jnz @b + jmp .namecopied +.bigfilename: + popad + mov eax, -ERROR_FILE_NOT_FOUND + ret + +.namecopied: + + mov [cmdline], ebx + test ebx, ebx + jz @F + + lea eax, [cmdline] + mov dword [eax+252], 0 + stdcall strncpy, eax, ebx, 255 +@@: + lea eax, [filename] + stdcall load_file, eax + mov ecx, -ERROR_FILE_NOT_FOUND + test eax, eax + jz .err_file + + mov [file_base], eax + mov [file_size], ebx + + lea ebx, [hdr_cmdline] + call test_app_header + mov ecx, -0x1F + test eax, eax + jz .err_hdr + + ;mov esi, new_process_loading + ;call sys_msg_board_str ; write message to message board + +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + test eax, eax + jnz .wait_lock + + call set_application_table_status + + call get_new_process_place + test eax, eax + mov ecx, -0x20 ; too many processes + jz .err + + mov [slot], eax + shl eax, 8 + add eax, SLOT_BASE + mov [slot_base], eax + mov edi, eax + _clear_ 256 ;clean extended information about process + +; write application name + lea eax, [filename] + stdcall strrchr, eax, '/' ; now eax points to name without path + + lea esi, [eax+1] + test eax, eax + jnz @F + lea esi, [filename] +@@: + mov ecx, 8 ; 8 chars for name + mov edi, [slot_base] +.copy_process_name_loop: + lodsb + cmp al, '.' + jz .copy_process_name_done + test al, al + jz .copy_process_name_done + stosb + loop .copy_process_name_loop +.copy_process_name_done: + + mov ebx, cr3 + mov [save_cr3], ebx + + stdcall create_app_space,[hdr_mem],[file_base],[file_size] + mov ecx, -30 ; no memory + test eax, eax + jz .failed + + mov ebx,[slot_base] + mov [ebx+APPDATA.dir_table],eax + mov eax,[hdr_mem] + mov [ebx+APPDATA.mem_size],eax + + xor edx, edx + cmp word [6], '02' + jne @f + + not edx +@@: + mov [ebx+APPDATA.tls_base],edx + +if GREEDY_KERNEL +else + mov ecx, [hdr_mem] + mov edi, [file_size] + add edi, 4095 + and edi, not 4095 + sub ecx, edi + jna @F + + xor eax, eax + cld + rep stosb +@@: +end if + +; release only virtual space, not phisical memory + + stdcall free_kernel_space, [file_base] + lea eax, [hdr_cmdline] + lea ebx, [cmdline] + lea ecx, [filename] + stdcall set_app_params ,[slot],eax,ebx,ecx,[flags] + + mov eax, [save_cr3] + call set_cr3 + + xor ebx, ebx + mov [application_table_status],ebx ;unlock application_table_status mutex + mov eax,[process_number] ;set result + ret +.failed: + mov eax, [save_cr3] + call set_cr3 +.err: +.err_hdr: + stdcall kernel_free,[file_base] +.err_file: + xor eax, eax + mov [application_table_status],eax + mov eax, ecx + ret +endp + +align 4 +test_app_header: + virtual at eax + APP_HEADER_00 APP_HEADER_00 + end virtual + virtual at eax + APP_HEADER_01 APP_HEADER_01 + end virtual + + cmp dword [eax], 'MENU' + jne .fail + cmp word [eax+4],'ET' + jne .fail + + cmp [eax+6], word '00' + jne .check_01_header + + mov ecx,[APP_HEADER_00.start] + mov [ebx+0x08], ecx ;app_eip + mov edx,[APP_HEADER_00.mem_size] + mov [ebx+0x10], edx ;app_mem + shr edx,1 + sub edx,0x10 + mov [ebx+0x0C], edx ;app_esp + mov ecx,[APP_HEADER_00.i_param] + mov [ebx], ecx ;app_cmdline + mov [ebx+4], dword 0 ;app_path + mov edx, [APP_HEADER_00.i_end] + mov [ebx+0x14], edx + ret + + .check_01_header: + + cmp [eax+6], word '01' + je @f + cmp [eax+6], word '02' + jne .fail +@@: + mov ecx,[APP_HEADER_01.start] + mov [ebx+0x08], ecx ;app_eip + mov edx,[APP_HEADER_01.mem_size] + +; \begin{diamond}[20.08.2006] +; sanity check (functions 19,58 load app_i_end bytes and that must +; fit in allocated memory to prevent kernel faults) + cmp edx,[APP_HEADER_01.i_end] + jb .fail +; \end{diamond}[20.08.2006] + + mov [ebx+0x10], edx ;app_mem + mov ecx,[APP_HEADER_01.stack_top] + mov [ebx+0x0C], ecx ;app_esp + mov edx,[APP_HEADER_01.i_param] + mov [ebx], edx ;app_cmdline + mov ecx,[APP_HEADER_01.i_icon] + mov [ebx+4], ecx ;app_path + mov edx, [APP_HEADER_01.i_end] + mov [ebx+0x14], edx + ret +.fail: + xor eax, eax + ret + +align 4 +proc get_new_process_place +;input: +; none +;result: +; eax=[new_process_place]<>0 - ok +; 0 - failed. +;This function find least empty slot. +;It doesn't increase [TASK_COUNT]! + mov eax,CURRENT_TASK + mov ebx,[TASK_COUNT] + inc ebx + shl ebx,5 + add ebx,eax ;ebx - address of process information for (last+1) slot +.newprocessplace: +;eax = address of process information for current slot + cmp eax,ebx + jz .endnewprocessplace ;empty slot after high boundary + add eax,0x20 + cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty + jnz .newprocessplace +.endnewprocessplace: + mov ebx,eax + sub eax,CURRENT_TASK + shr eax,5 ;calculate slot index + cmp eax,256 + jge .failed ;it should be <256 + mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) + ret +.failed: + xor eax,eax + ret +endp + +align 4 +proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword + locals + app_pages dd ? + img_pages dd ? + dir_addr dd ? + app_tabs dd ? + endl + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + xor eax, eax + mov [dir_addr], eax + + mov eax, [app_size] + add eax, 4095 + and eax, NOT(4095) + mov [app_size], eax + mov ebx, eax + shr eax, 12 + mov [app_pages], eax + + add ebx, 0x3FFFFF + and ebx, NOT(0x3FFFFF) + shr ebx, 22 + mov [app_tabs], ebx + + mov ecx, [img_size] + add ecx, 4095 + and ecx, NOT(4095) + + mov [img_size], ecx + shr ecx, 12 + mov [img_pages], ecx + + if GREEDY_KERNEL + lea eax, [ecx+ebx+2] ;only image size + else + lea eax, [eax+ebx+2] ;all requested memory + end if + cmp eax, [pg_data.pages_free] + ja .fail + + call alloc_page + test eax, eax + jz .fail + mov [dir_addr], eax + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW + + mov edi, [tmp_task_pdir] + mov ecx, (OS_BASE shr 20)/4 + xor eax, eax + cld + rep stosd + + mov ecx, (OS_BASE shr 20)/4 + mov esi, sys_pgdir+(OS_BASE shr 20) + rep movsd + + mov eax, [dir_addr] + or eax, PG_SW + mov [edi-4096+(page_tabs shr 20)], eax + + and eax, -4096 + call set_cr3 + + mov edx, [app_tabs] + mov edi, new_app_base +@@: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page_table, edi, eax + add edi, 0x00400000 + dec edx + jnz @B + + mov edi, new_app_base + shr edi, 10 + add edi, page_tabs + + mov ecx, [app_tabs] + shl ecx, 10 + xor eax, eax + rep stosd + + mov ecx, [img_pages] + mov ebx, PG_UW + mov edx, new_app_base + mov esi, [img_base] + mov edi, new_app_base + shr esi, 10 + shr edi, 10 + add esi, page_tabs + add edi, page_tabs +.remap: + lodsd + or eax, ebx ; force user level r/w access + stosd + add edx, 0x1000 + dec [app_pages] + dec ecx + jnz .remap + + mov ecx, [app_pages] + test ecx, ecx + jz .done + +if GREEDY_KERNEL + mov eax, 0x02 + rep stosd +else + +.alloc: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page,edx,eax,dword PG_UW + add edx, 0x1000 + dec [app_pages] + jnz .alloc +end if + +.done: + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + + dec [pg_data.pg_mutex] + mov eax, [dir_addr] + ret +.fail: + dec [pg_data.pg_mutex] + cmp [dir_addr], 0 + je @f + stdcall destroy_app_space, [dir_addr], 0 +@@: + xor eax, eax + ret +endp + +align 4 +set_cr3: + + mov ebx, [current_slot] + mov [ebx+APPDATA.dir_table], eax + mov cr3, eax + ret + +align 4 +proc destroy_page_table stdcall, pg_tab:dword + + push esi + + mov esi, [pg_tab] + mov ecx, 1024 +.free: + mov eax, [esi] + test eax, 1 + jz .next + test eax, 1 shl 9 + jnz .next ;skip shared pages + call free_page +.next: + add esi, 4 + dec ecx + jnz .free + pop esi + ret +endp + +align 4 +proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword + + xor edx,edx + push edx + mov eax,0x2 + mov ebx, [pg_dir] +.loop: +;eax = current slot of process + mov ecx,eax + shl ecx,5 + cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running? + jz @f ;skip empty slots + shl ecx,3 + add ecx,SLOT_BASE + cmp [ecx+APPDATA.dir_table],ebx ;compare page directory addresses + jnz @f + mov [ebp-4],ecx + inc edx ;thread found +@@: + inc eax + cmp eax,[TASK_COUNT] ;exit loop if we look through all processes + jle .loop + +;edx = number of threads +;our process is zombi so it isn't counted + pop ecx + cmp edx,1 + jg .ret +;if there isn't threads then clear memory. + mov esi, [dlls_list] + call destroy_all_hdlls + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + mov eax, [pg_dir] + and eax, not 0xFFF + stdcall map_page,[tmp_task_pdir],eax,PG_SW + mov esi, [tmp_task_pdir] + mov edi, (OS_BASE shr 20)/4 +.destroy: + mov eax, [esi] + test eax, 1 + jz .next + and eax, not 0xFFF + stdcall map_page,[tmp_task_ptab],eax,PG_SW + stdcall destroy_page_table, [tmp_task_ptab] + mov eax, [esi] + call free_page +.next: + add esi, 4 + dec edi + jnz .destroy + + mov eax, [pg_dir] + call free_page +.exit: + stdcall map_page,[tmp_task_ptab],0,PG_UNMAP + stdcall map_page,[tmp_task_pdir],0,PG_UNMAP + dec [pg_data.pg_mutex] +.ret: + ret +endp + +align 4 +get_pid: + mov eax, [TASK_BASE] + mov eax, [eax+TASKDATA.pid] + ret + +pid_to_slot: +;Input: +; eax - pid of process +;Output: +; eax - slot of process or 0 if process don't exists +;Search process by PID. + push ebx + push ecx + mov ebx,[TASK_COUNT] + shl ebx,5 + mov ecx,2*32 + +.loop: +;ecx=offset of current process info entry +;ebx=maximum permitted offset + cmp byte [CURRENT_TASK+ecx+0xa],9 + jz .endloop ;skip empty slots + cmp [CURRENT_TASK+ecx+0x4],eax ;check PID + jz .pid_found +.endloop: + add ecx,32 + cmp ecx,ebx + jle .loop + + pop ecx + pop ebx + xor eax,eax + ret + +.pid_found: + shr ecx,5 + mov eax,ecx ;convert offset to index of slot + pop ecx + pop ebx + ret + +check_region: +;input: +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + mov eax,[CURRENT_TASK] + jmp check_process_region +;----------------------------------------------------------------------------- +check_process_region: +;input: +; eax - slot +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + + test ecx,ecx + jle .ok + shl eax,5 + cmp word [CURRENT_TASK+eax+0xa],0 + jnz .failed + shl eax,3 + mov eax,[SLOT_BASE+eax+0xb8] + test eax,eax + jz .failed + + mov eax,1 + ret + + +; call MEM_Get_Linear_Address +; push ebx +; push ecx +; push edx +; mov edx,ebx +; and edx,not (4096-1) +; sub ebx,edx +; add ecx,ebx +; mov ebx,edx +; add ecx,(4096-1) +; and ecx,not (4096-1) +;.loop: +;;eax - linear address of page directory +;;ebx - current page +;;ecx - current size +; mov edx,ebx +; shr edx,22 +; mov edx,[eax+4*edx] +; and edx,not (4096-1) +; test edx,edx +; jz .failed1 +; push eax +; mov eax,edx +; call MEM_Get_Linear_Address +; mov edx,ebx +; shr edx,12 +; and edx,(1024-1) +; mov eax,[eax+4*edx] +; and eax,not (4096-1) +; test eax,eax +; pop eax +; jz .failed1 +; add ebx,4096 +; sub ecx,4096 +; jg .loop +; pop edx +; pop ecx +; pop ebx +.ok: + mov eax,1 + ret +; +;.failed1: +; pop edx +; pop ecx +; pop ebx +.failed: + xor eax,eax + ret + +align 4 +proc read_process_memory +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes read. + locals + slot dd ? + buff dd ? + r_count dd ? + offset dd ? + tmp_r_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + and [r_count], 0 + mov [tmp_r_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_r_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov ebx, [offset] + + push ecx + stdcall map_memEx, [proc_mem_map],\ + [slot], ebx, ecx, PG_MAP + pop ecx + + mov esi, [offset] + and esi, 0xfff + sub eax, esi + jbe .ret + cmp ecx, eax + jbe @f + mov ecx, eax + mov [tmp_r_cnt], eax +@@: + add esi, [proc_mem_map] + mov edi, [buff] + mov edx, ecx + rep movsb + add [r_count], edx + + add [offset], edx + sub [tmp_r_cnt], edx + jnz .read_mem +.ret: + popad + mov eax, [r_count] + ret +endp + +align 4 +proc write_process_memory +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes written + + locals + slot dd ? + buff dd ? + w_count dd ? + offset dd ? + tmp_w_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + and [w_count], 0 + mov [tmp_w_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_w_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov ebx, [offset] + ; add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [slot], ebx, ecx, PG_SW + pop ecx + + mov edi, [offset] + and edi, 0xfff + sub eax, edi + jbe .ret + cmp ecx, eax + jbe @f + mov ecx, eax + mov [tmp_w_cnt], eax +@@: + add edi, [proc_mem_map] + mov esi, [buff] + mov edx, ecx + rep movsb + + add [w_count], edx + add [offset], edx + sub [tmp_w_cnt], edx + jnz .read_mem +.ret: + popad + mov eax, [w_count] + ret +endp + +align 4 +proc new_sys_threads + locals + slot dd ? + app_cmdline dd ? ;0x00 + app_path dd ? ;0x04 + app_eip dd ? ;0x08 + app_esp dd ? ;0x0C + app_mem dd ? ;0x10 + endl + + cmp eax,1 + jne .failed ;other subfunctions + + xor eax,eax + mov [app_cmdline], eax + mov [app_path], eax + mov [app_eip], ebx + mov [app_esp], ecx + + ;mov esi,new_process_loading + ;call sys_msg_board_str +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + + call set_application_table_status + + call get_new_process_place + test eax, eax + jz .failed + + mov [slot], eax + + mov esi,[current_slot] + mov ebx,esi ;ebx=esi - pointer to extended information about current thread + + mov edi, eax + shl edi,8 + add edi,SLOT_BASE + mov edx,edi ;edx=edi - pointer to extended infomation about new thread + mov ecx,256/4 + xor eax, eax + cld + rep stosd ;clean extended information about new thread + mov esi,ebx + mov edi,edx + mov ecx,11 + rep movsb ;copy process name + + mov eax,[ebx+APPDATA.heap_base] + mov [edx+APPDATA.heap_base], eax + + mov ecx,[ebx+APPDATA.heap_top] + mov [edx+APPDATA.heap_top], ecx + + mov eax,[ebx+APPDATA.mem_size] + mov [edx+APPDATA.mem_size], eax + + mov ecx,[ebx+APPDATA.dir_table] + mov [edx+APPDATA.dir_table],ecx ;copy page directory + + mov eax,[ebx+APPDATA.dlls_list_ptr] + mov [edx+APPDATA.dlls_list_ptr],eax + + mov eax, [ebx+APPDATA.tls_base] + test eax, eax + jz @F + + push edx + stdcall user_alloc, 4096 + pop edx + test eax, eax + jz .failed +@@: + mov [edx+APPDATA.tls_base], eax + + lea eax, [app_cmdline] + stdcall set_app_params ,[slot],eax,dword 0,\ + dword 0,dword 0 + + ;mov esi,new_process_running + ;call sys_msg_board_str ;output information about succefull startup + + mov [application_table_status],0 ;unlock application_table_status mutex + mov eax,[process_number] ;set result + ret +.failed: + mov [application_table_status],0 + mov eax,-1 + ret +endp + +; param +; ebx=mutex + +align 4 +wait_mutex: +;;Maxis use atomic bts for mutex 4.4.2009 + push eax + push ebx +.do_wait: + bts dword [ebx],0 + jnc .locked + call change_task + jmp .do_wait +.locked: + pop ebx + pop eax + ret + +align 4 +tls_app_entry: + + call init_heap + stdcall user_alloc, 4096 + + mov edx, [current_slot] + mov [edx+APPDATA.tls_base], eax + mov [tls_data_l+2],ax + shr eax,16 + mov [tls_data_l+4],al + mov [tls_data_l+7],ah + mov dx, app_tls + mov fs, dx + popad + iretd + + +EFL_IF equ 0x0200 +EFL_IOPL1 equ 0x1000 +EFL_IOPL2 equ 0x2000 +EFL_IOPL3 equ 0x3000 + + +align 4 +proc set_app_params stdcall,slot:dword, params:dword,\ + cmd_line:dword, app_path:dword, flags:dword + + locals + pl0_stack dd ? + endl + + stdcall kernel_alloc, RING0_STACK_SIZE+512 + mov [pl0_stack], eax + + lea edi, [eax+RING0_STACK_SIZE] + + mov eax, [slot] + mov ebx, eax + + shl eax, 8 + mov [eax+SLOT_BASE+APPDATA.fpu_state], edi + mov [eax+SLOT_BASE+APPDATA.exc_handler], 0 + mov [eax+SLOT_BASE+APPDATA.except_mask], 0 + +;set default io permission map + mov ecx, [SLOT_BASE+256+APPDATA.io_map] + mov [eax+SLOT_BASE+APPDATA.io_map], ecx + mov ecx, [SLOT_BASE+256+APPDATA.io_map+4] + mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx + + mov esi, fpu_data + mov ecx, 512/4 + rep movsd + + cmp ebx,[TASK_COUNT] + jle .noinc + inc dword [TASK_COUNT] ;update number of processes +.noinc: + shl ebx,8 + lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET] + mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx + mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx + + add edx, APP_OBJ_OFFSET-APP_EV_OFFSET + mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx + mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx + + mov ecx, [def_cursor] + mov [SLOT_BASE+APPDATA.cursor+ebx],ecx + mov eax, [pl0_stack] + mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax + add eax, RING0_STACK_SIZE + mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax + + push ebx + stdcall kernel_alloc, 0x1000 + pop ebx + mov esi,[current_slot] + mov esi,[esi+APPDATA.cur_dir] + mov ecx,0x1000/4 + mov edi,eax + mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax + rep movsd + + shr ebx,3 + mov eax, new_app_base + mov dword [CURRENT_TASK+ebx+0x10],eax + +.add_command_line: + mov edx,[params] + mov edx,[edx] ;app_cmdline + test edx,edx + jz @f ;application doesn't need parameters + + mov eax, edx + add eax, 256 + jc @f + + cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] + ja @f + + mov byte [edx], 0 ;force empty string if no cmdline given + mov eax, [cmd_line] + test eax, eax + jz @f + stdcall strncpy, edx, eax, 256 +@@: + mov edx,[params] + mov edx, [edx+4] ;app_path + test edx,edx + jz @F ;application don't need path of file + mov eax, edx + add eax, 1024 + jc @f + cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] + ja @f + stdcall strncpy, edx, [app_path], 1024 +@@: + mov ebx,[slot] + mov eax,ebx + shl ebx,5 + lea ecx,[draw_data+ebx] ;ecx - pointer to draw data + + mov edx, irq0.return + cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1 + jne @F + mov edx, tls_app_entry +@@: +; set window state to 'normal' (non-minimized/maximized/rolled-up) state + mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL + mov [ebx+window_data+WDATA.fl_redraw], 1 + add ebx,CURRENT_TASK ;ebx - pointer to information about process + mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot + + mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) + + inc dword [process_number] + mov eax,[process_number] + mov [ebx+4],eax ;set PID + +;set draw data to full screen + + mov [ecx+0],dword 0 + mov [ecx+4],dword 0 + mov eax,[Screen_Max_X] + mov [ecx+8],eax + mov eax,[Screen_Max_Y] + mov [ecx+12],eax + + mov ebx, [pl0_stack] + mov esi,[params] + lea ecx, [ebx+REG_EIP] + xor eax, eax + + mov [ebx+REG_RET], edx + mov [ebx+REG_EDI], eax + mov [ebx+REG_ESI], eax + mov [ebx+REG_EBP], eax + mov [ebx+REG_ESP], ecx ;ebx+REG_EIP + mov [ebx+REG_EBX], eax + mov [ebx+REG_EDX], eax + mov [ebx+REG_ECX], eax + mov [ebx+REG_EAX], eax + + mov eax, [esi+0x08] ;app_eip + mov [ebx+REG_EIP], eax ;app_entry + mov [ebx+REG_CS], dword app_code + mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF + + mov eax, [esi+0x0C] ;app_esp + mov [ebx+REG_APP_ESP], eax ;app_stack + mov [ebx+REG_SS], dword app_data + + lea ecx, [ebx+REG_RET] + mov ebx, [slot] + shl ebx, 5 + mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx + + xor ecx, ecx ; process state - running +; set if debuggee + test byte [flags], 1 + jz .no_debug + inc ecx ; process state - suspended + mov eax,[CURRENT_TASK] + mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax +.no_debug: + mov [CURRENT_TASK+ebx+TASKDATA.state], cl + ;mov esi,new_process_running + ;call sys_msg_board_str ;output information about succefull startup + ret +endp + +include "debug.inc" diff --git a/kernel/tags/kolibri0.7.7.0/core/v86.inc b/kernel/tags/kolibri0.7.7.0/core/v86.inc new file mode 100644 index 000000000..497d01dd0 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/core/v86.inc @@ -0,0 +1,935 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +; Virtual-8086 mode manager +; diamond, 2007, 2008 + +DEBUG_SHOW_IO = 0 + +struc V86_machine +{ +; page directory + .pagedir dd ? +; translation table: V86 address -> flat linear address + .pages dd ? +; mutex to protect all data from writing by multiple threads at one time + .mutex dd ? +; i/o permission map + .iopm dd ? +.size = $ +} +virtual at 0 +V86_machine V86_machine +end virtual + +; Create V86 machine +; in: nothing +; out: eax = handle (pointer to struc V86_machine) +; eax = NULL => failure +; destroys: ebx, ecx, edx (due to malloc) +v86_create: +; allocate V86_machine structure + mov eax, V86_machine.size + call malloc + test eax, eax + jz .fail +; initialize mutex + and dword [eax+V86_machine.mutex], 0 +; allocate tables + mov ebx, eax +; We allocate 4 pages. +; First is main page directory for V86 mode. +; Second page: +; first half (0x800 bytes) is page table for addresses 0 - 0x100000, +; second half is for V86-to-linear translation. +; Third and fourth are for I/O permission map. + push 8000h ; blocks less than 8 pages are discontinuous + call kernel_alloc + test eax, eax + jz .fail2 + mov [ebx+V86_machine.pagedir], eax + push edi eax + mov edi, eax + add eax, 1800h + mov [ebx+V86_machine.pages], eax +; initialize tables + mov ecx, 2000h/4 + xor eax, eax + rep stosd + mov [ebx+V86_machine.iopm], edi + dec eax + mov ecx, 2000h/4 + rep stosd + pop eax +; page directory: first entry is page table... + mov edi, eax + add eax, 1000h + push eax + call get_pg_addr + or al, PG_UW + stosd +; ...and also copy system page tables +; thx to Serge, system is located at high addresses + add edi, (OS_BASE shr 20) - 4 + push esi + mov esi, (OS_BASE shr 20) + sys_pgdir + mov ecx, 0x80000000 shr 22 + rep movsd + + mov eax, [ebx+V86_machine.pagedir] ;root dir also is + call get_pg_addr ;used as page table + or al, PG_SW + mov [edi-4096+(page_tabs shr 20)], eax + + pop esi +; now V86 specific: initialize known addresses in first Mb + pop eax +; first page - BIOS data (shared between all machines!) +; physical address = 0x2f0000 +; linear address = BOOT_VAR = OS_BASE + 0x2f0000 + mov dword [eax], (BOOT_VAR - OS_BASE) or 111b + mov dword [eax+800h], BOOT_VAR +; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) +; physical address = 0x9C000 +; linear address = 0x8009C000 +; (I have seen one computer with EBDA segment = 0x9D80, +; all other computers use less memory) + mov ecx, 4 + mov edx, 0x9C000 + push eax + lea edi, [eax+0x9C*4] +@@: + lea eax, [edx + OS_BASE] + mov [edi+800h], eax + lea eax, [edx + 111b] + stosd + add edx, 0x1000 + loop @b + pop eax + pop edi +; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) +; physical address = 0xC0000 +; linear address = 0x800C0000 + mov ecx, 0xC0 +@@: + mov edx, ecx + shl edx, 12 + push edx + or edx, 111b + mov [eax+ecx*4], edx + pop edx + add edx, OS_BASE + mov [eax+ecx*4+0x800], edx + inc cl + jnz @b + mov eax, ebx + ret +.fail2: + mov eax, ebx + call free +.fail: + xor eax, eax + ret + +; Destroy V86 machine +; in: eax = handle +; out: nothing +; destroys: eax, ebx, ecx, edx (due to free) +v86_destroy: + push eax + stdcall kernel_free, [eax+V86_machine.pagedir] + pop eax + jmp free + +; Translate V86-address to linear address +; in: eax=V86 address +; esi=handle +; out: eax=linear address +; destroys: nothing +v86_get_lin_addr: + push ecx edx + mov ecx, eax + mov edx, [esi+V86_machine.pages] + shr ecx, 12 + and eax, 0xFFF + add eax, [edx+ecx*4] ; atomic operation, no mutex needed + pop edx ecx + ret + +; Sets linear address for V86-page +; in: eax=linear address (must be page-aligned) +; ecx=V86 page (NOT address!) +; esi=handle +; out: nothing +; destroys: nothing +v86_set_page: + push eax ebx + mov ebx, [esi+V86_machine.pagedir] + mov [ebx+ecx*4+0x1800], eax + call get_pg_addr + or al, 111b + mov [ebx+ecx*4+0x1000], eax + pop ebx eax + ret + +; Allocate memory in V86 machine +; in: eax=size (in bytes) +; esi=handle +; out: eax=V86 address, para-aligned (0x10 multiple) +; destroys: nothing +; ­Ґ¤®ЇЁб ­ !!! +;v86_alloc: +; push ebx ecx edx edi +; lea ebx, [esi+V86_machine.mutex] +; call wait_mutex +; add eax, 0x1F +; shr eax, 4 +; mov ebx, 0x1000 ; start with address 0x1000 (second page) +; mov edi, [esi+V86_machine.tables] +;.l: +; mov ecx, ebx +; shr ecx, 12 +; mov edx, [edi+0x1000+ecx*4] ; get linear address +; test edx, edx ; page allocated? +; jz .unalloc +; mov ecx, ebx +; and ecx, 0xFFF +; add edx, ecx +; cmp dword [edx], 0 ; free block? +; jnz .n +; cmp dword [edx+4], +; and [esi+V86_machine.mutex], 0 +; pop edi edx ecx ebx +; ret + +uglobal +sys_v86_machine dd ? +endg + +; Called from kernel.asm at first stages of loading +; Initialize system V86 machine (used to simulate BIOS int 13h) +init_sys_v86: + call v86_create + mov [sys_v86_machine], eax + test eax, eax + jz .ret + mov byte [BOOT_VAR + 0x500], 0xCD + mov byte [BOOT_VAR + 0x501], 0x13 + mov byte [BOOT_VAR + 0x502], 0xF4 + mov byte [BOOT_VAR + 0x503], 0xCD + mov byte [BOOT_VAR + 0x504], 0x10 + mov byte [BOOT_VAR + 0x505], 0xF4 + mov esi, eax + mov ebx, [eax+V86_machine.pagedir] +; one page for stack, two pages for results (0x2000 bytes = 16 sectors) + mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b + mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000 + mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b + mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000 + mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b + mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000 +if ~DEBUG_SHOW_IO +; allow access to all ports + mov ecx, [esi+V86_machine.iopm] + xor eax, eax + mov edi, ecx + mov ecx, 10000h/8/4 + rep stosd +end if +.ret: + ret + +struc v86_regs +{ +; don't change the order, it is important + .edi dd ? + .esi dd ? + .ebp dd ? + dd ? ; ignored + .ebx dd ? + .edx dd ? + .ecx dd ? + .eax dd ? + .eip dd ? + .cs dd ? + .eflags dd ? ; VM flag must be set! + .esp dd ? + .ss dd ? + .es dd ? + .ds dd ? + .fs dd ? + .gs dd ? +.size = $ +} +virtual at 0 +v86_regs v86_regs +end virtual + +; Run V86 machine +; in: ebx -> registers for V86 (two structures: in and out) +; esi = handle +; ecx = expected end address (CS:IP) +; edx = IRQ to hook or -1 if not required +; out: structure pointed to by ebx is filled with new values +; eax = 1 - exception has occured, cl contains code +; eax = 2 - access to disabled i/o port, ecx contains port address +; eax = 3 - IRQ is already hooked by another VM +; destroys: nothing +v86_start: + pushad + + cli + + mov ecx, [CURRENT_TASK] + shl ecx, 8 + add ecx, SLOT_BASE + + mov eax, [esi+V86_machine.iopm] + call get_pg_addr + inc eax + push dword [ecx+APPDATA.io_map] + push dword [ecx+APPDATA.io_map+4] + mov dword [ecx+APPDATA.io_map], eax + mov dword [page_tabs + (tss._io_map_0 shr 10)], eax + add eax, 0x1000 + mov dword [ecx+APPDATA.io_map+4], eax + mov dword [page_tabs + (tss._io_map_1 shr 10)], eax + + push [ecx+APPDATA.dir_table] + push [ecx+APPDATA.saved_esp0] + mov [ecx+APPDATA.saved_esp0], esp + mov [tss._esp0], esp + + mov eax, [esi+V86_machine.pagedir] + call get_pg_addr + mov [ecx+APPDATA.dir_table], eax + mov cr3, eax + +; mov [irq_tab+5*4], my05 + +; We do not enable interrupts, because V86 IRQ redirector assumes that +; machine is running +; They will be enabled by IRET. +; sti + + mov eax, esi + sub esp, v86_regs.size + mov esi, ebx + mov edi, esp + mov ecx, v86_regs.size/4 + rep movsd + + cmp edx, -1 + jz .noirqhook +uglobal +v86_irqhooks rd 16*2 +endg + cmp [v86_irqhooks+edx*8], 0 + jz @f + cmp [v86_irqhooks+edx*8], eax + jz @f + mov esi, v86_irqerr + call sys_msg_board_str + inc [v86_irqhooks+edx*8+4] + mov eax, 3 + jmp v86_exc_c.exit +@@: + mov [v86_irqhooks+edx*8], eax + inc [v86_irqhooks+edx*8+4] +.noirqhook: + + popad + iretd + +; It is only possible to leave virtual-8086 mode by faulting to +; a protected-mode interrupt handler (typically the general-protection +; exception handler, which in turn calls the virtual 8086-mode monitor). + +iglobal + v86_exc_str1 db 'V86 : unexpected exception ',0 + v86_exc_str2 db ' at ',0 + v86_exc_str3 db ':',0 + v86_exc_str4 db 13,10,'V86 : faulted code:',0 + v86_exc_str5 db ' (unavailable)',0 + v86_newline db 13,10,0 + v86_io_str1 db 'V86 : access to disabled i/o port ',0 + v86_io_byte db ' (byte)',13,10,0 + v86_io_word db ' (word)',13,10,0 + v86_io_dword db ' (dword)',13,10,0 + v86_irqerr db 'V86 : IRQ already hooked',13,10,0 +endg + +v86_exc_c: +; Did we all that we have wanted to do? + cmp bl,1 + jne @f + xor eax, eax + mov dr6, eax + @@: mov eax, [esp+v86_regs.size+10h+18h] + cmp word [esp+v86_regs.eip], ax + jnz @f + shr eax, 16 + cmp word [esp+v86_regs.cs], ax + jz .done +@@: +; Various system events, which must be handled, result in #GP + cmp bl, 13 + jnz .nogp +; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error + cmp word [esp+v86_regs.eip+2], 0 + jnz .nogp +; Otherwise we can safely access byte at CS:IP +; (because it is #GP, not #PF handler) +; …б«Ё Ўл ¬л ¬®Ј«Ё бе«®Ї®в вм ЁбЄ«о祭ЁҐ в®«мЄ® Ё§-§  з⥭Ёп Ў ©в®ў Є®¤ , +; ¬л Ўл ҐЈ® 㦥 бе«®Ї®в «Ё Ё нв® Ўл«® Ўл ­Ґ #GP + movzx esi, word [esp+v86_regs.cs] + shl esi, 4 + add esi, [esp+v86_regs.eip] + lodsb + cmp al, 0xCD ; int xx command = CD xx + jz .handle_int + cmp al, 0xCF + jz .handle_iret + cmp al, 0xF3 + jz .handle_rep + cmp al, 0xEC + jz .handle_in + cmp al, 0xED + jz .handle_in_word + cmp al, 0xEE + jz .handle_out + cmp al, 0xEF + jz .handle_out_word + cmp al, 0xE4 + jz .handle_in_imm + cmp al, 0xE6 + jz .handle_out_imm + cmp al, 0x9C + jz .handle_pushf + cmp al, 0x9D + jz .handle_popf + cmp al, 0xFA + jz .handle_cli + cmp al, 0xFB + jz .handle_sti + cmp al, 0x66 + jz .handle_66 + jmp .nogp +.handle_int: + cmp word [esp+v86_regs.eip], 0xFFFF + jae .nogp + xor eax, eax + lodsb +; call sys_msg_board_byte +; simulate INT command +; N.B. It is possible that some checks need to be corrected, +; but at least in case of normal execution the code works. +.simulate_int: + cmp word [esp+v86_regs.esp], 6 + jae @f + mov bl, 12 ; #SS exception + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + push eax + movzx eax, word [esp+4+v86_regs.esp] + sub eax, 6 + add edx, eax + mov eax, edx + mov esi, [esp+4+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + lea eax, [edx+5] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + sub word [esp+4+v86_regs.esp], 6 + mov eax, [esp+4+v86_regs.eip] + cmp byte [esp+1], 0 + jnz @f + inc eax + inc eax +@@: + mov word [edx], ax + mov eax, [esp+4+v86_regs.cs] + mov word [edx+2], ax + mov eax, [esp+4+v86_regs.eflags] + mov word [edx+4], ax + pop eax + mov ah, 0 + mov cx, [eax*4] + mov word [esp+v86_regs.eip], cx + mov cx, [eax*4+2] + mov word [esp+v86_regs.cs], cx +; note that interrupts will be disabled globally at IRET + and byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags +; continue V86 execution + popad + iretd +.handle_iret: + cmp word [esp+v86_regs.esp], 0x10000 - 6 + jbe @f + mov bl, 12 + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + movzx eax, word [esp+v86_regs.esp] + add edx, eax + mov eax, edx + mov esi, [esp+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + lea eax, [edx+5] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + mov ax, [edx] + mov word [esp+v86_regs.eip], ax + mov ax, [edx+2] + mov word [esp+v86_regs.cs], ax + mov ax, [edx+4] + mov word [esp+v86_regs.eflags], ax + add word [esp+v86_regs.esp], 6 + popad + iretd +.handle_pushf: + cmp word [esp+v86_regs.esp], 1 + jnz @f + mov bl, 12 + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + mov eax, [esp+v86_regs.esp] + sub eax, 2 + movzx eax, ax + add edx, eax + mov eax, edx + mov esi, [esp+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + lea eax, [edx+1] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + sub word [esp+v86_regs.esp], 2 + mov eax, [esp+v86_regs.eflags] + mov [edx], ax + inc word [esp+v86_regs.eip] + popad + iretd +.handle_pushfd: + cmp word [esp+v86_regs.esp], 4 + jae @f + mov bl, 12 ; #SS exception + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + movzx eax, word [esp+v86_regs.esp] + sub eax, 4 + add edx, eax + mov eax, edx + mov esi, [esp+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + lea eax, [edx+3] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + sub word [esp+v86_regs.esp], 4 + movzx eax, word [esp+v86_regs.eflags] + mov [edx], eax + add word [esp+v86_regs.eip], 2 + popad + iretd +.handle_popf: + cmp word [esp+v86_regs.esp], 0xFFFF + jnz @f + mov bl, 12 + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + movzx eax, word [esp+v86_regs.esp] + add edx, eax + mov eax, edx + mov esi, [esp+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 ; #PF exception + jmp .nogp +@@: + lea eax, [edx+1] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + mov ax, [edx] + mov word [esp+v86_regs.eflags], ax + add word [esp+v86_regs.esp], 2 + inc word [esp+v86_regs.eip] + popad + iretd +.handle_popfd: + cmp word [esp+v86_regs.esp], 0x10000 - 4 + jbe @f + mov bl, 12 + jmp .nogp +@@: + movzx edx, word [esp+v86_regs.ss] + shl edx, 4 + movzx eax, word [esp+v86_regs.esp] + add edx, eax + mov eax, edx + mov esi, [esp+v86_regs.size+10h+4] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + lea eax, [edx+3] + call v86_get_lin_addr + cmp eax, 0x1000 + jae @f + mov bl, 14 + jmp .nogp +@@: + mov eax, [edx] + mov word [esp+v86_regs.eflags], ax + add word [esp+v86_regs.esp], 4 + add word [esp+v86_regs.eip], 2 + popad + iretd +.handle_cli: + and byte [esp+v86_regs.eflags+1], not 2 + inc word [esp+v86_regs.eip] + popad + iretd +.handle_sti: + or byte [esp+v86_regs.eflags+1], 2 + inc word [esp+v86_regs.eip] + popad + iretd +.handle_rep: + cmp word [esp+v86_regs.eip], 0xFFFF + jae .nogp + lodsb + cmp al, 6Eh + jz .handle_rep_outsb + jmp .nogp +.handle_rep_outsb: +.handle_in: +.handle_out: +.invalid_io_byte: + movzx ebx, word [esp+v86_regs.edx] + mov ecx, 1 + jmp .invalid_io +.handle_in_imm: +.handle_out_imm: + cmp word [esp+v86_regs.eip], 0xFFFF + jae .nogp + lodsb + movzx ebx, al + mov ecx, 1 + jmp .invalid_io +.handle_66: + cmp word [esp+v86_regs.eip], 0xFFFF + jae .nogp + lodsb + cmp al, 0x9C + jz .handle_pushfd + cmp al, 0x9D + jz .handle_popfd + cmp al, 0xEF + jz .handle_out_dword + cmp al, 0xED + jz .handle_in_dword + jmp .nogp +.handle_in_word: +.handle_out_word: + movzx ebx, word [esp+v86_regs.edx] + mov ecx, 2 + jmp .invalid_io +.handle_in_dword: +.handle_out_dword: +.invalid_io_dword: + movzx ebx, word [esp+v86_regs.edx] + mov ecx, 4 +.invalid_io: + mov esi, v86_io_str1 + call sys_msg_board_str + mov eax, ebx + call sys_msg_board_dword + mov esi, v86_io_byte + cmp ecx, 1 + jz @f + mov esi, v86_io_word + cmp ecx, 2 + jz @f + mov esi, v86_io_dword +@@: + call sys_msg_board_str +if DEBUG_SHOW_IO + mov edx, ebx + mov ebx, 200 + call delay_hs + mov esi, [esp+v86_regs.size+10h+4] + mov eax, [esi+V86_machine.iopm] +@@: + btr [eax], edx + inc edx + loop @b + popad + iretd +else + mov eax, 2 + jmp .exit +end if +.nogp: + + mov esi, v86_exc_str1 + call sys_msg_board_str + mov al, bl + call sys_msg_board_byte + mov esi, v86_exc_str2 + call sys_msg_board_str + mov ax, [esp+32+4] + call sys_msg_board_word + mov esi, v86_exc_str3 + call sys_msg_board_str + mov ax, [esp+32] + call sys_msg_board_word + mov esi, v86_exc_str4 + call sys_msg_board_str + mov ecx, 8 + movzx edx, word [esp+32+4] + shl edx, 4 + add edx, [esp+32] +@@: + mov esi, [esp+v86_regs.size+10h+4] + mov eax, edx + call v86_get_lin_addr + cmp eax, 0x1000 + jb .nopage + mov esi, v86_exc_str3-2 + call sys_msg_board_str + mov al, [edx] + call sys_msg_board_byte + inc edx + loop @b + jmp @f +.nopage: + mov esi, v86_exc_str5 + call sys_msg_board_str +@@: + mov esi, v86_newline + call sys_msg_board_str + mov eax, 1 + jmp .exit + +.done: + xor eax, eax + +.exit: + mov [esp+v86_regs.size+10h+1Ch], eax + mov [esp+v86_regs.size+10h+18h], ebx + + mov edx, [esp+v86_regs.size+10h+14h] + cmp edx, -1 + jz @f + dec [v86_irqhooks+edx*8+4] + jnz @f + and [v86_irqhooks+edx*8], 0 +@@: + + mov esi, esp + mov edi, [esi+v86_regs.size+10h+10h] + add edi, v86_regs.size + mov ecx, v86_regs.size/4 + rep movsd + mov esp, esi + + cli + mov ecx, [CURRENT_TASK] + shl ecx, 8 + pop eax + mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax + mov [tss._esp0], eax + pop eax + mov [SLOT_BASE+ecx+APPDATA.dir_table], eax + pop ebx + mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx + mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx + pop ebx + mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx + mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx + mov cr3, eax +; mov [irq_tab+5*4], 0 + sti + + popad + ret + +;my05: +; mov dx, 30C2h +; mov cx, 4 +;.0: +; in al, dx +; cmp al, 0FFh +; jz @f +; test al, 4 +; jnz .1 +;@@: +; add dx, 8 +; in al, dx +; cmp al, 0FFh +; jz @f +; test al, 4 +; jnz .1 +;@@: +; loop .0 +; ret +;.1: +; or al, 84h +; out dx, al +;.2: +; mov dx, 30F7h +; in al, dx +; mov byte [BOOT_VAR + 48Eh], 0FFh +; ret + +v86_irq: +; push irq/pushad/jmp v86_irq +; eax = irq + lea esi, [esp+1Ch] + lea edi, [esi+4] + mov ecx, 8 + std + rep movsd + cld + mov edi, eax + pop eax +v86_irq2: + mov esi, [v86_irqhooks+edi*8] ; get VM handle + mov eax, [esi+V86_machine.pagedir] + call get_pg_addr + mov ecx, [CURRENT_TASK] + shl ecx, 8 + cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax + jnz .notcurrent + lea eax, [edi+8] + cmp al, 10h + mov ah, 1 + jb @f + add al, 60h +@@: + jmp v86_exc_c.simulate_int +.notcurrent: + mov ebx, SLOT_BASE + 0x100 + mov ecx, [TASK_COUNT] +.scan: + cmp [ebx+APPDATA.dir_table], eax + jnz .cont + push ecx + mov ecx, [ebx+APPDATA.saved_esp0] + cmp word [ecx-v86_regs.size+v86_regs.esp], 6 + jb .cont2 + movzx edx, word [ecx-v86_regs.size+v86_regs.ss] + shl edx, 4 + push eax + movzx eax, word [ecx-v86_regs.size+v86_regs.esp] + sub eax, 6 + add edx, eax + mov eax, edx + call v86_get_lin_addr + cmp eax, 0x1000 + jb .cont3 + lea eax, [edx+5] + call v86_get_lin_addr + cmp eax, 0x1000 + jb .cont3 + pop eax + pop ecx + jmp .found +.cont3: + pop eax +.cont2: + pop ecx +.cont: + loop .scan + mov al, 20h + out 20h, al + cmp edi, 8 + jb @f + out 0A0h, al +@@: + popad + iretd +.found: + mov cr3, eax + sub word [esi-v86_regs.size+v86_regs.esp], 6 + mov ecx, [esi-v86_regs.size+v86_regs.eip] + mov word [edx], cx + mov ecx, [esi-v86_regs.size+v86_regs.cs] + mov word [edx+2], cx + mov ecx, [esi-v86_regs.size+v86_regs.eflags] + mov word [edx+4], cx + lea eax, [edi+8] + cmp al, 10h + jb @f + add al, 60h +@@: + mov cx, [eax*4] + mov word [esi-v86_regs.size+v86_regs.eip], cx + mov cx, [eax*4+2] + mov word [esi-v86_regs.size+v86_regs.cs], cx + and byte [esi-v86_regs.size+v86_regs.eflags+1], not 3 + call update_counters + lea edi, [ebx + 0x100000000 - SLOT_BASE] + shr edi, 3 + add edi, TASK_DATA + call find_next_task.found + call do_change_task + popad + iretd diff --git a/kernel/tags/kolibri0.7.7.0/data16.inc b/kernel/tags/kolibri0.7.7.0/data16.inc new file mode 100644 index 000000000..e6e2e1348 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/data16.inc @@ -0,0 +1,55 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +flm db 0 +preboot_lfb db 0 +preboot_bootlog db 0 +boot_drive db 0 +bx_from_load: dw 'r1' ; структура для хранения параметров- откуда гашрузились, берется ниже из bx ; {SPraid}[13.03.2007] + ; a,b,c,d - винчестеры, r - рам диск + ; # диска... символ, а не байт. '1', а не 1 + +align 4 +old_ints_h: + dw 0x400 + dd 0 + dw 0 + +kernel_restart_bootblock: + db 1 ; version + dw 1 ; floppy image is in memory + dd 0 ; cannot save parameters + +; table for move to extended memory (int 15h, ah=87h) +align 8 +movedesc: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + + db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + +fwmovedesc: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 + + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + diff --git a/kernel/tags/kolibri0.7.7.0/data32.inc b/kernel/tags/kolibri0.7.7.0/data32.inc new file mode 100644 index 000000000..f11551ebf --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/data32.inc @@ -0,0 +1,467 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +keymap: + + db '6',27 + db '1234567890-=',8,9 + db 'qwertyuiop[]',13 + db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'AB?',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + +keymap_alt: + db ' ',27 + db ' @ $ {[]}\ ',8,9 + db ' ',13 + db ' ',0,' ',0,'4',0,' ' + db ' ',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + + + boot_memdetect db 'Determining amount of memory',0 + boot_fonts db 'Fonts loaded',0 + boot_tss db 'Setting TSSs',0 + boot_cpuid db 'Reading CPUIDs',0 + boot_devices db 'Detecting devices',0 + boot_timer db 'Setting timer',0 + boot_irqs db 'Reprogramming IRQs',0 + boot_setmouse db 'Setting mouse',0 + boot_windefs db 'Setting window defaults',0 + boot_bgr db 'Calculating background',0 + boot_resirqports db 'Reserving IRQs & ports',0 + boot_setrports db 'Setting addresses for IRQs',0 + boot_setostask db 'Setting OS task',0 + boot_allirqs db 'Unmasking all IRQs',0 + boot_tsc db 'Reading TSC',0 + boot_cpufreq db 'CPU frequency is ',' ',' MHz',0 + boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 + boot_pal_vga db 'Setting VGA 640x480 palette',0 + boot_failed db 'Failed to start first app',0 + boot_mtrr db 'Setting MTRR',0 +if preboot_blogesc + boot_tasking db 'All set - press ESC to start',0 +end if + +;new_process_loading db 'K : New Process - loading',13,10,0 +;new_process_running db 'K : New Process - done',13,10,0 +start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 + +msg_unresolved db 'unresolved ',0 +msg_module db 'in module ',0 +msg_version db 'incompatible driver version',13,10,0 +msg_www db 'please visit www.kolibrios.org',13,10,0 +msg_CR db 13,10,0 +aSis db 'SIS',0 + +intel_str db "GenuineIntel",0 +AMD_str db "AuthenticAMD",0 + +;szSound db 'SOUND',0 +;szInfinity db 'INFINITY',0 +szHwMouse db 'ATI2D',0 +szPS2MDriver db 'PS2MOUSE',0 +;szCOM_MDriver db 'COM_MOUSE',0 +szUSB db 'USB',0 +szAtiHW db '/rd/1/drivers/ati2d.drv',0 + +szSTART db 'START',0 +szEXPORTS db 'EXPORTS',0 +sz_EXPORTS db '_EXPORTS',0 + +szIMPORTS db 'IMPORTS',0 + +read_firstapp db '/sys/' +firstapp db 'LAUNCHER',0 + +char db '/sys/FONTS/CHAR.MT',0 +char2 db '/sys/FONTS/CHAR2.MT',0 + +bootpath db '/KOLIBRI ' +bootpath2 db 0 +vmode db '/sys/drivers/VMODE.MDR',0 +vrr_m db 'VRR_M',0 +kernel_file db 'KERNEL MNT' + + +align 4 + +shmem_list: + .bk dd shmem_list + .fd dd shmem_list + +dll_list: + .bk dd dll_list + .fd dd dll_list + +MAX_DEFAULT_DLL_ADDR = 0x20000000 +MIN_DEFAULT_DLL_ADDR = 0x10000000 +dll_cur_addr dd MIN_DEFAULT_DLL_ADDR + +; supported videomodes + + +; mike.dld { +db 0 +dd servetable-0x10000 +draw_line dd __sys_draw_line +draw_pointer dd __sys_draw_pointer +;//mike.dld, 2006-08-02 [ +;drawbar dd __sys_drawbar +drawbar dd __sys_drawbar.forced +;//mike.dld, 2006-08-02 ] +putpixel dd __sys_putpixel +; } mike.dld + + +align 4 +keyboard dd 1 +syslang dd 1 + +boot_y dd 10 + +pci_bios_entry dd 0 + dw pci_code_sel + +if __DEBUG__ eq 1 + include_debug_strings +end if + +IncludeIGlobals + +align 16 +gdts: + + dw gdte-$-1 + dd gdts + dw 0 + +; Attention! Do not change the order of the first four selectors. They are used in Fast System Call +; must be : os_code, os_data, app_code, app_data, .... + +int_code_l: +os_code_l: + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 + +int_data_l: +os_data_l: + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 + +app_code_l: + dw 0xFFFF + dw 0 + db 0 + db cpl3 + dw G32+D32+0xF; + +app_data_l: + dw 0xFFFF + dw 0 + db 0 + db drw3 + dw G32+D32+0xF; + +; ------------- PCI BIOS ------------------ + +pci_code_32: + dw 0 ;lim 0-15 + dw 0 ;base 0-15 + db 0 ;base 16-23 + db cpl0 ;type + db D32 ;lim 16-19+props + db 0 ;base 24-31 + +pci_data_32: + dw 0 ;lim 0-15 + dw 0 ;base 0-15 + db 0 ;base 16-23 + db dpl0 ;type + db D32 ;lim 16-19+props + db 0 ;base 24-31 + +; --------------- APM --------------------- +apm_code_32: + dw 0x0f ; limit 64kb + db 0, 0, 0 + dw 11010000b *256 +10011010b + db 0x00 +apm_code_16: + dw 0x0f + db 0, 0, 0 + dw 10010000b *256 +10011010b + db 0x00 +apm_data_16: + dw 0x0f + db 0, 0, 0 + dw 10010000b *256 +10010010b + db 0x00 +; ----------------------------------------- + +graph_data_l: + + dw 0x7ff + dw 0x0000 + db 0x00 + dw 11010000b *256 +11110010b + db 0x00 +tss0_l: + dw TSS_SIZE-1 + dw tss and 0xFFFF + db (tss shr 16) and 0xFF + db 10001001b + dw (tss shr 16) and 0xFF00 + +tls_data_l: + dw 0x0FFF + dw 0 + db 0 + db drw3 + dw D32 + +endofcode: +gdte: + +align 16 +cur_saved_data rb 4096 +fpu_data: rb 512 + +; device irq owners +irq_owner rd 16 ; process id + +; on irq read ports + +irq00read rd 16 +irq01read rd 16 +irq02read rd 16 +irq03read rd 16 +irq04read rd 16 +irq05read rd 16 +irq06read rd 16 +irq07read rd 16 +irq08read rd 16 +irq09read rd 16 +irq10read rd 16 +irq11read rd 16 +irq12read rd 16 +irq13read rd 16 +irq14read rd 16 +irq15read rd 16 + +irq_tab rd 16 + +mem_block_map rb 512 +mem_block_list rd 64 +large_block_list rd 31 +mem_block_mask rd 2 +large_block_mask rd 1 + +mem_used.fd rd 1 +mem_used.bk rd 1 + +mem_block_arr rd 1 +mem_block_start rd 1 +mem_block_end rd 1 + +heap_mutex rd 1 +heap_size rd 1 +heap_free rd 1 +heap_blocks rd 1 +free_blocks rd 1 + +mst MEM_STATE + +page_start rd 1 +page_end rd 1 +sys_page_map rd 1 +os_stack_seg rd 1 + + +srv.fd rd 1 +srv.bk rd 1 + + +align 16 + +_display display_t + +_WinMapAddress rd 1 +_WinMapSize rd 1 + +def_cursor rd 1 +current_cursor rd 1 +hw_cursor rd 1 +cur_saved_base rd 1 + +cur.lock rd 1 ;1 - lock update, 2- hide +cur.left rd 1 ;cursor clip box +cur.top rd 1 +cur.right rd 1 +cur.bottom rd 1 +cur.w rd 1 +cur.h rd 1 + +ipc_tmp rd 1 +ipc_pdir rd 1 +ipc_ptab rd 1 + +proc_mem_map rd 1 +proc_mem_pdir rd 1 +proc_mem_tab rd 1 + +tmp_task_pdir rd 1 +tmp_task_ptab rd 1 + +default_io_map rd 1 + +LFBSize rd 1 + +stall_mcs rd 1 +current_slot rd 1 + +; status +hd1_status rd 1 ; 0 - free : other - pid +application_table_status rd 1 ; 0 - free : other - pid + +; device addresses +mididp rd 1 +midisp rd 1 + +cdbase rd 1 +cdid rd 1 + +hdbase rd 1 ; for boot 0x1f0 +hdid rd 1 +hdpos rd 1 ; for boot 0x1 +fat32part rd 1 ; for boot 0x1 +cdpos rd 1 + +;CPUID information +cpu_vendor rd 3 +cpu_sign rd 1 +cpu_info rd 1 +cpu_caps rd 4 + + +pg_data PG_DATA +heap_test rd 1 + +buttontype rd 1 +windowtypechanged rd 1 + +hd_entries rd 1 ;unused ? 0xfe10 + +;* start code - Mario79 + +mouse_active rd 1 +mouse_pause rd 1 +MouseTickCounter rd 1 + +;* end code - Mario79 + +img_background rd 1 +mem_BACKGROUND rd 1 +static_background_data rd 1 + +cache_ide0: +cache_ide0_pointer rd 1 +cache_ide0_size rd 1 ; not use +cache_ide0_data_pointer rd 1 +cache_ide0_system_data_size rd 1 ; not use +cache_ide0_appl_data_size rd 1 ; not use +cache_ide0_system_data rd 1 +cache_ide0_appl_data rd 1 +cache_ide0_system_sad_size rd 1 +cache_ide0_appl_sad_size rd 1 +cache_ide0_search_start rd 1 +cache_ide0_appl_search_start rd 1 + +cache_ide1: +cache_ide1_pointer rd 1 +cache_ide1_size rd 1 ; not use +cache_ide1_data_pointer rd 1 +cache_ide1_system_data_size rd 1 ; not use +cache_ide1_appl_data_size rd 1 ; not use +cache_ide1_system_data rd 1 +cache_ide1_appl_data rd 1 +cache_ide1_system_sad_size rd 1 +cache_ide1_appl_sad_size rd 1 +cache_ide1_search_start rd 1 +cache_ide1_appl_search_start rd 1 + +cache_ide2: +cache_ide2_pointer rd 1 +cache_ide2_size rd 1 ; not use +cache_ide2_data_pointer rd 1 +cache_ide2_system_data_size rd 1 ; not use +cache_ide2_appl_data_size rd 1 ; not use +cache_ide2_system_data rd 1 +cache_ide2_appl_data rd 1 +cache_ide2_system_sad_size rd 1 +cache_ide2_appl_sad_size rd 1 +cache_ide2_search_start rd 1 +cache_ide2_appl_search_start rd 1 + +cache_ide3: +cache_ide3_pointer rd 1 +cache_ide3_size rd 1 ; not use +cache_ide3_data_pointer rd 1 +cache_ide3_system_data_size rd 1 ; not use +cache_ide3_appl_data_size rd 1 ; not use +cache_ide3_system_data rd 1 +cache_ide3_appl_data rd 1 +cache_ide3_system_sad_size rd 1 +cache_ide3_appl_sad_size rd 1 +cache_ide3_search_start rd 1 +cache_ide3_appl_search_start rd 1 + +debug_step_pointer rd 1 +hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache +cd_appl_data rb 1 ; 0 = system cache, 1 - application cache + +lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled +pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled +timer_ticks_enable rb 1 ; for cd driver + +NumBiosDisks rd 1 +BiosDisksData rb 200h +BiosDiskCaches rb 80h*(cache_ide1-cache_ide0) +BiosDiskPartitions rd 80h + +IncludeUGlobals diff --git a/kernel/tags/kolibri0.7.7.0/detect/biosdisk.inc b/kernel/tags/kolibri0.7.7.0/detect/biosdisk.inc new file mode 100644 index 000000000..2fc98039b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/biosdisk.inc @@ -0,0 +1,81 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Detect all BIOS hard drives. +; diamond, 2008 + + xor cx, cx + mov es, cx + mov di, 0x9080 + mov byte [es:di-1], cl + cmp [preboot_biosdisk], 1 + jnz bdde + mov dl, 80h +bdds: + mov ah, 15h + push cx dx di + int 13h + pop di dx cx + jc bddc + test ah, ah + jz bddc + inc cx + mov ah, 48h + push ds + push es + pop ds + mov si, 0xA000 + mov word [si], 1Eh + mov ah, 48h + int 13h + pop ds + jc bddc2 + inc byte [es:0x907F] + cmp word [es:si], 1Eh + jb bddl + cmp word [es:si+1Ah], 0xFFFF + jz bddl + mov al, dl + stosb + push ds + lds si, [es:si+1Ah] + mov al, [si+6] + and al, 0xF + stosb + mov al, byte [si+4] + shr al, 4 + and ax, 1 + cmp word [si], 1F0h + jz @f + inc ax + inc ax + cmp word [si], 170h + jz @f + or ax,-1 +; mov ax, -1 +@@: + stosw + pop ds + jmp bddc2 +bddl: + mov al, dl + stosb + xor ax,ax + stosb + dec ax + stosw +; mov al, 0 +; stosb +; mov ax, -1 +; stosw +bddc2: + cmp cl, [es:0x475] + jae bdde +bddc: + inc dl + jnz bdds +bdde: diff --git a/kernel/tags/kolibri0.7.7.0/detect/biosmem.inc b/kernel/tags/kolibri0.7.7.0/detect/biosmem.inc new file mode 100644 index 000000000..7b66cd4b6 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/biosmem.inc @@ -0,0 +1,43 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Query physical memory map from BIOS. +; diamond, 2009 + + push ds +; first call to fn E820 + mov eax, 0xE820 + xor ebx, ebx + mov es, bx + mov ds, bx + mov di, 0x9104 + mov [di-4], ebx ; no blocks yet + mov ecx, 20 + mov edx, 0x534D4150 + int 15h + jc no_E820 + cmp eax, 0x534D4150 + jnz no_E820 +e820_mem_loop: + cmp byte [di+16], 1 ; ignore non-free areas + jnz e820_mem_next + inc byte [0x9100] + add di, 20 +e820_mem_next: +; consequent calls to fn E820 + test ebx, ebx + jz e820_test_done + cmp byte [0x9100], 32 + jae e820_test_done + mov eax, 0xE820 + int 15h + jc e820_test_done + jmp e820_mem_loop +no_E820: +; let's hope for mem_test from init.inc +e820_test_done: + pop ds diff --git a/kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc b/kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc new file mode 100644 index 000000000..41bedcbdc --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/dev_fd.inc @@ -0,0 +1,30 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;*************************************************** +; предварительная очистка области таблицы +; поиск и занесение в таблицу приводов FDD +; автор Mario79 +;*************************************************** + xor eax,eax + mov edi,DRIVE_DATA + mov ecx,16384 + cld + rep stosd + + mov al,0x10 + out 0x70,al + mov cx,0xff +wait_cmos: + dec cx + test cx,cx + jnz wait_cmos + in al,0x71 + mov [DRIVE_DATA],al diff --git a/kernel/tags/kolibri0.7.7.0/detect/dev_hdcd.inc b/kernel/tags/kolibri0.7.7.0/detect/dev_hdcd.inc new file mode 100644 index 000000000..64b9327f3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/dev_hdcd.inc @@ -0,0 +1,385 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;****************************************************** +; поиск приводов HDD и CD +; автор исходного текста Кулаков Владимир Геннадьевич. +; адаптация и доработка Mario79 +;****************************************************** + +;**************************************************** +;* ПОИСК HDD и CD * +;**************************************************** +FindHDD: + mov [ChannelNumber],1 + mov [DiskNumber],0 + call FindHDD_3 +; mov ax,[Sector512+176] +; mov [DRIVE_DATA+6],ax +; mov ax,[Sector512+126] +; mov [DRIVE_DATA+8],ax +; mov ax,[Sector512+128] +; mov [DRIVE_DATA+8],ax + mov [DiskNumber],1 + call FindHDD_3 +; mov al,[Sector512+176] +; mov [DRIVE_DATA+7],al + inc [ChannelNumber] + mov [DiskNumber],0 + call FindHDD_3 +; mov al,[Sector512+176] +; mov [DRIVE_DATA+8],al + mov [DiskNumber],1 + call FindHDD_1 +; mov al,[Sector512+176] +; mov [DRIVE_DATA+9],al + + jmp EndFindHDD + +FindHDD_1: + call ReadHDD_ID + cmp [DevErrorCode],0 + jne FindHDD_2 + cmp [Sector512+6],word 16 + ja FindHDD_2 + cmp [Sector512+12],word 255 + ja FindHDD_2 + inc byte [DRIVE_DATA+1] + jmp FindHDD_2_2 + FindHDD_2: + call DeviceReset + cmp [DevErrorCode],0 + jne FindHDD_2_2 + call ReadCD_ID + cmp [DevErrorCode],0 + jne FindHDD_2_2 + inc byte [DRIVE_DATA+1] + inc byte [DRIVE_DATA+1] + FindHDD_2_2: + ret + +FindHDD_3: + call FindHDD_1 + shl byte [DRIVE_DATA+1],2 + ret + + +; Адрес считываемого сектора в режиме LBA +uglobal +SectorAddress DD ? +endg +;************************************************* +;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска на канале (0 или 1). * +;* Идентификационный блок данных считывается * +;* в массив Sector512. * +;************************************************* +ReadHDD_ID: +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать команду идентификации устройства + mov [ATAFeatures],0 + mov [ATAHead],0 + mov [ATACommand],0ECh + call SendCommandToHDD + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End ;закончить, сохранив код ошибки + mov DX,[ATABasePortAddr] + add DX,7 ;адрес регистра состояни + mov ecx,0xffff +@@WaitCompleet: + ; Проверить время выполнения команды + dec ecx +; cmp ecx,0 + jz @@Error1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitCompleet + test AL,1 ;состояние сигнала ERR + jnz @@Error6 + test AL,08h ;состояние сигнала DRQ + jz @@WaitCompleet +; Принять блок данных от контроллера +; mov AX,DS +; mov ES,AX + mov EDI,Sector512 ;offset Sector512 + mov DX,[ATABasePortAddr] ;регистр данных + mov CX,256 ;число считываемых слов + rep insw ;принять блок данных + ret +; Записать код ошибки +@@Error1: + mov [DevErrorCode],1 + ret +@@Error6: + mov [DevErrorCode],6 +@@End: ret + + +iglobal +; Стандартные базовые адреса каналов 1 и 2 +StandardATABases DW 1F0h, 170h +endg +uglobal +; Номер канала +ChannelNumber DW ? +; Номер диска +DiskNumber DB ? +; Базовый адрес группы портов контроллера ATA +ATABasePortAddr DW ? +; Параметры ATA-команды +ATAFeatures DB ? ;особенности +ATASectorCount DB ? ;количество обрабатываемых секторов +ATASectorNumber DB ? ;номер начального сектора +ATACylinder DW ? ;номер начального цилиндра +ATAHead DB ? ;номер начальной головки +ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) +ATACommand DB ? ;код команды, подлежащей выполнению +; Код ошибки (0 - нет ошибок, 1 - превышен допустимый +; интервал ожидания, 2 - неверный код режима адресации, +; 3 - неверный номер канала, 4 - неверный номер диска, +; 5 - неверный номер головки, 6 - ошибка при выполнении +; команды) +DevErrorCode dd ? +endg +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска (0 или 1); * +;* ATAFeatures - "особенности"; * +;* ATASectorCount - количество секторов; * +;* ATASectorNumber - номер начального сектора; * +;* ATACylinder - номер начального цилиндра; * +;* ATAHead - номер начальной головки; * +;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * +;* ATACommand - код команды. * +;* После успешного выполнения функции: * +;* в ATABasePortAddr - базовый адрес HDD; * +;* в DevErrorCode - ноль. * +;* При возникновении ошибки в DevErrorCode будет * +;* возвращен код ошибки. * +;**************************************************** +SendCommandToHDD: +; Проверить значение кода режима + cmp [ATAAddressMode],1 + ja @@Err2 +; Проверить корректность номера канала + mov BX,[ChannelNumber] + cmp BX,1 + jb @@Err3 + cmp BX,2 + ja @@Err3 +; Установить базовый адрес + dec BX + shl BX,1 + movzx ebx,bx + mov AX,[ebx+StandardATABases] + mov [ATABasePortAddr],AX +; Ожидание готовности HDD к приему команды + ; Выбрать нужный диск + mov DX,[ATABasePortAddr] + add DX,6 ;адрес регистра головок + mov AL,[DiskNumber] + cmp AL,1 ;проверить номера диска + ja @@Err4 + shl AL,4 + or AL,10100000b + out DX,AL + ; Ожидать, пока диск не будет готов + inc DX + mov ecx,0xfff +; mov eax,[timer_ticks] +; mov [TickCounter_1],eax +@@WaitHDReady: + ; Проверить время ожидани + dec ecx +; cmp ecx,0 + jz @@Err1 +; mov eax,[timer_ticks] +; sub eax,[TickCounter_1] +; cmp eax,300 ;ожидать 300 тиков +; ja @@Err1 ;ошибка тайм-аута + ; Прочитать регистр состояни + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady + ; Проверить состояние сигнала DRQ + test AL,08h + jnz @@WaitHDReady +; Загрузить команду в регистры контроллера + cli + mov DX,[ATABasePortAddr] + inc DX ;регистр "особенностей" + mov AL,[ATAFeatures] + out DX,AL + inc DX ;счетчик секторов + mov AL,[ATASectorCount] + out DX,AL + inc DX ;регистр номера сектора + mov AL,[ATASectorNumber] + out DX,AL + inc DX ;номер цилиндра (младший байт) + mov AX,[ATACylinder] + out DX,AL + inc DX ;номер цилиндра (старший байт) + mov AL,AH + out DX,AL + inc DX ;номер головки/номер диска + mov AL,[DiskNumber] + shl AL,4 + cmp [ATAHead],0Fh ;проверить номер головки + ja @@Err5 + or AL,[ATAHead] + or AL,10100000b + mov AH,[ATAAddressMode] + shl AH,6 + or AL,AH + out DX,AL +; Послать команду + mov AL,[ATACommand] + inc DX ;регистр команд + out DX,AL + sti +; Сбросить признак ошибки + mov [DevErrorCode],0 + ret +; Записать код ошибки +@@Err1: mov [DevErrorCode],1 + ret +@@Err2: mov [DevErrorCode],2 + ret +@@Err3: mov [DevErrorCode],3 + ret +@@Err4: mov [DevErrorCode],4 + ret +@@Err5: mov [DevErrorCode],5 +; Завершение работы программы + ret + +;************************************************* +;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;* Идентификационный блок данных считывается * +;* в массив Sector512. * +;************************************************* +ReadCD_ID: +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать команду идентификации устройства + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + mov [ATACylinder],0 + mov [ATAHead],0 + mov [ATACommand],0A1h + call SendCommandToHDD + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End_1 ;закончить, сохранив код ошибки +; Ожидать готовность данных HDD + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h + mov ecx,0xffff +@@WaitCompleet_1: + ; Проверить врем + dec ecx +; cmp ecx,0 + jz @@Error1_1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitCompleet_1 + test AL,1 ;состояние сигнала ERR + jnz @@Error6_1 + test AL,08h ;состояние сигнала DRQ + jz @@WaitCompleet_1 +; Принять блок данных от контроллера +; mov AX,DS +; mov ES,AX + mov EDI,Sector512 ;offset Sector512 + mov DX,[ATABasePortAddr] ;порт 1x0h + mov CX,256 ;число считываемых слов + rep insw + ret +; Записать код ошибки +@@Error1_1: + mov [DevErrorCode],1 + ret +@@Error6_1: + mov [DevErrorCode],6 +@@End_1: + ret + +;************************************************* +;* СБРОС УСТРОЙСТВА * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска (0 или 1). * +;************************************************* +DeviceReset: +; Проверить корректность номера канала + mov BX,[ChannelNumber] + cmp BX,1 + jb @@Err3_2 + cmp BX,2 + ja @@Err3_2 +; Установить базовый адрес + dec BX + shl BX,1 + movzx ebx,bx + mov DX,[ebx+StandardATABases] + mov [ATABasePortAddr],DX +; Выбрать нужный диск + add DX,6 ;адрес регистра головок + mov AL,[DiskNumber] + cmp AL,1 ;проверить номера диска + ja @@Err4_2 + shl AL,4 + or AL,10100000b + out DX,AL +; Послать команду "Сброс" + mov AL,08h + inc DX ;регистр команд + out DX,AL + mov ecx,0x80000 +@@WaitHDReady_1: + ; Проверить время ожидани + dec ecx +; cmp ecx,0 + je @@Err1_2 ;ошибка тайм-аута + ; Прочитать регистр состояни + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady_1 +; Сбросить признак ошибки + mov [DevErrorCode],0 + ret +; Обработка ошибок +@@Err1_2: mov [DevErrorCode],1 + ret +@@Err3_2: mov [DevErrorCode],3 + ret +@@Err4_2: mov [DevErrorCode],4 +; Записать код ошибки + ret + +EndFindHDD: + diff --git a/kernel/tags/kolibri0.7.7.0/detect/disks.inc b/kernel/tags/kolibri0.7.7.0/detect/disks.inc new file mode 100644 index 000000000..aba4571cf --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/disks.inc @@ -0,0 +1,15 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +include 'dev_fd.inc' +include 'dev_hdcd.inc' +include 'getcache.inc' +include 'sear_par.inc' + diff --git a/kernel/tags/kolibri0.7.7.0/detect/getcache.inc b/kernel/tags/kolibri0.7.7.0/detect/getcache.inc new file mode 100644 index 000000000..d554bfaec --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/getcache.inc @@ -0,0 +1,212 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + pusha + + mov eax,[pg_data.pages_free] +; 1/32 + shr eax,5 +; round off up to 8 pages + shr eax,3 + shl eax,3 +; translate pages in butes *4096 + shl eax,12 +; check a upper size of the cache, no more than 1 Mb on the physical device + cmp eax,1024*1024 + jbe @f + mov eax,1024*1024 + jmp .continue +@@: +; check a lower size of the cache, not less than 128 Kb on the physical device + cmp eax,128*1024 + jae @f + mov eax,128*1024 +@@: +.continue: + mov [cache_ide0_size],eax + mov [cache_ide1_size],eax + mov [cache_ide2_size],eax + mov [cache_ide3_size],eax + xor eax,eax + mov [hdd_appl_data],1 ;al + mov [cd_appl_data],1 + + mov ch,[DRIVE_DATA+1] + mov cl,ch + and cl,11b + je .ide2 + mov esi,cache_ide3 + call get_cache_ide +.ide2: + mov cl,ch + shr cl,2 + and cl,11b + je .ide1 + mov esi,cache_ide2 + call get_cache_ide +.ide1: + mov cl,ch + shr cl,4 + and cl,11b + je .ide0 + mov esi,cache_ide1 + call get_cache_ide +.ide0: + mov cl,ch + shr cl,6 + and cl,11b + je @f + mov esi,cache_ide0 + call get_cache_ide +@@: + xor ecx,ecx + cmp [NumBiosDisks],ecx + jz .endbd + mov esi,BiosDiskCaches +.loopbd: + push ecx + movsx ecx,byte [BiosDisksData+ecx*4+2] + inc ecx + jz .getbd + add ecx,ecx + movzx eax,byte [DRIVE_DATA+1] + shl eax,cl + and ah,3 + cmp ah,1 + jz .contbd + pop ecx + mov byte [BiosDisksData+ecx*4+2], -1 + push ecx +.getbd: + mov eax,[cache_ide0_size] + mov [esi+cache_ide0_size-cache_ide0],eax + mov cl,1 + call get_cache_ide +.contbd: + pop ecx + add esi,cache_ide1-cache_ide0 + inc ecx + cmp ecx,[NumBiosDisks] + jb .loopbd +.endbd: + jmp end_get_cache + +get_cache_ide: + and [esi+cache_ide0_search_start-cache_ide0],0 + and [esi+cache_ide0_appl_search_start-cache_ide0],0 + push ecx + stdcall kernel_alloc,[esi+cache_ide0_size-cache_ide0] + mov [esi+cache_ide0_pointer-cache_ide0],eax + pop ecx + mov edx,eax + mov eax,[esi+cache_ide0_size-cache_ide0] + shr eax,3 + mov [esi+cache_ide0_system_data_size-cache_ide0],eax + mov ebx,eax + imul eax,7 + mov [esi+cache_ide0_appl_data_size-cache_ide0],eax + add ebx,edx + mov [esi+cache_ide0_data_pointer-cache_ide0],ebx + + cmp cl,10b + je .cd + push ecx + mov eax,[esi+cache_ide0_system_data_size-cache_ide0] + call calculate_for_hd + add eax,[esi+cache_ide0_pointer-cache_ide0] + mov [esi+cache_ide0_system_data-cache_ide0],eax + mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx + + push edi + mov edi,[esi+cache_ide0_pointer-cache_ide0] + call clear_ide_cache + pop edi + + mov eax,[esi+cache_ide0_appl_data_size-cache_ide0] + call calculate_for_hd + add eax,[esi+cache_ide0_data_pointer-cache_ide0] + mov [esi+cache_ide0_appl_data-cache_ide0],eax + mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx + + push edi + mov edi,[esi+cache_ide0_data_pointer-cache_ide0] + call clear_ide_cache + pop edi + + pop ecx + ret +.cd: + push ecx + mov eax,[esi+cache_ide0_system_data_size-cache_ide0] + call calculate_for_cd + add eax,[esi+cache_ide0_pointer-cache_ide0] + mov [esi+cache_ide0_system_data-cache_ide0],eax + mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx + + push edi + mov edi,[esi+cache_ide0_pointer-cache_ide0] + call clear_ide_cache + pop edi + + mov eax,[esi+cache_ide0_appl_data_size-cache_ide0] + call calculate_for_cd + add eax,[esi+cache_ide0_data_pointer-cache_ide0] + mov [esi+cache_ide0_appl_data-cache_ide0],eax + mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx + + push edi + mov edi,[esi+cache_ide0_data_pointer-cache_ide0] + call clear_ide_cache + pop edi + + pop ecx + ret + +calculate_for_hd: + push eax + mov ebx,eax + shr eax,9 + shl eax,3 + sub ebx,eax + shr ebx,9 + mov ecx,ebx + shl ebx,9 + pop eax + sub eax,ebx + dec ecx + ret + +calculate_for_cd: + push eax + mov ebx,eax + shr eax,11 + shl eax,3 + sub ebx,eax + shr ebx,11 + mov ecx,ebx + shl ebx,11 + pop eax + sub eax,ebx + dec ecx + ret + +clear_ide_cache: + push eax + shl ecx,1 + xor eax,eax + cld + rep stosd + pop eax + ret + +end_get_cache: +; mov [cache_ide0_pointer],HD_CACHE +; mov [cache_ide0_system_data],HD_CACHE+65536 +; mov [cache_ide0_system_sad_size],1919 + popa \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/detect/sear_par.inc b/kernel/tags/kolibri0.7.7.0/detect/sear_par.inc new file mode 100644 index 000000000..970f58b34 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/detect/sear_par.inc @@ -0,0 +1,153 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;**************************************************** +; поиск логических дисков на обнаруженных HDD +; и занесение данных в область таблицы +; автор Mario79 +;**************************************************** + mov [transfer_adress],DRIVE_DATA+0xa + search_partitions_ide0: + test [DRIVE_DATA+1],byte 0x40 + jz search_partitions_ide1 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + mov [fat32part],1 + search_partitions_ide0_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide1 + inc byte [DRIVE_DATA+2] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide0_1 + + search_partitions_ide1: + test [DRIVE_DATA+1],byte 0x10 + jz search_partitions_ide2 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + mov [fat32part],1 + search_partitions_ide1_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide2 + inc byte [DRIVE_DATA+3] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide1_1 + + search_partitions_ide2: + test [DRIVE_DATA+1],byte 0x4 + jz search_partitions_ide3 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + mov [fat32part],1 + search_partitions_ide2_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide3 + inc byte [DRIVE_DATA+4] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide2_1 + + search_partitions_ide3: + test [DRIVE_DATA+1],byte 0x1 + jz end_search_partitions_ide + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 + mov [fat32part],1 + search_partitions_ide3_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne end_search_partitions_ide + inc byte [DRIVE_DATA+5] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide3_1 + +end_search_partitions_ide: + mov [hdpos], 80h + mov ecx, [NumBiosDisks] + test ecx, ecx + jz end_search_partitions +start_search_partitions_bd: + push ecx + mov eax, [hdpos] + and [BiosDiskPartitions+(eax-80h)*4], 0 + mov [fat32part], 1 +search_partitions_bd: + call set_FAT32_variables + cmp [problem_partition], 0 + jne end_search_partitions_bd + mov eax, [hdpos] + inc [BiosDiskPartitions+(eax-80h)*4] + call partition_data_transfer + add [transfer_adress], 100 + inc [fat32part] + jmp search_partitions_bd +end_search_partitions_bd: + pop ecx + inc [hdpos] + loop start_search_partitions_bd + jmp end_search_partitions + +partition_data_transfer: + mov edi,[transfer_adress] + mov esi,PARTITION_START + mov ecx,(file_system_data_size+3)/4 + rep movsd + ret +uglobal +transfer_adress dd 0 +endg +partition_data_transfer_1: +; cli + push edi + mov edi,PARTITION_START + mov esi,[transfer_adress] + mov ecx,(file_system_data_size+3)/4 + rep movsd + pop edi +; sti + ret + + end_search_partitions: + +;PARTITION_START dd 0x3f +;PARTITION_END dd 0 +;SECTORS_PER_FAT dd 0x1f3a +;NUMBER_OF_FATS dd 0x2 +;SECTORS_PER_CLUSTER dd 0x8 +;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes +;ROOT_CLUSTER dd 2 ; first rootdir cluster +;FAT_START dd 0 ; start of fat table +;ROOT_START dd 0 ; start of rootdir (only fat16) +;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) +;DATA_START dd 0 ; start of data area (=first cluster 2) +;LAST_CLUSTER dd 0 ; last availabe cluster +;ADR_FSINFO dd 0 ; used only by fat32 +; +;fatRESERVED dd 0x0FFFFFF6 +;fatBAD dd 0x0FFFFFF7 +;fatEND dd 0x0FFFFFF8 +;fatMASK dd 0x0FFFFFFF +; +;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 + diff --git a/kernel/tags/kolibri0.7.7.0/docs/apm.txt b/kernel/tags/kolibri0.7.7.0/docs/apm.txt new file mode 100644 index 000000000..5b253195e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/docs/apm.txt @@ -0,0 +1,518 @@ +--------p-155300----------------------------- +INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK + AX = 5300h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AH = major version (BCD) + AL = minor version (BCD) + BX = 504Dh ("PM") + CX = flags (see #00472) + CF set on error + AH = error code (06h,09h,86h) (see #00473) +BUG: early versions of the Award Modular BIOS with built-in APM support + reportedly do not set BX on return + +Bitfields for APM flags: +Bit(s) Description (Table 00472) + 0 16-bit protected mode interface supported + 1 32-bit protected mode interface supported + 2 CPU idle call reduces processor speed + 3 BIOS power management disabled + 4 BIOS power management disengaged (APM v1.1) + 5-7 reserved + +(Table 00473) +Values for APM error code: + 01h power management functionality disabled + 02h interface connection already in effect + 03h interface not connected + 04h real-mode interface not connected + 05h 16-bit protected-mode interface already connected + 06h 16-bit protected-mode interface not supported + 07h 32-bit protected-mode interface already connected + 08h 32-bit protected-mode interface not supported + 09h unrecognized device ID + 0Ah invalid parameter value in CX + 0Bh (APM v1.1) interface not engaged + 0Ch (APM v1.2) function not supported + 0Dh (APM v1.2) Resume Timer disabled + 0Eh-1Fh reserved for other interface and general errors + 20h-3Fh reserved for CPU errors + 40h-5Fh reserved for device errors + 60h can't enter requested state + 61h-7Fh reserved for other system errors + 80h no power management events pending + 81h-85h reserved for other power management event errors + 86h APM not present + 87h-9Fh reserved for other power management event errors + A0h-FEh reserved + FFh undefined +--------p-155301----------------------------- +INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE + AX = 5301h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + CF set on error + AH = error code (02h,05h,07h,09h) (see #00473) +Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5302h,AX=5303h,AX=5304h +--------p-155302----------------------------- +INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE + AX = 5302h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AX = real-mode segment base address of protected-mode 16-bit code + segment + BX = offset of entry point + CX = real-mode segment base address of protected-mode 16-bit data + segment + ---APM v1.1--- + SI = APM BIOS code segment length + DI = APM BIOS data segment length + CF set on error + AH = error code (02h,05h,06h,07h,09h) (see #00473) +Notes: the caller must initialize two consecutive descriptors with the + returned segment base addresses; these descriptors must be valid + whenever the protected-mode interface is called, and will have + their limits arbitrarily set to 64K. + the protected mode interface is invoked by making a far call with the + same register values as for INT 15; it must be invoked while CPL=0, + the code segment descriptor must have a DPL of 0, the stack must be + in a 16-bit segment and have enough room for BIOS use and possible + interrupts, and the current I/O permission bit map must allow access + to the I/O ports used for power management. + functions 00h-03h are not available from protected mode + on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5301h,AX=5303h,AX=5304h +--------p-155303----------------------------- +INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE + AX = 5303h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AX = real-mode segment base address of protected-mode 32-bit code + segment + EBX = offset of entry point + CX = real-mode segment base address of protected-mode 16-bit code + segment + DX = real-mode segment base address of protected-mode 16-bit data + segment + ---APM v1.1--- + SI = APM BIOS code segment length + DI = APM BIOS data segment length + CF set on error + AH = error code (02h,05h,07h,08h,09h) (see #00473) +Notes: the caller must initialize three consecutive descriptors with the + returned segment base addresses for 32-bit code, 16-bit code, and + 16-bit data, respectively; these descriptors must be valid whenever + the protected-mode interface is called, and will have their limits + arbitrarily set to 64K. + the protected mode interface is invoked by making a far call to the + 32-bit code segment with the same register values as for INT 15; it + must be invoked while CPL=0, the code segment descriptor must have a + DPL of 0, the stack must be in a 32-bit segment and have enough room + for BIOS use and possible interrupts, and the current I/O permission + bit map must allow access to the I/O ports used for power management. + functions 00h-03h are not available from protected mode + on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5301h,AX=5302h,AX=5304h +--------p-155304----------------------------- +INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE + AX = 5304h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + CF set on error + AH = error code (03h,09h) (see #00473) +SeeAlso: AX=5301h,AX=5302h,AX=5303h +--------p-155305----------------------------- +INT 15 - Advanced Power Management v1.0+ - CPU IDLE + AX = 5305h +Return: CF clear if successful (after system leaves idle state) + CF set on error + AH = error code (03h,0Bh) (see #00473) +Notes: call when the system is idle and should be suspended until the next + system event or interrupt + should not be called from within a hardware interrupt handler to avoid + reentrance problems + if an interrupt causes the system to resume normal processing, the + interrupt may or may not have been handled when the BIOS returns + from this call; thus, the caller should allow interrupts on return + interrupt handlers may not retain control if the BIOS allows + interrupts while in idle mode even if they are able to determine + that they were called from idle mode + the caller should issue this call continuously in a loop until it needs + to perform some processing of its own +SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h +--------p-155306----------------------------- +INT 15 - Advanced Power Management v1.0+ - CPU BUSY + AX = 5306h +Return: CF clear if successful + CF set on error + AH = error code (03h,0Bh) (see #00473) +Notes: called to ensure that the system runs at full speed even on systems + where the BIOS is unable to recognize increased activity (especially + if interrupts are hooked by other programs and not chained to the + BIOS) + this call may be made even when the system is already running at full + speed, but it will create unnecessary overhead + should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5305h +--------p-155307----------------------------- +INT 15 - Advanced Power Management v1.0+ - SET POWER STATE + AX = 5307h + BX = device ID (see #00474) + CX = system state ID (see #00475) +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) +Note: should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=530Ch + +(Table 00474) +Values for APM device IDs: + 0000h system BIOS + 0001h all devices for which the system BIOS manages power + 01xxh display (01FFh for all attached display devices) + 02xxh secondary storage (02FFh for all attached secondary storage devices) + 03xxh parallel ports (03FFh for all attached parallel ports) + 04xxh serial ports (04FFh for all attached serial ports) +---APM v1.1+ --- + 05xxh network adapters (05FFh for all attached network adapters) + 06xxh PCMCIA sockets (06FFh for all) + 0700h-7FFFh reserved + 80xxh system battery devices (APM v1.2) + 8100h-DFFFh reserved + Exxxh OEM-defined power device IDs + F000h-FFFFh reserved + +(Table 00475) +Values for system state ID: + 0000h ready (not supported for device ID 0001h) + 0001h stand-by + 0002h suspend + 0003h off (not supported for device ID 0001h in APM v1.0) +---APM v1.1--- + 0004h last request processing notification (only for device ID 0001h) + 0005h last request rejected (only for device ID 0001h) + 0006h-001Fh reserved system states + 0020h-003Fh OEM-defined system states + 0040h-007Fh OEM-defined device states + 0080h-FFFFh reserved device states +--------p-155307CX0001----------------------- +INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY + AX = 5307h + CX = 0001h + BX = 0001h (device ID for all power-managed devices) +Return: CF clear +Notes: puts the entire system into stand-by mode; normally called in response + to a System Stand-by Request notification after any necessary + processing, but may also be invoked at the caller's discretion + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the stand-by state is typically exited on an interrupt +SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh +--------p-155307CX0002----------------------- +INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM + AX = 5307h + CX = 0002h + BX = 0001h (device ID for all power-managed devices) +Return: after system is resumed + CF clear +Notes: puts the entire system into a low-power suspended state; normally + called in response to a Suspend System Request notification after + any necessary processing, but may also be invoked at the caller's + discretion + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the caller may need to update its date and time values because the + system could have been suspended for a long period of time +SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh +--------p-155307CX0003----------------------- +INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM + AX = 5307h + CX = 0003h + BX = 0001h (device ID for all power-managed devices) +Return: after system is resumed + CF clear +Notes: if supported by the system's power supply, turns off the system power +SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh +--------p-155308----------------------------- +INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT + AX = 5308h + BX = device ID for all devices power-managed by APM + 0001h (APM v1.1+) + FFFFh (APM v1.0) + CX = new state + 0000h disabled + 0001h enabled +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) +Notes: when power management is disabled, the system BIOS will not + automatically power down devices, enter stand-by or suspended mode, + or perform any power-saving actions in response to AX=5305h calls + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the APM BIOS should never be both disabled and disengaged at the same + time +SeeAlso: AX=5309h,AX=530Dh,AX=530Fh +--------p-155309----------------------------- +INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS + AX = 5309h + BX = device ID for all devices power-managed by APM + 0001h (APM v1.1) + FFFFh (APM v1.0) +Return: CF clear if successful + CF set on error + AH = error code (03h,09h,0Bh) (see #00473) +Note: should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5308h +--------p-15530A----------------------------- +INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS + AX = 530Ah + BX = device ID + 0001h all devices power-managed by APM + 80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) +Return: CF clear if successful + BH = AC line status + 00h off-line + 01h on-line + 02h on backup power (APM v1.1) + FFh unknown + other reserved + BL = battery status (see #00476) + CH = battery flag (APM v1.1+) (see #00477) + CL = remaining battery life, percentage + 00h-64h (0-100) percentage of full charge + FFh unknown + DX = remaining battery life, time (APM v1.1) (see #00478) + ---if specific battery unit specified--- + SI = number of battery units currently installed + CF set on error + AH = error code (09h,0Ah) (see #00473) +Notes: should not be called from within a hardware interrupt handler to avoid + reentrance problems + supported in real mode (INT 15) and both 16-bit and 32-bit protected + mode + +(Table 00476) +Values for APM v1.0+ battery status: + 00h high + 01h low + 02h critical + 03h charging + FFh unknown + other reserved +SeeAlso: #00477,#00478 + +Bitfields for APM v1.1+ battery flag: +Bit(s) Description (Table 00477) + 0 high + 1 low + 2 critical + 3 charging + 4 selected battery not present (APM v1.2) + 5-6 reserved (0) + 7 no system battery +Note: all bits set (FFh) if unknown +SeeAlso: #00476,#00478 + +Bitfields for APM v1.1+ remaining battery life: +Bit(s) Description (Table 00478) + 15 time units: 0=seconds, 1=minutes + 14-0 battery life in minutes or seconds +Note: all bits set (FFFFh) if unknown +SeeAlso: #00476,#00477 +--------p-15530B----------------------------- +INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT + AX = 530Bh +Return: CF clear if successful + BX = event code (see #00479) + CX = event information (APM v1.2) if BX=0003h or BX=0004h + bit 0: PCMCIA socket was powered down in suspend state + CF set on error + AH = error code (03h,0Bh,80h) (see #00473) +Notes: although power management events are often asynchronous, notification + will not be made until polled via this call to permit software to + only receive event notification when it is prepared to process + power management events; since these events are not very time- + critical, it should be sufficient to poll once or twice per second + the critical resume notification is made after the system resumes + from an emergency suspension; normally, the system BIOS only notifies + its partner that it wishes to suspend and relies on the partner to + actually request the suspension, but no notification is made on an + emergency suspension + should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" + +(Table 00479) +Values for APM event code: + 0001h system stand-by request + 0002h system suspend request + 0003h normal resume system notification + 0004h critical resume system notification + 0005h battery low notification +---APM v1.1--- + 0006h power status change notification + 0007h update time notification + 0008h critical system suspend notification + 0009h user system standby request notification + 000Ah user system suspend request notification + 000Bh system standby resume notification +---APM v1.2--- + 000Ch capabilities change notification (see AX=5310h) +------ + 000Dh-00FFh reserved system events + 01xxh reserved device events + 02xxh OEM-defined APM events + 0300h-FFFFh reserved +--------p-15530C----------------------------- +INT 15 - Advanced Power Management v1.1+ - GET POWER STATE + AX = 530Ch + BX = device ID (see #00474) +Return: CF clear if successful + CX = system state ID (see #00475) + CF set on error + AH = error code (01h,09h) (see #00473) +SeeAlso: AX=5307h +--------p-15530D----------------------------- +INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT + AX = 530Dh + BX = device ID (see #00474) + CX = function + 0000h disable power management + 0001h enable power management +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) +Desc: specify whether automatic power management should be active for a + given device +SeeAlso: AX=5308h,AX=530Fh +--------p-15530E----------------------------- +INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION + AX = 530Eh + BX = device ID of system BIOS (0000h) + CH = APM driver major version (BCD) + CL = APM driver minor version (BCD) (02h for APM v1.2) +Return: CF clear if successful + AH = APM connection major version (BCD) + AL = APM connection minor version (BCD) + CF set on error + AH = error code (03h,09h,0Bh) (see #00473) +SeeAlso: AX=5300h,AX=5303h +--------p-15530F----------------------------- +INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT + AX = 530Fh + BX = device ID (see #00474) + CX = function + 0000h disengage power management + 0001h engage power management +Return: CF clear if successful + CF set on error + AH = error code (01h,09h) (see #00473) +Notes: unlike AX=5308h, this call does not affect the functioning of the APM + BIOS + when cooperative power management is disengaged, the APM BIOS performs + automatic power management of the system or device +SeeAlso: AX=5308h,AX=530Dh +--------p-155310----------------------------- +INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES + AX = 5310h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved +Return: CF clear if successful + BL = number of battery units supported (00h if no system batteries) + CX = capabilities flags (see #00480) + CF set on error + AH = error code (01h,09h,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces; it does not require that a + connection be established prior to use + this function will return the capabilities currently in effect, not + any new settings which have been made but do not take effect until + a system restart +SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h + +Bitfields for APM v1.2 capabilities flags: +Bit(s) Description (Table 00480) + 15-8 reserved + 7 PCMCIA Ring Indicator will wake up system from suspend mode + 6 PCMCIA Ring Indicator will wake up system from standby mode + 5 Resume on Ring Indicator will wake up system from suspend mode + 4 Resume on Ring Indicator will wake up system from standby mode + 3 resume timer will wake up system from suspend mode + 2 resume timer will wake up system from standby mode + 1 can enter global suspend state + 0 can enter global standby state +--------p-155311----------------------------- +INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER + AX = 5311h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable Resume Timer + 01h get Resume Timer + 02h set Resume Timer + CH = resume time, seconds (BCD) + DL = resume time, minutes (BCD) + DH = resume time, hours (BCD) + SI = resume date (BCD), high byte = month, low byte = day + DI = resume date, year (BCD) +Return: CF clear if successful + ---if getting timer--- + CH = resume time, seconds (BCD) + DL = resume time, minutes (BCD) + DH = resume time, hours (BCD) + SI = resume date (BCD), high byte = month, low byte = day + DI = resume date, year (BCD) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces +SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h +--------p-155312----------------------------- +INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING + AX = 5312h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable Resume on Ring Indicator + 01h enable Resume on Ring Indicator + 02h get Resume on Ring Indicator status +Return: CF clear if successful + CX = resume status (0000h disabled, 0001h enabled) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces +SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h +--------p-155313----------------------------- +INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS + AX = 5313h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable timer-based requests + 01h enable timer-based requests + 02h get timer-based requests status +Return: CF clear if successful + CX = timer-based requests status (0000h disabled, 0001h enabled) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces + some BIOSes set AH on return even when successful +SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h diff --git a/kernel/tags/kolibri0.7.7.0/docs/loader_doc.txt b/kernel/tags/kolibri0.7.7.0/docs/loader_doc.txt new file mode 100644 index 000000000..d1e57e4a1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/docs/loader_doc.txt @@ -0,0 +1,88 @@ +; (english text below) + +;------------------------------------------ +; Интерфейс сохранения параметров +;------------------------------------------ +Если при передаче управления ядру загрузчик устанавливает AX='KL', +то в DS:SI ядро ожидает дальнего указателя на следующую структуру: + db версия структуры, должна быть 1 + dw флаги: + бит 0 установлен = присутствует образ рамдиска в памяти + dd дальний указатель на процедуру сохранения параметров + может быть 0, если загрузчик не поддерживает +Процедура сохранения параметров должна записать первый сектор ядра +kernel.mnt назад на то место, откуда она его считала; возврат из +процедуры осуществляется по retf. + +;------------------------------------------ +; Указание загрузчиком системного каталога +;------------------------------------------ +Перед передачей управления ядру могут быть установлены следующие регистры: +CX='HA' +DX='RD' +Это указывает на то, что регистр BX указывает на системный раздел. Каталог /kolibri/ на +этом разделе является системным, к нему можно обращаться как к /sys/ + +Возможные значения регистра BL (указывает на устройство): +'a' - Primary Master +'b' - Primary Slave +'c' - Secondary Master +'d' - Secondary Slave +'r' - RAM диск +'m' - Приводы CD-ROM + +Возможные значения регистра BH (указывает на раздел): +для BL='a','b','c','d','r' - указывает на раздел, где расположен системный каталог +для BL='m',указывает на номер физического устройства, с которого надо начинать поиск системного каталога. + +примеры значений регистра BX: +'a1' - /hd0/1/ +'a2' - /hd0/2/ +'b1' - /hd1/1/ +'d4' - /hd3/4/ +'m0' - поиск по сидюкам каталога kolibri +'r1' - /rd/1/ + + +;------------------------------------------ +; Interface for saving boot-screen settings +;------------------------------------------ +If a loader sets AX='KL' when transferring control to the kernel, +the kernel expects in DS:SI far pointer to the following structure: + db structure version, must be 1 + dw flags + bit 0 set = ramdisk image in memory is present + dd far pointer to save settings procedure + may be 0 if such procedure is not supported by loader +Procedure for saving settings must write the first sector of the kernel +kernel.mnt back to the place, from where it has been read; return from +this procedure must be with retf. + +;------------------------------------------ +; System directory information from loader +;------------------------------------------ +Before transfer of control to the kernel following registers can be set: +CX = 'HA' +DX = 'RD' +This indicates that the register BX identifies system partition. The folder /kolibri/ in +this partition is system folder, it can be referenced as /sys/ + +Possible values for register BL (indicates the device): +'a' - Primary Master +'b' - Primary Slave +'c' - Secondary Master +'d' - Secondary Slave +'r' - RAM disc +'m' - ROM drives + +Possible values for register BH (indicates section): +for BL = 'a', 'b', 'c', 'd', 'r' to denote partition where the system folder +for BL = 'm', indicates the number of physical devices, which must begin a systematic search directory. + +Examples of register BX: +'a1' - /hd0/1/ +'a2' - /hd0/2/ +'b1' - /hd1/1/ +'d4' - /hd3/4/ +'m0' - search directory 'kolibri' by all CD-ROMs +'r1' - /rd/1/ diff --git a/kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt b/kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt new file mode 100644 index 000000000..a07697c31 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/docs/sysfuncr.txt @@ -0,0 +1,4626 @@ +‘€‘’…ЊЌ›… ”“ЌЉ–€€ ЋЏ…ђЂ–€ЋЌЌЋ‰ ‘€‘’…Њ› Kolibri 0.7.5.0+ + +Ќ®¬Ґа дг­ЄжЁЁ Ї®¬Ґй Ґвбп ў ॣЁбва eax. +‚л§®ў бЁб⥬­®© дг­ЄжЁЁ ®бгйҐбвў«пҐвбп Є®¬ ­¤®© "int 0x40". +‚ᥠॣЁбвал, Єа®¬Ґ пў­® гЄ § ­­ле ў ў®§ўа й Ґ¬®¬ §­ зҐ­ЁЁ, + ўЄ«оз п ॣЁбва д« Ј®ў eflags, б®еа ­повбп. + + +====================================================================== +============== ”г­ЄжЁп 0 - ®ЇаҐ¤Ґ«Ёвм Ё ­ аЁб®ў вм ®Є­®. ============= +====================================================================== +ЋЇаҐ¤Ґ«пҐв ®Є­® ЇаЁ«®¦Ґ­Ёп. ђЁбгҐв а ¬Єг ®Є­ , § Ј®«®ў®Є Ё а Ў®зго +®Ў« бвм. „«п ®Є®­ б® бЄЁ­®¬ ®ЇаҐ¤Ґ«пҐв бв ­¤ ав­лҐ Є­®ЇЄЁ § ЄалвЁп Ё +¬Ё­Ё¬Ё§ жЁЁ. +Џ а ¬Ґвал: + * eax = 0 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  Ї® ®бЁ y]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = 0xXYRRGGBB, Ј¤Ґ: + * Y = бвЁ«м ®Є­ : + * Y=0 - вЁЇ I - ®Є­® дЁЄбЁа®ў ­­ле а §¬Ґа®ў + * Y=1 - в®«мЄ® ®ЇаҐ¤Ґ«Ёвм ®Ў« бвм ®Є­ , ­ЁзҐЈ® ­Ґ аЁб®ў вм + * Y=2 - вЁЇ II - ®Є­® Ё§¬Ґ­пҐ¬ле а §¬Ґа®ў + * Y=3 - ®Є­® б® бЄЁ­®¬ + * Y=4 - ®Є­® б® бЄЁ­®¬ дЁЄбЁа®ў ­­ле а §¬Ґа®ў + * ®бв «м­лҐ ў®§¬®¦­лҐ §­ зҐ­Ёп (®в 5 ¤® 15) § аҐ§ҐаўЁа®ў ­л, + ўл§®ў дг­ЄжЁЁ б в ЄЁ¬Ё Y ЁЈ­®аЁагҐвбп + * RR, GG, BB = ᮮ⢥вб⢥­­® Єа б­ п, §Ґ«Ґ­ п, бЁ­пп + б®бв ў«пойЁҐ жўҐв  а Ў®зҐ© ®Ў« бвЁ ®Є­  + (ЁЈ­®аЁагҐвбп ¤«п бвЁ«п Y=2) + * X = DCBA (ЎЁвл) + * A = 1 - г ®Є­  Ґбвм § Ј®«®ў®Є; ¤«п бвЁ«Ґ© Y=3,4  ¤аҐб бва®ЄЁ + § Ј®«®ўЄ  § ¤ свбп ў edi, ¤«п Їа®зЁе бвЁ«Ґ© + ЁбЇ®«м§гҐвбп Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 71 + * B = 1 - Є®®а¤Ё­ вл ўбҐе Ја дЁзҐбЄЁе ЇаЁ¬ЁвЁў®ў § ¤ овбп + ®в­®бЁвҐ«м­® Є«ЁҐ­вбЄ®© ®Ў« бвЁ ®Є­  + * C = 1 - ­Ґ § Єа иЁў вм а Ў®зго ®Ў« бвм ЇаЁ ®ваЁб®ўЄҐ ®Є­  + * D = 0 - ­®а¬ «м­ п § «ЁўЄ  а Ў®зҐ© ®Ў« бвЁ, 1 - Ја ¤ЁҐ­в­ п + ‘«Ґ¤гойЁҐ Ї а ¬Ґвал ЇаҐ¤­ §­ зҐ­л ¤«п ®Є®­ вЁЇ  I Ё II Ё + ЁЈ­®аЁаговбп ¤«п бвЁ«Ґ© Y=1,3: + * esi = 0xXYRRGGBB - 梥⠧ Ј®«®ўЄ  + * RR, GG, BB ®ЇаҐ¤Ґ«пов б ¬ 梥в + * Y=0 - ®Ўлз­®Ґ ®Є­®, Y=1 - ­ҐЇҐаҐ¬Ґй Ґ¬®Ґ ®Є­® + * X ®ЇаҐ¤Ґ«пҐв Ја ¤ЁҐ­в § Ј®«®ўЄ : X=0 - ­Ґв Ја ¤ЁҐ­в , + X=8 - ®Ўлз­л© Ја ¤ЁҐ­в, + ¤«п ®Є®­ вЁЇ  II X=4 - ­ҐЈ вЁў­л© Ја ¤ЁҐ­в + * Їа®зЁҐ §­ зҐ­Ёп X Ё Y § аҐ§ҐаўЁа®ў ­л + * edi = 0x00RRGGBB - 梥в а ¬ЄЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®«®¦Ґ­ЁҐ Ё а §¬Ґал ®Є­  гбв ­ ў«Ёў овбп ЇаЁ ЇҐаў®¬ ўл§®ўҐ + нв®© дг­ЄжЁЁ Ё ЁЈ­®аЁаговбп ЇаЁ Ї®б«Ґ¤гойЁе; ¤«п Ё§¬Ґ­Ґ­Ёп + Ї®«®¦Ґ­Ёп Ё/Ё«Ё а §¬Ґа®ў 㦥 б®§¤ ­­®Ј® ®Є­  ЁбЇ®«м§г©вҐ + 67-о дг­ЄжЁо. + * „«п ®Є®­ бвЁ«Ґ© Y=3,4 б § Ј®«®ўЄ®¬ (A=1) бва®Є  § Ј®«®ўЄ  + гбв ­ ў«Ёў Ґвбп ЇаЁ ЇҐаў®¬ ўл§®ўҐ нв®© дг­ЄжЁЁ Ё ЁЈ­®аЁагҐвбп ЇаЁ + Ї®б«Ґ¤гойЁе (в®з­ҐҐ Ј®ў®ап, ЁЈ­®аЁагҐвбп Ї®б«Ґ ўл§®ў  + Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 12 - Є®­ж  ЇҐаҐаЁб®ўЄЁ); + ¤«п Ё§¬Ґ­Ґ­Ёп бва®ЄЁ § Ј®«®ўЄ  㦥 б®§¤ ­­®Ј® ®Є­  ЁбЇ®«м§г©вҐ + Ї®¤дг­ЄжЁо 1 дг­ЄжЁЁ 71. + * …б«Ё ЁбЇ®«м§®ў вм ®Є­  ᮮ⢥вбвўгойЁе бвЁ«Ґ©, в® Ї®«®¦Ґ­ЁҐ + Ё/Ё«Ё а §¬Ґал ®Є­  ¬®Јгв ¬Ґ­пвмбп Ї®«м§®ў вҐ«Ґ¬. + ’ҐЄгйЁҐ Ї®«®¦Ґ­ЁҐ Ё а §¬Ґал ¬®Јгв Ўлвм Ї®«гзҐ­л ўл§®ў®¬ дг­ЄжЁЁ 9. + * ЋЄ­® ¤®«¦­® 㬥й вмбп ­  нЄа ­Ґ. …б«Ё ЇҐаҐ¤ ­­лҐ Є®®а¤Ё­ вл + Ё а §¬Ґал ­Ґ 㤮ў«Ґвў®апов н⮬г гб«®ўЁо, ⮠ᮮ⢥вбвўгой п + Є®®а¤Ё­ в  (Ё«Ё, ў®§¬®¦­®, ®ЎҐ) бзЁв Ґвбп ­г«Ґ¬,   Ґб«Ё Ё нв® + ­Ґ Ї®¬®Ј Ґв, ⮠ᮮ⢥вбвўгойЁ© а §¬Ґа (Ё«Ё, ў®§¬®¦­®, ®Ў ) + гбв ­ ў«Ёў Ґвбп ў а §¬Ґа нЄа ­ . + + „ «ҐҐ ®Ў®§­ зЁ¬ xpos,ypos,xsize,ysize - §­ зҐ­Ёп, ЇҐаҐ¤ ў Ґ¬лҐ + ў ebx,ecx. Љ®®а¤Ё­ вл ЇаЁў®¤пвбп ®в­®бЁвҐ«м­® «Ґў®Ј® ўҐае­ҐЈ® + гЈ«  ®Є­ , Є®в®ал©, в ЄЁ¬ ®Ўа §®¬, § ¤ Ґвбп Є Є (0,0), Є®®а¤Ё­ вл + Їа ў®Ј® ­Ё¦­ҐЈ® гЈ«  бгвм (xsize,ysize). + * ђ §¬Ґал ®Є­  Ї®­Ё¬ овбп ў б¬лб«Ґ Є®®а¤Ё­ в Їа ў®Ј® ­Ё¦­ҐЈ® гЈ« . + ќв® ¦Ґ ®в­®бЁвбп Ё Є® ўбҐ¬ ®бв «м­л¬ дг­ЄжЁп¬. + ќв® ®§­ з Ґв, з⮠ॠ«м­лҐ а §¬Ґал ­  1 ЇЁЄбҐ«м Ў®«миҐ. + * ‚Ё¤ ®Є­  вЁЇ  I: + * аЁбгҐвбп ў­Ґи­пп а ¬Є  梥в , гЄ § ­­®Ј® ў edi, + иЁаЁ­®© 1 ЇЁЄбҐ«м + * аЁбгҐвбп § Ј®«®ў®Є - Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (1,1) + Ё Їа ўл¬ ­Ё¦­Ё¬ (xsize-1,min(25,ysize)) 梥в , гЄ § ­­®Ј® ў esi + (б гзҐв®¬ Ја ¤ЁҐ­в ) + * Ґб«Ё ysize>=26, в® § Єа иЁў Ґвбп а Ў®з п ®Ў« бвм ®Є­  - + Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (1,21) Ё Їа ўл¬ ­Ё¦­Ё¬ + (xsize-1,ysize-1) (а §¬Ґа ¬Ё (xsize-1)*(ysize-21)) - 梥⮬, + гЄ § ­­л¬ ў edx (б гзҐв®¬ Ја ¤ЁҐ­в ) + * Ґб«Ё A=1 Ё бва®Є  § Ј®«®ўЄ  гбв ­®ў«Ґ­  Ї®¤дг­ЄжЁҐ© 1 + дг­ЄжЁЁ 71, в® ®­  ўлў®¤Ёвбп ў ᮮ⢥вбвўго饬 ¬Ґб⥠§ Ј®«®ўЄ  + * ‚Ё¤ ®Є­  бвЁ«п Y=1: + * Ї®«­®бвмо ®ЇаҐ¤Ґ«пҐвбп ЇаЁ«®¦Ґ­ЁҐ¬ + * ‚Ё¤ ®Є­  вЁЇ  II: + * аЁбгҐвбп ў­Ґи­пп а ¬Є  иЁаЁ­®© 1 ЇЁЄбҐ«м "§ вҐ­с­­®Ј®" жўҐв  + edi (ўбҐ б®бв ў«пойЁҐ жўҐв  г¬Ґ­ми овбп ў ¤ў  а § ) + * аЁбгҐвбп Їа®¬Ґ¦гв®з­ п а ¬Є  иЁаЁ­®© 3 ЇЁЄбҐ«п жўҐв  edi + * аЁбгҐвбп ў­гв७­пп а ¬Є  иЁаЁ­®© 1 ЇЁЄбҐ«м + "§ вҐ­с­­®Ј®" жўҐв  edi + * аЁбгҐвбп § Ј®«®ў®Є - Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (4,4) + Ё Їа ўл¬ ­Ё¦­Ё¬ (xsize-4,min(20,ysize)) 梥в , гЄ § ­­®Ј® ў esi + (б гзҐв®¬ Ја ¤ЁҐ­в ) + * Ґб«Ё ysize>=26, в® § Єа иЁў Ґвбп а Ў®з п ®Ў« бвм ®Є­  - + Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (5,20) Ё Їа ўл¬ ­Ё¦­Ё¬ + (xsize-5,ysize-5) - 梥⮬, гЄ § ­­л¬ ў edx (б гзҐв®¬ Ја ¤ЁҐ­в ) + * Ґб«Ё A=1 Ё бва®Є  § Ј®«®ўЄ  гбв ­®ў«Ґ­  Ї®¤дг­ЄжЁҐ© 1 + дг­ЄжЁЁ 71, в® ®­  ўлў®¤Ёвбп ў ᮮ⢥вбвўго饬 ¬Ґб⥠§ Ј®«®ўЄ  + * ‚Ё¤ ®Є­  б® бЄЁ­®¬: + * аЁбгҐвбп ў­Ґи­пп а ¬Є  иЁаЁ­®© 1 ЇЁЄбҐ«м + жўҐв  'outer' Ё§ бЄЁ­  + * аЁбгҐвбп Їа®¬Ґ¦гв®з­ п а ¬Є  иЁаЁ­®© 3 ЇЁЄбҐ«п + жўҐв  'frame' Ё§ бЄЁ­  + * аЁбгҐвбп ў­гв७­пп а ¬Є  иЁаЁ­®© 1 ЇЁЄбҐ«м + жўҐв  'inner' Ё§ бЄЁ­  + * аЁбгҐвбп § Ј®«®ў®Є (Ї® Є авЁ­Є ¬ Ё§ бЄЁ­ ) ў Їаאַ㣮«м­ЁЄҐ + (0,0) - (xsize,_skinh-1) + * Ґб«Ё ysize>=26, в® § Єа иЁў Ґвбп а Ў®з п ®Ў« бвм ®Є­  - + Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (5,_skinh) Ё Їа ўл¬ ­Ё¦­Ё¬ + (xsize-5,ysize-5) - 梥⮬, гЄ § ­­л¬ ў edx (б гзҐв®¬ Ја ¤ЁҐ­в ) + * ®ЇаҐ¤Ґ«повбп ¤ўҐ бв ­¤ ав­лҐ Є­®ЇЄЁ: § ЄалвЁп Ё ¬Ё­Ё¬Ё§ жЁЁ + (ᬮваЁ дг­ЄжЁо 8) + * Ґб«Ё A=1 Ё ў edi (­Ґ­г«Ґў®©) гЄ § вҐ«м ­  бва®Єг § Ј®«®ўЄ , + в® ®­  ўлў®¤Ёвбп ў § Ј®«®ўЄҐ ў ¬ҐбвҐ, ®ЇаҐ¤Ґ«пҐ¬®¬ бЄЁ­®¬ + * ‡­ зҐ­ЁҐ ЇҐаҐ¬Ґ­­®© _skinh ¤®бвгЇ­® Є Є १г«мв в ўл§®ў  + Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 48 + +====================================================================== +================= ”г­ЄжЁп 1 - Ї®бв ўЁвм в®зЄг ў ®Є­Ґ. ================ +====================================================================== +Џ а ¬Ґвал: + * eax = 1 - ­®¬Ґа дг­ЄжЁЁ + * ebx = x-Є®®а¤Ё­ в  (®в­®бЁвҐ«м­® ®Є­ ) + * ecx = y-Є®®а¤Ё­ в  (®в­®бЁвҐ«м­® ®Є­ ) + * edx = 0x00RRGGBB - 梥в в®зЄЁ + edx = 0x01xxxxxx - Ё­ўҐавЁа®ў вм 梥в в®зЄЁ + (¬« ¤иЁҐ 24 ЎЁв  ЁЈ­®аЁаговбп) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +============== ”г­ЄжЁп 2 - Ї®«гзЁвм Є®¤ ­ ¦ в®© Є« ўЁиЁ. ============= +====================================================================== +‡ ЎЁа Ґв Є®¤ ­ ¦ в®© Є« ўЁиЁ Ё§ ЎгдҐа . +Џ а ¬Ґвал: + * eax = 2 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ЎгдҐа Їгбв, ў®§ўа й Ґвбп eax=1 + * Ґб«Ё ЎгдҐа ­ҐЇгбв, в® ў®§ўа й Ґвбп al=0, ah=Є®¤ ­ ¦ в®© Є« ўЁиЁ, + бв а襥 б«®ў® ॣЁбва  eax ®Ў­г«Ґ­® + * Ґб«Ё Ґбвм "Ј®апз п Є« ўЁи ", в® ў®§ўа й Ґвбп + al=2, ah=бЄ ­Є®¤ ­ ¦ в®© Є« ўЁиЁ (0 ¤«п гЇа ў«пойЁе Є« ўЁи), + бв а襥 б«®ў® ॣЁбва  eax ᮤҐа¦Ёв б®бв®п­ЁҐ гЇа ў«пойЁе Є« ўЁи + ў ¬®¬Ґ­в ­ ¦ вЁп Ј®ап祩 Є« ўЁиЁ +‡ ¬Ґз ­Ёп: + * ‘гйҐбвўгҐв ®ЎйҐбЁб⥬­л© ЎгдҐа ­ ¦ вле Є« ўЁи а §¬Ґа®¬ 120 Ў ©в, + ®аЈ ­Ё§®ў ­­л© Є Є ®зҐаҐ¤м. + * ‘гйҐбвўгҐв Ґйс ®¤Ё­ ®ЎйҐбЁб⥬­л© ЎгдҐа ­  120 "Ј®апзЁе Є« ўЁи". + * ЏаЁ ўл§®ўҐ нв®© дг­ЄжЁЁ ЇаЁ«®¦Ґ­ЁҐ¬ б ­Ґ ЄвЁў­л¬ ®Є­®¬ + бзЁв Ґвбп, зв® ЎгдҐа ­ ¦ вле Є« ўЁи Їгбв. + * Џ® 㬮«з ­Ёо нв  дг­ЄжЁп ў®§ўа й Ґв ASCII-Є®¤л; ЇҐаҐЄ«озЁвмбп ­  + ०Ё¬ бЄ ­Є®¤®ў (Ё ­ § ¤) ¬®¦­® б ЁбЇ®«м§®ў ­ЁҐ¬ дг­ЄжЁЁ 66. + Ћ¤­ Є®, Ј®апзЁҐ Є« ўЁиЁ ўбҐЈ¤  ў®§ўа й овбп Є Є бЄ ­Є®¤л. + * “§­ вм, Є ЄЁҐ Є®¬ЎЁ­ жЁЁ Є« ўЁи ᮮ⢥вбвўгов Є ЄЁ¬ Є®¤ ¬, ¬®¦­®, + § ЇгбвЁў ЇаЁ«®¦Ґ­Ёп keyascii Ё scancode. + * ‘Є ­Є®¤л ў®§ўа й овбп ­ҐЇ®б।б⢥­­® Є« ўЁ вга®© Ё дЁЄбЁа®ў ­л; + ASCII-Є®¤л Ї®«гз овбп б ЁбЇ®«м§®ў ­ЁҐ¬ в Ў«Ёж ЇаҐ®Ўа §®ў ­Ёп, + Є®в®алҐ ¬®¦­® гбв ­®ўЁвм Ї®¤дг­ЄжЁҐ© 2 дг­ЄжЁЁ 21 Ё Їа®зЁв вм + Ї®¤дг­ЄжЁҐ© 2 дг­ЄжЁЁ 26. + * Љ Є б«Ґ¤бвўЁҐ, ASCII-Є®¤л гзЁвлў ов ⥪гйго а бЄ« ¤Єг Є« ўЁ вгал + (rus/en) ў ®в«ЁзЁҐ ®в бЄ ­Є®¤®ў. + * Џ®бвгЇ Ґв Ё­д®а¬ жЁп в®«мЄ® ® вҐе Ј®апзЁе Є« ўЁи е, Є®в®алҐ Ўл«Ё + ®ЇаҐ¤Ґ«Ґ­л нвЁ¬ Ї®в®Є®¬ Ї®¤дг­ЄжЁҐ© 4 дг­ЄжЁЁ 66. + +====================================================================== +================ ”г­ЄжЁп 3 - Ї®«гзЁвм бЁб⥬­®Ґ ўаҐ¬п. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 3 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00SSMMHH, Ј¤Ґ HH:MM:SS = з бл:¬Ё­гвл:ᥪ㭤л + * Є ¦¤л© н«Ґ¬Ґ­в ў®§ўа й Ґвбп Є Є BCD-зЁб«®, ­ ЇаЁ¬Ґа, + ¤«п ўаҐ¬Ґ­Ё 23:59:59 १г«мв в Ўг¤Ґв 0x00595923 +‡ ¬Ґз ­Ёп: + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 9 дг­ЄжЁЁ 26 - Ї®«г祭ЁҐ ўаҐ¬Ґ­Ё + б ¬®¬Ґ­в  § ЇгбЄ  бЁб⥬л; ®­  ў® ¬­®ЈЁе б«гз пе 㤮Ў­ҐҐ, + Ї®бЄ®«мЄг ў®§ўа й Ґв Їа®бв® DWORD-§­ зҐ­ЁҐ бзҐвзЁЄ  ўаҐ¬Ґ­Ё. + * ‘Ёб⥬­®Ґ ўаҐ¬п ¬®¦­® гбв ­®ўЁвм дг­ЄжЁҐ© 22. + +====================================================================== +============== ”г­ЄжЁп 4 - ўлўҐбвЁ бва®Єг ⥪бв  ў ®Є­®. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 4 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] + * ecx = 0xX0RRGGBB, Ј¤Ґ + * RR, GG, BB § ¤ ов 梥в ⥪бв  + * X=ABnn (ЎЁвл): + * nn § ¤ Ґв ЁбЇ®«м§гҐ¬л© иаЁдв: 0=бЁб⥬­л© ¬®­®иЁаЁ­­л©, + 1=бЁб⥬­л© иаЁдв ЇҐаҐ¬Ґ­­®© иЁаЁ­л + * A=0 - ўлў®¤Ёвм esi бЁ¬ў®«®ў, A=1 - ўлў®¤Ёвм ASCIIZ-бва®Єг + * B=1 - § Єа иЁў вм д®­ 梥⮬ edi + * edx = гЄ § вҐ«м ­  ­ з «® бва®ЄЁ + * esi = ¤«п A=0 ¤«Ё­  бва®ЄЁ, ¤®«¦­  Ўлвм ­Ґ Ў®«миҐ 255; + ¤«п A=1 ЁЈ­®аЁагҐвбп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏҐаўл© бЁб⥬­л© иаЁдв бзЁвлў Ґвбп ЇаЁ § Јаг§ЄҐ Ё§ д ©«  char.mt, + ўв®а®© - Ё§ char2.mt. + * ЋЎ  иаЁдв  Ё¬Ґов ўлб®вг 9 ЇЁЄбҐ«Ґ©, иЁаЁ­  ¬®­®иЁаЁ­­®Ј® иаЁдв  + а ў­  6 ЇЁЄбҐ«Ґ©. + +====================================================================== +========================= ”г­ЄжЁп 5 - Ї г§ . ========================= +====================================================================== +‡ ¤Ґа¦Ёў Ґв ўлЇ®«­Ґ­ЁҐ Їа®Ја ¬¬л ­  § ¤ ­­®Ґ ўаҐ¬п. +Џ а ¬Ґвал: + * eax = 5 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ўаҐ¬п ў б®вле ¤®«пе ᥪ㭤л +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏҐаҐ¤ з  ebx=0 ­Ґ ЇҐаҐ¤ Ґв гЇа ў«Ґ­ЁҐ б«Ґ¤го饬㠯а®жҐббг Ё + ў®®ЎйҐ ­Ґ Їа®Ё§ў®¤Ёв ­ЁЄ ЄЁе ¤Ґ©бвўЁ©. …б«Ё ¤Ґ©б⢨⥫쭮 + вॡгҐвбп ЇҐаҐ¤ вм гЇа ў«Ґ­ЁҐ б«Ґ¤го饬㠯а®жҐббг + (§ Є®­зЁвм ⥪гйЁ© Єў ­в ўаҐ¬Ґ­Ё), ЁбЇ®«м§г©вҐ Ї®¤дг­ЄжЁо 1 + дг­ЄжЁЁ 68. + +====================================================================== +=============== ”г­ЄжЁп 6 - Їа®зЁв вм д ©« б а ¬¤ЁбЄ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 6 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  + * ecx = ­®¬Ґа бв ав®ў®Ј® Ў«®Є , бзЁв п б 1; + ecx=0 - зЁв вм б ­ з «  д ©«  (в® ¦Ґ б ¬®Ґ, зв® Ё ecx=1) + * edx = зЁб«® Ў«®Є®ў ¤«п з⥭Ёп; + edx=0 - зЁв вм ®¤Ё­ Ў«®Є (в® ¦Ґ б ¬®Ґ, зв® Ё edx=1) + * esi = гЄ § вҐ«м ­  ®Ў« бвм Ї ¬пвЁ, Єг¤  Ўг¤гв § ЇЁб ­л ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¤«Ё­  д ©«  ў Ў ©в е, Ґб«Ё д ©« гбЇҐи­® Їа®зЁв ­ + * eax = -1, Ґб«Ё д ©« ­Ґ ­ ©¤Ґ­ +‡ ¬Ґз ­Ёп: + * „ ­­ п дг­ЄжЁп пў«пҐвбп гбв аҐўиҐ©; дг­ЄжЁп 70 + Ї®§ў®«пҐв ўлЇ®«­пвм ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * Ѓ«®Є = 512 Ў ©в. + * „«п з⥭Ёп ўбҐЈ® д ©«  ¬®¦­® гЄ § вм § ўҐ¤®¬® Ў®«м讥 §­ зҐ­ЁҐ + ў edx, ­ ЇаЁ¬Ґа, edx = -1; ­® ў н⮬ б«гз Ґ Ўг¤м⥠Ј®в®ўл Є ⮬г, + зв® Їа®Ја ¬¬  "гЇ ¤Ґв", Ґб«Ё д ©« ®Є ¦Ґвбп б«ЁиЄ®¬ Ў®«миЁ¬ + Ё "­Ґ ў«Ґ§Ґв" ў Ї ¬пвм Їа®Ја ¬¬л. + * €¬п д ©«  ¤®«¦­® Ўлвм «ЁЎ® ў д®а¬ вҐ 8+3 бЁ¬ў®«®ў + (ЇҐаўлҐ 8 бЁ¬ў®«®ў - б®Ўб⢥­­® Ё¬п, Ї®б«Ґ¤­ЁҐ 3 - а биЁаҐ­ЁҐ, + Є®а®вЄЁҐ Ё¬Ґ­  Ё а биЁаҐ­Ёп ¤®Ї®«­повбп Їа®ЎҐ« ¬Ё), + «ЁЎ® ў д®а¬ вҐ 8.3 бЁ¬ў®«®ў "FILE.EXT"/"FILE.EX " + (Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ 3 бЁ¬ў®« , + ¤®Ї®«­Ґ­­®Ґ ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ Їа®ЎҐ« ¬Ё). + €¬п д ©«  ¤®«¦­® Ўлвм § ЇЁб ­® § Ј« ў­л¬Ё ЎгЄў ¬Ё. + ‡ ўҐаи ойЁ© бЁ¬ў®« б Є®¤®¬ 0 ­Ґ ­г¦Ґ­ (­Ґ ASCIIZ-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї ЇЄЁ ­  а ¬¤ЁбЄҐ. + +====================================================================== +=============== ”г­ЄжЁп 7 - ўлўҐбвЁ Ё§®Ўа ¦Ґ­ЁҐ ў ®Є­®. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 7 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё§®Ўа ¦Ґ­ЁҐ ў д®а¬ вҐ BBGGRRBBGGRR... + * ecx = [а §¬Ґа Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл Ё§®Ўа ¦Ґ­Ёп - нв® Є®®а¤Ё­ вл ўҐае­ҐЈ® «Ґў®Ј® гЈ«  + Ё§®Ўа ¦Ґ­Ёп ®в­®бЁвҐ«м­® ®Є­ . + * ђ §¬Ґа Ё§®Ўа ¦Ґ­Ёп ў Ў ©в е Ґбвм 3*xsize*ysize. + +====================================================================== +=============== ”г­ЄжЁп 8 - ®ЇаҐ¤Ґ«Ёвм/г¤ «Ёвм Є­®ЇЄг. =============== +====================================================================== +Џ а ¬Ґвал ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп Є­®ЇЄЁ: + * eax = 8 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  Ї® ®бЁ y]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = 0xXYnnnnnn, Ј¤Ґ: + * nnnnnn = Ё¤Ґ­вЁдЁЄ в®а Є­®ЇЄЁ + * бв аиЁ© (31-©) ЎЁв edx бЎа®иҐ­ + * Ґб«Ё 30-© ЎЁв edx гбв ­®ў«Ґ­ - ­Ґ Їа®аЁб®ўлў вм Є­®ЇЄг + * Ґб«Ё 29-© ЎЁв edx гбв ­®ў«Ґ­ - ­Ґ аЁб®ў вм а ¬Єг + ЇаЁ ­ ¦ вЁЁ ­  Є­®ЇЄг + * esi = 0x00RRGGBB - 梥⠪­®ЇЄЁ +Џ а ¬Ґвал ¤«п г¤ «Ґ­Ёп Є­®ЇЄЁ: + * eax = 8 - ­®¬Ґа дг­ЄжЁЁ + * edx = 0x80nnnnnn, Ј¤Ґ nnnnnn - Ё¤Ґ­вЁдЁЄ в®а Є­®ЇЄЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ђ §¬Ґал Є­®ЇЄЁ ¤®«¦­л Ўлвм Ў®«миҐ 0 Ё ¬Ґ­миҐ 0x8000. + * „«п ®Є®­ б® бЄЁ­®¬ ЇаЁ ®ЇаҐ¤Ґ«Ґ­ЁЁ ®Є­  (ўл§®ўҐ 0-© дг­ЄжЁЁ) + б®§¤ овбп ¤ўҐ бв ­¤ ав­лҐ Є­®ЇЄЁ - § ЄалвЁп ®Є­  + б Ё¤Ґ­вЁдЁЄ в®а®¬ 1 Ё ¬Ё­Ё¬Ё§ жЁЁ ®Є­  б Ё¤Ґ­вЁдЁЄ в®а®¬ 0xffff. + * ‘®§¤ ­ЁҐ ¤ўге Є­®Ї®Є б ®¤Ё­ Є®ўл¬Ё Ё¤Ґ­вЁдЁЄ в®а ¬Ё + ўЇ®«­Ґ ¤®ЇгбвЁ¬®. + * Љ­®ЇЄ  б Ё¤Ґ­вЁдЁЄ в®а®¬ 0xffff ЇаЁ ­ ¦ вЁЁ Ё­вҐаЇаҐвЁагҐвбп + бЁб⥬®© Є Є Є­®ЇЄ  ¬Ё­Ё¬Ё§ жЁЁ, бЁб⥬  ®Ўа Ў влў Ґв в Є®Ґ + ­ ¦ вЁҐ б ¬®бв®п⥫쭮, ­Ґ ®Ўа й пбм Є ЇаЁ«®¦Ґ­Ёо. + ‚ ®бв «м­®¬ нв® ®Ўлз­ п Є­®ЇЄ . + * ЋЎйҐҐ Є®«ЁзҐбвў® Є­®Ї®Є ¤«п ўбҐе ЇаЁ«®¦Ґ­Ё© ®Ја ­ЁзҐ­® + зЁб«®¬ 4095. + +====================================================================== +============= ”г­ЄжЁп 9 - Ё­д®а¬ жЁп ® Ї®в®ЄҐ ўлЇ®«­Ґ­Ёп. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 9 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа  1 ЉЎ + * ecx = ­®¬Ґа б«®в  Ї®в®Є  + ecx = -1 - Ї®«гзЁвм Ё­д®а¬ жЁо ® ⥪г饬 Ї®в®ЄҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¬ ЄбЁ¬ «м­л© ­®¬Ґа б«®в  Ї®в®Є  + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв ebx, ᮤҐа¦Ёв б«Ґ¤гойго Ё­д®а¬ жЁо: + * +0: dword: ЁбЇ®«м§®ў ­ЁҐ Їа®жҐбб®а  (бЄ®«мЄ® в Єв®ў ў ᥪ㭤г + г室Ёв ­  ЁбЇ®«­Ґ­ЁҐ Ё¬Ґ­­® нв®Ј® Ї®в®Є ) + * +4: word: Ї®§ЁжЁп ®Є­  Ї®в®Є  ў ®Є®­­®¬ бвнЄҐ + * +6: word: (­Ґ Ё¬ҐҐв ®в­®иҐ­Ёп Є § Їа®иҐ­­®¬г Ї®в®Єг) + ­®¬Ґа б«®в  Ї®в®Є , ®Є­® Є®в®а®Ј® ­ е®¤Ёвбп ў ®Є®­­®¬ бвнЄҐ + ў Ї®§ЁжЁЁ ecx + * +8: word: § аҐ§ҐаўЁа®ў ­® + * +10 = +0xA: 11 Ў ©в: Ё¬п Їа®жҐбб  + (Ё¬п ᮮ⢥вбвўго饣® ЁбЇ®«­пҐ¬®Ј® д ©«  ў д®а¬ вҐ 8+3) + * +21 = +0x15: byte: § аҐ§ҐаўЁа®ў ­®, нв®в Ў ©в ­Ґ Ё§¬Ґ­пҐвбп + * +22 = +0x16: dword:  ¤аҐб Їа®жҐбб  ў Ї ¬пвЁ + * +26 = +0x1A: dword: а §¬Ґа ЁбЇ®«м§гҐ¬®© Ї ¬пвЁ - 1 + * +30 = +0x1E: dword: Ё¤Ґ­вЁдЁЄ в®а (PID/TID) + * +34 = +0x22: dword: Є®®а¤Ё­ в  ®Є­  Ї®в®Є  Ї® ®бЁ x + * +38 = +0x26: dword: Є®®а¤Ё­ в  ®Є­  Ї®в®Є  Ї® ®бЁ y + * +42 = +0x2A: dword: а §¬Ґа ®Є­  Ї®в®Є  Ї® ®бЁ x + * +46 = +0x2E: dword: а §¬Ґа ®Є­  Ї®в®Є  Ї® ®бЁ y + * +50 = +0x32: word: б®бв®п­ЁҐ б«®в  Ї®в®Є : + * 0 = Ї®в®Є ўлЇ®«­пҐвбп + * 1 = Ї®в®Є ЇаЁ®бв ­®ў«Ґ­ + * 2 = Ї®в®Є ЇаЁ®бв ­®ў«Ґ­ ў ¬®¬Ґ­в ®¦Ё¤ ­Ёп б®ЎлвЁп + * 3 = Ї®в®Є § ўҐаи Ґвбп ў १г«мв вҐ ўл§®ў  дг­ЄжЁЁ -1 Ё«Ё + ­ бЁ«мб⢥­­® Є Є б«Ґ¤бвўЁҐ ўл§®ў  Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 18 + Ё«Ё § ўҐа襭Ёп а Ў®вл бЁб⥬л + * 4 = Ї®в®Є § ўҐаи Ґвбп ў १г«мв вҐ ЁбЄ«о祭Ёп + * 5 = Ї®в®Є ®¦Ё¤ Ґв б®ЎлвЁп + * 9 = § Їа®иҐ­­л© б«®в бў®Ў®¤Ґ­, ўбп ®бв «м­ п Ё­д®а¬ жЁп ® + ᫮⥠­Ґ Ё¬ҐҐв б¬лб«  + * +52 = +0x34: word: § аҐ§ҐаўЁа®ў ­®, нв® б«®ў® ­Ґ Ё§¬Ґ­пҐвбп + * +54 = +0x36: dword: Є®®а¤Ё­ в  ­ з «  Є«ЁҐ­вбЄ®© ®Ў« бвЁ + Ї® ®бЁ x + * +58 = +0x3A: dword: Є®®а¤Ё­ в  ­ з «  Є«ЁҐ­вбЄ®© ®Ў« бвЁ + Ї® ®бЁ y + * +62 = +0x3E: dword: иЁаЁ­  Є«ЁҐ­вбЄ®© ®Ў« бвЁ + * +66 = +0x42: dword: ўлб®в  Є«ЁҐ­вбЄ®© ®Ў« бвЁ + * +70 = +0x46: byte: б®бв®п­ЁҐ ®Є­  - ЎЁв®ў®Ґ Ї®«Ґ + * ЎЁв 0 (¬ бЄ  1): ®Є­® ¬ ЄбЁ¬Ё§Ёа®ў ­® + * ЎЁв 1 (¬ бЄ  2): ®Є­® ¬Ё­Ё¬Ё§Ёа®ў ­® ў Ї ­Ґ«м § ¤ з + * ЎЁв 2 (¬ бЄ  4): ®Є­® бўса­гв® ў § Ј®«®ў®Є +‡ ¬Ґз ­Ёп: + * ‘«®вл ­г¬Ґаговбп б 1. + * ‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ­Ґ Ґбвм ®ЎйҐҐ зЁб«® Ї®в®Є®ў, Ї®бЄ®«мЄг + Ўлў ов бў®Ў®¤­лҐ б«®вл. + * ЏаЁ б®§¤ ­ЁЁ Їа®жҐбб   ўв®¬ вЁзҐбЄЁ б®§¤ Ґвбп Ї®в®Є ўлЇ®«­Ґ­Ёп. + * ”г­ЄжЁп ўл¤ Ґв Ё­д®а¬ жЁо ® Ї®в®ЄҐ. Љ ¦¤л© Їа®жҐбб Ё¬ҐҐв + е®вп Ўл ®¤Ё­ Ї®в®Є. Ћ¤Ё­ Їа®жҐбб ¬®¦Ґв б®§¤ вм ­ҐбЄ®«мЄ® Ї®в®Є®ў, + ў н⮬ б«гз Ґ Є ¦¤л© Ї®в®Є Ї®«гз Ґв бў®© б«®в, ЇаЁзҐ¬ Ї®«п + +10, +22, +26 ў нвЁе б«®в е б®ўЇ ¤ ов. + „«п ЇаЁ«®¦Ґ­Ё© ­Ґ бгйҐбвўгҐв ®ЎйҐЈ® бЇ®б®Ў  ®ЇаҐ¤Ґ«Ёвм, + ЇаЁ­ ¤«Ґ¦ в «Ё ¤ў  Ї®в®Є  ®¤­®¬г Їа®жҐббг. + * ЂЄвЁў­®Ґ ®Є­® - ®Є­®, ­ е®¤п饥бп ­  ўҐаиЁ­Ґ ®Є®­­®Ј® бвнЄ , + ®­® Ї®«гз Ґв б®®ЎйҐ­Ёп ® ўў®¤Ґ б Є« ўЁ вгал. „«п ­ҐЈ® Ї®§ЁжЁп ў + ®Є®­­®¬ бвнЄҐ б®ўЇ ¤ Ґв б ў®§ўа й Ґ¬л¬ §­ зҐ­ЁҐ¬. + * ‘«®в 1 ᮮ⢥вбвўгҐв бЇҐжЁ «м­®¬г Ї®в®Єг ®ЇҐа жЁ®­­®© бЁб⥬л, + ¤«п Є®в®а®Ј®: + * ®Є­® ­ е®¤Ёвбп ў­Ё§г ®Є®­­®Ј® бвнЄ , Ї®«п +4 Ё +6 ᮤҐа¦ в + §­ зҐ­ЁҐ 1 + * Ё¬п Їа®жҐбб  - "OS/IDLE" (¤®Ї®«­Ґ­­®Ґ Їа®ЎҐ« ¬Ё) + *  ¤аҐб Їа®жҐбб  ў Ї ¬пвЁ а ўҐ­ 0, а §¬Ґа ЁбЇ®«м§гҐ¬®© Ї ¬пвЁ + 16 Mb (0x1000000) + * PID=1 + * Є®®а¤Ё­ вл Ё а §¬Ґал ®Є­ , а ў­® Є Є Ё Є«ЁҐ­вбЄ®© ®Ў« бвЁ, + гб«®ў­® Ї®« Ј овбп а ў­л¬Ё 0 + * б®бв®п­ЁҐ б«®в  - ўбҐЈ¤  0 (ўлЇ®«­пҐвбп) + * ўаҐ¬п ўлЇ®«­Ґ­Ёп бЄ« ¤лў Ґвбп Ё§ ўаҐ¬Ґ­Ё, г室п饣® ­  + б®Ўб⢥­­® а Ў®вг, Ё ўаҐ¬Ґ­Ё Їа®бв®п ў ®¦Ё¤ ­ЁЁ ЇаҐалў ­Ёп + (Є®в®а®Ґ ¬®¦­® Ї®«гзЁвм ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 18). + * Ќ зЁ­ п б® б«®в  2, а §¬Ґй овбп ®Ўлз­лҐ ЇаЁ«®¦Ґ­Ёп. + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп а §¬Ґй овбп ў Ї ¬пвЁ Ї®  ¤аҐбг 0x60400000 + (Є®­бв ­в  п¤а  std_application_base_address). + Ќ «®¦Ґ­Ёп ­Ґ Їа®Ёб室Ёв, Ї®бЄ®«мЄг г Є ¦¤®Ј® Їа®жҐбб  бў®п + в Ў«Ёж  бва ­Ёж. + * ЏаЁ б®§¤ ­ЁЁ Ї®в®Є  Ґ¬г ­ §­ з овбп б«®в ў бЁб⥬­®© в Ў«ЁжҐ Ё + Ё¤Ґ­вЁдЁЄ в®а (Process/Thread IDentifier = PID/TID), Є®в®алҐ ¤«п + § ¤ ­­®Ј® Ї®в®Є  ­Ґ Ё§¬Ґ­повбп б® ўаҐ¬Ґ­Ґ¬. + Џ®б«Ґ § ўҐа襭Ёп Ї®в®Є  ҐЈ® б«®в ¬®¦Ґв Ўлвм § ­®ў® ЁбЇ®«м§®ў ­ + ¤«п ¤агЈ®Ј® Ї®в®Є . €¤Ґ­вЁдЁЄ в®а Ї®в®Є  ­Ґ ¬®¦Ґв Ўлвм ­ §­ зҐ­ + ¤агЈ®¬г Ї®в®Єг ¤ ¦Ґ Ї®б«Ґ § ўҐа襭Ёп ЇҐаў®Ј®. + Ќ §­ з Ґ¬лҐ ­®ўл¬ Ї®в®Є ¬ Ё¤Ґ­вЁдЁЄ в®ал ¬®­®в®­­® а бвгв. + * …б«Ё Ї®в®Є ҐйҐ ­Ґ ®ЇаҐ¤Ґ«Ё« бў®Ґ ®Є­® ўл§®ў®¬ дг­ЄжЁЁ 0, в® + Ї®«®¦Ґ­ЁҐ Ё а §¬Ґал нв®Ј® ®Є­  Ї®« Ј овбп ­г«п¬Ё. + * Љ®®а¤Ё­ вл Є«ЁҐ­вбЄ®© ®Ў« бвЁ ®Є­  ЎҐагвбп ®в­®бЁвҐ«м­® ®Є­ . + * ‚ ¤ ­­л© ¬®¬Ґ­в ЁбЇ®«м§гҐвбп в®«мЄ® з бвм ЎгдҐа  а §¬Ґа®¬ + 71 = 0x47 Ў ©в . ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ४®¬Ґ­¤гҐвбп ЁбЇ®«м§®ў вм ЎгдҐа + а §¬Ґа®¬ 1 ЉЎ ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ, ў Ўг¤г饬 ¬®Јгв Ўлвм + ¤®Ў ў«Ґ­л ­ҐЄ®в®алҐ Ї®«п. + +====================================================================== +==================== ”г­ЄжЁп 10 - ®¦Ё¤ вм б®ЎлвЁп. =================== +====================================================================== +…б«Ё ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв , в® ¦¤Ґв Ї®пў«Ґ­Ёп б®®ЎйҐ­Ёп ў ®зҐаҐ¤Ё. +‚ в Є®¬ б®бв®п­ЁЁ Ї®в®Є ­Ґ Ї®«гз Ґв Їа®жҐбб®а­®Ј® ўаҐ¬Ґ­Ё. +‡ вҐ¬ бзЁвлў Ґв б®®ЎйҐ­ЁҐ Ё§ ®зҐаҐ¤Ё. + +Џ а ¬Ґвал: + * eax = 10 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п Їа®ўҐаЄЁ, Ґбвм «Ё б®®ЎйҐ­ЁҐ ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 11. + —в®Ўл ¦¤ вм ­Ґ Ў®«ҐҐ ®ЇаҐ¤Ґ«Ґ­­®Ј® ўаҐ¬Ґ­Ё, ЁбЇ®«м§г©вҐ + дг­ЄжЁо 23. + +====================================================================== +======= ”г­ЄжЁп 11 - Їа®ўҐаЁвм, Ґбвм «Ё б®ЎлвЁҐ, ЎҐ§ ®¦Ё¤ ­Ёп. ======= +====================================================================== +…б«Ё ў ®зҐаҐ¤Ё б®®ЎйҐ­Ё© Ґбвм Є Є®Ґ-в® б®ЎлвЁҐ, в® бзЁвлў Ґв Ё +ў®§ўа й Ґв ҐЈ®. …б«Ё ®зҐаҐ¤м Їгбв , ў®§ўа й Ґв ­г«м. +Џ а ¬Ґвал: + * eax = 11 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв  + * Ё­ зҐ eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п ®¦Ё¤ ­Ёп Ї®пў«Ґ­Ёп б®ЎлвЁп ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 10. + —в®Ўл ¦¤ вм ­Ґ Ў®«ҐҐ ®ЇаҐ¤Ґ«Ґ­­®Ј® ўаҐ¬Ґ­Ё, ЁбЇ®«м§г©вҐ + дг­ЄжЁо 23. + +====================================================================== +=========== ”г­ЄжЁп 12 - ­ з вм/§ Є®­зЁвм ЇҐаҐаЁб®ўЄг ®Є­ . ========== +====================================================================== + +-------------- Џ®¤дг­ЄжЁп 1 - ­ з вм ЇҐаҐаЁб®ўЄг ®Є­ . --------------- +Џ а ¬Ґвал: + * eax = 12 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------------- Џ®¤дг­ЄжЁп 2 - § Є®­зЁвм ЇҐаҐаЁб®ўЄг ®Є­ . ------------- +Џ а ¬Ґвал: + * eax = 12 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­ з «  ЇҐаҐаЁб®ўЄЁ г¤ «пҐв ўбҐ ®ЇаҐ¤Ґ«с­­лҐ + дг­ЄжЁҐ© 8 Є­®ЇЄЁ, Ёе б«Ґ¤гҐв ®ЇаҐ¤Ґ«Ёвм Ї®ўв®а­®. + +====================================================================== +============ ”г­ЄжЁп 13 - ­ аЁб®ў вм Їаאַ㣮«м­ЁЄ ў ®Є­Ґ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 13 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  Ї® ®бЁ y]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = 梥в 0xRRGGBB Ё«Ё 0x80RRGGBB ¤«п Ја ¤ЁҐ­в­®© § «ЁўЄЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®¤ Є®®а¤Ё­ в ¬Ё Ї®­Ё¬ овбп Є®®а¤Ё­ вл «Ґў®Ј® ўҐае­ҐЈ® гЈ«  + Їаאַ㣮«м­ЁЄ  ®в­®бЁвҐ«м­® ®Є­ . + +====================================================================== +================ ”г­ЄжЁп 14 - Ї®«гзЁвм а §¬Ґал нЄа ­ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 14 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [xsize]*65536 + [ysize], Ј¤Ґ + * xsize = x-Є®®а¤Ё­ в  Їа ў®Ј® ­Ё¦­ҐЈ® гЈ«  нЄа ­  = + а §¬Ґа Ї® Ј®аЁ§®­в «Ё - 1 + * ysize = y-Є®®а¤Ё­ в  Їа ў®Ј® ­Ё¦­ҐЈ® гЈ«  нЄа ­  = + а §¬Ґа Ї® ўҐавЁЄ «Ё - 1 +‡ ¬Ґз ­Ёп: + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 5 дг­ЄжЁЁ 48 - Ї®«гзЁвм а §¬Ґал а Ў®зҐ© + ®Ў« бвЁ нЄа ­ . + +====================================================================== += ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм а §¬Ґа д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. = +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = иЁаЁ­  Ё§®Ўа ¦Ґ­Ёп + * edx = ўлб®в  Ё§®Ўа ¦Ґ­Ёп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‚л§®ў дг­ЄжЁЁ ®Ўп§ вҐ«Ґ­ ЇҐаҐ¤ ўл§®ў®¬ Ї®¤дг­ЄжЁ© 2 Ё 5. + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п дг­ЄжЁп Ї®«г祭Ёп а §¬Ґа®ў д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 39. + +====================================================================== += ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 2 - Ї®бв ўЁвм в®зЄг ­  д®­®ў®¬ Ё§®Ўа ¦Ґ­ЁЁ. = +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ᬥ饭ЁҐ + * edx = 梥в в®зЄЁ 0xRRGGBB +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‘¬ҐйҐ­ЁҐ ¤«п в®зЄЁ б Є®®а¤Ё­ в ¬Ё (x,y) ўлзЁб«пҐвбп Є Є + (x+y*xsize)*3. + * …б«Ё гЄ § ­­®Ґ ᬥ饭ЁҐ ЇаҐўли Ґв гбв ­®ў«Ґ­­л© Ї®¤дг­ЄжЁҐ© 1 + а §¬Ґа, ўл§®ў ЁЈ­®аЁагҐвбп. + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п дг­ЄжЁп Ї®«г祭Ёп в®зЄЁ б д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 2 дг­ЄжЁЁ 39. + +====================================================================== +============ ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 3 - ЇҐаҐаЁб®ў вм д®­. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +===== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм ०Ё¬ ®ваЁб®ўЄЁ д®­ . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ०Ё¬ ®ваЁб®ўЄЁ: + * 1 = § ¬®бвЁвм + * 2 = а бвп­гвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п Є®¬ ­¤  Ї®«г祭Ёп ०Ё¬  ®ваЁб®ўЄЁ д®­  - + Ї®¤дг­ЄжЁп 4 дг­ЄжЁЁ 39. + +====================================================================== +===== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 5 - Ї®¬ҐбвЁвм Ў«®Є ЇЁЄбҐ«Ґ© ­  д®­. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ ў д®а¬ вҐ BBGGRRBBGGRR... + * edx = ᬥ饭ЁҐ ў ¤ ­­ле д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп + * esi = а §¬Ґа ¤ ­­ле ў Ў ©в е = 3 * зЁб«® ЇЁЄбҐ«Ґ© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄЁ Є®а४⭮б⨠ᬥ饭Ёп Ё а §¬Ґа  ­Ґ Їа®Ё§ў®¤Ёвбп. + * –ўҐв Є ¦¤®Ј® ЇЁЄбҐ«п еа ­Ёвбп Є Є 3-Ў ©в­ п ўҐ«ЁзЁ­  BBGGRR. + * ЏЁЄбҐ«Ё д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп § ЇЁблў овбп Ї®б«Ґ¤®ў вҐ«м­® + б«Ґў  ­ Їа ў®, ᢥаег ў­Ё§. + * ‘¬ҐйҐ­ЁҐ ЇЁЄбҐ«п б Є®®а¤Ё­ в ¬Ё (x,y) Ґбвм (x+y*xsize)*3. + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + +====================================================================== +====================== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 6 ====================== +==== ‘Їа®ҐжЁа®ў вм ¤ ­­лҐ д®­  ­   ¤аҐб­®Ґ Їа®бва ­бвў® Їа®жҐбб . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = гЄ § вҐ«м ­  ¤ ­­лҐ д®­ , 0 ЇаЁ ®иЁЎЄҐ +‡ ¬Ґз ­Ёп: + * ‘Їа®ҐжЁа®ў ­­лҐ ¤ ­­лҐ ¤®бвгЇ­л ­  з⥭ЁҐ Ё § ЇЁбм. + * ђ §¬Ґа ¤ ­­ле д®­  а ўҐ­ 3*xsize*ysize. €§¬Ґ­Ґ­ЁҐ а §¬Ґа®ў д®­  + Ў«®ЄЁагҐвбп ­  ўаҐ¬п а Ў®вл б бЇа®ҐжЁа®ў ­­л¬Ё ¤ ­­л¬Ё. + * –ўҐв Є ¦¤®Ј® ЇЁЄбҐ«п еа ­Ёвбп Є Є 3-Ў ©в®ў п ўҐ«ЁзЁ­  BBGGRR. + * ЏЁЄбҐ«Ё д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп § ЇЁблў овбп Ї®б«Ґ¤®ў вҐ«м­® + б«Ґў  ­ Їа ў®, ᢥаег ў­Ё§. + +====================================================================== +====================== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 7 ====================== +=== ‡ Єалвм Їа®ҐЄжЁо ¤ ­­ле д®­  ­   ¤аҐб­®Ґ Їа®бва ­бвў® Їа®жҐбб . == +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ д®­  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 1 ЇаЁ гбЇҐеҐ, 0 ЇаЁ ®иЁЎЄҐ + +====================================================================== +============= ”г­ЄжЁп 16 - б®еа ­Ёвм а ¬¤ЁбЄ ­  ¤ЁбЄҐвг. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 16 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 Ё«Ё ebx = 2 - ­  Є Єго ¤ЁбЄҐвг б®еа ­пвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  + +====================================================================== +============== ”г­ЄжЁп 17 - Ї®«гзЁвм Є®¤ ­ ¦ в®© Є­®ЇЄЁ. ============= +====================================================================== +‡ ЎЁа Ґв Є®¤ ­ ¦ в®© Є­®ЇЄЁ Ё§ ЎгдҐа . +Џ а ¬Ґвал: + * eax = 17 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ЎгдҐа Їгбв, ў®§ўа й Ґвбп eax=1 + * Ґб«Ё ЎгдҐа ­ҐЇгбв: + * бв аиЁҐ 24 ЎЁв  eax ᮤҐа¦ в Ё¤Ґ­вЁдЁЄ в®а Є­®ЇЄЁ + (ў з бв­®бвЁ, ў ah ®Є §лў Ґвбп ¬« ¤иЁ© Ў ©в Ё¤Ґ­вЁдЁЄ в®а ; + Ґб«Ё ўбҐ Є­®ЇЄЁ Ё¬Ґов Ё¤Ґ­вЁдЁЄ в®а, ¬Ґ­миЁ© 256, + в® ¤«п а §«ЁзҐ­Ёп ¤®бв в®з­® ah) + * al = 0 - Є­®ЇЄ  Ўл«  ­ ¦ в  «Ґў®© Є­®ЇЄ®© ¬лиЁ + * al = ЎЁв, ᮮ⢥вбвўгойЁ© ­ ¦ ўиҐ© Є­®ЇЄҐ ¬лиЁ, Ґб«Ё ­Ґ «Ґў®© +‡ ¬Ґз ­Ёп: + * "ЃгдҐа" еа ­Ёв в®«мЄ® ®¤­г Є­®ЇЄг, ЇаЁ ­ ¦ вЁЁ ­®ў®© Є­®ЇЄЁ + Ё­д®а¬ жЁп ® бв а®© вҐапҐвбп. + * ЏаЁ ўл§®ўҐ нв®© дг­ЄжЁЁ ЇаЁ«®¦Ґ­ЁҐ¬ б ­Ґ ЄвЁў­л¬ ®Є­®¬ + ў®§ўа й Ґвбп ®вўҐв "ЎгдҐа Їгбв". + * ‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ al ᮮ⢥вбвўгҐв б®бв®п­Ёо Є­®Ї®Є ¬лиЁ + ў д®а¬ вҐ Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 37 ў ¬®¬Ґ­в ­ з «  ­ ¦ вЁп + ­  Є­®ЇЄг, §  ЁбЄ«о祭ЁҐ¬ ¬« ¤иҐЈ® ЎЁв  (ᮮ⢥вбвўго饣® «Ґў®© + Є­®ЇЄҐ ¬лиЁ), Є®в®ал© бЎа блў Ґвбп. + +====================================================================== +==== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 2 - § ўҐаиЁвм Їа®жҐбб/Ї®в®Є Ї® б«®вг. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа б«®в  Їа®жҐбб /Ї®в®Є  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЌҐ«м§п § ўҐаиЁвм Ї®в®Є ®ЇҐа жЁ®­­®© бЁб⥬л OS/IDLE (­®¬Ґа б«®в  + 1), ¬®¦­® § ўҐаиЁвм «оЎ®© ®Ўлз­л© Ї®в®Є/Їа®жҐбб. + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 18 - § ўҐа襭ЁҐ + Їа®жҐбб /Ї®в®Є  б § ¤ ­­л¬ Ё¤Ґ­вЁдЁЄ в®а®¬. + +====================================================================== += ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 3 - ᤥ« вм  ЄвЁў­л¬ ®Є­® § ¤ ­­®Ј® Ї®в®Є . = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа б«®в  Ї®в®Є  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаЁ гЄ § ­ЁЁ Є®а४⭮Ј®, ­® ­ҐбгйҐбвўго饣® б«®в   ЄвЁўЁ§ЁагҐвбп + Є Є®Ґ-в® ®Є­®. + * “§­ вм, Є Є®Ґ ®Є­® пў«пҐвбп  ЄвЁў­л¬, ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7. + +====================================================================== + ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм бзсвзЁЄ Їгбвле в Єв®ў ў ᥪ㭤г. +====================================================================== +Џ®¤ Їгбвл¬Ё в Єв ¬Ё Ї®­Ё¬ Ґвбп ўаҐ¬п, ў Є®в®а®Ґ Їа®жҐбб®а Їа®бв Ёў Ґв +ў ®¦Ё¤ ­ЁЁ ЇаҐалў ­Ёп (ў Ё­бвагЄжЁЁ hlt). + +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = §­ зҐ­ЁҐ бзсвзЁЄ  Їгбвле в Єв®ў ў ᥪ㭤г + +====================================================================== +======== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 5 - Ї®«гзЁвм в Єв®ўго з бв®вг. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = в Єв®ў п з бв®в  (Ї® ¬®¤г«о 2^32 в Єв®ў = 4ѓѓж) + +====================================================================== + ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 6 - б®еа ­Ёвм а ¬¤ЁбЄ ў д ©« ­  ¦сбвЄ®¬ ¤ЁбЄҐ. +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  бва®Єг б Ї®«­л¬ Ё¬Ґ­Ґ¬ д ©«  + (­ ЇаЁ¬Ґа, "/hd0/1/kolibri/kolibri.img") +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * Ё­ зҐ eax = Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ‚ᥠЇ ЇЄЁ ў гЄ § ­­®¬ ЇгвЁ ¤®«¦­л бгйҐбвў®ў вм, Ё­ зҐ ўҐа­свбп + §­ зҐ­ЁҐ 5, "д ©« ­Ґ ­ ©¤Ґ­". + +====================================================================== +====== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 7 - Ї®«гзЁвм ­®¬Ґа  ЄвЁў­®Ј® ®Є­ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа  ЄвЁў­®Ј® ®Є­  (­®¬Ґа б«®в  Ї®в®Є , ®Є­® Є®в®а®Ј® +  ЄвЁў­®) +‡ ¬Ґз ­Ёп: + * ЂЄвЁў­®Ґ ®Є­® ­ е®¤Ёвбп ўўҐаег ®Є®­­®Ј® бвнЄ  Ё Ї®«гз Ґв + б®®ЎйҐ­Ёп ®Ў® ўбс¬ ўў®¤Ґ б Є« ўЁ вгал. + * ‘¤Ґ« вм ®Є­®  ЄвЁў­л¬ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 3. + +====================================================================== +==== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 8 - ®вЄ«озЁвм/а §аҐиЁвм §ўгЄ бЇЁЄҐа . ==== +====================================================================== +ЏаЁ ®вЄ«озс­­®¬ §ўгЄҐ ўл§®ўл Ї®¤дг­ЄжЁЁ 55 дг­ЄжЁЁ 55 ЁЈ­®аЁаговбп. +ЏаЁ ўЄ«озс­­®¬ - ­ Їа ў«повбп ­  ўбв஥­­л© бЇЁЄҐа. + +--------------- Џ®¤Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм б®бв®п­ЁҐ. ---------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 1 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - §ўгЄ бЇЁЄҐа  а §аҐис­; 1 - § ЇаҐйс­ + +-------------- Џ®¤Ї®¤дг­ЄжЁп 2 - ЇҐаҐЄ«озЁвм б®бв®п­ЁҐ. -------------- +ЏҐаҐЄ«оз Ґв б®бв®п­Ёп а §аҐиҐ­Ёп/§ ЇаҐйҐ­Ёп. +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== += ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 9 - § ўҐа襭ЁҐ а Ў®вл бЁб⥬л б Ї а ¬Ґв஬. = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ї а ¬Ґва: + * 2 = ўлЄ«озЁвм Є®¬ЇмовҐа + * 3 = ЇҐаҐ§ Јаг§Ёвм Є®¬ЇмовҐа + * 4 = ЇҐаҐ§ ЇгбвЁвм п¤а® Ё§ д ©«  kernel.mnt ­  а ¬¤ЁбЄҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ЇаЁ ­ҐўҐа­®¬ ecx ॣЁбвал ­Ґ ¬Ґ­повбп (в.Ґ. eax=18) + * ЇаЁ Їа ўЁ«м­®¬ ўл§®ўҐ ўбҐЈ¤  ў®§ўа й Ґвбп ЇаЁ§­ Є гбЇҐе  eax=0 +‡ ¬Ґз ­Ёп: + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ЇаЁ ­ҐўҐа­®¬ + ўл§®ўҐ, ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў Ї®б«Ґ¤гойЁе ўҐабЁпе п¤а . + +====================================================================== +======== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 10 - ᢥа­гвм ®Є­® ЇаЁ«®¦Ґ­Ёп. ======= +====================================================================== +‘ў®а зЁў Ґв б®Ўб⢥­­®Ґ ®Є­®. +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЊЁ­Ё¬Ё§Ёа®ў ­­®Ґ ®Є­® б в®зЄЁ §аҐ­Ёп дг­ЄжЁЁ 9 б®еа ­пҐв Ї®«®¦Ґ­ЁҐ + Ё а §¬Ґал. + * ‚®ббв ­®ў«Ґ­ЁҐ ®Є­  ЇаЁ«®¦Ґ­Ёп Їа®Ёб室Ёв ЇаЁ  ЄвЁўЁ§Ёа®ў ­ЁЁ + Ї®¤дг­ЄжЁҐ© 3. + * ЋЎлз­® ­Ґв ­Ґ®Ўе®¤Ё¬®бвЁ пў­® бў®а зЁў вм/а §ў®а зЁў вм бў®с ®Є­®: + бў®а зЁў ­ЁҐ ®Є­  ®бгйҐбвў«пҐвбп бЁб⥬®© ЇаЁ ­ ¦ вЁЁ ­  Є­®ЇЄг + ¬Ё­Ё¬Ё§ жЁЁ (Є®в®а п ¤«п ®Є®­ б® бЄЁ­®¬ ®ЇаҐ¤Ґ«пҐвбп  ўв®¬ вЁзҐбЄЁ + дг­ЄжЁҐ© 0, ¤«п ®Є®­ ЎҐ§ бЄЁ­  Ґс ¬®¦­® ®ЇаҐ¤Ґ«Ёвм дг­ЄжЁҐ© 8), + ў®ббв ­®ў«Ґ­ЁҐ - ЇаЁ«®¦Ґ­ЁҐ¬ @panel. + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 11 ===================== +============= Џ®«гзЁвм Ё­д®а¬ жЁо ® ¤ЁбЄ®ў®© Ї®¤бЁб⥬Ґ. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вЁЇ в Ў«Ёжл: + * 1 = Є®а®вЄ п ўҐабЁп, 10 Ў ©в + * 2 = Ї®«­ п ўҐабЁп, 65536 Ў ©в + * edx = гЄ § вҐ«м ­  ЎгдҐа (ў ЇаЁ«®¦Ґ­ЁЁ) ¤«п в Ў«Ёжл +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в в Ў«Ёжл: Є®а®вЄ п ўҐабЁп: + * +0: byte: Ё­д®а¬ жЁп ® ЌѓЊ„ (¤ЁбЄ®ў®¤ е ¤«п ¤ЁбЄҐв), AAAABBBB, + Ј¤Ґ AAAA § ¤ св вЁЇ ЇҐаў®Ј® ¤ЁбЄ®ў®¤ , BBBB - ўв®а®Ј® б®Ј« б­® + б«Ґ¤го饬г бЇЁбЄг: + * 0 = ­Ґв ¤ЁбЄ®ў®¤  + * 1 = 360Kb, 5.25'' + * 2 = 1.2Mb, 5.25'' + * 3 = 720Kb, 3.5'' + * 4 = 1.44Mb, 3.5'' + * 5 = 2.88Mb, 3.5'' (в ЄЁҐ ¤ЁбЄҐвл ᥩз б 㦥 ­Ґ ЁбЇ®«м§говбп) + Ќ ЇаЁ¬Ґа, ¤«п бв ­¤ ав­®© Є®­дЁЈга жЁЁ Ё§ ®¤­®Ј® 1.44-¤ЁбЄ®ў®¤  + §¤Ґбм Ўг¤Ґв 40h,   ¤«п б«гз п 1.2Mb ­  A: Ё 1.44Mb ­  B: + §­ зҐ­ЁҐ ®Є §лў Ґвбп 24h. + * +1: byte: Ё­д®а¬ жЁп ® ¦сбвЄЁе ¤ЁбЄ е Ё CD-ЇаЁў®¤ е, AABBCCDD, + Ј¤Ґ AA ᮮ⢥вбвўгҐв Є®­ва®««Ґаг IDE0, ..., DD - IDE3: + * 0 = гбва®©бвў® ®вбгвбвўгҐв + * 1 = ¦сбвЄЁ© ¤ЁбЄ + * 2 = CD-ЇаЁў®¤ + Ќ ЇаЁ¬Ґа, ў б«гз Ґ HD ­  IDE0 Ё CD ­  IDE2 §¤Ґбм Ўг¤Ґв 48h. + * +2: 4 db: зЁб«® ­ ©¤Ґ­­ле а §¤Ґ«®ў ­  ¦сбвЄЁе ¤ЁбЄ е б + ᮮ⢥вб⢥­­® IDE0,...,IDE3. + ЏаЁ ®вбгвбвўЁЁ ¦сбвЄ®Ј® ¤ЁбЄ  ­  IDEx ᮮ⢥вбвўгойЁ© Ў ©в + ­г«Ґў®©, ЇаЁ ­ «ЁзЁЁ Ї®Є §лў Ґв зЁб«® а бЇ®§­ ­­ле а §¤Ґ«®ў, + Є®в®але ¬®¦Ґв Ё ­Ґ Ўлвм (Ґб«Ё ­®бЁвҐ«м ­Ґ ®вд®а¬ вЁа®ў ­ Ё«Ё + Ґб«Ё д ©«®ў п бЁб⥬  ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп). ‚ ⥪г饩 ўҐабЁЁ п¤а  + ¤«п ¦сбвЄЁе ¤ЁбЄ®ў Ї®¤¤Ґа¦Ёў овбп в®«мЄ® FAT16, FAT32 Ё NTFS. + * +6: 4 db: § аҐ§ҐаўЁа®ў ­® +”®а¬ в в Ў«Ёжл: Ї®«­ п ўҐабЁп: + * +0: 10 db: в ЄЁҐ ¦Ґ, Є Є Ё ў Є®а®вЄ®© ўҐабЁЁ + * +10: 100 db: ¤ ­­лҐ ¤«п ЇҐаў®Ј® а §¤Ґ«  + * +110: 100 db: ¤ ­­лҐ ¤«п ўв®а®Ј® а §¤Ґ«  + * ... + * +10+100*(n-1): 100 db: ¤ ­­лҐ ¤«п Ї®б«Ґ¤­ҐЈ® а §¤Ґ«  +ђ §¤Ґ«л а бЇ®«®¦Ґ­л ў б«Ґ¤го饬 Ї®ап¤ЄҐ: б­ з «  Ї®б«Ґ¤®ў вҐ«м­® ўбҐ +а бЇ®§­ ­­лҐ а §¤Ґ«л ­  HD ­  IDE0 (Ґб«Ё Ґбвм), +§ вҐ¬ ­  HD ­  IDE1 (Ґб«Ё Ґбвм) Ё в.¤. ¤® IDE3. +”®а¬ в Ё­д®а¬ жЁЁ ® а §¤Ґ«Ґ: + * +0: dword: ­ з «м­л© дЁ§ЁзҐбЄЁ© ᥪв®а а §¤Ґ«  + * +4: dword: Ї®б«Ґ¤­Ё© дЁ§ЁзҐбЄЁ© ᥪв®а а §¤Ґ«  + (ЇаЁ­ ¤«Ґ¦Ёв а §¤Ґ«г) + * +8: byte: вЁЇ д ©«®ў®© бЁб⥬л: + 16=FAT16, 32=FAT32, 1=NTFS + * д®а¬ в ¤ «м­Ґ©иЁе ¤ ­­ле § ўЁбЁв ®в д ©«®ў®© бЁб⥬л, + ¬®¦Ґв ¬Ґ­пвмбп б Ё§¬Ґ­Ґ­Ёп¬Ё ў п¤аҐ Ё Ї®н⮬㠭Ґ ®ЇЁблў Ґвбп +‡ ¬Ґз ­Ёп: + * Љ®а®вЄ п в Ў«Ёж  ¬®¦Ґв Ўлвм ЁбЇ®«м§®ў ­  ¤«п Ї®«г祭Ёп Ё­д®а¬ жЁЁ + ®Ў Ё¬ҐойЁебп гбва®©бвў е. + +====================================================================== +========== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 13 - Ї®«гзЁвм ўҐабЁо п¤а . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа (­Ґ ¬Ґ­ҐҐ 16 Ў ©в), Єг¤  Ўг¤Ґв Ї®¬ҐйҐ­  + Ё­д®а¬ жЁп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‘вагЄвга  ЎгдҐа : +db a,b,c,d ¤«п ўҐабЁЁ a.b.c.d +db UID_xxx: ®¤­® Ё§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 +dd REV - ­®¬Ґа svn-ॢЁ§ЁЁ п¤а  +„«п п¤а  Kolibri 0.7.1.0: +db 0,7,1,0 +db 2 +dd 638 + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 14 ===================== +======= Ћ¦Ё¤ вм ­ з «  ®Ўа в­®Ј® 室  «гз  а §ўсавЄЁ ¬®­Ёв®а . ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 14 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 Є Є ЇаЁ§­ Є гбЇҐе  +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ЇаҐ¤­ §­ зҐ­  ЁбЄ«озЁвҐ«м­® ¤«п  ЄвЁў­ле + ўлб®Є®Їа®Ё§ў®¤ЁвҐ«м­ле Ја дЁзҐбЄЁе ЇаЁ«®¦Ґ­Ё©; ЁбЇ®«м§гҐвбп ¤«п + Ї« ў­®Ј® ўлў®¤  Ја дЁЄЁ. + +====================================================================== +== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 15 - Ї®¬ҐбвЁвм Єгаб®а ¬лиЁ ў 業ва нЄа ­ . = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 15 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 Є Є ЇаЁ§­ Є гбЇҐе  + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 16 ===================== +============ Џ®«гзЁвм а §¬Ґа бў®Ў®¤­®© ®ЇҐа вЁў­®© Ї ¬пвЁ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 16 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = а §¬Ґа бў®Ў®¤­®© Ї ¬пвЁ ў ЄЁ«®Ў ©в е + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 17 ===================== +============ Џ®«гзЁвм а §¬Ґа Ё¬Ґо饩бп ®ЇҐа вЁў­®© Ї ¬пвЁ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 17 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ®ЎйЁ© а §¬Ґа Ё¬Ґо饩бп Ї ¬пвЁ ў ЄЁ«®Ў ©в е + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 18 ===================== +============= ‡ ўҐаиЁвм Їа®жҐбб/Ї®в®Є Ї® Ё¤Ґ­вЁдЁЄ в®аг. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 18 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Їа®жҐбб /Ї®в®Є  (PID/TID) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎЄ  (Їа®жҐбб ­Ґ ­ ©¤Ґ­ Ё«Ё пў«пҐвбп бЁб⥬­л¬) +‡ ¬Ґз ­Ёп: + * ЌҐ«м§п § ўҐаиЁвм Ї®в®Є ®ЇҐа жЁ®­­®© бЁб⥬л OS/IDLE (­®¬Ґа б«®в  + 1), ¬®¦­® § ўҐаиЁвм «оЎ®© ®Ўлз­л© Ї®в®Є/Їа®жҐбб. + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 2 - § ўҐа襭ЁҐ + Їа®жҐбб /Ї®в®Є  Ї® § ¤ ­­®¬г б«®вг. + +====================================================================== +=== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 19 - Ї®«гзЁвм/гбв ­®ўЁвм ­ бва®©ЄЁ ¬лиЁ. == +====================================================================== + +------------- Џ®¤Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм бЄ®а®бвм ¬лиЁ. -------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ⥪гй п бЄ®а®бвм ¬лиЁ + +------------ Џ®¤Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм бЄ®а®бвм ¬лиЁ. ------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 1 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = ­®ў®Ґ §­ зҐ­ЁҐ бЄ®а®бвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------------- Џ®¤Ї®¤дг­ЄжЁп 2 - Ї®«гзЁвм § ¤Ґа¦Єг ¬лиЁ. -------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ⥪гй п § ¤Ґа¦Є  ¬лиЁ + +------------ Џ®¤Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм § ¤Ґа¦Єг ¬лиЁ. ------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 3 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = ­®ў®Ґ §­ зҐ­ЁҐ § ¤Ґа¦ЄЁ ¬лиЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +-------- Џ®¤Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм Ї®«®¦Ґ­ЁҐ Єгаб®а  ¬лиЁ. -------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 4 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------- Џ®¤Ї®¤дг­ЄжЁп 5 - бЁ¬г«Ёа®ў вм б®бв®п­ЁҐ Є« ўЁи ¬лиЁ. -------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 5 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = Ё­д®а¬ жЁп ® н¬г«Ёа㥬®¬ б®бв®п­ЁЁ Є­®Ї®Є ¬лиЁ: + (ᮮ⢥вбвўгҐв ў®§ўа й Ґ¬®¬г §­ зҐ­Ёо Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 37) + * ЎЁв 0 гбв ­®ў«Ґ­ = «Ґў п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 1 гбв ­®ў«Ґ­ = Їа ў п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 2 гбв ­®ў«Ґ­ = б।­пп Є­®ЇЄ  ­ ¦ в  + * ЎЁв 3 гбв ­®ў«Ґ­ = 4-п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 4 гбв ­®ў«Ґ­ = 5-п Є­®ЇЄ  ­ ¦ в  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ђҐЄ®¬Ґ­¤гҐ¬ п бЄ®а®бвм ¬лиЁ (ў Ї®¤Ї®¤дг­ЄжЁЁ 1) ®в 1 ¤® 9. + “бв ­ ў«Ёў Ґ¬ п ўҐ«ЁзЁ­  ­Ґ Їа®ўҐапҐвбп Є®¤®¬ п¤а , Ї®н⮬г + ЁбЇ®«м§г©вҐ ®бв®а®¦­®, ЇаЁ ­ҐЄ®а४⭮¬ §­ зҐ­ЁЁ Єгаб®а ¬®¦Ґв + "§ ¬са§­гвм". ‘Є®а®бвм ¬лиЁ ¬®¦­® ॣ㫨஢ вм ў ЇаЁ«®¦Ґ­ЁЁ SETUP. + * ђҐЄ®¬Ґ­¤гҐ¬ п ўҐ«ЁзЁ­  § ¤Ґа¦ЄЁ (ў Ї®¤Ї®¤дг­ЄжЁЁ 3) = 10. + ЊҐ­миЁҐ §­ зҐ­Ёп ­Ґ ®Ўа Ў влў овбп COM-¬ли ¬Ё. ЏаЁ ®зҐ­м Ў®«миЁе + §­ зҐ­Ёпе ­Ґў®§¬®¦­® ЇҐаҐ¤ўЁ¦Ґ­ЁҐ ¬лиЁ ­  1 ЇЁЄбҐ«м Ё Єгаб®а Ўг¤Ґв + ЇалЈ вм ­  ўҐ«ЁзЁ­г гбв ­®ў«Ґ­­®© бЄ®а®бвЁ (Ї®¤Ї®¤дг­ЄжЁп 1). + “бв ­ ў«Ёў Ґ¬ п ўҐ«ЁзЁ­  ­Ґ Їа®ўҐапҐвбп Є®¤®¬ п¤а . + ‚Ґ«ЁзЁ­г § ¤Ґа¦ЄЁ ¬®¦­® ¬Ґ­пвм ў ЇаЁ«®¦Ґ­ЁЁ SETUP. + * Џ®¤Ї®¤дг­ЄжЁп 4 ­Ґ Їа®ўҐапҐв ЇҐаҐ¤ ­­®Ґ §­ зҐ­ЁҐ. ЏҐаҐ¤ ўл§®ў®¬ + ­Ґ®Ўе®¤Ё¬® г§­ вм ⥪г饥 а §аҐиҐ­ЁҐ нЄа ­  (Ї®¤дг­ЄжЁҐ© 14) + Ё Їа®ўҐаЁвм, зв® гбв ­ ў«Ёў Ґ¬®Ґ Ї®«®¦Ґ­ЁҐ ­Ґ ўл室Ёв §  ЇаҐ¤Ґ«л + нЄа ­ . + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 20 ===================== +============= Џ®«гзЁвм Ё­д®а¬ жЁо ®Ў ®ЇҐа вЁў­®© Ї ¬пвЁ. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 20 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа ¤«п Ё­д®а¬ жЁЁ (36 Ў ©в) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ®ЎйЁ© а §¬Ґа Ё¬Ґо饩бп ®ЇҐа вЁў­®© Ї ¬пвЁ ў Ў ©в е + Ё«Ё -1 ў б«гз Ґ ®иЁЎЄЁ + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв ecx, ᮤҐа¦Ёв б«Ґ¤гойго Ё­д®а¬ жЁо: + * +0: dword: ®ЎйЁ© а §¬Ґа Ё¬Ґо饩бп ®ЇҐа вЁў­®© Ї ¬пвЁ ў бва ­Ёж е + * +4: dword: а §¬Ґа бў®Ў®¤­®© ®ЇҐа вЁў­®© Ї ¬пвЁ ў бва ­Ёж е + * +8: dword: зЁб«® бва ­Ёз­ле ®иЁЎ®Є (ЁбЄ«о祭Ё© #PF) + ў ЇаЁ«®¦Ґ­Ёпе + * +12: dword: а §¬Ґа ЄгзЁ п¤а  ў Ў ©в е + * +16: dword: а §¬Ґа бў®Ў®¤­®© Ї ¬пвЁ ў ЄгзҐ п¤а  ў Ў ©в е + * +20: dword: ®ЎйҐҐ Є®«ЁзҐбвў® Ў«®Є®ў Ї ¬пвЁ ў ЄгзҐ п¤а  + * +24: dword: Є®«ЁзҐбвў® бў®Ў®¤­ле Ў«®Є®ў Ї ¬пвЁ ў ЄгзҐ п¤а  + * +28: dword: а §¬Ґа ­ ЁЎ®«м襣® бў®Ў®¤­®Ј® Ў«®Є  ў ЄгзҐ п¤а  + (§ аҐ§ҐаўЁа®ў ­®) + * +32: dword: а §¬Ґа ­ ЁЎ®«м襣® ўл¤Ґ«Ґ­­®Ј® Ў«®Є  ў ЄгзҐ п¤а  + (§ аҐ§ҐаўЁа®ў ­®) + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 21 ===================== +======= Џ®«гзЁвм ­®¬Ґа б«®в  Їа®жҐбб /Ї®в®Є  Ї® Ё¤Ґ­вЁдЁЄ в®аг. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 21 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Їа®жҐбб /Ї®в®Є  (PID/TID) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ®иЁЎЄ  (­ҐўҐа­л© Ё¤Ґ­вЁдЁЄ в®а) + * Ё­ зҐ eax = ­®¬Ґа б«®в  + +====================================================================== + ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 22 - ®ЇҐа жЁЁ б ®Є­®¬ ¤агЈ®Ј® Їа®жҐбб /Ї®в®Є . +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 22 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вЁЇ ®ЇҐа жЁЁ: + * 0 = ¬Ё­Ё¬Ё§ жЁп ®Є­ , Ї®в®Є § ¤ ­ ­®¬Ґа®¬ б«®в  + * 1 = ¬Ё­Ё¬Ё§ жЁп ®Є­ , Ї®в®Є § ¤ ­ Ё¤Ґ­вЁдЁЄ в®а®¬ + * 2 = ў®ббв ­®ў«Ґ­ЁҐ ®Є­ , Ї®в®Є § ¤ ­ ­®¬Ґа®¬ б«®в  + * 3 = ў®ббв ­®ў«Ґ­ЁҐ ®Є­ , Ї®в®Є § ¤ ­ Ё¤Ґ­вЁдЁЄ в®а®¬ + * edx = Ї а ¬Ґва ®ЇҐа жЁЁ (­®¬Ґа б«®в  Ё«Ё PID/TID) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎЄ  (­ҐЇа ўЁ«м­л© Ї а ¬Ґва) +‡ ¬Ґз ­Ёп: + * Џ®в®Є ¬®¦Ґв ᢥа­гвм бў®с ®Є­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 10. + * ‚®ббв ­®ў«Ґ­ЁҐ ®Є­  б ®¤­®ўаҐ¬Ґ­­®©  ЄвЁўЁ§ жЁҐ© ®бгйҐбвў«пҐвбп + Ї®¤дг­ЄжЁЁ 3 (ЇаЁ­Ё¬ о饩 ­®¬Ґа б«®в ). + +====================================================================== +==================== ”г­ЄжЁп 20 - Ё­вҐа䥩б MIDI. ==================== +====================================================================== + +------------------------ Џ®¤дг­ЄжЁп 1 - бЎа®б ------------------------ +Џ а ¬Ґвал: + * eax = 20 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + +-------------------- Џ®¤дг­ЄжЁп 2 - ўлўҐбвЁ Ў ©в --------------------- +Џ а ¬Ґвал: + * eax = 20 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl = Ў ©в ¤«п ўлў®¤  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ (®¤Ё­ Є®ў® ¤«п ®ЎҐЁе Ї®¤дг­ЄжЁ©): + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«с­ Ў §®ўл© Ї®ав +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм ®ЇаҐ¤Ґ«с­ Ў §®ўл© Ї®ав ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 21. + +====================================================================== +==== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм Ў §®ўл© Ї®ав MPU MIDI. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа Ў §®ў®Ј® Ї®ав  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎ®з­л© ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Ї®ав  ¤®«¦Ґ­ 㤮ў«Ґвў®апвм гб«®ўЁп¬ 0x100<=ecx<=0xFFFF. + * “бв ­®ўЄ  Ў §л ­г¦­  ¤«п а Ў®вл дг­ЄжЁЁ 20. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 26. + +====================================================================== +===== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм а бЄ« ¤Єг Є« ўЁ вгал. ==== +====================================================================== +ђ бЄ« ¤Є  Є« ўЁ вгал ЁбЇ®«м§гҐвбп ¤«п ЇаҐ®Ўа §®ў ­Ёп бЄ ­Є®¤®ў, +Ї®бвгЇ ойЁе ®в Є« ўЁ вгал, ў ASCII-Є®¤л, бзЁвлў Ґ¬лҐ дг­ЄжЁҐ© 2. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Є Єго а бЄ« ¤Єг гбв ­ ў«Ёў вм: + * 1 = ­®а¬ «м­го + * 2 = а бЄ« ¤Єг ЇаЁ ­ ¦ в®¬ Shift + * 3 = а бЄ« ¤Єг ЇаЁ ­ ¦ в®¬ Alt + * edx = гЄ § вҐ«м ­  а бЄ« ¤Єг - в Ў«Ёжг ¤«Ё­®© 128 Ў ©в +€«Ё: + * ecx = 9 + * dx = Ё¤Ґ­вЁдЁЄ в®а бва ­л (1=eng, 2=fi, 3=ger, 4=rus) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї а ¬Ґва § ¤ ­ ­ҐўҐа­® +‡ ¬Ґз ­Ёп: + * …б«Ё ­ ¦ в Alt, в® ЁбЇ®«м§гҐвбп а бЄ« ¤Є  б Alt; + Ґб«Ё ­Ґ ­ ¦ в Alt, ­® ­ ¦ в Shift, в® + ЁбЇ®«м§гҐвбп а бЄ« ¤Є  б Shift; + Ґб«Ё ­Ґ ­ ¦ вл Alt Ё Shift, ­® ­ ¦ в Ctrl, в® ЁбЇ®«м§гҐвбп + ­®а¬ «м­ п а бЄ« ¤Є , Ї®б«Ґ 祣® Ё§ Є®¤  ўлзЁв Ґвбп 0x60; + Ґб«Ё ­Ґ ­ ¦ в  ­Ё ®¤­  Ё§ гЇа ў«пойЁе Є« ўЁи, в® ЁбЇ®«м§гҐвбп + ­®а¬ «м­ п а бЄ« ¤Є . + * Џ®«гзЁвм а бЄ« ¤ЄЁ Ё Ё¤Ґ­вЁдЁЄ в®а бва ­л ¬®¦­® б Ї®¬®ймо + Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 26. + * €¤Ґ­вЁдЁЄ в®а бва ­л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, Є®в®а п + б ¬Ё¬ п¤а®¬ ­Ґ ЁбЇ®«м§гҐвбп; ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel ®в®Ўа ¦ Ґв + ᮮ⢥вбвўгойго ⥪г饩 бва ­Ґ ЁЄ®­Єг. + * ЏаЁ«®¦Ґ­ЁҐ @panel ЇҐаҐЄ«оз Ґв а бЄ« ¤ЄЁ Ї® § Їа®бг Ї®«м§®ў вҐ«п. + +====================================================================== +=========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм Ў §г CD. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ў §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * Ѓ §  CD ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 24. + * Џ®«гзЁвм гбв ­®ў«Ґ­­го Ў §г CD ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 26. + +====================================================================== +========= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 5 - гбв ­®ўЁвм п§лЄ бЁб⥬л. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = п§лЄ бЁб⥬л (1=eng, 2=fi, 3=ger, 4=rus) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * џ§лЄ бЁб⥬л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, ­ЁЄ Є + ­Ґ ЁбЇ®«м§гҐ¬ п б ¬Ё¬ п¤а®¬, ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel аЁбгҐв + ᮮ⢥вбвўгойго ЁЄ®­Єг. + * Џа®ўҐа®Є ­  Є®а४⭮бвм ­Ґ ¤Ґ« Ґвбп, Ї®бЄ®«мЄг п¤а® нвг + ЇҐаҐ¬Ґ­­го ­Ґ ЁбЇ®«м§гҐв. + * Џ®«гзЁвм п§лЄ бЁбвҐ¬л ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 5 дг­ЄжЁЁ 26. + +====================================================================== +=========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 7 - гбв ­®ўЁвм Ў §г HD. =========== +====================================================================== +Ѓ §  HD ­г¦­  ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© ¦сбвЄЁ© ¤ЁбЄ ЇЁб вм, ЇаЁ +ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиҐЈ® бЁ­в ЄбЁб  /HD ў гбв аҐўиҐ© дг­ЄжЁЁ 58; +ЇаЁ ЁбЇ®«м§®ў ­ЁЁ ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  /HD0,/HD1,/HD2,/HD3 +Ў §  гбв ­ ў«Ёў Ґвбп  ўв®¬ вЁзҐбЄЁ. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ў §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм Ў §г. + * ЌҐ б«Ґ¤гҐв Ё§¬Ґ­пвм Ў §г, Є®Ј¤  Є Є®Ґ-­ЁЎг¤м ЇаЁ«®¦Ґ­ЁҐ а Ў®в Ґв + б ¦сбвЄЁ¬ ¤ЁбЄ®¬. …б«Ё ­Ґ е®вЁвҐ Ј«оЄ®ў бЁб⥬л. + * Џ®«гзЁвм гбв ­®ў«Ґ­­го Ў §г ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7 дг­ЄжЁЁ 26. + * ‘«Ґ¤гҐв в Є¦Ґ ®ЇаҐ¤Ґ«Ёвм ЁбЇ®«м§гҐ¬л© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  + Ї®¤дг­ЄжЁҐ© 8. + +====================================================================== +========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 8 - гбв ­®ўЁвм а §¤Ґ« HD. ========== +====================================================================== +ђ §¤Ґ« HD ­г¦Ґ­ ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  +ЇЁб вм, ЇаЁ ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиҐЈ® бЁ­в ЄбЁб  /HD ў гбв аҐўиҐ© +дг­ЄжЁЁ 58; ЇаЁ ЁбЇ®«м§®ў ­ЁЁ ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  +/HD0,/HD1,/HD2,/HD3 Ў §  Ё а §¤Ґ« гбв ­ ў«Ёў овбп  ўв®¬ вЁзҐбЄЁ. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = а §¤Ґ« HD (бзЁв п б 1) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм а §¤Ґ«. + * ЌҐ б«Ґ¤гҐв Ё§¬Ґ­пвм а §¤Ґ«, Є®Ј¤  Є Є®Ґ-­ЁЎг¤м ЇаЁ«®¦Ґ­ЁҐ а Ў®в Ґв + б ¦сбвЄЁ¬ ¤ЁбЄ®¬. …б«Ё ­Ґ е®вЁвҐ Ј«оЄ®ў бЁб⥬л. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© а §¤Ґ« ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 8 + дг­ЄжЁЁ 26. + * Џа®ўҐа®Є ­  Є®а४⭮бвм ­Ґ ¤Ґ« Ґвбп. + * “§­ вм зЁб«® а §¤Ґ«®ў ­  ¦сбвЄ®¬ ¤ЁбЄҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 18. + * ‘«Ґ¤гҐв в Є¦Ґ ®ЇаҐ¤Ґ«Ёвм ЁбЇ®«м§гҐ¬го Ў §г ¦сбвЄ®Ј® ¤ЁбЄ  + Ї®¤дг­ЄжЁҐ© 7. + +====================================================================== +====================== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 11 ===================== +=========== ђ §аҐиЁвм/§ ЇаҐвЁвм ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є HD. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0/1 - § ЇаҐвЁвм/а §аҐиЁвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ LBA-з⥭ЁЁ (Ї®¤дг­ЄжЁп 8 дг­ЄжЁЁ 58). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * Џ®«гзЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 26. + +====================================================================== +====================== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 12 ===================== +========== ђ §аҐиЁвм/§ ЇаҐвЁвм ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0/1 - § ЇаҐвЁвм/а §аҐиЁвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ а Ў®вҐ б иЁ­®© PCI (дг­ЄжЁп 62). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * Џ®«гзЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 12 дг­ЄжЁЁ 26. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 1 ============= +==== €­ЁжЁ «Ё§Ёа®ў вм + Ї®«гзЁвм Ё­д®а¬ жЁо ® ¤а ©ўҐаҐ vmode.mdr. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 1 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  + * edx = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа  512 Ў ©в +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ¤а ©ўҐа ­Ґ § Ја㦥­ (­ЁЄ®Ј¤  ­Ґ Ўлў Ґв ў ⥪г饩 ॠ«Ё§ жЁЁ): + * eax = -1 + * ebx, ecx а §аги овбп + * Ґб«Ё ¤а ©ўҐа § Ја㦥­: + * eax = 'MDAZ' (ў бвЁ«Ґ fasm' , в.Ґ. 'M' - ¬« ¤иЁ© Ў ©в, + 'Z' - бв аиЁ©) - бЁЈ­ вга  + * ebx = ⥪гй п з бв®в  а §ўсавЄЁ (ў ѓж) + * ecx а §аги Ґвбп + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв edx, § Ї®«­Ґ­ +”®а¬ в ЎгдҐа : + * +0: 32*byte: Ё¬п ¤а ©ўҐа , "Trans VideoDriver" (ЎҐ§ Є ўл祪, + ¤®Ї®«­Ґ­® Їа®ЎҐ« ¬Ё) + * +32 = +0x20: dword: ўҐабЁп ¤а ©ўҐа  (ўҐабЁп x.y Є®¤ЁагҐвбп Є Є + y*65536+x), ¤«п ⥪г饩 ॠ«Ё§ жЁЁ 1 (1.0) + * +36 = +0x24: 7*dword: § аҐ§ҐаўЁа®ў ­® (0 ў ⥪г饩 ॠ«Ё§ жЁЁ) + * +64 = +0x40: 32*word: бЇЁб®Є Ї®¤¤Ґа¦Ёў Ґ¬ле ўЁ¤Ґ®аҐ¦Ё¬®ў (Є ¦¤®Ґ + б«®ў® - ­®¬Ґа ўЁ¤Ґ®аҐ¦Ё¬ , Ї®б«Ґ б®Ўб⢥­­® бЇЁбЄ  Ё¤гв ­г«Ё) + * +128 = +0x80: 32*(5*word): бЇЁб®Є Ї®¤¤Ґа¦Ёў Ґ¬ле з бв®в а §ўсав®Є + ¤«п ўЁ¤Ґ®аҐ¦Ё¬®ў: ¤«п Є ¦¤®Ј® ўЁ¤Ґ®аҐ¦Ё¬ , гЄ § ­­®Ј® ў ЇаҐ¤л¤г饬 + Ї®«Ґ, гЄ § ­® ¤® 5 Ї®¤¤Ґа¦Ёў Ґ¬ле з бв®в + (ў ­ҐЁбЇ®«м§гҐ¬ле Ї®§ЁжЁпе § ЇЁб ­л ­г«Ё) +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп Ё­ЁжЁ «Ё§ЁагҐв ¤а ©ўҐа (Ґб«Ё ®­ Ґйс ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­) + Ё ¤®«¦­  ўл§лў вмбп ЇҐаў®©, ЇҐаҐ¤ ®бв «м­л¬Ё (Ё­ зҐ ®­Ё Ўг¤гв + ў®§ўа й вм -1, ­ЁзҐЈ® ­Ґ ¤Ґ« п). + * ‚ ⥪г饩 ॠ«Ё§ жЁЁ Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® ®¤­  з бв®в  а §ўсавЄЁ + ­  ўЁ¤Ґ®аҐ¦Ё¬. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 2 ============= +============= Џ®«гзЁвм Ё­д®а¬ жЁо ® ⥪г饬 ўЁ¤Ґ®аҐ¦Ё¬Ґ. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­; + ebx,ecx а §аги овбп + * eax = [иЁаЁ­ ]*65536 + [ўлб®в ] + * ebx = з бв®в  ўҐавЁЄ «м­®© а §ўсавЄЁ (ў ѓж) + * ecx = ­®¬Ґа ⥪г饣® ўЁ¤Ґ®аҐ¦Ё¬  +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * …б«Ё ­г¦­л в®«мЄ® а §¬Ґал нЄа ­ , 楫Ґб®®Ўа §­Ґ© ЁбЇ®«м§®ў вм + дг­ЄжЁо 14 б гзс⮬ в®Ј®, зв® ®­  ў®§ўа й Ґв а §¬Ґал ­  1 ¬Ґ­миҐ. + +====================================================================== += ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм ўЁ¤Ґ®аҐ¦Ё¬. +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 3 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  + * edx = [з бв®в  а §ўсавЄЁ]*65536 + [­®¬Ґа ўЁ¤Ґ®аҐ¦Ё¬ ] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­, ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ Ё«Ё + Їа®Ё§®и«  ®иЁЎЄ  + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * Ќ®¬Ґа ўЁ¤Ґ®аҐ¦Ё¬  Ё з бв®в  ¤®«¦­л Ўлвм ў в Ў«ЁжҐ, ў®§ўа й Ґ¬®© + дг­ЄжЁҐ© ¤а ©ўҐа  1. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 4 ============= +================= ‚Ґа­гвмбп Є ­ з «м­®¬г ўЁ¤Ґ®аҐ¦Ё¬г. ================ +====================================================================== +‚®§ўа й Ґв нЄа ­ ў ўЁ¤Ґ®аҐ¦Ё¬, гбв ­®ў«Ґ­­л© ЇаЁ § Јаг§ЄҐ бЁб⥬л. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 4 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 5 ============= +======== “ўҐ«ЁзЁвм/㬥­миЁвм а §¬Ґа ўЁ¤Ё¬®© ®Ў« бвЁ ¬®­Ёв®а . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 5 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  + * edx = 0/1 - 㬥­миЁвм/㢥«ЁзЁвм а §¬Ґа Ї® Ј®аЁ§®­в «Ё + ­  ®¤­г Ї®§ЁжЁо + * edx = 2/3 - ў ⥪г饩 ॠ«Ё§ жЁЁ ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп; Ї« ­ЁагҐвбп + Є Є 㬥­м襭ЁҐ/㢥«ЁзҐ­ЁҐ а §¬Ґа  Ї® ўҐавЁЄ «Ё ­  ®¤­г Ї®§ЁжЁо +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * ”г­ЄжЁп ў«ЁпҐв в®«мЄ® ­  дЁ§ЁзҐбЄЁ© а §¬Ґа Ё§®Ўа ¦Ґ­Ёп + ­  ¬®­Ёв®аҐ; «®ЈЁзҐбЄЁ© а §¬Ґа (зЁб«® ЇЁЄбҐ«Ґ©) ­Ґ ¬Ґ­пҐвбп. + +====================================================================== +============ ”г­ЄжЁп 22 - гбв ­®ўЁвм бЁб⥬­го ¤ вг/ўаҐ¬п. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 22 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - гбв ­®ўЁвм ўаҐ¬п + * ecx = 0x00SSMMHH - ўаҐ¬п ў ¤ў®Ёз­®-¤ҐбпвЁз­®¬ Є®¤Ґ (BCD): + * HH=з б 00..23 + * MM=¬Ё­гв  00..59 + * SS=ᥪ㭤  00..59 + * ebx = 1 - гбв ­®ўЁвм ¤ вг + * ecx = 0x00DDMMYY - ¤ в  ў ¤ў®Ёз­®-¤ҐбпвЁз­®¬ Є®¤Ґ (BCD): + * DD=¤Ґ­м 01..31 + * MM=¬Ґбпж 01..12 + * YY=Ј®¤ 00..99 + * ebx = 2 - гбв ­®ўЁвм ¤Ґ­м ­Ґ¤Ґ«Ё + * ecx = 1 ¤«п ў®бЄаҐбҐ­мп, ..., 7 ¤«п бгЎЎ®вл + * ebx = 3 - гбв ­®ўЁвм Ўг¤Ё«м­ЁЄ + * ecx = 0x00SSMMHH +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї а ¬Ґва § ¤ ­ ­ҐўҐа­® + * eax = 2 - CMOS-Ў в аҐ©ЄЁ а §ап¤Ё«Ёбм +‡ ¬Ґз ­Ёп: + * –Ґ­­®бвм гбв ­®ўЄЁ ¤­п ­Ґ¤Ґ«Ё ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©, + Ї®бЄ®«мЄг ®­ ¬ «® Ј¤Ґ ЁбЇ®«м§гҐвбп + (¤Ґ­м ­Ґ¤Ґ«Ё ¬®¦­® а ббзЁв вм Ї® ¤ вҐ). + * Ѓг¤Ё«м­ЁЄ ¬®¦­® гбв ­®ўЁвм ­  ба Ў влў ­ЁҐ ў § ¤ ­­®Ґ ўаҐ¬п + Є ¦¤лҐ бгвЄЁ. ЏаЁ н⮬ ®вЄ«озЁвм ҐЈ® бгйҐбвўгойЁ¬Ё бЁб⥬­л¬Ё + дг­ЄжЁп¬Ё ­Ґ«м§п. + * ‘а Ў влў ­ЁҐ Ўг¤Ё«м­ЁЄ  § Є«оз Ґвбп ў ЈҐ­Ґа жЁЁ IRQ8. + * ‚®®ЎйҐ-в® CMOS Ї®¤¤Ґа¦Ёў Ґв ¤«п Ўг¤Ё«м­ЁЄ  гбв ­®ўЄг §­ зҐ­Ёп + 0xFF ў Є зҐб⢥ ®¤­®Ј® Ё§ Ї а ¬Ґва®ў Ё ®§­ з Ґв нв®, зв® + ᮮ⢥вбвўгойЁ© Ї а ¬Ґва ЁЈ­®аЁагҐвбп. Ќ® ў ⥪г饩 ॠ«Ё§ жЁЁ + нв® ­Ґ Їа®©¤св (ўҐа­свбп §­ зҐ­ЁҐ 1). + * Ѓг¤Ё«м­ЁЄ - Ј«®Ў «м­л© бЁб⥬­л© аҐбгаб; гбв ­®ўЄ  Ўг¤Ё«м­ЁЄ  +  ўв®¬ вЁзҐбЄЁ ®в¬Ґ­пҐв ЇаҐ¤л¤гйго гбв ­®ўЄг. ‚Їа®зҐ¬, ­  ¤ ­­л© + ¬®¬Ґ­в ­Ё ®¤­  Їа®Ја ¬¬  ҐЈ® ­Ґ ЁбЇ®«м§гҐв. + +====================================================================== +============== ”г­ЄжЁп 23 - ®¦Ё¤ вм б®ЎлвЁп б в ©¬ г⮬. ============= +====================================================================== +…б«Ё ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв , ¦¤св Ї®пў«Ґ­Ёп б®®ЎйҐ­Ёп ў ®зҐаҐ¤Ё, +­® ­Ґ Ў®«ҐҐ гЄ § ­­®Ј® ўаҐ¬Ґ­Ё. ‡ вҐ¬ бзЁвлў Ґв б®®ЎйҐ­ЁҐ Ё§ ®зҐаҐ¤Ё. + +Џ а ¬Ґвал: + * eax = 23 - ­®¬Ґа дг­ЄжЁЁ + * ebx = в ©¬ гв (ў б®вле ¤®«пе ᥪ㭤л) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв  + * Ё­ зҐ eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п Їа®ўҐаЄЁ, Ґбвм «Ё б®®ЎйҐ­ЁҐ ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 11. + —в®Ўл ¦¤ вм бЄ®«м гЈ®¤­® ¤®«Ј®, ЁбЇ®«м§г©вҐ дг­ЄжЁо 10. + * ЏҐаҐ¤ з  ebx=0 ЇаЁў®¤Ёв Є ¬®¬Ґ­в «м­®¬г ў®§ўа йҐ­Ёо eax=0. + * ЏаЁ ⥪г饩 ॠ«Ё§ жЁЁ Їа®Ё§®©¤св ­Ґ¬Ґ¤«Ґ­­л© ў®§ўа в Ё§ дг­ЄжЁЁ + б eax=0, Ґб«Ё б«®¦Ґ­ЁҐ ebx б ⥪гйЁ¬ §­ зҐ­ЁҐ¬ бзсвзЁЄ  ўаҐ¬Ґ­Ё + ўл§®ўҐв 32-ЎЁв­®Ґ ЇҐаҐЇ®«­Ґ­ЁҐ. + +====================================================================== +======= ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 1 - ­ з вм Їа®ЁЈалў вм CD-audio. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0x00FRSSMM, Ј¤Ґ + * MM = ­ з «м­ п ¬Ё­гв  + * SS = ­ з «м­ п ᥪ㭤  + * FR = ­ з «м­л© д३¬ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  CD +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав CD ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + * ‚ ᥪ㭤Ґ 75 д३¬®ў, ў ¬Ё­г⥠60 ᥪ㭤. + * ”г­ЄжЁп  бЁ­еа®­­  (ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, Є®Ј¤  ­ з «®бм + Їа®ЁЈалў ­ЁҐ). + +====================================================================== +===== ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 2 - Ї®«гзЁвм Ё­д®а¬ жЁо ® ¤®а®¦Є е. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа ¤«п в Ў«Ёжл + (¬ ЄбЁ¬г¬ 8*64h+4 Ў ©в=100 ¤®а®¦ҐЄ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  CD +‡ ¬Ґз ­Ёп: + * ”®а¬ в в Ў«Ёжл б Ё­д®а¬ жЁҐ© ® ¤®а®¦Є е в Є®© ¦Ґ, Є Є Ё ¤«п + ATAPI-CD Є®¬ ­¤л 43h (READ TOC), ®Ўлз­®© в Ў«Ёжл (Ї®¤Є®¬ ­¤  00h). + Ђ¤аҐб  ў®§ўа й овбп ў д®а¬ вҐ MSF. + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав CD ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + * ”г­ЄжЁп ў®§ўа й Ґв Ё­д®а¬ жЁо в®«мЄ® ® ­Ґ Ў®«ҐҐ 祬 100 + ЇҐаўле ¤®а®¦Є е. ‚ Ў®«миЁ­б⢥ б«гз Ґў нв®Ј® ¤®бв в®з­®. + +====================================================================== +==== ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 3 - ®бв ­®ўЁвм Їа®ЁЈалў Ґ¬®Ґ CD-audio. === +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  CD +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав CD ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + +====================================================================== +======= ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 4 - Ё§ў«Ґзм «®в®Є ЇаЁў®¤  ¤ЁбЄ . ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа CD/DVD-¤ЁбЄ  + (®в 0=Primary Master ¤® 3=Secondary Slave) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® ¤«п ATAPI-гбва®©бвў (CD Ё DVD). + * ЏаЁ Ё§ў«ҐзҐ­ЁЁ «®вЄ  Їа®Ё§ў®¤Ёвбп а §Ў«®ЄЁа®ўЄ  агз­®Ј® гЇа ў«Ґ­Ёп + ¬Ґе ­Ё§¬®¬ «®вЄ . + * ЏаЁ Ё§ў«ҐзҐ­ЁЁ «®вЄ  Є®¤ Їа®Ё§ў®¤Ёв ®зЁбвЄг Єни  б®®вўҐвбвўго饣® + гбва®©бвў . + * ЏаЁ¬Ґа®¬ ЁбЇ®«м§®ў ­Ёп дг­ЄжЁЁ пў«пҐвбп ЇаЁ«®¦Ґ­ЁҐ CD_tray. + +====================================================================== +====== ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 5 - § Јаг§Ёвм «®в®Є ЇаЁў®¤  ¤ЁбЄ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа CD/DVD-¤ЁбЄ  + (®в 0=Primary Master ¤® 3=Secondary Slave) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® ¤«п ATAPI-гбва®©бвў (CD Ё DVD). + * ЏаЁ¬Ґа®¬ ЁбЇ®«м§®ў ­Ёп дг­ЄжЁЁ пў«пҐвбп ЇаЁ«®¦Ґ­ЁҐ CD_tray. + +====================================================================== +===== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм Ў §®ўл© Ї®ав MPU MIDI. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * “бв ­®ўЁвм Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 21. + +====================================================================== +====== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 2 - Ї®«гзЁвм а бЄ« ¤Єг Є« ўЁ вгал. ===== +====================================================================== +ђ бЄ« ¤Є  Є« ўЁ вгал ЁбЇ®«м§гҐвбп ¤«п ЇаҐ®Ўа §®ў ­Ёп бЄ ­Є®¤®ў, +Ї®бвгЇ ойЁе ®в Є« ўЁ вгал, ў ASCII-Є®¤л, бзЁвлў Ґ¬лҐ дг­ЄжЁҐ© 2. +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Є Єго а бЄ« ¤Єг Ї®«гз вм: + * 1 = ­®а¬ «м­го + * 2 = а бЄ« ¤Єг ЇаЁ ­ ¦ в®¬ Shift + * 3 = а бЄ« ¤Єг ЇаЁ ­ ¦ в®¬ Alt + * edx = гЄ § вҐ«м ­  ЎгдҐа ¤«Ё­®© 128 Ў ©в, Єг¤  Ўг¤Ґв бЄ®ЇЁа®ў ­  + а бЄ« ¤Є  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +€«Ё: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 9 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ё¤Ґ­вЁдЁЄ в®а бва ­л (1=eng, 2=fi, 3=ger, 4=rus) +‡ ¬Ґз ­Ёп: + * …б«Ё ­ ¦ в Alt, в® ЁбЇ®«м§гҐвбп а бЄ« ¤Є  б Alt; + Ґб«Ё ­Ґ ­ ¦ в Alt, ­® ­ ¦ в Shift, в® ЁбЇ®«м§гҐвбп + а бЄ« ¤Є  б Shift; + Ґб«Ё ­Ґ ­ ¦ вл Alt Ё Shift, ­® ­ ¦ в Ctrl, в® ЁбЇ®«м§гҐвбп + ­®а¬ «м­ п а бЄ« ¤Є , Ї®б«Ґ 祣® Ё§ Є®¤  ўлзЁв Ґвбп 0x60; + Ґб«Ё ­Ґ ­ ¦ в  ­Ё ®¤­  Ё§ гЇа ў«пойЁе Є« ўЁи, в® ЁбЇ®«м§гҐвбп + ­®а¬ «м­ п а бЄ« ¤Є . + * “бв ­®ўЁвм а бЄ« ¤ЄЁ Ё Ё¤Ґ­вЁдЁЄ в®а бва ­л ¬®¦­® б Ї®¬®ймо + Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 21. + * €¤Ґ­вЁдЁЄ в®а бва ­л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, Є®в®а п + б ¬Ё¬ п¤а®¬ ­Ґ ЁбЇ®«м§гҐвбп; ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel ®в®Ўа ¦ Ґв + ᮮ⢥вбвўгойго ⥪г饩 бва ­Ґ ЁЄ®­Єг + (ЁбЇ®«м§гп ®ЇЁблў Ґ¬го дг­ЄжЁо). + * ЏаЁ«®¦Ґ­ЁҐ @panel ЇҐаҐЄ«оз Ґв а бЄ« ¤ЄЁ Ї® § Їа®бг Ї®«м§®ў вҐ«п. + +====================================================================== +============ ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 3 - Ї®«гзЁвм Ў §г CD. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ў §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‡ ¬Ґз ­Ёп: + * Ѓ §  CD ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 24. + * “бв ­®ўЁвм Ў §г CD ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + +====================================================================== +========== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 5 - Ї®«гзЁвм п§лЄ бЁб⥬л. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = п§лЄ бЁб⥬л (1=eng, 2=fi, 3=ger, 4=rus) +‡ ¬Ґз ­Ёп: + * џ§лЄ бЁб⥬л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, ­ЁЄ Є + ­Ґ ЁбЇ®«м§гҐ¬ п б ¬Ё¬ п¤а®¬, ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel аЁбгҐв + ᮮ⢥вбвўгойго ЁЄ®­Єг (ЁбЇ®«м§гп ®ЇЁблў Ґ¬го дг­ЄжЁо). + * “бв ­®ўЁвм п§лЄ бЁбвҐ¬л ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 5 дг­ЄжЁЁ 21. + +====================================================================== +============ ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 7 - Ї®«гзЁвм Ў §г HD. ============ +====================================================================== +Ѓ §  HD ­г¦­  ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© ¦сбвЄЁ© ¤ЁбЄ ЇЁб вм, ЇаЁ +ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиҐЈ® бЁ­в ЄбЁб  /HD ў гбв аҐўиҐ© дг­ЄжЁЁ 58; +ЇаЁ ЁбЇ®«м§®ў ­ЁЁ ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  /HD0,/HD1,/HD2,/HD3 +Ў §  гбв ­ ў«Ёў Ґвбп  ўв®¬ вЁзҐбЄЁ. +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ў §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм Ў §г. + * “бв ­®ўЁвм Ў §г ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7 дг­ЄжЁЁ 21. + * Џ®«гзЁвм ЁбЇ®«м§гҐ¬л© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  ¬®¦­® Ї®¤дг­ЄжЁҐ© 8. + +====================================================================== +=========== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 8 - Ї®«гзЁвм а §¤Ґ« HD. =========== +====================================================================== +ђ §¤Ґ« HD ­г¦Ґ­ ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  +ЇЁб вм, ЇаЁ ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиҐЈ® бЁ­в ЄбЁб  /HD ў гбв аҐўиҐ© +дг­ЄжЁЁ 58; ЇаЁ ЁбЇ®«м§®ў ­ЁЁ ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  +/HD0,/HD1,/HD2,/HD3 Ў §  Ё а §¤Ґ« гбв ­ ў«Ёў овбп  ўв®¬ вЁзҐбЄЁ. +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = а §¤Ґ« HD (бзЁв п б 1) +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм а §¤Ґ«. + * “бв ­®ўЁвм а §¤Ґ« ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 8 дг­ЄжЁЁ 21. + * “§­ вм зЁб«® а §¤Ґ«®ў ­  ¦сбвЄ®¬ ¤ЁбЄҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 18. + * Џ®«гзЁвм ЁбЇ®«м§гҐ¬го Ў §г ¦сбвЄ®Ј® ¤ЁбЄ  ¬®¦­® Ї®¤дг­ЄжЁҐ© 7. + +====================================================================== +=== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 9 - Ї®«гзЁвм §­ зҐ­ЁҐ бзсвзЁЄ  ўаҐ¬Ґ­Ё. === +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® б®вле ¤®«Ґ© ᥪ㭤л, Їа®иҐ¤иЁе б ¬®¬Ґ­в  + § ЇгбЄ  бЁб⥬л +‡ ¬Ґз ­Ёп: + * ‘зсвзЁЄ ЎҐасвбп Ї® ¬®¤г«о 2^32, з⮠ᮮ⢥вбвўгҐв ­Ґ¬­®ЈЁ¬ Ў®«ҐҐ + 497 бгв®Є. + * ‘Ёб⥬­®Ґ ўаҐ¬п ¬®¦­® Ї®«гзЁвм дг­ЄжЁҐ© 3. + +====================================================================== +====================== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 11 ===================== +=========== “§­ вм, а §аҐис­ «Ё ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є HD. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0/1 - § ЇаҐйс­/а §аҐис­ +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ LBA-з⥭ЁЁ (Ї®¤дг­ЄжЁп 8 дг­ЄжЁЁ 58). + * “бв ­®ўЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 21. + +====================================================================== +====================== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 12 ===================== +========== “§­ вм, а §аҐис­ «Ё ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0/1 - § ЇаҐйс­/а §аҐис­ +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ а Ў®вҐ б иЁ­®© PCI (дг­ЄжЁп 62). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * “бв ­®ўЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 12 дг­ЄжЁЁ 21. + +====================================================================== +================ ”г­ЄжЁп 29 - Ї®«гзЁвм бЁб⥬­го ¤ вг. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 29 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00DDMMYY, Ј¤Ґ + (ЁбЇ®«м§гҐвбп ¤ў®Ёз­®-¤ҐбпвЁз­®Ґ Є®¤Ёа®ў ­ЁҐ, BCD) + * YY = ¤ўҐ ¬« ¤иЁҐ жЁдал Ј®¤  (00..99) + * MM = ¬Ґбпж (01..12) + * DD = ¤Ґ­м (01..31) +‡ ¬Ґз ­Ёп: + * ‘Ёб⥬­го ¤ вг ¬®¦­® гбв ­®ўЁвм дг­ЄжЁҐ© 22. + +====================================================================== +================ ”г­ЄжЁп 30 - а Ў®в  б ⥪г饩 Ї ЇЄ®©. =============== +====================================================================== + +-------- Џ®¤дг­ЄжЁп 1 - гбв ­®ўЁвм ⥪гйго Ї ЇЄг ¤«п Ї®в®Є . --------- +Џ а ¬Ґвал: + * eax = 30 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Їгвс¬ Є ­®ў®© ⥪г饩 Ї ЇЄҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +--------- Џ®¤дг­ЄжЁп 2 - Ї®«гзЁвм ⥪гйго Ї ЇЄг ¤«п Ї®в®Є . ---------- +Џ а ¬Ґвал: + * eax = 30 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа + * edx = а §¬Ґа ЎгдҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = - 1 ®йЁЎЄ , Ї ЇЄ  ⥪г饣® Ї®в®Є  Ё¬ҐҐв ¤«Ё­­г Ў®«ҐҐ 祬 4096 бЁ¬ў®«®ў. + * eax = ¤«Ё­  Ё¬Ґ­Ё ⥪г饩 Ї ЇЄЁ (ўЄ«оз п § ўҐаи ойЁ© 0) +‡ ¬Ґз ­Ёп: + * …б«Ё а §¬Ґа  ЎгдҐа  ­Ґ¤®бв в®з­® ¤«п Є®ЇЁа®ў ­Ёп ўбҐЈ® Ё¬Ґ­Ё, + Є®ЇЁаговбп в®«мЄ® ЇҐаўлҐ (edx-1) Ў ©в + Ё ў Є®­жҐ бв ўЁвбп § ўҐаи ойЁ© 0. + +====================================================================== +================ ”г­ЄжЁп 32 - г¤ «Ёвм д ©« б а ¬¤ЁбЄ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 32 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®; Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« ; дг­ЄжЁп 58 Ї®§ў®«пҐв ўлЇ®«­пвм + ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * ’ҐЄгй п ॠ«Ё§ жЁп ў®§ўа й Ґв в®«мЄ® §­ зҐ­Ёп 0(гбЇҐе) Ё + 5(д ©« ­Ґ ­ ©¤Ґ­). + * €¬п д ©«  ¤®«¦­® Ўлвм «ЁЎ® ў д®а¬ вҐ 8+3 бЁ¬ў®«®ў (ЇҐаўлҐ + 8 бЁ¬ў®«®ў - б®Ўб⢥­­® Ё¬п, Ї®б«Ґ¤­ЁҐ 3 - а биЁаҐ­ЁҐ, + Є®а®вЄЁҐ Ё¬Ґ­  Ё а биЁаҐ­Ёп ¤®Ї®«­повбп Їа®ЎҐ« ¬Ё), + «ЁЎ® ў д®а¬ вҐ 8.3 бЁ¬ў®«®ў "FILE.EXT"/"FILE.EX " + (Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ 3 бЁ¬ў®« , + ¤®Ї®«­Ґ­­®Ґ ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ Їа®ЎҐ« ¬Ё). + €¬п д ©«  ¤®«¦­® Ўлвм § ЇЁб ­® § Ј« ў­л¬Ё ЎгЄў ¬Ё. + ‡ ўҐаи ойЁ© бЁ¬ў®« б Є®¤®¬ 0 ­Ґ ­г¦Ґ­ (­Ґ ASCIIZ-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї Ї®Є ­  а ¬¤ЁбЄҐ. + +====================================================================== +=============== ”г­ЄжЁп 33 - § ЇЁб вм д ©« ­  а ¬¤ЁбЄ. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 33 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * б«Ґ¤гҐв гбв ­ ў«Ёў вм esi=0 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« ; дг­ЄжЁп 70 Ї®§ў®«пҐв ўлЇ®«­пвм + ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * …б«Ё гЄ § вм ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ ў esi Ё ­  а ¬¤ЁбЄҐ 㦥 Ґбвм + гЄ § ­­л© д ©«, в® Ўг¤Ґв б®§¤ ­ Ґйс ®¤Ё­ д ©« б ⥬ ¦Ґ Ё¬Ґ­Ґ¬. + * ‚ Їа®вЁў­®¬ б«гз Ґ д ©« ЇҐаҐ§ ЇЁблў Ґвбп. + * €¬п д ©«  ¤®«¦­® Ўлвм «ЁЎ® ў д®а¬ вҐ 8+3 бЁ¬ў®«®ў + (ЇҐаўлҐ 8 бЁ¬ў®«®ў - б®Ўб⢥­­® Ё¬п, Ї®б«Ґ¤­ЁҐ 3 - а биЁаҐ­ЁҐ, + Є®а®вЄЁҐ Ё¬Ґ­  Ё а биЁаҐ­Ёп ¤®Ї®«­повбп Їа®ЎҐ« ¬Ё), + «ЁЎ® ў д®а¬ вҐ 8.3 бЁ¬ў®«®ў "FILE.EXT"/"FILE.EX " + (Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ 3 бЁ¬ў®« , + ¤®Ї®«­Ґ­­®Ґ ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ Їа®ЎҐ« ¬Ё). + €¬п д ©«  ¤®«¦­® Ўлвм § ЇЁб ­® § Ј« ў­л¬Ё ЎгЄў ¬Ё. + ‡ ўҐаи ойЁ© бЁ¬ў®« б Є®¤®¬ 0 ­Ґ ­г¦Ґ­ (­Ґ ASCIIZ-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї Ї®Є ­  а ¬¤ЁбЄҐ. + +====================================================================== +============ ”г­ЄжЁп 35 - Їа®зЁв вм 梥в в®зЄЁ ­  нЄа ­Ґ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 35 + * ebx = y*xsize+x, Ј¤Ґ + * (x,y) = Є®®а¤Ё­ вл в®зЄЁ (бзЁв п ®в 0) + * xsize = а §¬Ґа нЄа ­  Ї® Ј®аЁ§®­в «Ё +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 梥в 0x00RRGGBB +‡ ¬Ґз ­Ёп: + * “§­ вм а §¬Ґал нЄа ­  ¬®¦­® ўл§®ў®¬ дг­ЄжЁЁ 14. ЋЎа вЁвҐ ў­Ё¬ ­ЁҐ, + зв® ®­  ўлзЁв Ґв 1 Ё§ ®Ў®Ёе а §¬Ґа®ў. + * Љ ўЁ¤Ґ®Ї ¬пвЁ Ґбвм в Є¦Ґ Їаאַ© ¤®бвгЇ (ЎҐ§ ўл§®ў®ў бЁб⥬­ле + дг­ЄжЁ©) зҐаҐ§ ᥫҐЄв®а gs. Џ а ¬Ґвал ⥪г饣® ўЁ¤Ґ®аҐ¦Ё¬  + ¬®¦­® Ї®«гзЁвм дг­ЄжЁҐ© 61. + +====================================================================== +=============== ”г­ЄжЁп 36 - Їа®зЁв вм ®Ў« бвм нЄа ­ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 36 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  ЇаҐ¤ў аЁвҐ«м­® ўл¤Ґ«Ґ­­го ®Ў« бвм Ї ¬пвЁ, + Єг¤  Ўг¤Ґв Ї®¬ҐйҐ­® Ё§®Ўа ¦Ґ­ЁҐ ў д®а¬ вҐ BBGGRRBBGGRR... + * ecx = [а §¬Ґа Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл ®Ў« бвЁ - нв® Є®®а¤Ё­ вл ўҐае­ҐЈ® «Ґў®Ј® гЈ«  + ®Ў« бвЁ ®в­®бЁвҐ«м­® нЄа ­ . + * ђ §¬Ґа Ё§®Ўа ¦Ґ­Ёп ў Ў ©в е Ґбвм 3*xsize*ysize. + +====================================================================== +==================== ”г­ЄжЁп 37 - а Ў®в  б ¬лимо. ==================== +====================================================================== + +-------------- Џ®¤дг­ЄжЁп 0 - нЄа ­­лҐ Є®®а¤Ё­ вл ¬лиЁ --------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = x*65536 + y, (x,y)=Є®®а¤Ё­ вл Єгаб®а  ¬лиЁ (бзЁв п ®в 0) + +---------- Џ®¤дг­ЄжЁп 1 - Є®®а¤Ё­ вл ¬лиЁ ®в­®бЁвҐ«м­® ®Є­  ---------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = x*65536 + y, (x,y)=Є®®а¤Ё­ вл Єгаб®а  ¬лиЁ ®в­®бЁвҐ«м­® + ®Є­  ЇаЁ«®¦Ґ­Ёп (бзЁв п ®в 0) +‡ ¬Ґз ­Ёп: + * ‡­ зҐ­ЁҐ ўлзЁб«пҐвбп Ї® д®а¬г«Ґ (x-xwnd)*65536 + (y-ywnd). + …б«Ё y>=ywnd, в® ¬« ¤иҐҐ б«®ў® ­Ґ®ваЁж вҐ«м­® Ё ᮤҐа¦Ёв + ®в­®бЁвҐ«м­го y-Є®®а¤Ё­ вг,   бв а襥 - ®в­®бЁвҐ«м­го x-Є®®а¤Ё­ вг + (Їа ўЁ«м­®Ј® §­ Є ). ‚ Їа®вЁў­®¬ б«гз Ґ ¬« ¤иҐҐ б«®ў® ®ваЁж вҐ«м­® + Ё ўбс а ў­® ᮤҐа¦Ёв ®в­®бЁвҐ«м­го y-Є®®а¤Ё­ вг, +   Є бв а襬г б«®ўг б«Ґ¤гҐв ЇаЁЎ ўЁвм 1. + +----------------- Џ®¤дг­ЄжЁп 2 - ­ ¦ влҐ Є­®ЇЄЁ ¬лиЁ ----------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax ᮤҐа¦Ёв Ё­д®а¬ жЁо ® ­ ¦ вле Є­®ЇЄ е ¬лиЁ: + * ЎЁв 0 гбв ­®ў«Ґ­ = «Ґў п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 1 гбв ­®ў«Ґ­ = Їа ў п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 2 гбв ­®ў«Ґ­ = б।­пп Є­®ЇЄ  ­ ¦ в  + * ЎЁв 3 гбв ­®ў«Ґ­ = 4-п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 4 гбв ­®ў«Ґ­ = 5-п Є­®ЇЄ  ­ ¦ в  + * Їа®зЁҐ ЎЁвл бЎа®иҐ­л + +------------------ Џ®¤дг­ЄжЁп 4 - § Јаг§Ёвм Єгаб®а ------------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * dx = Ёбв®з­ЁЄ ¤ ­­ле: + * dx = LOAD_FROM_FILE = 0 - ¤ ­­лҐ ў д ©«Ґ + * ecx = гЄ § вҐ«м ­  Ї®«­л© Їгвм Є д ©«г Єгаб®а  + * д ©« Єгаб®а  ¤®«¦Ґ­ Ўлвм ў д®а¬ вҐ .cur, бв ­¤ ав­®¬ ¤«п + MS Windows, ЇаЁзс¬ а §¬Ґа®¬ 32*32 ЇЁЄбҐ«п + * dx = LOAD_FROM_MEM = 1 - ¤ ­­лҐ д ©«  㦥 § Ја㦥­л ў Ї ¬пвм + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ д ©«  Єгаб®а  + * д®а¬ в ¤ ­­ле в Є®© ¦Ґ, Є Є Ё ў ЇаҐ¤л¤г饬 б«гз Ґ + * dx = LOAD_INDIRECT = 2 - ¤ ­­лҐ ў Ї ¬пвЁ + * ecx = гЄ § вҐ«м ­  ®Ўа § Єгаб®а  ў д®а¬ вҐ ARGB 32*32 ЇЁЄбҐ«п + * edx = 0xXXYY0002, Ј¤Ґ + * XX = x-Є®®а¤Ё­ в  "Ј®ап祩 в®зЄЁ" Єгаб®а  + * YY = y-Є®®а¤Ё­ в  + * 0 <= XX, YY <= 31 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ­Ґг¤ з  + * Ё­ зҐ eax = ен­¤« Єгаб®а  + +------------------ Џ®¤дг­ЄжЁп 5 - гбв ­®ўЁвм Єгаб®а ------------------ +“бв ­ ў«Ёў Ґв ­®ўл© Єгаб®а ¤«п ®Є­  ⥪г饣® Ї®в®Є . +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« Єгаб®а  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ен­¤« ЇаҐ¤л¤г饣® гбв ­®ў«Ґ­­®Ј® Єгаб®а  +‡ ¬Ґз ­Ёп: + * …б«Ё ЇҐаҐ¤ ­ ­ҐЄ®а४в­л© ен­¤«, в® дг­ЄжЁп ў®ббв ­®ўЁв Єгаб®а + Ї® 㬮«з ­Ёо (бв ­¤ ав­го бв५Єг). ‚ з бв­®бвЁ, Є ў®ббв ­®ў«Ґ­Ёо + Єгаб®а  Ї® 㬮«з ­Ёо ЇаЁў®¤Ёв ЇҐаҐ¤ з  ecx=0. + +------------------- Џ®¤дг­ЄжЁп 6 - г¤ «Ёвм Єгаб®а -------------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« Єгаб®а  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Љгаб®а ¤®«¦Ґ­ Ўл« Ўлвм а ­ҐҐ § Ја㦥­ ⥪гйЁ¬ Ї®в®Є®¬ + (ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 4). ”г­ЄжЁп ­Ґ г¤ «пҐв бЁб⥬­лҐ Єгаб®ал Ё + Єгаб®ал, § Ја㦥­­лҐ ¤агЈЁ¬Ё ЇаЁ«®¦Ґ­Ёп¬Ё. + * …б«Ё г¤ «пҐвбп  ЄвЁў­л© (гбв ­®ў«Ґ­­л© Ї®¤дг­ЄжЁҐ© 5) Єгаб®а, в® + ў®ббв ­ ў«Ёў Ґвбп Єгаб®а Ї® 㬮«з ­Ёо (бв ­¤ ав­ п бв५Є ). + +------------------ Џ®¤дг­ЄжЁп 7 - ¤ ­­лҐ Їа®ЄагвЄЁ ------------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [horizontal offset]*65536 + [vertical offset] +‡ ¬Ґз ­Ёп: + * „ ­­лҐ ¤®бвгЇ­л в®«мЄ®  ЄвЁў­®¬г ®Є­г. + * Џ®б«Ґ Їа®з⥭Ёп §­ зҐ­Ёп ®Ў­г«повбп. + * „ ­­лҐ Ё¬Ґов §­ Є®ўлҐ §­ зҐ­Ёп. + +====================================================================== +================== ”г­ЄжЁп 38 - ­ аЁб®ў вм ®в१®Є. ================== +====================================================================== +Џ а ¬Ґвал: + * eax = 38 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  ­ з «  Ї® ®бЁ x]*65536 + + [Є®®а¤Ё­ в  Є®­ж  Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  ­ з «  Ї® ®бЁ y]*65536 + + [Є®®а¤Ё­ в  Є®­ж  Ї® ®бЁ y] + * edx = 0x00RRGGBB - 梥в + edx = 0x01xxxxxx - аЁб®ў вм Ё­ўҐаб­л© ®в१®Є + (¬« ¤иЁҐ 24 ЎЁв  ЁЈ­®аЁаговбп) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл ЎҐагвбп ®в­®бЁвҐ«м­® ®Є­ . + * Љ®­Ґз­ п в®зЄ  в Є¦Ґ аЁбгҐвбп. + +====================================================================== +== ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм а §¬Ґа д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. == +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [иЁаЁ­ ]*65536 + [ўлб®в ] +‡ ¬Ґз ­Ёп: + * …бвм Ї а­ п Є®¬ ­¤  гбв ­®ўЄЁ а §¬Ґа®ў д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 15. Џ®б«Ґ Є®в®а®©, ࠧ㬥Ґвбп, б«Ґ¤гҐв + § ­®ў® ®ЇаҐ¤Ґ«Ёвм б ¬® Ё§®Ўа ¦Ґ­ЁҐ. + +====================================================================== += ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 2 - Їа®зЁв вм в®зЄг б д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. = +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ᬥ饭ЁҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00RRGGBB - 梥в в®зЄЁ, Ґб«Ё ᬥ饭ЁҐ ¤®ЇгбвЁ¬® + (¬Ґ­миҐ 0x160000-16) + * eax = 2 - Ё­ зҐ +‡ ¬Ґз ­Ёп: + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ў б«гз Ґ ­ҐўҐа­®Ј® + ᬥ饭Ёп, ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў б«Ґ¤гойЁе ўҐабЁпе п¤а . + * ‘¬ҐйҐ­ЁҐ в®зЄЁ б Є®®а¤Ё­ в ¬Ё (x,y) ўлзЁб«пҐвбп Є Є (x+y*xsize)*3. + * …бвм Ї а­ п дг­ЄжЁп гбв ­®ўЄЁ в®зЄЁ ­  д®­®ў®¬ Ё§®Ўа ¦Ґ­ЁЁ - + Ї®¤дг­ЄжЁп 2 дг­ЄжЁЁ 15. + +====================================================================== +====== ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм ०Ё¬ ®ваЁб®ўЄЁ д®­ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 1 - § ¬®бвЁвм + * eax = 2 - а бвп­гвм +‡ ¬Ґз ­Ёп: + * …бвм Ї а­ п дг­ЄжЁп гбв ­®ўЄЁ ०Ё¬  ®ваЁб®ўЄЁ д®­  - + Ї®¤дг­ЄжЁп 4 дг­ЄжЁЁ 15. + +====================================================================== +======== ”г­ЄжЁп 40 - гбв ­®ўЁвм ¬ бЄг ¤«п ®¦Ё¤ Ґ¬ле б®ЎлвЁ©. ======== +====================================================================== +Њ бЄ  ¤«п ®¦Ё¤ Ґ¬ле б®ЎлвЁ© ў«ЁпҐв ­  дг­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё 10, +11, 23 - ®­Ё б®®Ўй ов в®«мЄ® ® б®ЎлвЁпе, а §аҐис­­ле нв®© ¬ бЄ®©. +Џ а ¬Ґвал: + * eax = 40 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ¬ бЄ : ЎЁв i ᮮ⢥вбвўгҐв б®ЎлвЁо i+1 (б¬. бЇЁб®Є б®ЎлвЁ©) + (гбв ­®ў«Ґ­­л© ЎЁв а §аҐи Ґв Ё§ўҐйҐ­ЁҐ ® б®ЎлвЁЁ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ЇаҐ¤л¤г饥 §­ зҐ­ЁҐ ¬ бЄЁ +‡ ¬Ґз ­Ёп: + * Њ бЄ  Ї® 㬮«з ­Ёо (7=111b) а §аҐи Ґв Ё§ўҐйҐ­Ёп ® ЇҐаҐаЁб®ўЄҐ + Ё ­ ¦ вЁпе Є« ўЁи Ё Є­®Ї®Є. + ќв®Ј® ¤®бв в®з­® ¤«п Ў®«миЁ­бвў  ЇаЁ«®¦Ґ­Ё©. + * ‘®ЎлвЁп, § ЇаҐйс­­лҐ ў ¬ бЄҐ, ўбс а ў­® б®еа ­повбп, Ґб«Ё + ЇаЁе®¤пв; ® ­Ёе Їа®бв® ­Ґ Ё§ўҐй ов дг­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё. + * ”г­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё гзЁвлў ов ¬ бЄг ­  ¬®¬Ґ­в + ўл§®ў  дг­ЄжЁЁ,   ­Ґ ­  ¬®¬Ґ­в Ї®бвгЇ«Ґ­Ёп б®®ЎйҐ­Ёп. + +====================================================================== +================= ”г­ЄжЁп 41 - г§­ вм ў« ¤Ґ«мж  IRQ. ================= +====================================================================== +Џ а ¬Ґвал: + * eax = 41 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = PID ў« ¤Ґ«мж  + * eax = 0, Ґб«Ё ў« ¤Ґ«мж  ­Ґв + * eax = -1 ¤«п ­ҐЄ®а४⭮Ј® ebx + +====================================================================== +========= ”г­ЄжЁп 42 - а Ў®в  б ¤ ­­л¬Ё, Ї®«г祭­л¬Ё Ї® IRQ. ========= +====================================================================== +ЏаЁ ў®§­ЁЄ­®ўҐ­ЁЁ IRQ бЁб⥬  ¬®¦Ґв бзЁвлў вм ¤ ­­лҐ Ё§ гЄ § ­­ле +а ­ҐҐ дг­ЄжЁҐ© 44 Ї®ав®ў Ё § ЇЁблў вм нвЁ ¤ ­­лҐ ў ЎгдҐа. + +-------------------- Џ®¤дг­ЄжЁп 0 - з⥭ЁҐ ¤ ­­ле -------------------- +Џ а ¬Ґвал: + * eax = 42 - ­®¬Ґа дг­ЄжЁЁ + * bl = ­®¬Ґа IRQ, 0..15 + * bh = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ®бв «м­ п з бвм ॣЁбва  ebx ¤®«¦­  Ўлвм ®Ў­г«Ґ­  + * ecx = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа®¬ ­Ґ ¬Ґ­ҐҐ 4000 Ў ©в +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: (бЁвг жЁо ¬®¦­® а §«ЁзЁвм Ї® §­ зҐ­Ёо eax) + * Ґб«Ё Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 IRQ + (Ё«Ё ­®¬Ґа IRQ § ¤ ­ ­ҐўҐа­®): eax = -1 + * Ґб«Ё ¤ ­­ле ­Ґв: eax = 0 + * Ґб«Ё ўбс ў Ї®ап¤ЄҐ Ё ¤ ­­лҐ Ўл«Ё: + eax = а §¬Ґа ¤ ­­ле, Їа®зЁв ­­ле Ё§ ЎгдҐа  (ў Ў ©в е) + +------------ Џ®¤дг­ЄжЁп 1 - г§­ вм а §¬Ґа ¤ ­­ле ў ЎгдҐаҐ ------------ +Џ а ¬Ґвал: + * eax = 42 - ­®¬Ґа дг­ЄжЁЁ + * bl = ­®¬Ґа IRQ, 0..15 + * bh = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ®бв «м­ п з бвм ॣЁбва  ebx ¤®«¦­  Ўлвм ®Ў­г«Ґ­  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 IRQ + (Ё«Ё ­®¬Ґа IRQ § ¤ ­ ­ҐўҐа­®): eax = -1 + * Ё­ зҐ eax = а §¬Ґа ¤ ­­ле ў ЎгдҐаҐ +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® Ї®в®Є ¤®«¦Ґ­ § аҐ§ҐаўЁа®ў вм ¤«п ᥡп гЄ § ­­л© IRQ + дг­ЄжЁҐ© 45. + * ђ §¬Ґа ЎгдҐа  ¤«п ¤ ­­ле - 4000 Ў ©в, ЇаЁ ЇҐаҐЇ®«­Ґ­ЁЁ + "ᢥ¦ЁҐ" ¤ ­­лҐ ЇҐаҐбв ов § ЇЁблў вмбп ў ЎгдҐа. + +====================================================================== +=================== ”г­ЄжЁп 43 - ўў®¤/ўлў®¤ ў Ї®ав. ================== +====================================================================== + +------------------------ ‚лў®¤ ¤ ­­ле ў Ї®ав ------------------------- +Џ а ¬Ґвал: + * eax = 43 - ­®¬Ґа дг­ЄжЁЁ + * bl = Ў ©в ¤«п ўлў®¤  + * ecx = ­®¬Ґа Ї®ав  0xnnnn (®в 0 ¤® 0xFFFF) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї®в®Є ­Ґ § аҐ§ҐаўЁа®ў « гЄ § ­­л© Ї®ав + +------------------------ ‚ў®¤ ¤ ­­ле Ё§ Ї®ав  ------------------------ +Џ а ¬Ґвал: + * eax = 43 - ­®¬Ґа дг­ЄжЁЁ + * ebx ЁЈ­®аЁагҐвбп + * ecx = 0x8000nnnn, Ј¤Ґ nnnn = ­®¬Ґа Ї®ав  (®в 0 ¤® 0xFFFF) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, ЇаЁ н⮬ ebx = ўўҐ¤с­­л© Ў ©в + * eax = 1 - Ї®в®Є ­Ґ § аҐ§ҐаўЁа®ў « ¤ ­­л© Ї®ав +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® Ї®в®Є ¤®«¦Ґ­ § аҐ§ҐаўЁа®ў вм §  б®Ў®© + гЄ § ­­л© Ї®ав дг­ЄжЁҐ© 46. + * „«п § аҐ§ҐаўЁа®ў ­­ле Ї®ав®ў ў¬Ґбв® ўл§®ў  нвЁе дг­ЄжЁ© + «гзиҐ ЁбЇ®«м§®ў вм Є®¬ ­¤л Їа®жҐбб®а  in/out - нв® §­ зЁвҐ«м­® + Ўлбв॥ Ё ­ҐбЄ®«мЄ® Є®а®зҐ Ё Їа®йҐ. €§ ­Ґ§ аҐ§ҐаўЁа®ў ­­ле + Ї®ав®ў зЁв вм ўбс а ў­® ­Ґ«м§п. + +====================================================================== +======== ”г­ЄжЁп 44 - ®ЇаҐ¤Ґ«Ёвм ¤Ґ©бвўЁп ЇаЁ Ї®бвгЇ«Ґ­ЁЁ IRQ. ======= +====================================================================== +ЏаЁ ў®§­ЁЄ­®ўҐ­ЁЁ IRQ бЁб⥬  ¬®¦Ґв бзЁвлў вм ¤ ­­лҐ Ё§ гЄ § ­­ле нв®© +дг­ЄжЁҐ© Ї®ав®ў Ё § ЇЁблў вм нвЁ ¤ ­­лҐ ў ЎгдҐа, ®вЄг¤  Ёе ¬®¦­® +Їа®зЁв вм дг­ЄжЁҐ© 42. +Џ а ¬Ґвал: + * eax = 44 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  ¬ ббЁў бвагЄвга, ®ЇЁблў ойЁе Ї® ®¤­®¬г Ї®авг: + * +0: word: 0 ®§­ з Ґв Є®­Ґж ¬ ббЁў , Ё­ зҐ ­®¬Ґа Ї®ав  + * +2: byte: § аҐ§ҐаўЁа®ў ­® (ЁЈ­®аЁагҐвбп) + * +3: byte: 1=бзЁвлў вм Ў ©в Ё§ нв®Ј® Ї®ав , 2=бзЁвлў вм б«®ў® + * ecx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 гЄ § ­­®Ј® IRQ +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® Ї®в®Є ¤®«¦Ґ­ § аҐ§ҐаўЁа®ў вм §  б®Ў®© + гЄ §лў Ґ¬л© IRQ дг­ЄжЁҐ© 45. + * ЏаЁ­Ё¬ овбп ў® ў­Ё¬ ­ЁҐ в®«мЄ® ЇҐаўлҐ 16 Ї®ав®ў. + * ’ҐЄгй п ॠ«Ё§ жЁп а бб¬ ваЁў Ґв ­ҐЇа ўЁ«м­®Ґ §­ зҐ­ЁҐ Ї®«п +3 + Є Є бЁЈ­ « ЇаҐЄа йҐ­Ёп ®Ўа Ў®вЄЁ IRQ. + +====================================================================== +============ ”г­ЄжЁп 45 - § аҐ§ҐаўЁа®ў вм/®бў®Ў®¤Ёвм IRQ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 45 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - § аҐ§ҐаўЁа®ў вм, 1 = ®бў®Ў®¤Ёвм + * ecx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  (­ҐўҐа­л© ­®¬Ґа IRQ Ё«Ё + Ї®ЇлвЄ  § аҐ§ҐаўЁа®ў вм ­Ґбў®Ў®¤­л© IRQ Ё«Ё ®бў®Ў®¤Ёвм IRQ, ­Ґ + § аҐ§ҐаўЁа®ў ­­л© ⥪гйЁ¬ Ї®в®Є®¬) +‡ ¬Ґз ­Ёп: + * ђҐ§ҐаўЁа®ў ­ЁҐ IRQ ­г¦­® ¤«п а Ў®вл дг­ЄжЁ© 42 Ё 44. + * ’®«мЄ® ®¤Ё­ Ї®в®Є ¬®¦Ґв § аҐ§ҐаўЁа®ў вм Є®­ЄаҐв­л© IRQ. + * IRQ, ®Ўа Ў влў Ґ¬лҐ бЁб⥬®© б ¬®бв®п⥫쭮, १ҐаўЁаговбп + бЁб⥬®© (Ї®в®Є®¬ 1) ЇаЁ § Јаг§ЄҐ. + * ЏаЁ § ўҐа襭ЁЁ Ї®в®Є   ўв®¬ вЁзҐбЄЁ ®бў®Ў®¦¤ овбп + ўбҐ § аҐ§ҐаўЁа®ў ­­лҐ Ё¬ IRQ. + +====================================================================== += ”г­ЄжЁп 46 - § аҐ§ҐаўЁа®ў вм/®бў®Ў®¤Ёвм ЈагЇЇг Ї®ав®ў ўў®¤ /ўлў®¤ . +====================================================================== +Љ § аҐ§ҐаўЁа®ў ­­л¬ Ї®ав ¬ ¬®¦­® ®Ўа й вмбп ­ Їап¬го Ё§ ЇаЁ«®¦Ґ­Ёп +Є®¬ ­¤ ¬Ё in/out (४®¬Ґ­¤гҐ¬л© бЇ®б®Ў) Ё ўл§®ў®¬ дг­ЄжЁЁ 43 +(­ҐаҐЄ®¬Ґ­¤гҐ¬л© бЇ®б®Ў). +Џ а ¬Ґвал: + * eax = 46 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - § аҐ§ҐаўЁа®ў вм, 1 - ®бў®Ў®¤Ёвм + * ecx = ­®¬Ґа ­ з «  ¤Ё Ї §®­  Ї®ав®ў + * edx = ­®¬Ґа Є®­ж  ¤Ё Ї §®­  Ї®ав®ў (ўЄ«озЁвҐ«м­®) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  +‡ ¬Ґз ­Ёп: + * ‚ б«гз Ґ १ҐаўЁа®ў ­Ёп Ї®ав®ў ®иЁЎЄ®© бзЁв Ґвбп ўлЇ®«­Ґ­ЁҐ + ®¤­®Ј® Ё§ гб«®ўЁ©: + * ­ з «м­л©  ¤аҐб Ў®«миҐ Є®­Ґз­®Ј®; + * гЄ § ­­л© ¤Ё Ї §®­ ᮤҐа¦Ёв ­ҐЄ®а४в­л© ­®¬Ґа Ї®ав  + (Є®а४в­лҐ - ®в 0 ¤® 0xFFFF); + * ЇаҐўл襭® ®Ја ­ЁзҐ­ЁҐ ­  ®ЎйҐҐ зЁб«® § аҐ§ҐаўЁа®ў ­­ле ®Ў« б⥩ + - ¤®ЇгбЄ Ґвбп ¬ ЄбЁ¬г¬ 255; + * гЄ § ­­л© ¤Ё Ї §®­ ЇҐаҐбҐЄ Ґвбп б ®¤­Ё¬ Ё§ + а ­ҐҐ § аҐ§ҐаўЁа®ў ­­ле + * ‚ б«гз Ґ ®бў®Ў®¦¤Ґ­Ёп Ї®ав®ў ®иЁЎЄ®© бзЁв Ґвбп Ї®ЇлвЄ  + ®бў®Ў®¦¤Ґ­Ёп ¤Ё Ї §®­ , Є®в®ал© а ­ҐҐ ­Ґ Ўл« 楫ЁЄ®¬ + § аҐ§ҐаўЁа®ў ­ нв®© ¦Ґ дг­ЄжЁҐ© (б в ЄЁ¬Ё ¦Ґ §­ зҐ­Ёп¬Ё ecx,edx). + * ЏаЁ ®Ў­ а㦥­ЁЁ ®иЁЎЄЁ (ў ®Ў®Ёе б«гз пе) ­ЁЄ ЄЁе ¤Ґ©бвўЁ© + ­Ґ Їа®Ё§ў®¤Ёвбп. + * ЏаЁ § Јаг§ЄҐ бЁб⥬  १ҐаўЁагҐв §  б®Ў®© Ї®авл + 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (ўЄ«озЁвҐ«м­®). + * ЏаЁ § ўҐа襭ЁЁ Ї®в®Є   ўв®¬ вЁзҐбЄЁ ®бў®Ў®¦¤ овбп ўбҐ + § аҐ§ҐаўЁа®ў ­­лҐ Ё¬ Ї®авл. + +====================================================================== +================= ”г­ЄжЁп 47 - ўлўҐбвЁ зЁб«® ў ®Є­®. ================= +====================================================================== +Џ а ¬Ґвал: + * eax = 47 - ­®¬Ґа дг­ЄжЁЁ + * ebx = Ї а ¬Ґвал ЇаҐ®Ўа §®ў ­Ёп зЁб«  ў ⥪бв: + * bl = 0 - ecx ᮤҐа¦Ёв зЁб«® + * bl = 1 - ecx ᮤҐа¦Ёв гЄ § вҐ«м ­  dword/qword-зЁб«® + * bh = 0 - ®в®Ўа ¦ вм ў ¤ҐбпвЁз­®© бЁб⥬Ґ бзЁб«Ґ­Ёп + * bh = 1 - ®в®Ўа ¦ вм ў иҐбв­ ¤ж вҐаЁз­®© бЁб⥬Ґ + * bh = 2 - ®в®Ўа ¦ вм ў ¤ў®Ёз­®© бЁб⥬Ґ + * ЎЁвл 16-21 = бЄ®«мЄ® жЁда ®в®Ўа ¦ вм + * ЎЁвл 22-29 § аҐ§ҐаўЁа®ў ­л Ё ¤®«¦­л Ўлвм гбв ­®ў«Ґ­л ў 0 + * ЎЁв 30 гбв ­®ў«Ґ­ = ўлў®¤Ёвм qword (64-ЎЁв­®Ґ зЁб«®); + ЇаЁ н⮬ ¤®«¦­® Ўлвм bl = 1 + * ЎЁв 31 гбв ­®ў«Ґ­ = ­Ґ ўлў®¤Ёвм ўҐ¤гйЁҐ ­г«Ё зЁб«  + * ecx = зЁб«® (ЇаЁ bl=0) Ё«Ё гЄ § вҐ«м (ЇаЁ bl=1) + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] + * esi = 0xX0RRGGBB: + * RR, GG, BB § ¤ ов 梥в + * X = ABnn (ЎЁвл) + * nn = иаЁдв (0/1) + * A ЁЈ­®аЁагҐвбп + * B=1 - § Єа иЁў вм д®­ 梥⮬ edi +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * “Є § ­­ п ¤«Ё­  ­Ґ ¤®«¦­  ЇаҐў®б室Ёвм 60. + * ‚лў®¤Ёвбп а®ў­® гЄ § ­­®Ґ Є®«ЁзҐбвў® жЁда. …б«Ё зЁб«® ¬ «® Ё + ¬®¦Ґв Ўлвм § ЇЁб ­® ¬Ґ­миЁ¬ Є®«ЁзҐбвў®¬ жЁда, ®­® ¤®Ї®«­пҐвбп + ўҐ¤гйЁ¬Ё ­г«п¬Ё; Ґб«Ё зЁб«® ўҐ«ЁЄ® Ё ­Ґ ¬®¦Ґв Ўлвм § ЇЁб ­® + в ЄЁ¬ Є®«ЁзҐбвў®¬ жЁда, "«Ёи­ЁҐ" ўҐ¤гйЁҐ жЁдал ®ЎаҐ§ овбп. + * Џ а ¬Ґвал иаЁдв®ў гЄ § ­л ў ®ЇЁб ­ЁЁ дг­ЄжЁЁ 4 (ўлў®¤  ⥪бв ). + +====================================================================== +======= ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 0 - ЇаЁ¬Ґ­Ёвм ­ бва®©ЄЁ нЄа ­ . ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - § аҐ§ҐаўЁа®ў ­® +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ЇҐаҐаЁб®ўлў Ґв нЄа ­ Ї®б«Ґ Ё§¬Ґ­Ґ­Ёп Ї а ¬Ґва®ў + Ї®¤дг­ЄжЁп¬Ё 1 Ё 2. + * ‚л§®ў дг­ЄжЁЁ ЎҐ§ ЇаҐ¤иҐбвўгойЁе ўл§®ў®ў гЄ § ­­ле Ї®¤дг­ЄжЁ© + ЁЈ­®аЁагҐвбп. + * ‚л§®ў дг­ЄжЁЁ б ­Ґ­г«Ґўл¬ ecx ЁЈ­®аЁагҐвбп. + +====================================================================== +========= ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм бвЁ«м Є­®Ї®Є. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вЁЇ Є­®Ї®Є: + * 0 = Ї«®бЄЁҐ + * 1 = ®Ўкс¬­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®б«Ґ ўл§®ў  ®ЇЁблў Ґ¬®© дг­ЄжЁЁ б«Ґ¤гҐв ЇҐаҐаЁб®ў вм нЄа ­ + Ї®¤дг­ЄжЁҐ© 0. + * ’ЁЇ Є­®Ї®Є ў«ЁпҐв в®«мЄ® ­  Ёе Їа®аЁб®ўЄг дг­ЄжЁҐ© 8. + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм бв ­¤ ав­лҐ жўҐв  ®Є®­. === +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  в Ў«Ёжг 梥⮢ + * edx = а §¬Ґа в Ў«Ёжл 梥⮢ + (¤®«¦Ґ­ Ўлвм 40 Ў ©в ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ) +”®а¬ в в Ў«Ёжл 梥⮢ гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 3. +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®б«Ґ ўл§®ў  ®ЇЁблў Ґ¬®© дг­ЄжЁЁ б«Ґ¤гҐв ЇҐаҐаЁб®ў вм нЄа ­ + Ї®¤дг­ЄжЁҐ© 0. + * ’ Ў«Ёж  бв ­¤ ав­ле 梥⮢ ў«ЁпҐв в®«мЄ® ­  ЇаЁ«®¦Ґ­Ёп, + Є®в®алҐ нвг в Ў«Ёжг пў­л¬ ®Ўа §®¬ Ї®«гз ов (Ї®¤дг­ЄжЁҐ© 3) Ё + ЁбЇ®«м§гов (гЄ §лў п жўҐв  Ё§ ­Ґс ЇаЁ ўл§®ў е дг­ЄжЁ© аЁб®ў ­Ёп). + * ’ Ў«Ёж  бв ­¤ ав­ле 梥⮢ ўе®¤Ёв ў бЄЁ­ Ё гбв ­ ў«Ёў Ґвбп § ­®ў® + ЇаЁ гбв ­®ўЄҐ бЄЁ­  (Ї®¤дг­ЄжЁЁ 8). + * ’ Ў«Ёжг 梥⮢ ¬®¦­® Їа®б¬ ваЁў вм/Ё§¬Ґ­пвм Ё­вҐа ЄвЁў­® б Ї®¬®ймо + ЇаЁ«®¦Ґ­Ёп desktop. + +====================================================================== +===== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 3 - Ї®«гзЁвм бв ­¤ ав­лҐ жўҐв  ®Є®­. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа®¬ edx Ў ©в, + Єг¤  Ўг¤Ґв § ЇЁб ­  в Ў«Ёж  + * edx = а §¬Ґа в Ў«Ёжл 梥⮢ + (¤®«¦Ґ­ Ўлвм 40 Ў ©в ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в в Ў«Ёжл 梥⮢: Є ¦¤л© н«Ґ¬Ґ­в - +dword-§­ зҐ­ЁҐ жўҐв  0x00RRGGBB + * +0: dword: frames - 梥в а ¬ЄЁ + * +4: dword: grab - 梥⠧ Ј®«®ўЄ  + * +8: dword: grab_button - 梥⠪­®ЇЄЁ ­  Ї®«®бҐ § Ј®«®ўЄ  + * +12 = +0xC: dword: grab_button_text - 梥в ⥪бв  ­  Є­®ЇЄҐ + ­  Ї®«®бҐ § Ј®«®ўЄ  + * +16 = +0x10: dword: grab_text - 梥в ⥪бв  ­  § Ј®«®ўЄҐ + * +20 = +0x14: dword: work - 梥в а Ў®зҐ© ®Ў« бвЁ + * +24 = +0x18: dword: work_button - 梥⠪­®ЇЄЁ ў а Ў®зҐ© ®Ў« бвЁ + * +28 = +0x1C: dword: work_button_text - 梥в ⥪бв  ­  Є­®ЇЄҐ + ў а Ў®зҐ© ®Ў« бвЁ + * +32 = +0x20: dword: work_text - 梥в ⥪бв  ў а Ў®зҐ© ®Ў« бвЁ + * +36 = +0x24: dword: work_graph - 梥⠣а дЁЄЁ ў а Ў®зҐ© ®Ў« бвЁ +‡ ¬Ґз ­Ёп: + * ‘вагЄвга  в Ў«Ёжл 梥⮢ ®ЇЁб ­  ў бв ­¤ ав­®¬ ўЄ«оз Ґ¬®¬ д ©«Ґ + macros.inc Ї®¤ ­ §ў ­ЁҐ¬ system_colors; ­ ЇаЁ¬Ґа, ¬®¦­® ЇЁб вм: + sc system_colors ; ®Ўкпў«Ґ­ЁҐ ЇҐаҐ¬Ґ­­®© + ... ; Ј¤Ґ-в® ­ ¤® ўл§ў вм + ; ®ЇЁблў Ґ¬го дг­ЄжЁо б ecx=sc + mov ecx, [sc.work_button_text] ; зЁв Ґ¬ 梥в ⥪бв  + ; ­  Є­®ЇЄҐ ў а Ў®зҐ© ®Ў« бвЁ + * €бЇ®«м§®ў ­ЁҐ/­ҐЁбЇ®«м§®ў ­ЁҐ нвЁе 梥⮢ - ¤Ґ«® ЁбЄ«озЁвҐ«м­® + б ¬®© Їа®Ја ¬¬л. „«п ЁбЇ®«м§®ў ­Ёп ­г¦­® Їа®бв® ЇаЁ ўл§®ўҐ дг­ЄжЁ© + аЁб®ў ­Ёп гЄ §лў вм 梥в, ў§пвл© Ё§ нв®© в Ў«Ёжл. + * ЏаЁ Ё§¬Ґ­Ґ­ЁЁ в Ў«Ёжл бв ­¤ ав­ле 梥⮢ (Ї®¤дг­ЄжЁҐ© 2 б + Ї®б«Ґ¤гойЁ¬ ЇаЁ¬Ґ­Ґ­ЁҐ¬ Ё§¬Ґ­Ґ­Ё© Ї®¤дг­ЄжЁҐ© 0 Ё«Ё + ЇаЁ гбв ­®ўЄҐ бЄЁ­  Ї®¤дг­ЄжЁҐ© 8) ўбҐ¬ ®Є­ ¬ Ї®бл« Ґвбп б®®ЎйҐ­ЁҐ + ® ­Ґ®Ўе®¤Ё¬®бвЁ ЇҐаҐаЁб®ўЄЁ (б®ЎлвЁҐ б Є®¤®¬ 1). + * ‘в ­¤ ав­лҐ жўҐв  ¬®¦­® Їа®б¬ ваЁў вм/Ё§¬Ґ­пвм Ё­вҐа ЄвЁў­® + б Ї®¬®ймо ЇаЁ«®¦Ґ­Ёп desktop. + +====================================================================== +========== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм ўлб®вг бЄЁ­ . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ўлб®в  бЄЁ­  +‡ ¬Ґз ­Ёп: + * ‚лб®в®© бЄЁ­  Ї® ®ЇаҐ¤Ґ«Ґ­Ёо бзЁв Ґвбп ўлб®в  § Ј®«®ўЄ  ®Є®­, + ЁбЇ®«м§гойЁе бЄЁ­. + * ‘¬®ваЁ в Є¦Ґ ®Ўйго бвагЄвгаг ®Є­  ў ®ЇЁб ­ЁЁ дг­ЄжЁЁ 0. + +====================================================================== +===== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 5 - Ї®«гзЁвм а Ў®зго ®Ў« бвм нЄа ­ . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +‡ ¬Ґз ­Ёп: + * ђ Ў®з п ®Ў« бвм нЄа ­  ®ЇаҐ¤Ґ«пҐв Ї®«®¦Ґ­ЁҐ Ё Є®®а¤Ё­ вл + ¬ ЄбЁ¬Ё§Ёа®ў ­­®Ј® ®Є­ . + * ђ Ў®з п ®Ў« бвм нЄа ­  ЇаЁ ­®а¬ «м­®© а Ў®вҐ Ґбвм ўҐбм нЄа ­ + §  ўлзҐв®¬ Ї ­Ґ«Ё (@panel). + * (left,top) - Є®®а¤Ё­ вл «Ґў®Ј® ўҐае­ҐЈ® гЈ« , + (right,bottom) - Є®®а¤Ё­ вл Їа ў®Ј® ­Ё¦­ҐЈ®. + ’ ЄЁ¬ ®Ўа §®¬, а §¬Ґа а Ў®зҐ© ®Ў« бвЁ Ї® ®бЁ x ®ЇаҐ¤Ґ«пҐвбп + д®а¬г«®© right-left+1, Ї® ®бЁ y - д®а¬г«®© bottom-right+1. + * ‘¬®ваЁ в Є¦Ґ дг­ЄжЁо 14, + Ї®§ў®«пойго ®ЇаҐ¤Ґ«Ёвм а §¬Ґал ўбҐЈ® нЄа ­ . + * …бвм Ї а­ п дг­ЄжЁп гбв ­®ўЄЁ а Ў®зҐ© ®Ў« бвЁ - Ї®¤дг­ЄжЁп 6. + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 6 - гбв ­®ўЁвм а Ў®зго ®Ў« бвм нЄа ­ . === +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = [left]*65536 + [right] + * edx = [top]*65536 + [bottom] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ђ Ў®з п ®Ў« бвм нЄа ­  ®ЇаҐ¤Ґ«пҐв Ї®«®¦Ґ­ЁҐ Ё Є®®а¤Ё­ вл + ¬ ЄбЁ¬Ё§Ёа®ў ­­®Ј® ®Є­ . + * ќв  дг­ЄжЁп ЁбЇ®«м§гҐвбп в®«мЄ® ЇаЁ«®¦Ґ­ЁҐ¬ @panel, + гбв ­ ў«Ёў ойЁ¬ а Ў®зҐ© ®Ў« бвмо ўҐбм нЄа ­ §  ўлзҐв®¬ Ї ­Ґ«Ё. + * (left,top) - Є®®а¤Ё­ вл «Ґў®Ј® ўҐае­ҐЈ® гЈ« , + (right,bottom) - Є®®а¤Ё­ вл Їа ў®Ј® ­Ё¦­ҐЈ®. + ’ ЄЁ¬ ®Ўа §®¬, а §¬Ґа а Ў®зҐ© ®Ў« бвЁ Ї® ®бЁ x ®ЇаҐ¤Ґ«пҐвбп + д®а¬г«®© right-left+1, Ї® ®бЁ y - д®а¬г«®© bottom-right+1. + * …б«Ё left>=right, в® x-Є®®а¤Ё­ вл а Ў®зҐ© ®Ў« бвЁ ­Ґ Ё§¬Ґ­повбп. + …б«Ё left<0, в® left ­Ґ гбв ­ ў«Ёў Ґвбп. …б«Ё right Ў®«миҐ + Ё«Ё а ў­® иЁаЁ­л нЄа ­ , в® right ­Ґ гбв ­ ў«Ёў Ґвбп. + Ђ­ «®ЈЁз­® Ї® ®бЁ y. + * ‘¬®ваЁ в Є¦Ґ дг­ЄжЁо 14, + Ї®§ў®«пойго ®ЇаҐ¤Ґ«Ёвм а §¬Ґал ўбҐЈ® нЄа ­ . + * …бвм Ї а­ п дг­ЄжЁп Ї®«г祭Ёп а Ў®зҐ© ®Ў« бвЁ - + Ї®¤дг­ЄжЁп 5. + * ќв  дг­ЄжЁп  ўв®¬ вЁзҐбЄЁ ЇҐаҐаЁб®ўлў Ґв нЄа ­, Ї® 室㠤Ґ«  + ®Ў­®ў«пҐв Є®®а¤Ё­ вл Ё а §¬Ґал ¬ ЄбЁ¬Ё§Ёа®ў ­­ле ®Є®­. + ‚ᥠ®Є­  Ё§ўҐй овбп ® ­Ґ®Ўе®¤Ё¬®бвЁ ЇҐаҐаЁб®ўЄЁ (б®ЎлвЁҐ 1). + +====================================================================== +====================== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 7 ====================== +============ Џ®«гзЁвм ®Ў« бвм бЄЁ­  ¤«п ⥪бв  § Ј®«®ўЄ . ============ +====================================================================== +‚®§ўа й Ґв ®Ў« бвм § Ј®«®ўЄ  ®Є­  б® бЄЁ­®¬, ЇаҐ¤­ §­ зҐ­­го +¤«п ўлў®¤  ⥪бв  § Ј®«®ўЄ . +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +‡ ¬Ґз ­Ёп: + * €бЇ®«м§®ў ­ЁҐ/­ҐЁбЇ®«м§®ў ­ЁҐ нв®© дг­ЄжЁЁ - + «Ёз­®Ґ ¤Ґ«® ЇаЁ«®¦Ґ­Ёп. + * ђҐЄ®¬Ґ­¤гҐвбп гзЁвлў вм §­ зҐ­Ёп, ў®§ўа й Ґ¬лҐ нв®© дг­ЄжЁҐ©, + ЇаЁ ўлЎ®аҐ ¬Ґбв  ¤«п аЁб®ў ­Ёп ⥪бв  § Ј®«®ўЄ  (дг­ЄжЁҐ© 4) Ё«Ё + Є Є®Ј®-­ЁЎг¤м § ¬Ґ­ЁвҐ«п ⥪бв  § Ј®«®ўЄ  + (Ї® гᬮв७Ёо ЇаЁ«®¦Ґ­Ёп). + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 8 - гбв ­®ўЁвм ЁбЇ®«м§гҐ¬л© бЄЁ­ ®Є®­. === +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  Ё¬п д ©«  бЄЁ­  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ г¤ «®бм § Јаг§Ёвм д ©« + * eax = 2 - д ©« ­Ґ пў«пҐвбп д ©«®¬ бЄЁ­  +‡ ¬Ґз ­Ёп: + * ЏаЁ гбЇҐи­®© § Јаг§ЄҐ бЄЁ­  ўбҐ ®Є­  Ё§ўҐй овбп ® ­Ґ®Ўе®¤Ё¬®бвЁ + ЇҐаҐаЁб®ўЄЁ (б®ЎлвЁҐ 1). + * ЏаЁ § Јаг§ЄҐ бЁб⥬  бзЁвлў Ґв бЄЁ­ Ё§ д ©«  default.skn + ­  а ¬¤ЁбЄҐ. + * Џ®«м§®ў вҐ«м ¬®¦Ґв Ё§¬Ґ­пвм бЄЁ­ бв вЁзҐбЄЁ, б®§¤ ў бў®© + default.skn, Ё«Ё ¤Ё­ ¬ЁзҐбЄЁ б Ї®¬®ймо ЇаЁ«®¦Ґ­Ёп desktop. + +====================================================================== +============ ”г­ЄжЁп 49 - Advanced Power Management (APM). =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 49 - ­®¬Ґа дг­ЄжЁЁ + * dx = ­®¬Ґа дг­ЄжЁЁ APM ( ­ «®Ј ax ў бЇҐжЁдЁЄ жЁЁ) + * bx, cx = Ї а ¬Ґвал дг­ЄжЁЁ APM +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * 16-ЎЁв­лҐ ॣЁбвал ax, bx, cx, dx, si, di Ё д« Ј CF + гбв ­®ў«Ґ­л ў ᮮ⢥вбвўЁЁ б® бЇҐжЁдЁЄ жЁҐ© APM + * бв аиЁҐ Ї®«®ўЁ­л 32-ЎЁв­ле ॣЁбва®ў eax, ebx, ecx, + edx, esi, edi а §аги овбп +‡ ¬Ґз ­Ёп: + * ‘ЇҐжЁдЁЄ жЁп APM 1.2 ®ЇЁблў Ґвбп ў ¤®Єг¬Ґ­вҐ + "Advanced Power Management (APM) BIOS Specification" + (Revision 1.2), ¤®бвгЇ­®¬ ­  + http://www.microsoft.com/whdc/archive/amp_12.mspx; + Єа®¬Ґ в®Ј®, ®­  ўЄ«о祭  ў Ё§ўҐбв­л© Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). + +====================================================================== +================= ”г­ЄжЁп 50 - гбв ­®ўЄ  д®а¬л ®Є­ . ================= +====================================================================== +ЋЎлз­лҐ ®Є­  ЇаҐ¤бв ў«пов б®Ў®© Їаאַ㣮«м­ЁЄЁ. ‘ Ї®¬®ймо нв®© дг­ЄжЁЁ +®Є­г ¬®¦­® ЇаЁ¤ вм Їа®Ё§ў®«м­го д®а¬г. ”®а¬  § ¤ свбп ­ Ў®а®¬ в®зҐЄ +ў­гваЁ ®Ўа ¬«по饣® Їаאַ㣮«м­ЁЄ , ЇаЁ­ ¤«Ґ¦ йЁе ®Є­г. Џ®«®¦Ґ­ЁҐ Ё +а §¬Ґал ®Ўа ¬«по饣® Їаאַ㣮«м­ЁЄ  § ¤ овбп дг­ЄжЁҐ© 0 Ё Ё§¬Ґ­повбп +дг­ЄжЁҐ© 67. + +--------------- “бв ­®ўЄ  ¤ ­­ле б Ё­д®а¬ жЁҐ© ® д®а¬Ґ --------------- +Џ а ¬Ґвал: + * eax = 50 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ д®а¬л (¬ ббЁў Ў ©в 0/1) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------------------ “бв ­®ўЄ  ¬ бив Ў  ¤ ­­ле д®а¬л ------------------- +Џ а ¬Ґвал: + * eax = 50 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx § ¤ св ¬ бив Ў: Є ¦¤л© Ў ©в ¤ ­­ле ®ЇаҐ¤Ґ«пҐв + (2^scale)*(2^scale) ЇЁЄбҐ«Ґ© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Њ бив Ў Ї® 㬮«з ­Ёо а ўҐ­ 0 (¬ бив ЎЁагойЁ© ¬­®¦ЁвҐ«м 1). …б«Ё ў + ¤ ­­ле д®а¬л ®¤Ё­ Ў ©в ᮮ⢥вбвўгҐв ®¤­®¬г ЇЁЄбҐ«о, в® ¬ бив Ў + ¬®¦­® ­Ґ гбв ­ ў«Ёў вм. + * ЋЎ®§­ зЁ¬ xsize = иЁаЁ­  ®Є­  (ў ЇЁЄбҐ«пе), ysize = ўлб®в ; + ®Ўа вЁвҐ ў­Ё¬ ­ЁҐ, зв® ®­Ё ­  Ґ¤Ё­Ёжг Ў®«миҐ, 祬 гбв ­ ў«Ёў Ґ¬лҐ + дг­ЄжЁп¬Ё 0, 67. + * Џ® ®ЇаҐ¤Ґ«Ґ­Ёо ¬ бив Ў  xsize Ё ysize ¤®«¦­л ¤Ґ«Ёвмбп ­  2^scale. + * Ѓ ©в ¤ ­­ле Ї® ᬥ饭Ёо a ¤®«¦Ґ­ Ўлвм 0/1 Ё + ®ЇаҐ¤Ґ«пҐв ЇаЁ­ ¤«Ґ¦­®бвм ®Є­г Єў ¤а в  б® бв®а®­®© 2^scale + (ЇаЁ scale=0 Ї®«гз Ґ¬ ЇЁЄбҐ«м) Ё Є®®а¤Ё­ в ¬Ё «Ґў®Ј® ўҐае­ҐЈ® гЈ«  + (a mod (xsize shr scale), a div (xsize shr scale)) + * ђ §¬Ґа ¤ ­­ле: (xsize shr scale)*(ysize shr scale). + * „ ­­лҐ ¤®«¦­л ЇаЁбгвбвў®ў вм ў Ї ¬пвЁ Ё ­Ґ ¬Ґ­пвмбп + Ї®б«Ґ гбв ­®ўЄЁ д®а¬л. + * ‘Ёб⥬  Їа®б¬ ваЁў Ґв ¤ ­­лҐ ® д®а¬Ґ ЇаЁ Є ¦¤®© ЇҐаҐаЁб®ўЄҐ ®Є­  + дг­ЄжЁҐ© 0. + * ‚л§®ў Ї®¤дг­ЄжЁЁ 0 б ­г«Ґўл¬ гЄ § вҐ«Ґ¬ ЇаЁў®¤Ёв Є ў®§ўа вг + Є Їаאַ㣮«м­®© д®а¬Ґ. + +====================================================================== +===================== ”г­ЄжЁп 51 - б®§¤ вм Ї®в®Є. ==================== +====================================================================== +Џ а ¬Ґвал: + * eax = 51 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - Ґ¤Ё­б⢥­­ п Ї®¤дг­ЄжЁп + * ecx =  ¤аҐб в®зЄЁ ўе®¤  Ї®в®Є  (­ з «м­л© eip) + * edx = гЄ § вҐ«м бвнЄ  Ї®в®Є  (­ з «м­л© esp) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  (ў бЁб⥬Ґ б«ЁиЄ®¬ ¬­®Ј® Ї®в®Є®ў) + * Ё­ зҐ eax = TID - Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + +====================================================================== += ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм Є®­дЁЈга жЁо бҐвҐў®Ј® ¤а ©ўҐа . +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¤ў®©­®Ґ б«®ў® Є®­дЁЈга жЁЁ +‡ ¬Ґз ­Ёп: + * ‘«®ў® Є®­дЁЈга жЁЁ ¬®¦­® гбв ­®ўЁвм Ї®¤дг­ЄжЁҐ© 2. + * џ¤а® ­Ґ ЁбЇ®«м§гҐв ᮮ⢥вбвўгойго ЇҐаҐ¬Ґ­­го. + –Ґ­­®бвм нв®© ЇҐаҐ¬Ґ­­®© Ё а Ў®в ойЁе б ­Ґ© Ї®¤дг­ЄжЁ© 0 Ё 2 + ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©. + +====================================================================== +======= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм «®Є «м­л© IP- ¤аҐб. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = IP- ¤аҐб (4 Ў ©в ) +‡ ¬Ґз ­Ёп: + * ‹®Є «м­л© IP- ¤аҐб гбв ­ ў«Ёў Ґвбп Ї®¤дг­ЄжЁҐ© 3. + +====================================================================== + ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм Є®­дЁЈга жЁо бҐвҐў®Ј® ¤а ©ўҐа . +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ¤ў®©­®Ґ б«®ў® Є®­дЁЈга жЁЁ; Ґб«Ё ¬« ¤иЁҐ 7 ЎЁв ®Ўа §гов + зЁб«® 3, нв® ў®бЇаЁ­Ё¬ Ґвбп Є Є § Їа®б ­  [ЇҐаҐ-]Ё­ЁжЁ «Ё§ жЁо + Ethernet-Є авл, ў Їа®вЁў­®¬ б«гз Ґ Ethernet ўлЄ«оз Ґвбп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ­Ґ § Їа®иҐ­ Ethernet-Ё­вҐа䥩б, в® ў®§ўа й Ґвбп eax=2, + ­® нв® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў Ўг¤гйЁе ўҐабЁпе п¤а  + * Ґб«Ё § Їа®иҐ­ Ethernet-Ё­вҐа䥩б, в® eax=0 ®§­ з Ґв ®иЁЎЄг + (®вбгвбвўЁҐ Ethernet-Є авл),   ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ - гбЇҐе +‡ ¬Ґз ­Ёп: + * ‘«®ў® Є®­дЁЈга жЁЁ ¬®¦­® Їа®зЁв вм Ї®¤дг­ЄжЁҐ© 0. + * џ¤а® ­Ґ ЁбЇ®«м§гҐв ᮮ⢥вбвўгойго ЇҐаҐ¬Ґ­­го. + –Ґ­­®бвм нв®© ЇҐаҐ¬Ґ­­®©, Ї®¤дг­ЄжЁЁ 0 Ё з бвЁ Ї®¤дг­ЄжЁЁ 2, + гбв ­ ў«Ёў о饩 нвг ЇҐаҐ¬Ґ­­го, ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©. + +====================================================================== +====== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм «®Є «м­л© IP- ¤аҐб. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = IP- ¤аҐб (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=3, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ўҐабЁпе +‡ ¬Ґз ­Ёп: + * ‹®Є «м­л© IP- ¤аҐб ¬®¦­® Ї®«гзЁвм Ї®¤дг­ЄжЁҐ© 1. + +====================================================================== += ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 6 - ¤®Ў ўЁвм ¤ ­­лҐ ў б⥪ ўе®¤­®© ®зҐаҐ¤Ё. = +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * edx = а §¬Ґа ¤ ­­ле + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  + * eax = 0 - гбЇҐи­® +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп ЇаҐ¤­ §­ зҐ­  в®«мЄ® ¤«п ¬Ґ¤«Ґ­­ле бҐвҐўле ¤а ©ўҐа®ў + (PPP, SLIP). + * ђ §¬Ґа ¤ ­­ле ­Ґ ¤®«¦Ґ­ ЇаҐў®б室Ёвм 1500 Ў ©в, + е®вп Їа®ўҐа®Є Є®а४⭮бвЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +====================== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 8 ====================== +============= Џа®зЁв вм ¤ ­­лҐ Ё§ бҐвҐў®© ®зҐаҐ¤Ё ўлў®¤ . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * esi = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа®¬ 1500 Ў ©в +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Їа®зЁв ­­ле Ў ©в (ў ⥪г饩 ॠ«Ё§ жЁЁ + «ЁЎ® 0 = ­Ґв ¤ ­­ле, «ЁЎ® 1500) + * ¤ ­­лҐ бЄ®ЇЁа®ў ­л ў ЎгдҐа +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп ЇаҐ¤­ §­ зҐ­  в®«мЄ® ¤«п ¬Ґ¤«Ґ­­ле бҐвҐўле ¤а ©ўҐа®ў + (PPP, SLIP). + +====================================================================== +=========== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 9 - Ї®«гзЁвм gateway IP. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = gateway IP (4 Ў ©в ) + +====================================================================== +========= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 10 - Ї®«гзЁвм ¬ бЄг Ї®¤бҐвЁ. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¬ бЄ  Ї®¤бҐвЁ + +====================================================================== +========= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 11 - гбв ­®ўЁвм gateway IP. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = gateway IP (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=11, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ॠ«Ё§ жЁпе + +====================================================================== +======== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 12 - гбв ­®ўЁвм ¬ бЄг Ї®¤бҐвЁ. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ¬ бЄ  Ї®¤бҐвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=12, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ўҐабЁпе + +====================================================================== +============ ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 13 - Ї®«гзЁвм DNS IP. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = DNS IP (4 Ў ©в ) + +====================================================================== +=========== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 14 - гбв ­®ўЁвм DNS IP. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 14 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = DNS IP (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=14, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў б«Ґ¤гойЁе ўҐабЁпе + +====================================================================== +====== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 15 - Ї®«гзЁвм «®Є «м­л© MAC- ¤аҐб. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 15 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - зЁв вм ЇҐаўлҐ 4 Ў ©в , + ecx = 4 - зЁв вм Ї®б«Ґ¤­ЁҐ 2 Ў ©в  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ¤«п ecx=0: eax = ЇҐаўлҐ 4 Ў ©в  MAC- ¤аҐб  + * ¤«п ecx=4: ax = Ї®б«Ґ¤­ЁҐ 2 Ў ©в  MAC- ¤аҐб , + бв аи п Ї®«®ўЁ­  eax а §аги Ґвбп + * ¤«п ¤агЈЁе ecx: eax = -1 Є Є ЇаЁ§­ Є ®иЁЎЄЁ + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 0 - ®вЄалвм UDP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®), + ecx = 0 - ЇаҐ¤®бв ўЁвм бЁб⥬Ґ ўлЎ®а «®Є «м­®Ј® Ї®ав  + * edx = г¤ «с­­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * esi = г¤ «с­­л© IP +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 = 0xFFFFFFFF - ®иЁЎЄ ; ebx а §аги Ґвбп + * eax = ен­¤« б®ЄҐв  (­ҐЄ®в®а®Ґ зЁб«®, ®¤­®§­ з­® Ё¤Ґ­вЁдЁжЁаго饥 + б®ЄҐв Ё Ё¬Ґо饥 б¬лб« в®«мЄ® ¤«п бЁб⥬л) - гбЇҐи­®; + ebx а §аги Ґвбп + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 1 - § Єалвм UDP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ­ҐўҐа­л© ен­¤« + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ § Єалў Ґв  ўв®¬ вЁзҐбЄЁ ўбҐ б®ЄҐвл Ї®в®Є  + ЇаЁ ҐЈ® § ўҐа襭ЁЁ. ‚ з бв­®бвЁ, ­Ґ б«Ґ¤гҐв ЇаЁЎЁў вм Ї®в®Є + б Єг祩 ®вЄалвле б®ЄҐв®ў - Ўг¤Ґв гвҐзЄ  аҐбгаб®ў. + +====================================================================== +============== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 2 - ®Їа®б б®ЄҐв . ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Ї®«г祭­ле Ў ©в, 0 ¤«п ­ҐўҐа­®Ј® ен­¤«  + * ebx а §аги Ґвбп + +====================================================================== +======== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 3 - Їа®зЁв вм Ў ©в Ё§ б®ЄҐв . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ­Ґв ЇаЁ­пвле ¤ ­­ле Ё«Ё гЄ § ­ ­ҐўҐа­л© ен­¤«: + eax=0, bl=0, Їа®зЁҐ Ў ©вл ebx а §аги овбп + * Ґб«Ё Ўл«Ё ЇаЁ­пвлҐ ¤ ­­лҐ: eax=зЁб«® ®бв ўиЁебп Ў ©в + (ў®§¬®¦­®, 0), bl=Їа®зЁв ­­л© Ў ©в, Їа®зЁҐ Ў ©вл ebx а §аги овбп + +====================================================================== +========== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 4 - § ЇЁб вм ў UDP-б®ЄҐв. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0xffffffff - ®иЁЎЄ  (­ҐўҐа­л© ен­¤« Ё«Ё ­Ґ¤®бв в®з­® Ї ¬пвЁ) + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-28, е®вп + ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 5 - ®вЄалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®), + ecx = 0 - ЇаҐ¤®бв ўЁвм бЁб⥬Ґ ўлЎ®а «®Є «м­®Ј® Ї®ав  + * edx = г¤ «с­­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * esi = г¤ «с­­л© IP + * edi = ०Ё¬ ®вЄалвЁп: SOCKET_PASSIVE=0 Ё«Ё SOCKET_ACTIVE=1 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 = 0xFFFFFFFF - ®иЁЎЄ ; ebx а §аги Ґвбп + * eax = ен­¤« б®ЄҐв  (­ҐЄ®в®а®Ґ зЁб«®, ®¤­®§­ з­® Ё¤Ґ­вЁдЁжЁаго饥 + б®ЄҐв Ё Ё¬Ґо饥 б¬лб« в®«мЄ® ¤«п бЁб⥬л) - гбЇҐи­®; + ebx а §аги Ґвбп + +====================================================================== +====== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 6 - Ї®«гзЁвм б®бв®п­ЁҐ TCP-б®ЄҐв . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 ¤«п ­ҐўҐа­®Ј® б®ЄҐв  Ё«Ё бв вгб: ®¤­® Ё§ + * TCB_LISTEN = 1 + * TCB_SYN_SENT = 2 + * TCB_SYN_RECEIVED = 3 + * TCB_ESTABLISHED = 4 + * TCB_FIN_WAIT_1 = 5 + * TCB_FIN_WAIT_2 = 6 + * TCB_CLOSE_WAIT = 7 + * TCB_CLOSING = 8 + * TCB_LAST_ASK = 9 + * TCB_TIME_WAIT = 10 + * TCB_CLOSED = 11 + * ebx а §аги Ґвбп + +====================================================================== +========== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў TCP-б®ЄҐв. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0xffffffff - ®иЁЎЄ  (­ҐўҐа­л© ен­¤« Ё«Ё ­Ґ¤®бв в®з­® Ї ¬пвЁ) + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-40, + е®вп ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 8 - § Єалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  (­ҐўҐа­л© ен­¤« Ё«Ё + ­Ґ¤®бв в®з­® Ї ¬пвЁ ¤«п Ї ЄҐв  § ЄалвЁп б®ЄҐв ) + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ § Єалў Ґв  ўв®¬ вЁзҐбЄЁ ўбҐ б®ЄҐвл Ї®в®Є  + ЇаЁ ҐЈ® § ўҐа襭ЁЁ. ‚ з бв­®бвЁ, ­Ґ б«Ґ¤гҐв ЇаЁЎЁў вм Ї®в®Є + б Єг祩 ®вЄалвле б®ЄҐв®ў - Ўг¤Ґв гвҐзЄ  аҐбгаб®ў. + +====================================================================== +== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 9 - Їа®ўҐаЁвм, бў®Ў®¤Ґ­ «Ё «®Є «м­л© Ї®ав. = +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа «®Є «м­®Ј® Ї®ав  (ЁбЇ®«м§говбп в®«мЄ® ¬« ¤иЁҐ 16 ЎЁв) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - Ї®ав ЁбЇ®«м§гҐвбп + * eax = 1 - Ї®ав бў®Ў®¤Ґ­ + * ebx а §аги Ґвбп + +====================================================================== +==== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 10 - Ї®«гзЁвм бв вгб Є ЎҐ«п Ethernet. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * al = -1 - ¤а ©ўҐа бҐвҐў®© Є авл ­Ґ § Ја㦥­ Ё«Ё + ­Ґ Ї®¤¤Ґа¦Ёў Ґв нвг дг­ЄжЁо + * al = 0 - Є ЎҐ«м ­Ґ Ї®¤Є«озс­ + * al = 1 - Є ЎҐ«м Ї®¤Є«озс­ + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп п¤а  Ї®¤¤Ґа¦Ёў Ґв нвг дг­ЄжЁо + в®«мЄ® ¤«п бҐвҐўле Є ав RTL8139. + +====================================================================== +==== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 11 - Їа®зЁв вм ¤ ­­лҐ бҐвҐў®Ј® б⥪ . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  + * edx = гЄ § вҐ«м ­  ЎгдҐа + * esi = зЁб«® Ў ©в ¤«п з⥭Ёп; + * esi = 0 - зЁв вм ўбҐ ¤ ­­лҐ (¬ ЄбЁ¬г¬ 4096 Ў ©в) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Їа®зЁв ­­ле Ў ©в (0 ЇаЁ ­ҐўҐа­®¬ ен­¤«Ґ) + * ebx а §аги Ґвбп + +====================================================================== + ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 255 - ®в« ¤®з­ п Ё­д®а¬ жЁп бҐвҐў®Ј® ¤а ©ўҐа . +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 255 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вЁЇ § Їа иЁў Ґ¬®© Ё­д®а¬ жЁЁ (ᬮваЁ ­Ё¦Ґ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = § Їа®иҐ­­ п Ё­д®а¬ жЁп + * ebx а §аги Ґвбп +‚®§¬®¦­лҐ §­ зҐ­Ёп ecx: + * 100: ¤«Ё­  ®зҐаҐ¤Ё 0 (empty queue) + * 101: ¤«Ё­  ®зҐаҐ¤Ё 1 (ip-out queue) + * 102: ¤«Ё­  ®зҐаҐ¤Ё 2 (ip-in queue) + * 103: ¤«Ё­  ®зҐаҐ¤Ё 3 (net1out queue) + * 200: зЁб«® н«Ґ¬Ґ­в®ў ў в Ў«ЁжҐ ARP + * 201: а §¬Ґа в Ў«Ёжл ARP (ў н«Ґ¬Ґ­в е) (20 ў ⥪г饩 ўҐабЁЁ) + * 202: Їа®зЁв вм н«Ґ¬Ґ­в edx в Ў«Ёжл ARP ў® ўаҐ¬Ґ­­л© ЎгдҐа, ®вЄг¤  + ЎҐагв Ё­д®а¬ жЁо 5 Ї®б«Ґ¤гойЁе вЁЇ®ў; + ў н⮬ б«гз Ґ eax ­Ґ®ЇаҐ¤Ґ«с­ + * 203: IP- ¤аҐб, § Ї®¬­Ґ­­л© вЁЇ®¬ 202 + * 204: бв а襥 dword MAC- ¤аҐб , § Ї®¬­Ґ­­®Ј® вЁЇ®¬ 202 + * 205: ¬« ¤иҐҐ word MAC- ¤аҐб , § Ї®¬­Ґ­­®Ј® вЁЇ®¬ 202 + * 206: б«®ў® бв вгб , § Ї®¬­Ґ­­®Ґ вЁЇ®¬ 202 + * 207: б«®ў® ttl, § Ї®¬­Ґ­­®Ґ вЁЇ®¬ 202 + * 2: ®ЎйҐҐ зЁб«® Ї®«г祭­ле IP-Ї ЄҐв®ў + * 3: ®ЎйҐҐ зЁб«® ЇҐаҐ¤ ­­ле IP-Ї ЄҐв®ў + * 4: ®ЎйҐҐ зЁб«® б¤ ¬Ї«Ґ­­ле Ї®«г祭­ле Ї ЄҐв®ў + * 5: ®ЎйҐҐ зЁб«® Ї®«г祭­ле ARP-Ї ЄҐв®ў + * 6: бв вгб ¤а ©ўҐа  Ї ЄҐв®ў, 0=­Ґ ЄвЁўҐ­, + ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ= ЄвЁўҐ­ + +====================================================================== +====================== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 55 ===================== +========== Ќ з вм Їа®ЁЈалў вм ¤ ­­лҐ ­  ўбв஥­­®¬ бЇЁЄҐаҐ. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 55 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 55 - ®иЁЎЄ  (бЇЁЄҐа ®вЄ«озс­ Ё«Ё § ­пв) +„ ­­лҐ - нв® ¬ ббЁў н«Ґ¬Ґ­в®ў ЇҐаҐ¬Ґ­­®© ¤«Ё­л. +”®а¬ в Є ¦¤®Ј® н«Ґ¬Ґ­в  ®ЇаҐ¤Ґ«пҐвбп ЇҐаўл¬ Ў ©в®¬: + * 0 = Є®­Ґж ¤ ­­ле + * 1..0x80 = § ¤ св ¤«ЁвҐ«м­®бвм §ўгз ­Ёп ў б®вле ¤®«пе ᥪ㭤л + ­®вл, ®ЇаҐ¤Ґ«пҐ¬®© ­ҐЇ®б।б⢥­­л¬ §­ зҐ­ЁҐ¬ з бв®вл + * б«Ґ¤го饥 б«®ў® (2 Ў ©в ) ᮤҐа¦Ёв ¤Ґ«ЁвҐ«м з бв®вл; + з бв®в  ®ЇаҐ¤Ґ«пҐвбп Є Є 1193180/divider + * 0x81 = invalid + * 0x82..0xFF = ­®в , ®ЇаҐ¤Ґ«пҐ¬ п ®Єв ў®© Ё ­®¬Ґа®¬: + * ¤«ЁвҐ«м­®бвм ў б®вле ¤®«пе ᥪ㭤л = (ЇҐаўл© Ў ©в)-0x81 + * ЇаЁбгвбвўгҐв Ґйс ®¤Ё­ Ў ©в; + * (ўв®а®© Ў ©в)=0xFF - Ї г§  + * Ё­ зҐ ®­ Ё¬ҐҐв ўЁ¤ a*0x10+b, Ј¤Ґ b=­®¬Ґа ­®вл ў ®Єв ўҐ ®в 1 + ¤® 12, a=­®¬Ґа ®Єв ўл (бзЁв п б 0) +‡ ¬Ґз ­Ёп: + * ЏЁй ­ЁҐ бЇЁЄҐа®¬ ¬®¦Ґв Ўлвм § ЇаҐйҐ­®/а §аҐиҐ­® Ї®¤дг­ЄжЁҐ© 8 + дг­ЄжЁЁ 18. + * ”г­ЄжЁп ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, б®®ЎйЁў Єг¤  б«Ґ¤гҐв Ё­д®а¬ жЁо + ® § Їа®бҐ. ‘ ¬® Їа®ЁЈалў ­ЁҐ Ё¤св ­Ґ§ ўЁбЁ¬® ®в Їа®Ја ¬¬л. + * „ ­­лҐ ¤®«¦­л б®еа ­пвмбп ў Ї ¬пвЁ Ї® Єа ©­Ґ© ¬ҐаҐ + ¤® Є®­ж  Їа®ЁЈалў ­Ёп. + +====================================================================== +======================= ”г­ЄжЁп 57 - PCI BIOS. ======================= +====================================================================== +Џ а ¬Ґвал: + * eax = 57 - ­®¬Ґа дг­ЄжЁЁ + * ebp ᮮ⢥вбвўгҐв ॣЁбваг al ў бЇҐжЁдЁЄ жЁЁ PCI BIOS + * ®бв «м­лҐ ॣЁбвал - Ї® бЇҐжЁдЁЄ жЁЁ PCI BIOS +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * CF ­Ґ ®ЇаҐ¤Ґ«с­ + * ®бв «м­лҐ ॣЁбвал - Ї® бЇҐжЁдЁЄ жЁЁ PCI BIOS +‡ ¬Ґз ­Ёп: + * Њ­®ЈЁе १г«мв в®ў нв®© дг­ЄжЁЁ ¬®¦­® в Є¦Ґ ¤®ЎЁвмбп ўл§®ў®¬ + ᮮ⢥вбвўгойЁе Ї®¤дг­ЄжЁ© дг­ЄжЁЁ 62. + * ”г­ЄжЁп ўл§лў Ґв а биЁаҐ­ЁҐ PCI32 BIOS, ¤®Єг¬Ґ­вЁа®ў ­­®Ґ, + ­ ЇаЁ¬Ґа, ў http://alpha1.dyns.net/files/PCI/bios21.pdf. + * …б«Ё BIOS ­Ґ Ї®¤¤Ґа¦Ёў Ґв нв® а биЁаҐ­ЁҐ, Ї®ўҐ¤Ґ­ЁҐ дг­ЄжЁЁ + н¬г«ЁагҐвбп (зҐаҐ§  ­ «®ЈЁ Ї®¤дг­ЄжЁ© дг­ЄжЁЁ 62 ०Ё¬  п¤а ). + +====================================================================== +============== ”г­ЄжЁп 58 - а Ў®в  б д ©«®ў®© бЁб⥬®©. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 58 + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®; Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ў § ўЁбЁ¬®бвЁ ®в Ї®¤дг­ЄжЁЁ ¬®¦Ґв ў®§ўа й вмбп §­ зҐ­ЁҐ Ё + ў ¤агЈЁе ॣЁбва е +ЋЎйЁ© д®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ­®¬Ґа Ў«®Є  + * +8: dword: а §¬Ґа + * +12 = +0xC: dword: гЄ § вҐ«м ­  ¤ ­­лҐ + * +16 = +0x10: dword: гЄ § вҐ«м ­  Ї ¬пвм ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: n db: ASCIIZ-бва®Є  б Ё¬Ґ­Ґ¬ д ©«  +“в®з­Ґ­Ёп - ў ¤®Єг¬Ґ­в жЁЁ ­  ᮮ⢥вбвўгойго Ї®¤дг­ЄжЁо. +€¬п д ©«  ­Ґзгўб⢨⥫쭮 Є ॣЁбваг « вЁ­бЄЁе ЎгЄў, +агббЄЁҐ ЎгЄўл ¤®«¦­л Ўлвм § Ј« ў­л¬Ё. +”®а¬ в Ё¬Ґ­Ё д ©« : +/base/number/dir1/dir2/.../dirn/file, +Ј¤Ґ /base/number Ё¤Ґ­вЁдЁжЁагҐв гбва®©бвў®, ­  Є®в®а®¬ ЁйҐвбп д ©«: +®¤­® Ё§ + * /RD/1 = /RAMDISK/1 ¤«п ¤®бвгЇ  Є а ¬¤ЁбЄг + * /FD/1 = /FLOPPYDISK/1 ¤«п ¤®бвгЇ  Є ЇҐаў®¬г д«®ЇЇЁ-¤ЁбЄ®ў®¤г, + /FD/2 = /FLOPPYDISK/2 ¤«п ўв®а®Ј® д«®ЇЇЁ-¤ЁбЄ®ў®¤  + * /HD/x = /HARDDISK/x - гбв аҐўиЁ© ў аЁ ­в ¤®бвгЇ  Є ¦сбвЄ®¬г ¤ЁбЄг + (ў н⮬ б«гз Ґ Ў §  ®ЇаҐ¤Ґ«пҐвбп Ї®¤дг­ЄжЁҐ© 7 дг­ЄжЁЁ 21), + x - ­®¬Ґа а §¤Ґ«  (бзЁв п б 1) + * /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«п ¤®бвгЇ  ᮮ⢥вб⢥­­® + Є гбва®©бвў ¬ IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - ­®¬Ґа а §¤Ґ«  ­  ўлЎа ­­®¬ ўЁ­зҐбвҐаҐ, Ё§¬Ґ­пҐвбп ®в 1 ¤® 255 + (­  Є ¦¤®¬ Ё§ ўЁ­зҐбвҐа®ў ­г¬Ґа жЁп ­ зЁ­ Ґвбп б 1) +‡ ¬Ґз ­Ёп: + * ‚ ЇҐаўле ¤ўге б«гз пе ¤®ЇгбЄ Ґвбп ЁбЇ®«м§®ў ­ЁҐ FIRST ў¬Ґбв® 1, + SECOND ў¬Ґбв® 2, ­® ЁбЇ®«м§®ў вм нвг ў®§¬®¦­®бвм + ­Ґ ४®¬Ґ­¤гҐвбп ¤«п 㤮Ўбвў  ЇҐаҐе®¤  ­  Ўг¤гйЁҐ а биЁаҐ­Ёп. + * Ќ Є« ¤лў Ґвбп ®Ја ­ЁзҐ­ЁҐ n<=39. + * €¬Ґ­  Ї Ї®Є Ё д ©«  dir1,...,dirn,file ¤®«¦­л Ўлвм ў д®а¬ вҐ 8.3: + Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ ­Ґ Ў®«ҐҐ 3 бЁ¬ў®«®ў. + •ў®бв®ўлҐ Їа®ЎҐ«л ЁЈ­®аЁаговбп. „агЈЁе Їа®ЎҐ«®ў Ўлвм ­Ґ ¤®«¦­®. + …б«Ё Ё¬п § ­Ё¬ Ґв а®ў­® 8 бЁ¬ў®«®ў, в®зЄг ¬®¦­® ®ЇгбвЁвм + (е®вп Ї®«м§®ў вмбп нвЁ¬ ­Ґ ४®¬Ґ­¤гҐвбп ¤«п 㤮Ўбвў  ЇҐаҐе®¤  + ­  Ўг¤гйЁҐ а биЁаҐ­Ёп). + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї Ї®Є ­  а ¬¤ЁбЄҐ. +ЏаЁ¬Ґал: + * '/RAMDISK/FIRST/KERNEL.ASM',0 + '/rd/1/kernel.asm',0 + * '/HD0/1/kernel.asm',0 + * '/hd0/1/menuet/pics/tanzania.bmp',0 +„®бвгЇ­лҐ Ї®¤дг­ЄжЁЁ: + * Ї®¤дг­ЄжЁп 0 - з⥭ЁҐ д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 8 - LBA-з⥭ЁҐ б гбва®©бвў  + * Ї®¤дг­ЄжЁп 15 - Ї®«г祭ЁҐ Ё­д®а¬ жЁЁ ® д ©«®ў®© бЁб⥬Ґ + +====================================================================== +========== ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 0 - Їа®зЁв вм д ©«/Ї ЇЄг. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 58 + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 0 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ­®¬Ґа Ў«®Є  ¤«п з⥭Ёп (бзЁв п б 0) + * +8: dword: зЁб«® Ў«®Є®ў ¤«п з⥭Ёп + * +12 = +0xC: dword: гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв § ЇЁб ­л ¤ ­­лҐ + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx = а §¬Ґа д ©«  (ў Ў ©в е) Ё«Ё + -1=0xffffffff, Ґб«Ё д ©« ­Ґ ­ ©¤Ґ­ +‡ ¬Ґз ­Ёп: + * ђ §¬Ґа Ў«®Є  - 512 Ў ©в. + * ќв  дг­ЄжЁп гбв аҐ« , ¤«п з⥭Ёп д ©«®ў ЁбЇ®«м§г©вҐ Ї®¤дг­ЄжЁо 0 + дг­ЄжЁЁ 70, ¤«п з⥭Ёп Ї Ї®Є - Ї®¤дг­ЄжЁо 1 дг­ЄжЁЁ 70. + * ”г­ЄжЁп Ї®§ў®«пҐв зЁв вм ᮤҐа¦Ё¬®Ґ Ї ЇЄЁ. €§ д ©«®ўле бЁб⥬ + Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® FAT. ”®а¬ в FAT-Ї ЇЄЁ ®ЇЁб ­ ў «оЎ®© + ¤®Єг¬Ґ­в жЁЁ Ї® FAT. + * ђ §¬Ґа Ї ЇЄЁ ®ЇаҐ¤Ґ«пҐвбп Ї® а §¬Ґаг 楯®зЄЁ Є« бвҐа®ў ў FAT. + * …б«Ё д ©« Є®­зЁ«бп а ­миҐ, 祬 Ўл« Їа®зЁв ­ Ї®б«Ґ¤­Ё© § Їа®иҐ­­л© + Ў«®Є, в® дг­ЄжЁп Їа®зЁв Ґв, бЄ®«мЄ® ᬮ¦Ґв, Ї®б«Ґ 祣® ўҐа­св + eax=6 (EOF). + * ”г­ЄжЁп Ї®§ў®«пҐв зЁв вм Є®а­ҐўлҐ Ї ЇЄЁ /rd/1,/fd/x,/hd[n]/x, ­® + ў ЇҐаўле ¤ўге б«гз пе ⥪гй п ॠ«Ё§ жЁп ­Ґ б«Ґ¤гҐв + гбв ­®ў«Ґ­­л¬ Їа ўЁ« ¬: + ¤«п /rd/1: + * Ґб«Ё гЄ § ­® 0 Ў«®Є®ў ¤«п з⥭Ёп, бзЁв Ґвбп, + зв® § Їа иЁў Ґвбп 1; + * Ґб«Ё § Їа иЁў Ґвбп Ў®«миҐ 14 Ў«®Є®ў Ё«Ё ­ з «м­л© Ў«®Є + ­Ґ ¬Ґ­миҐ 14-Ј®, в® ў®§ўа й Ґвбп eax=5 (not found) Ё ebx=-1; + * а §¬Ґа Є®а­Ґў®Ј® Є в «®Ј  а ¬¤ЁбЄ  = 14 Ў«®Є®ў, + 0x1C00=7168 Ў ©в; ­® ў®§ўа й Ґвбп ebx=0 + (§  ЁбЄ«о祭ЁҐ¬ б«гз п ЇаҐ¤л¤г饣® Їг­Єв ); + * Є Є ­Ё бва ­­®, ¬®¦­® Їа®зЁв вм 14-© Ў«®Є (в ¬, ў®®ЎйҐ Ј®ў®ап, + ¬гб®а - ­ Ї®¬Ё­ о, бзсв ўҐ¤свбп б 0); + * Ґб«Ё Ўл« § Їа®иҐ­ е®вп Ўл ®¤Ё­ Ў«®Є б ­®¬Ґа®¬, ­Ґ ¬Ґ­миЁ¬ 14, + в® ў®§ўа й Ґвбп eax=6(EOF); Ё­ зҐ eax=0. + „«п /fd/x: + * Ґб«Ё ­ з «м­л© Ў«®Є ­Ґ ¬Ґ­миҐ 14-Ј®, в® ў®§ўа й Ґвбп + eax=5 (not found) Ё ebx=0; + * Єбв вЁ Ј®ў®ап, д®а¬ в FAT12 ¤®ЇгбЄ Ґв ¤ЁбЄҐвл б а §¬Ґа®¬ + Є®а­Ґў®Ј® Є в «®Ј  ¬Ґ­миҐ Ё«Ё Ў®«миҐ 14 Ў«®Є®ў; + * Їа®ўҐаЄЁ ¤«Ё­л ­Ґ ¤Ґ« Ґвбп; + * Ґб«Ё г¤ «®бм Їа®зЁв вм ¤ ­­лҐ б ¤ЁбЄҐвл, ў®§ўа й Ґвбп + eax=0,ebx=0; ў Їа®вЁў­®¬ б«гз Ґ eax=10 (access denied), ebx=-1. + * ”г­ЄжЁп ®Ўа Ў влў Ґв з⥭ЁҐ бЇҐжЁ «м­ле Ї Ї®Є /,/rd,/fd,/hd[n]; + ­® १г«мв в ­Ґ ᮮ⢥вбвўгҐв ®¦Ё¤ Ґ¬®¬г + (Ї® а Ў®вҐ б ®Ўлз­л¬Ё д ©« ¬Ё/Ї ЇЄ ¬Ё), ­Ґ б«Ґ¤гҐв гбв ­®ў«Ґ­­л¬ + Їа ўЁ« ¬, ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў б«Ґ¤гойЁе ўҐабЁпе п¤а  Ё Ї®в®¬г + ­Ґ ®ЇЁблў Ґвбп. „«п Ї®«г祭Ёп Ё­д®а¬ жЁЁ ®Ў ®Ў®а㤮ў ­ЁЁ + ЁбЇ®«м§г©вҐ Ї®¤дг­ЄжЁо 11 дг­ЄжЁЁ 18 Ё«Ё + зЁв ©вҐ ᮮ⢥вбвўгойЁҐ Ї ЇЄЁ Ї®¤дг­ЄжЁҐ© 1 дг­ЄжЁЁ 70. + +====================================================================== +========= ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 8 - LBA-з⥭ЁҐ б гбва®©бвў . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 8 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ­®¬Ґа Ў«®Є  ¤«п з⥭Ёп (бзЁв п б 0) + * +8: dword: ЁЈ­®аЁагҐвбп (гбв ­ ў«Ёў ©вҐ ў 1) + * +12 = +0xC: dword: гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв § ЇЁб ­л ¤ ­­лҐ + (512 Ў ©в) + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п гбва®©бвў : ­Ґзгўб⢨⥫쭮 Є ॣЁбваг, + ®¤­® Ё§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, + 1<=n<=4 - ­®¬Ґа гбва®©бвў : 1=IDE0, ..., 4=IDE3. + ‚¬Ґбв® жЁда ¤®ЇгбЄ Ґвбп, е®вп Ё ­Ґ ४®¬Ґ­¤гҐвбп ¤«п 㤮Ўбвў  + ЇҐаҐе®¤  ­  Ўг¤гйЁҐ а биЁаҐ­Ёп, + ЁбЇ®«м§®ў ­ЁҐ 'first','second','third','fourth'. +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё гЄ § ­® Ё¬п гбва®©бвў  /hd/xxx, Ј¤Ґ xxx ­Ґ ­ е®¤Ёвбп + ў бЇЁбЄҐ ўлиҐ: + * eax = ebx = 1 + * Ґб«Ё гЄ § ­® ­ҐЇа ўЁ«м­®Ґ Ё¬п гбва®©бвў  + (§  ЁбЄ«о祭ЁҐ¬ ЇаҐ¤л¤г饣® б«гз п): + * eax = 5 + * ebx ­Ґ ¬Ґ­пҐвбп + * Ґб«Ё LBA-¤®бвгЇ § ЇаҐйс­ Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 21: + * eax = 2 + * ebx а §аги Ґвбп + * ¤«п а ¬¤ЁбЄ : Ї®ЇлвЄ  з⥭Ёп Ў«®Є  §  ЇаҐ¤Ґ« ¬Ё а ¬¤ЁбЄ  + (18*2*80 Ў«®Є®ў) ЇаЁў®¤Ёв Є + * eax = 3 + * ebx = 0 + * ЇаЁ гбЇҐи­®¬ з⥭ЁЁ: + * eax = ebx = 0 +‡ ¬Ґз ­Ёп: + * ђ §¬Ґа Ў«®Є  - 512 Ў ©в; зЁв Ґвбп ®¤Ё­ Ў«®Є. + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ, + ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў б«Ґ¤гойЁе ўҐабЁпе. + * ’ॡгҐвбп, зв®Ўл Ўл« а §аҐис­ LBA-¤®бвгЇ Є гбва®©бвў ¬ + Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 21. “§­ вм нв® ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 26. + * LBA-з⥭ЁҐ ¤ЁбЄҐвл ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп. + * ”г­ЄжЁп бзЁвлў Ґв ¤ ­­лҐ дЁ§ЁзҐбЄ®Ј® ¦сбвЄ®Ј® ¤ЁбЄ ; + Ґб«Ё Ї® Є ЄЁ¬-в® ЇаЁзЁ­ ¬ ­г¦­л ¤ ­­лҐ Є®­ЄаҐв­®Ј® а §¤Ґ« , + ЇаЁ¤свбп ®ЇаҐ¤Ґ«пвм ­ з «м­л© ᥪв®а нв®Ј® а §¤Ґ«  + («ЁЎ® ­ Їап¬го зҐаҐ§ MBR, «ЁЎ® Ё§ а биЁаҐ­­®© бвагЄвгал, + ў®§ўа й Ґ¬®© в®© ¦Ґ Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 18). + * ”г­ЄжЁп ­Ґ Їа®ўҐапҐв Є®¤ ®иЁЎЄЁ ¦сбвЄ®Ј® ¤ЁбЄ , в Є зв® § Їа®б + ­ҐбгйҐбвўго饣® ᥪв®а  ўбс а ў­® зв®-в® Їа®зЁв Ґв + (ўҐа®пв­ҐҐ ўбҐЈ®, ­г«Ё, ­® нв® ®ЇаҐ¤Ґ«пҐвбп гбва®©бвў®¬) Ё + нв® Ўг¤Ґв бзЁв вмбп гᯥ宬 (eax=0). + +====================================================================== += ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 15 - Ї®«гзЁвм Ё­д®а¬ жЁо ® д ©«®ў®© бЁб⥬Ґ. +====================================================================== +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 15 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ЁЈ­®аЁагҐвбп + * +8: dword: ЁЈ­®аЁагҐвбп + * +12 = +0xC: dword: ЁЈ­®аЁагҐвбп + * +16 = +0x10: dword: ЁЈ­®аЁагҐвбп + * +20 = +0x14: (Їа®ўҐапҐвбп в®«мЄ® ўв®а®© бЁ¬ў®«, ба §г Ї®б«Ґ б«ни ) + /rd=/RAMDISK Ё«Ё /hd=/HARDDISK +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ўв®а®© бЁ¬ў®« ­Ґ ЇаЁ­ ¤«Ґ¦Ёв ¬­®¦Ґбвўг {'r','R','h','H'}: + * eax = 3 + * ebx = ecx = dword [fileinfo] = 0 + * ¤«п а ¬¤ЁбЄ : + * eax = 0 (гбЇҐе) + * ebx = ®ЎйҐҐ зЁб«® Є« бвҐа®ў = 2847 + * ecx = зЁб«® бў®Ў®¤­ле Є« бвҐа®ў + * dword [fileinfo] = а §¬Ґа Є« бвҐа  = 512 + * ¤«п ¦сбвЄ®Ј® ¤ЁбЄ : Ў §  Ё а §¤Ґ« ®ЇаҐ¤Ґ«повбп Ї®¤дг­ЄжЁп¬Ё 7 Ё 8 + дг­ЄжЁЁ 21: + * eax = 0 (гбЇҐе) + * ebx = ®ЎйҐҐ зЁб«® Є« бвҐа®ў + * ecx = зЁб«® бў®Ў®¤­ле Є« бвҐа®ў + * dword [fileinfo] = а §¬Ґа Є« бвҐа  (ў Ў ©в е) +‡ ¬Ґз ­Ёп: + * ЌҐ г¤Ёў«п©вҐбм бва ­­®¬г а бЇ®«®¦Ґ­Ёо 4-Ј® ў®§ўа й Ґ¬®Ј® + Ї а ¬Ґва  - Є®Ј¤  ЇЁб «бп нв®в Є®¤, ЇаЁ бЁб⥬­ле ўл§®ў е + ЇаЁ«®¦Ґ­Ёо ў®§ўа й «Ёбм в®«мЄ® ॣЁбвал eax,ebx,ecx (Ё§ + pushad-бвагЄвгал, ЇҐаҐ¤ о饩бп Є Є  аЈг¬Ґ­в бЁб⥬­®© дг­ЄжЁЁ). + ’ҐЇҐам нв® ЁбЇа ў«Ґ­®, в Є зв®, ў®§¬®¦­®, Ё¬ҐҐв б¬лб« ў®§ўа й вм + а §¬Ґа Є« бвҐа  ў edx, Ї®Є  нвг дг­ЄжЁо ­Ґ ­ з «Ё ЁбЇ®«м§®ў вм. + * ‚®®ЎйҐ-в® Ґйс бгйҐбвўгҐв Ї®¤дг­ЄжЁп 11 дг­ЄжЁЁ 18, ў®§ўа й ой п + Ё­д®а¬ жЁо ® д ©«®ў®© бЁб⥬Ґ. Џ® а биЁаҐ­­®© в Ў«ЁжҐ ¤ЁбЄ®ў®© + Ї®¤бЁбвҐ¬л ¬®¦­® ®ЇаҐ¤Ґ«Ёвм а §¬Ґа Є« бвҐа  (в ¬ ®­ еа ­Ёвбп + ў ᥪв®а е) Ё ®ЎйҐҐ зЁб«® Є« бвҐа®ў ¤«п ¦сбвЄЁе ¤ЁбЄ®ў. + +====================================================================== +=========== ”г­ЄжЁп 60 - Inter Process Communication (IPC). ========== +====================================================================== +IPC ЇаЁ¬Ґ­пҐвбп ¤«п Ї®бл«®Є б®®ЎйҐ­Ё© ®в ®¤­®Ј® Їа®жҐбб /Ї®в®Є  +¤агЈ®¬г. ЏаЁ н⮬ б«Ґ¤гҐв ЇаҐ¤ў аЁвҐ«м­® ¤®Ј®ў®аЁвмбп ® ⮬, Є Є +Ё­вҐаЇаҐвЁа®ў вм Є®­ЄаҐв­®Ґ б®®ЎйҐ­ЁҐ. + +-------- Џ®¤дг­ЄжЁп 1 - гбв ­®ўЁвм ®Ў« бвм ¤«п Ї®«г祭Ёп IPC --------- +‚л§лў Ґвбп Їа®жҐбᮬ-ЇаЁс¬­ЁЄ®¬. +Џ а ¬Ґвал: + * eax = 60 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа + * edx = а §¬Ґа ЎгдҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ўбҐЈ¤  гбЇҐи­® +”®а¬ в IPC-ЎгдҐа : + * +0: dword: Ґб«Ё §¤Ґбм ­Ґ 0, в® ЎгдҐа бзЁв Ґвбп § Ў«®ЄЁа®ў ­­л¬; + Ў«®ЄЁаг©вҐ/а §Ў«®ЄЁаг©вҐ ЎгдҐа, Є®Ј¤  ўл б ­Ё¬  ЄвЁў­® а Ў®в ҐвҐ + Ё ў ¬ ­ ¤®, зв®Ўл Ё§ў­Ґ ­Ґ Ё§¬Ґ­п«Ёбм ¤ ­­лҐ ЎгдҐа  + (­Ґ Ї®бвгЇ «Ё ­®ўлҐ б®®ЎйҐ­Ёп) + * +4: dword: § ­пв® ¬Ґбв  ў ЎгдҐаҐ (ў Ў ©в е) + * +8: ЇҐаў®Ґ б®®ЎйҐ­ЁҐ + * +8+n: ўв®а®Ґ б®®ЎйҐ­ЁҐ + * ... +”®а¬ в б®®ЎйҐ­Ёп: + * +0: dword: PID Їа®жҐбб /Ї®в®Є , Ї®б« ўиҐЈ® б®®ЎйҐ­ЁҐ + * +4: dword: ¤«Ё­  б®®ЎйҐ­Ёп (­Ґ бзЁв п нв®в § Ј®«®ў®Є) + * +8: n*byte: ¤ ­­лҐ б®®ЎйҐ­Ёп + +--------------- Џ®¤дг­ЄжЁп 2 - Ї®б« вм б®®ЎйҐ­ЁҐ IPC. ---------------- +‚л§лў Ґвбп Їа®жҐбᮬ-Ё­ЁжЁ в®а®¬. +Џ а ¬Ґвал: + * eax = 60 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = PID ЇаЁс¬­ЁЄ  + * edx = гЄ § вҐ«м ­  ¤ ­­лҐ б®®ЎйҐ­Ёп + * esi = ¤«Ё­  б®®ЎйҐ­Ёп (ў Ў ©в е) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ЇаЁс¬­ЁЄ ­Ґ ®ЇаҐ¤Ґ«Ё« ЎгдҐа ¤«п IPC-б®®ЎйҐ­Ё© + (¬®¦Ґв Ўлвм, Ґйс ­Ґ гбЇҐ«,   ¬®¦Ґв Ўлвм, нв® ­Ґ в®в Ї®в®Є, + Є®в®ал© ­г¦Ґ­) + * eax = 2 - ЇаЁс¬­ЁЄ § Ў«®ЄЁа®ў « IPC-ЎгдҐа; + Ї®Їа®Ўг©вҐ ­Ґ¬­®Ј® Ї®¤®¦¤ вм + * eax = 3 - ЇҐаҐЇ®«­Ґ­ЁҐ IPC-ЎгдҐа  ЇаЁс¬­ЁЄ  + * eax = 4 - Їа®жҐбб /Ї®в®Є  б в ЄЁ¬ PID ­Ґ бгйҐбвўгҐв +‡ ¬Ґз ­Ёп: + * ‘Ёб⥬  ба §г Ї®б«Ґ § ЇЁбЁ IPC-б®®ЎйҐ­Ёп ў ЎгдҐа Ї®бл« Ґв + Ї®в®Єг-ЇаЁс¬­ЁЄг б®ЎлвЁҐ б Є®¤®¬ 7 (б¬. Є®¤л б®ЎлвЁ©). + +====================================================================== +=== ”г­ЄжЁп 61 - Ї®«гзЁвм Ї а ¬Ґвал ¤«п ЇаאַЈ® ¤®бвгЇ  Є Ја дЁЄҐ. === +====================================================================== +Џа®Ја ¬¬Ґ ¤®бвгЇ­л ¤ ­­лҐ Ја дЁзҐбЄ®Ј® нЄа ­  (®Ў« бвм Ї ¬пвЁ, Є®в®а п +б®Ўб⢥­­® Ё ®в®Ўа ¦ Ґв ᮤҐа¦Ё¬®Ґ нЄа ­ ) ­ Їап¬го ЎҐ§ ўл§®ў®ў +бЁб⥬­ле дг­ЄжЁ© зҐаҐ§ ᥫҐЄв®а gs: + mov eax, [gs:0] +Ї®¬ҐбвЁв ў eax ЇҐаўл© dword ЎгдҐа , ᮤҐа¦ йЁ© Ё­д®а¬ жЁо ® 梥⥠+«Ґў®© ўҐае­Ґ© в®зЄЁ (Ё, ў®§¬®¦­®, жўҐв  ­ҐбЄ®«мЄЁе б«Ґ¤гойЁе). + mov [gs:0], eax +ЇаЁ а Ў®вҐ ў ०Ё¬ е VESA c LFB +гбв ­®ўЁв 梥⠫Ґў®© ўҐае­Ґ© в®зЄЁ +(Ё ў®§¬®¦­®, жўҐв  ­ҐбЄ®«мЄЁе б«Ґ¤гойЁе). +„«п Ё­вҐаЇаҐв жЁЁ ¤ ­­ле Ја дЁзҐбЄ®Ј® нЄа ­  вॡгҐвбп §­ ­ЁҐ +­ҐЄ®в®але Ї а ¬Ґва®ў, Є®в®алҐ ў®§ўа й овбп нв®© дг­ЄжЁҐ©. +‡ ¬Ґз ­Ёп: + * Џ а ¬Ґвал Ја дЁЄЁ ®зҐ­м ।Є® ¬Ґ­повбп ЇаЁ а Ў®вҐ бЁб⥬л, +   Ё¬Ґ­­®, в®«мЄ® ў б«гз пе, Є®Ј¤  Ї®«м§®ў вҐ«м а Ў®в Ґв + б Їа®Ја ¬¬®© VRR. + * ЏаЁ Ё§¬Ґ­Ґ­ЁЁ ўЁ¤Ґ®аҐ¦Ё¬  бЁб⥬  ЇҐаҐаЁб®ўлў Ґв ўбҐ ®Є­  + (б®ЎлвЁҐ б Є®¤®¬ 1) Ё ЇҐаҐаЁб®ўлў Ґв д®­ (б®ЎлвЁҐ 5). + ќвЁ ¦Ґ б®ЎлвЁп Їа®Ёб室пв Ё ў ¤агЈЁе б«гз пе, + Є®в®алҐ ўбваҐз овбп §­ зЁвҐ«м­® з йҐ, 祬 Ё§¬Ґ­Ґ­ЁҐ ўЁ¤Ґ®аҐ¦Ё¬ . + * ЏаЁ а Ў®вҐ ў ўЁ¤Ґ®аҐ¦Ё¬ е б LFB ᥫҐЄв®а gs гЄ §лў Ґв ­  + б®Ўб⢥­­® LFB, в Є зв® з⥭ЁҐ/§ ЇЁбм Ї® gs ЇаЁў®¤пв + ­ҐЇ®б।б⢥­­® Є Ё§¬Ґ­Ґ­Ёо ᮤҐа¦Ё¬®Ј® нЄа ­ . ЏаЁ а Ў®вҐ ў + ўЁ¤Ґ®аҐ¦Ё¬ е ЎҐ§ LFB gs гЄ §лў Ґв ­  ­ҐЄ®в®аго ®Ў« бвм ¤ ­­ле + п¤а , ЇаЁзс¬ ўбҐ дг­ЄжЁЁ ўлў®¤  ­  нЄа ­ ¤®Ўа®б®ўҐбв­® ўлЇ®«­пов + ¤ў®©­го а Ў®вг Ї® § ЇЁбЁ ­ҐЇ®б।б⢥­­® ­  нЄа ­ Ё Ї® § ЇЁбЁ + ў нв®в ЎгдҐа. ‚ १г«мв вҐ ЇаЁ з⥭ЁЁ ᮤҐа¦Ё¬®Ј® нв®Ј® ЎгдҐа  + १г«мв вл ᮮ⢥вбвўгов ᮤҐа¦Ё¬®¬г нЄа ­  + (б, ў®®ЎйҐ Ј®ў®ап, Ў®«миЁ¬ жўҐв®ўл¬ а §аҐиҐ­ЁҐ¬), +   § ЇЁбм ЁЈ­®аЁагҐвбп. + €бЄ«о祭ЁҐ¬ пў«пҐвбп ०Ё¬ 320*200, ¤«п Є®в®а®Ј® ў Ј« ў­®¬ жЁЄ«Ґ + бЁб⥬­®Ј® Ї®в®Є  ўлЇ®«­пҐвбп ®Ў­®ў«Ґ­ЁҐ нЄа ­  ў ᮮ⢥вбвўЁЁ + б ¤ўЁ¦Ґ­Ёп¬Ё Єгаб®а  ¬лиЁ. + +------------------------- ђ §аҐиҐ­ЁҐ нЄа ­  -------------------------- +Џ а ¬Ґвал: + * eax = 61 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [а §аҐиҐ­ЁҐ Ї® ®бЁ x]*65536 + [а §аҐиҐ­ЁҐ Ї® ®бЁ y] +‡ ¬Ґз ­Ёп: + * Њ®¦­® ЁбЇ®«м§®ў вм дг­ЄжЁо 14 б гзс⮬ в®Ј®, зв® ®­  ў®§ўа й Ґв + а §¬Ґал ­  1 ¬Ґ­миҐ. ќв® Ї®«­®бвмо нЄўЁў «Ґ­в­л© бЇ®б®Ў. + +------------------------ —Ёб«® ЎЁв ­  ЇЁЄбҐ«м ------------------------ +Џ а ¬Ґвал: + * eax = 61 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® ЎЁв ­  ЇЁЄбҐ«м (24 Ё«Ё 32) + +------------------------ —Ёб«® Ў ©в ­  бва®Єг ------------------------ +Џ а ¬Ґвал: + * eax = 61 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Ў ©в, Є®в®а®Ґ § ­Ё¬ Ґв ®¤­  бва®Є  а §ўсавЄЁ + (Ј®аЁ§®­в «м­ п «Ё­Ёп ­  нЄа ­Ґ) + +====================================================================== +===== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм ўҐабЁо PCI-Ё­вҐа䥩б . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * ah.al = ўҐабЁп PCI-Ё­вҐадҐ©б  (ah=ўҐабЁп, al=Ї®¤ўҐабЁп) + * бв а襥 б«®ў® eax ®Ў­г«Ґ­® +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * …б«Ё PCI BIOS ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп, в® §­ зҐ­ЁҐ ax ­Ґ®ЇаҐ¤Ґ«Ґ­®. + +====================================================================== +==== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм ­®¬Ґа Ї®б«Ґ¤­Ґ© PCI-иЁ­л. === +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * al = ­®¬Ґа Ї®б«Ґ¤­Ґ© PCI-иЁ­л; ®бв ўиЁҐбп Ў ©вл eax а §аги овбп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * …б«Ё PCI BIOS ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп, в® §­ зҐ­ЁҐ al ­Ґ®ЇаҐ¤Ґ«Ґ­®. + +====================================================================== +====================== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 2 ====================== +== Џ®«гзЁвм ¬Ґе ­Ё§¬ ®Ўа йҐ­Ёп Є Є®­дЁЈга жЁ®­­®¬г Їа®бва ­бвўг PCI. = +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * al = ¬Ґе ­Ё§¬ (1 Ё«Ё 2); Їа®зЁҐ Ў ©вл eax а §аги овбп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * ЊҐе ­Ё§¬ ®Ўа йҐ­Ёп ўлЎЁа Ґвбп ў ᮮ⢥вбвўЁЁ + б е а ЄвҐаЁбвЁЄ ¬Ё ®Ў®а㤮ў ­Ёп. + * Џ®¤дг­ЄжЁЁ з⥭Ёп Ё § ЇЁбЁ  ўв®¬ вЁзҐбЄЁ а Ў®в ов + б ўлЎа ­­л¬ ¬Ґе ­Ё§¬®¬. + +====================================================================== +======== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁЁ 4,5,6 - Їа®зЁв вм PCI-ॣЁбва. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 4 - зЁв вм Ў ©в + * bl = 5 - зЁв вм б«®ў® + * bl = 6 - зЁв вм ¤ў®©­®Ґ б«®ў® + * bh = ­®¬Ґа PCI-иЁ­л + * ch = dddddfff, Ј¤Ґ ddddd = ­®¬Ґа гбва®©бвў  ­  иЁ­Ґ, + fff = ­®¬Ґа дг­ЄжЁЁ гбва®©бвў  + * cl = ­®¬Ґа ॣЁбва  (¤®«¦Ґ­ Ўлвм зсв­л¬ ¤«п bl=5, + ¤Ґ«Ёвмбп ­  4 ¤«п bl=6) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  (§ ЇаҐйс­ ¤®бвгЇ Є PCI Ё«Ё + ­ҐЇ®¤¤Ґа¦Ёў Ґ¬лҐ Ї а ¬Ґвал); Ё­ зҐ + * al/ax/eax (ў § ўЁбЁ¬®бвЁ ®в § Їа®иҐ­­®Ј® а §¬Ґа ) ᮤҐа¦Ёв ¤ ­­лҐ; + ®бв ўи пбп з бвм ॣЁбва  eax а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * ЊҐе ­Ё§¬ ¤®бвгЇ  2 Ї®¤¤Ґа¦Ёў Ґв в®«мЄ® 16 гбва®©бвў ­  иЁ­Ґ Ё + ЁЈ­®аЁагҐв ­®¬Ґа дг­ЄжЁЁ. Џ®«гзЁвм ¬Ґе ­Ё§¬ ¤®бвгЇ  ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 2. + * ЌҐЄ®в®алҐ аҐЈЁбвал бв ­¤ ав­л Ё бгйҐбвўгов ¤«п ўбҐе гбва®©бвў, + ­ҐЄ®в®алҐ ®ЇаҐ¤Ґ«повбп Є®­ЄаҐв­л¬ гбва®©бвў®¬. ‘ЇЁб®Є ЇҐаўле + ўе®¤Ёв, ­ ЇаЁ¬Ґа, ў Ё§ўҐбв­л© Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); + бЇЁб®Є ўв®але ¤®«¦Ґ­ Ўлвм гЄ § ­ ў ¤®Єг¬Ґ­в жЁЁ Ї® гбва®©бвўг. + +====================================================================== +======= ”г­ЄжЁп 62, Ї®¤дг­ЄжЁЁ 8,9,10 - § ЇЁб вм ў PCI-ॣЁбва. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 8 - ЇЁб вм Ў ©в + * bl = 9 - ЇЁб вм б«®ў® + * bl = 10 - ЇЁб вм ¤ў®©­®Ґ б«®ў® + * bh = ­®¬Ґа PCI-иЁ­л + * ch = dddddfff, Ј¤Ґ ddddd = ­®¬Ґа гбва®©бвў  ­  иЁ­Ґ, + fff = ­®¬Ґа дг­ЄжЁЁ гбва®©бвў  + * cl = ­®¬Ґа ॣЁбва  (¤®«¦Ґ­ Ўлвм зсв­л¬ ¤«п bl=9, + ¤Ґ«Ёвмбп ­  4 ¤«п bl=10) + * dl/dx/edx (ў § ўЁбЁ¬®бвЁ ®в § Їа®иҐ­­®Ј® а §¬Ґа ) ᮤҐа¦Ёв + ¤ ­­лҐ ¤«п § ЇЁбЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  (§ ЇаҐйс­ ¤®бвгЇ Є PCI Ё«Ё + ­ҐЇ®¤¤Ґа¦Ёў Ґ¬лҐ Ї а ¬Ґвал) + * eax = 0 - гбЇҐи­® +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * ЊҐе ­Ё§¬ ¤®бвгЇ  2 Ї®¤¤Ґа¦Ёў Ґв в®«мЄ® 16 гбва®©бвў ­  иЁ­Ґ Ё + ЁЈ­®аЁагҐв ­®¬Ґа дг­ЄжЁЁ. Џ®«гзЁвм ¬Ґе ­Ё§¬ ¤®бвгЇ  ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 2. + * ЌҐЄ®в®алҐ аҐЈЁбвал бв ­¤ ав­л Ё бгйҐбвўгов ¤«п ўбҐе гбва®©бвў, + ­ҐЄ®в®алҐ ®ЇаҐ¤Ґ«повбп Є®­ЄаҐв­л¬ гбва®©бвў®¬. ‘ЇЁб®Є ЇҐаўле + ўе®¤Ёв, ­ ЇаЁ¬Ґа, ў Ё§ўҐбв­л© Interrupt List by Ralf Brown; + бЇЁб®Є ўв®але ¤®«¦Ґ­ Ўлвм гЄ § ­ ў ¤®Єг¬Ґ­в жЁЁ Ї® гбва®©бвўг. + +====================================================================== +================ ”г­ЄжЁп 63 - а Ў®в  б ¤®бЄ®© ®в« ¤ЄЁ. =============== +====================================================================== +„®бЄ  ®в« ¤ЄЁ ЇаҐ¤бв ў«пҐв б®Ў®© бЁб⥬­л© ЎгдҐа (­  4096 Ў ©в), +ў Є®в®ал© «оЎ п Їа®Ја ¬¬  ¬®¦Ґв § ЇЁб вм (ў®®ЎйҐ Ј®ў®ап, Їа®Ё§ў®«м­лҐ) +¤ ­­лҐ Ё Ё§ Є®в®а®Ј® ¤агЈ п Їа®Ја ¬¬  ¬®¦Ґв нвЁ ¤ ­­лҐ Їа®зЁв вм. +…бвм б®Ј« иҐ­ЁҐ, ў ᮮ⢥вбвўЁЁ б Є®в®ал¬ § ЇЁблў Ґ¬лҐ ¤ ­­лҐ - +⥪бв®ўлҐ бва®ЄЁ, Ё­вҐаЇаҐвЁагҐ¬лҐ Є Є ®в« ¤®з­лҐ б®®ЎйҐ­Ёп ® 室Ґ +ўлЇ®«­Ґ­Ёп Їа®Ја ¬¬л. џ¤а® ў ®ЇаҐ¤Ґ«с­­ле бЁвг жЁпе в Є¦Ґ § ЇЁблў Ґв +­  ¤®бЄг ®в« ¤ЄЁ ᢥ¤Ґ­Ёп ® ўлЇ®«­Ґ­ЁЁ ­ҐЄ®в®але дг­ЄжЁ©; +Ї® б®Ј« иҐ­Ёо б®®ЎйҐ­Ёп п¤а  ­ зЁ­ овбп б ЇаҐдЁЄб  "K : ". +„«п Їа®б¬®ва  ¤®бЄЁ ®в« ¤ЄЁ б®§¤ ­® ЇаЁ«®¦Ґ­ЁҐ board, +Є®в®а®Ґ бзЁвлў Ґв ¤ ­­лҐ Ё§ ЎгдҐа  Ё ®в®Ўа ¦ Ґв Ёе ў бў®с¬ ®Є­Ґ. board +Ї®­Ё¬ Ґв Ї®б«Ґ¤®ў вҐ«м­®бвм Є®¤®ў 13,10 Є Є ЇҐаҐе®¤ ­  ­®ўго бва®Єг. +‘Ё¬ў®« б ­г«Ґўл¬ Є®¤®¬ ў Є®­жҐ бва®ЄЁ ­Ґ ®Ўп§ вҐ«Ґ­, ­® Ё ­Ґ ¬Ґи Ґв. +‚ бўп§Ё б Ї®пў«Ґ­ЁҐ¬ ®в« ¤зЁЄ  業­®бвм ¤®бЄЁ ®в« ¤ЄЁ ­ҐбЄ®«мЄ® +б­Ё§Ё« бм, Ї®бЄ®«мЄг ®в« ¤зЁЄ Ї®§ў®«пҐв Ї®«­®бвмо Є®­ва®«Ёа®ў вм 室 +ўлЇ®«­Ґ­Ёп Їа®Ја ¬¬л, ЇаЁзс¬ ¤«п нв®Ј® ­Ґ вॡгҐвбп ­ЁЄ ЄЁе гбЁ«Ё© +б® бв®а®­л б ¬®© Їа®Ја ¬¬л. ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ў® ¬­®ЈЁе б«гз пе +¤®бЄ  ®в« ¤ЄЁ Їа®¤®«¦ Ґв ®бв ў вмбп Ї®«Ґ§­®©. + +---------------------------- ‡ ЇЁбм Ў ©в  ---------------------------- +Џ а ¬Ґвал: + * eax = 63 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl = Ў ©в ¤ ­­ле +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Ѓ ©в § ЇЁблў Ґвбп ў ЎгдҐа. „«Ё­  ЎгдҐа  - 512 Ў ©в. + ЏаЁ ЇҐаҐЇ®«­Ґ­ЁЁ ЎгдҐа  ўбҐ Ї®«г祭­лҐ ¤ ­­лҐ вҐаповбп + Ё § Ї®«­Ґ­ЁҐ ­ зЁ­ Ґвбп б­®ў  б ­г«п. + * „«п ўлў®¤  ­  ¤®бЄг ®в« ¤ЄЁ Ў®«ҐҐ б«®¦­ле ®ЎкҐЄв®ў (бва®Є, зЁбҐ«) + ¤®бв в®з­® нв®© дг­ЄжЁЁ, ўл§лў Ґ¬®© ў жЁЄ«Ґ. Њ®¦­® ­Ґ ЇЁб вм + ўагз­го ᮮ⢥вбвўгойЁ© Є®¤,   ў®бЇ®«м§®ў вмбп д ©«®¬ debug.inc, + ўе®¤пйЁ¬ ў ¤ЁбваЁЎгвЁў. + +---------------------------- —⥭ЁҐ Ў ©в  ---------------------------- +‡ ЎЁа Ґв Ў ©в Ё§ ЎгдҐа . +Џ а ¬Ґвал: + * eax = 63 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ebx = 0 - ЎгдҐа Їгбв + * eax = Ў ©в, ebx = 1 - Ў ©в гбЇҐи­® Їа®зЁв ­ + +====================================================================== +========== ”г­ЄжЁп 64 - ЇҐаҐа бЇаҐ¤Ґ«Ёвм Ї ¬пвм ЇаЁ«®¦Ґ­Ёп. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 64 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - Ґ¤Ё­б⢥­­ п Ї®¤дг­ЄжЁп + * ecx = ­®ўл© а §¬Ґа Ї ¬пвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ¤®бв в®з­® Ї ¬пвЁ +‡ ¬Ґз ­Ёп: + * …бвм ¤агЈ®© бЇ®б®Ў ўл¤Ґ«Ґ­Ёп/®бў®Ў®¦¤Ґ­Ёп ¤Ё­ ¬ЁзҐбЄ®© Ї ¬пвЁ - + Ї®¤дг­ЄжЁЁ 11, 12, 13 дг­ЄжЁЁ 68. + * ”г­ЄжЁп ­Ґ ¬®¦Ґв ЁбЇ®«м§®ў вмбп б®ў¬Ґбв­® б 68.11, 68.12, 68.13. + ‚л§®ў дг­ЄжЁЁ Ўг¤Ґв ЁЈ­®аЁа®ў вмбп, Ґб«Ё ЇаЁ«®¦Ґ­ЁҐ б®§¤ бв + «®Є «м­го Єгзг ўл§®ў®¬ 68.11. + +====================================================================== +========= ”г­ЄжЁп 65 - ўлўҐбвЁ Ё§®Ўа ¦Ґ­ЁҐ б Ї «Ёва®© ў ®Є­®. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 65 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё§®Ўа ¦Ґ­ЁҐ + * ecx = [а §¬Ґа Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] + * esi = зЁб«® ЎЁв ­  ЇЁЄбҐ«м, ¤®«¦­® Ўлвм 1,2,4,8,15,16,24 Ё«Ё 32 + * edi = гЄ § вҐ«м ­  Ї «Ёваг (2 ў б⥯Ґ­Ё esi 梥⮢ 0x00RRGGBB); + ЁЈ­®аЁагҐвбп ЇаЁ esi > 8 + * ebp = ᬥ饭ЁҐ ¤ ­­ле Є ¦¤®© б«Ґ¤го饩 бва®ЄЁ Ё§®Ўа ¦Ґ­Ёп + ®в­®бЁвҐ«м­® ЇаҐ¤л¤г饩 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл Ё§®Ўа ¦Ґ­Ёп - нв® Є®®а¤Ё­ вл ўҐае­ҐЈ® «Ґў®Ј® гЈ«  + Ё§®Ўа ¦Ґ­Ёп ®в­®бЁвҐ«м­® ®Є­ . + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 1 ЎЁв®¬ ­  ЇЁЄбҐ«м: Є ¦¤л© Ў ©в Ё§®Ўа ¦Ґ­Ёп, + §  ЁбЄ«о祭ЁҐ¬, Ўлвм ¬®¦Ґв, Ї®б«Ґ¤­Ёе Ў ©в®ў бва®Є, ᮤҐа¦Ёв + Ё­д®а¬ жЁо ® 梥⥠8 ЇЁЄбҐ«Ґ©, бв аиЁ© ЎЁв ᮮ⢥вбвўгҐв ЇҐаў®¬г + ЇЁЄбҐ«о. + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 2 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: Є ¦¤л© Ў ©в Ё§®Ўа ¦Ґ­Ёп, + §  ЁбЄ«о祭ЁҐ¬, Ўлвм ¬®¦Ґв, Ї®б«Ґ¤­Ёе Ў ©в®ў бва®Є, ᮤҐа¦Ёв + Ё­д®а¬ жЁо ® 梥⥠4 ЇЁЄбҐ«Ґ©, бв аиЁҐ ¤ў  ЎЁв  ᮮ⢥вбвўгов + ЇҐаў®¬г ЇЁЄбҐ«о. + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 4 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: Є ¦¤л© Ў ©в Ё§®Ўа ¦Ґ­Ёп, + §  ЁбЄ«о祭ЁҐ¬ Ї®б«Ґ¤­Ёе Ў ©в®ў бва®Є (Ґб«Ё иЁаЁ­  Ё§®Ўа ¦Ґ­Ёп + ­Ґзсв­ ), ᮤҐа¦Ёв Ё­д®а¬ жЁо ® 梥⥠2 ЇЁЄбҐ«Ґ©, бв аи п вҐва ¤  + ᮮ⢥вбвўгҐв ЇҐаў®¬г ЇЁЄбҐ«о. + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 8 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: Є ¦¤л© Ў ©в Ё§®Ўа ¦Ґ­Ёп + а бб¬ ваЁў Ґвбп Є Є Ё­¤ҐЄб ў Ї «ЁваҐ. + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 15 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: 梥⠪ ¦¤®Ј® ЇЁЄбҐ«п + Є®¤ЁагҐвбп Є Є (ў ЎЁв®ў®¬ ЇаҐ¤бв ў«Ґ­ЁЁ) 0RRRRRGGGGGBBBBB - + Ї® 5 ЇЁЄбҐ«Ґ© ­  Є ¦¤л© 梥в. + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 16 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: 梥⠪ ¦¤®Ј® ЇЁЄбҐ«п + Є®¤ЁагҐвбп Є Є RRRRRGGGGGGBBBBB (б奬  5+6+5). + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 24 ЎЁв ¬Ё ­  ЇЁЄбҐ«м: 梥⠪ ¦¤®Ј® ЇЁЄбҐ«п + Є®¤ЁагҐвбп ваҐ¬п Ў ©в ¬Ё - Ї®б«Ґ¤®ў вҐ«м­® бЁ­пп, §Ґ«с­ п, Єа б­ п + б®бв ў«пойЁҐ 梥в . + * ”®а¬ в Ё§®Ўа ¦Ґ­Ёп б 32 ЎЁв ¬Ё ­  ЇЁЄбҐ«м:  ­ «®ЈЁз­® 24, в®«мЄ® + Ґбвм Ґйс ЁЈ­®аЁагҐ¬л© зҐвўсавл© Ў ©в. + * ‚л§®ў дг­ЄжЁЁ 7 нЄўЁў «Ґ­вҐ­ ўл§®ўг нв®© дг­ЄжЁЁ б Ї а ¬Ґва ¬Ё + esi=24, ebp=0. + +====================================================================== +================= ”г­ЄжЁп 66 - а Ў®в  б Є« ўЁ вга®©. ================= +====================================================================== +ђҐ¦Ё¬ ўў®¤  ў«ЁпҐв ­  १г«мв вл з⥭Ёп Є« ўЁи дг­ЄжЁҐ© 2. +ЏаЁ § Јаг§ЄҐ Їа®Ја ¬¬л ¤«п ­Ґс гбв ­ ў«Ёў Ґвбп ASCII-०Ё¬ ўў®¤ . + +-------- Џ®¤дг­ЄжЁп 1 - гбв ­®ўЁвм ०Ё¬ ўў®¤  б Є« ўЁ вгал. --------- +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ०Ё¬: + * 0 = ®Ўлз­л© (ASCII-бЁ¬ў®«л) + * 1 = бЄ ­Є®¤л +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +--------- Џ®¤дг­ЄжЁп 2 - Ї®«гзЁвм ०Ё¬ ўў®¤  б Є« ўЁ вгал. ---------- +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ⥪гйЁ© ०Ё¬ + +------- Џ®¤дг­ЄжЁп 3 - Ї®«гзЁвм б®бв®п­ЁҐ гЇа ў«пойЁе Є« ўЁи. -------- +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ЎЁв®ў п ¬ бЄ : + * ЎЁв 0 (¬ бЄ  1): «Ґўл© Shift ­ ¦ в + * ЎЁв 1 (¬ бЄ  2): Їа ўл© Shift ­ ¦ в + * ЎЁв 2 (¬ бЄ  4): «Ґўл© Ctrl ­ ¦ в + * ЎЁв 3 (¬ бЄ  8): Їа ўл© Ctrl ­ ¦ в + * ЎЁв 4 (¬ бЄ  0x10): «Ґўл© Alt ­ ¦ в + * ЎЁв 5 (¬ бЄ  0x20): Їа ўл© Alt ­ ¦ в + * ЎЁв 6 (¬ бЄ  0x40): CapsLock ўЄ«озс­ + * ЎЁв 7 (¬ бЄ  0x80): NumLock ўЄ«озс­ + * ЎЁв 8 (¬ бЄ  0x100): ScrollLock ўЄ«озс­ + * Їа®зЁҐ ЎЁвл бЎа®иҐ­л + +----- Џ®¤дг­ЄжЁп 4 - гбв ­®ўЁвм ®ЎйҐбЁб⥬­го "Ј®апзго Є« ўЁиг". ----- +Ћ ­ ¦ вЁЁ "Ј®ап祩 Є« ўЁиЁ" Ё§ўҐй овбп в®«мЄ® ЇаЁ«®¦Ґ­Ёп, +гбв ­®ўЁўиЁҐ Ґс;  ЄвЁў­®Ґ ЇаЁ«®¦Ґ­ЁҐ (Є Є®в®а®¬г Ї®бвгЇ Ґв +ўҐбм ­®а¬ «м­л© ўў®¤) в ЄЁе Є« ўЁи ­Ґ Ї®«гз Ґв. +€§ўҐйҐ­ЁҐ § Є«оз Ґвбп ў Ї®бл«ЄҐ б®ЎлвЁп б Є®¤®¬ 2. +Џа®зЁв вм "Ј®апзго Є« ўЁиг" ¬®¦­® в Є ¦Ґ, Є Є Ё ®Ўлз­го, - +дг­ЄжЁҐ© 2. +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl § ¤ св бЄ ­Є®¤ Є« ўЁиЁ; + ЁбЇ®«м§г©вҐ cl=0 ¤«п § ¤ ­Ёп Є®¬ЎЁ­ жЁ© вЁЇ  Ctrl+Shift + * edx = 0xXYZ § ¤ св ў®§¬®¦­лҐ б®бв®п­Ёп гЇа ў«пойЁе Є« ўЁи: + * Z (¬« ¤иЁҐ 4 ЎЁв ) § ¤ св б®бв®п­ЁҐ Є« ўЁи LShift Ё RShift: + * 0 = ­Ё ®¤­  Ё§ Є« ўЁи ­Ґ ¤®«¦­  Ўлвм ­ ¦ в ; + * 1 = а®ў­® ®¤­  Ё§ Є« ўЁи ¤®«¦­  Ўлвм ­ ¦ в ; + * 2 = ®ЎҐ Є« ўЁиЁ ¤®«¦­л Ўлвм ­ ¦ вл; + * 3 = ¤®«¦­  Ўлвм ­ ¦ в  LShift, ­® ­Ґ RShift; + * 4 = ¤®«¦­  Ўлвм ­ ¦ в  RShift, ­® ­Ґ LShift + * Y -  ­ «®ЈЁз­® ¤«п LCtrl Ё RCtrl; + * X -  ­ «®ЈЁз­® ¤«п LAlt Ё RAlt +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax=0 - гбЇҐи­® + * eax=1 - б«ЁиЄ®¬ ¬­®Ј® "Ј®апзЁе Є« ўЁи" (¤®ЇгбЄ Ґвбп ¬ ЄбЁ¬г¬ 256) +‡ ¬Ґз ­Ёп: + * ѓ®апз п Є« ўЁи  ¬®¦Ґв ба Ў влў вм «ЁЎ® ЇаЁ ­ ¦ вЁЁ, + «ЁЎ® ЇаЁ ®вЇгбЄ ­ЁЁ. ‘Є ­Є®¤ ®вЇгбЄ ­Ёп Є« ўЁиЁ ­  128 Ў®«миҐ, + 祬 бЄ ­Є®¤ ­ ¦ вЁп (в.Ґ. гбв ­®ў«Ґ­ бв аиЁ© ЎЁв). + * ЌҐбЄ®«мЄ® ЇаЁ«®¦Ґ­Ё© ¬®Јгв гбв ­®ўЁвм ®¤­г Ё вг ¦Ґ Є®¬ЎЁ­ жЁо; + ® ­ ¦ вЁЁ в Є®© Є®¬ЎЁ­ жЁЁ Ўг¤гв Ё§ўҐй вмбп ўбҐ в ЄЁҐ ЇаЁ«®¦Ґ­Ёп. + +------ Џ®¤дг­ЄжЁп 5 - г¤ «Ёвм гбв ­®ў«Ґ­­го "Ј®апзго Є« ўЁиг". ------- +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl = бЄ ­Є®¤ Є« ўЁиЁ Ё edx = 0xXYZ в ЄЁҐ ¦Ґ, Є Є Ё ў Ї®¤дг­ЄжЁЁ 4 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґв в Є®© Ј®ап祩 Є« ўЁиЁ +‡ ¬Ґз ­Ёп: + * ЏаЁ § ўҐа襭ЁЁ Їа®жҐбб /Ї®в®Є  г¤ «повбп ўбҐ гбв ­®ў«Ґ­­лҐ Ё¬ + Ј®апзЁҐ Є« ўЁиЁ. + * ‚л§®ў дг­ЄжЁЁ ­Ґ ў«ЁпҐв ­  ¤агЈЁҐ ЇаЁ«®¦Ґ­Ёп. + …б«Ё ¤агЈ®Ґ ЇаЁ«®¦Ґ­ЁҐ ®ЇаҐ¤Ґ«Ё«® нвг ¦Ґ Є®¬ЎЁ­ жЁо, + ®­® Ї®-ЇаҐ¦­Ґ¬г Ўг¤Ґв Ї®«гз вм 㢥¤®¬«Ґ­Ёп. + +====================================================================== +============ ”г­ЄжЁп 67 - Ё§¬Ґ­Ёвм Ї®«®¦Ґ­ЁҐ/а §¬Ґал ®Є­ . =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 67 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®ў п x-Є®®а¤Ё­ в  ®Є­  + * ecx = ­®ў п y-Є®®а¤Ё­ в  ®Є­  + * edx = ­®ўл© x-а §¬Ґа ®Є­  + * esi = ­®ўл© y-а §¬Ґа ®Є­  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‡­ зҐ­ЁҐ -1 ¤«п Ї а ¬Ґва  ®§­ з Ґв "­Ґ Ё§¬Ґ­пвм"; ­ ЇаЁ¬Ґа, ¤«п + ЇҐаҐ¬ҐйҐ­Ёп ®Є­  ЎҐ§ Ё§¬Ґ­Ґ­Ёп а §¬Ґа®ў ¬®¦­® гЄ § вм edx=esi=-1. + * ЏаҐ¤ў аЁвҐ«м­® ®Є­® ¤®«¦­® Ўлвм ®ЇаҐ¤Ґ«Ґ­® дг­ЄжЁҐ© 0. + Ћ­  ¦Ґ § ¤ св ­ з «м­лҐ Є®®а¤Ё­ вл Ё а §¬Ґал ®Є­ . + * ђ §¬Ґал ®Є­  Ї®­Ё¬ овбп ў б¬лб«Ґ дг­ЄжЁЁ 0, в.Ґ. + ­  ®¤Ё­ ЇЁЄбҐ«м ¬Ґ­миҐ, 祬 ॠ«м­лҐ а §¬Ґал. + * ‚л§®ў дг­ЄжЁЁ ¤«п ¬ ЄбЁ¬Ё§Ёа®ў ­­ле ®Є®­ Їа®бв® ЁЈ­®аЁагҐвбп. + * „«п ®Є®­ ᮮ⢥вбвўгойЁе бвЁ«Ґ© Ї®«®¦Ґ­ЁҐ Ё/Ё«Ё а §¬Ґал ¬®Јгв Ўлвм + Ё§¬Ґ­Ґ­л Ї®«м§®ў вҐ«Ґ¬; ⥪гйЁҐ Ї®«®¦Ґ­ЁҐ Ё а §¬Ґал ¬®Јгв Ўлвм + Ї®«гзҐ­л ўл§®ў®¬ дг­ЄжЁЁ 9. + * ”г­ЄжЁп Ї®бл« Ґв ®Є­г б®ЎлвЁҐ ЇҐаҐаЁб®ўЄЁ (б Є®¤®¬ 1). + +====================================================================== +=== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм бзсвзЁЄ ЇҐаҐЄ«о祭Ё© § ¤ з. == +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® ЇҐаҐЄ«о祭Ё© § ¤ з б ¬®¬Ґ­в  § Јаг§ЄЁ бЁб⥬л + (Ї® ¬®¤г«о 2^32) + +====================================================================== +====================== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 1 ====================== +============ ЏҐаҐЄ«озЁвмбп ­  б«Ґ¤гойЁ© Ї®в®Є ўлЇ®«­Ґ­Ёп. ============ +====================================================================== +”г­ЄжЁп § ўҐаи Ґв ⥪гйЁ© Єў ­в ўаҐ¬Ґ­Ё, ўл¤Ґ«Ґ­­л© Ї®в®Єг, +Ё ЇҐаҐЄ«оз Ґвбп ­  б«Ґ¤гойЁ©. +(Љ Є®© Ї®в®Є Є Є®Ј® Їа®жҐбб  Ўг¤Ґв б«Ґ¤гойЁ¬, ЇаҐ¤бЄ § вм ­Ґ«м§п). +Џ®§¤­ҐҐ, Є®Ј¤  ¤® ⥪г饣® Ї®в®Є  ¤®©¤св ®зҐаҐ¤м, +ўлЇ®«­Ґ­ЁҐ ў®§®Ў­®ўЁвбп. +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +=============== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 2 - Єни + rdpmc. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вॡ㥬®Ґ ¤Ґ©бвўЁҐ: + * ecx = 0 - а §аҐиЁвм ўлЇ®«­Ґ­ЁҐ Ё­бвагЄжЁЁ rdpmc + (ReaD Performance-Monitoring Counters) + * ecx = 1 - г§­ вм, ўЄ«озс­/ўлЄ«о祭 Єни + * ecx = 2 - ўЄ«озЁвм Єни + * ecx = 3 - ўлЄ«озЁвм Єни +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ¤«п ecx=0: + * eax = §­ зҐ­ЁҐ cr4 + * ¤«п ecx=1: + * eax = (cr0 and 0x60000000): + * eax = 0 - Єни ўЄ«озс­ + * eax <> 0 - Єни ўлЄ«о祭 + * ¤«п ecx=2 Ё ecx=3: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +========== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 3 - Їа®зЁв вм MSR-ॣЁбва. ========= +====================================================================== +MSR = Model Specific Register; Ї®«­л© бЇЁб®Є MSR-ॣЁбва®ў Їа®жҐбб®а  +ᮤҐа¦Ёвбп ў ¤®Єг¬Ґ­в жЁЁ Ї® Їа®жҐбб®аг (­ ЇаЁ¬Ґа, IA-32 Intel +Architecture Software Developer's Manual, Volume 3, Appendix B); +Є ¦¤®Ґ ᥬҐ©бвў® Їа®жҐбб®а®ў Ё¬ҐҐв бў®с Ї®¤¬­®¦Ґбвў® MSR-ॣЁбва®ў. +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx ЁЈ­®аЁагҐвбп + * edx =  ¤аҐб MSR +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ebx:eax = бв аиЁ©:¬« ¤иЁ© dword १г«мв в  +‡ ¬Ґз ­Ёп: + * “Є § ­ЁҐ ў ecx ­ҐбгйҐбвўго饣® Ё«Ё ­ҐаҐ «Ё§®ў ­­®Ј® ¤«п ¤ ­­®Ј® + Їа®жҐбб®а  MSR Ї®ў«Ґзсв ЁбЄ«о祭ЁҐ ў п¤аҐ, Є®в®а®Ґ ЇаЁЎмсв Ї®в®Є. + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв ®ЇаҐ¤Ґ«Ёвм, Ї®¤¤Ґа¦Ёў овбп «Ё MSR ў 楫®¬, + Є®¬ ­¤®© cpuid. €­ зҐ ў®§­ЁЄ­Ґв 㦥 ¤агЈ®Ґ ЁбЄ«о祭ЁҐ ў п¤аҐ, + Є®в®а®Ґ ўбс а ў­® ЇаЁЎмсв Ї®в®Є. + +====================================================================== +========= ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 4 - § ЇЁб вм ў MSR-ॣЁбва. ========= +====================================================================== +MSR = Model Specific Register; Ї®«­л© бЇЁб®Є MSR-ॣЁбва®ў Їа®жҐбб®а  +ᮤҐа¦Ёвбп ў ¤®Єг¬Ґ­в жЁЁ Ї® Їа®жҐбб®аг (­ ЇаЁ¬Ґа, IA-32 Intel +Architecture Software Developer's Manual, Volume 3, Appendix B); +Є ¦¤®Ґ ᥬҐ©бвў® Їа®жҐбб®а®ў Ё¬ҐҐв бў®с Ї®¤¬­®¦Ґбвў® MSR-ॣЁбва®ў. +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx ЁЈ­®аЁагҐвбп + * edx =  ¤аҐб MSR + * esi:edi = бв аиЁ©:¬« ¤иЁ© dword +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * “Є § ­ЁҐ ў ecx ­ҐбгйҐбвўго饣® Ё«Ё ­ҐаҐ «Ё§®ў ­­®Ј® ¤«п ¤ ­­®Ј® + Їа®жҐбб®а  MSR Ї®ў«Ґзсв ЁбЄ«о祭ЁҐ ў п¤аҐ, Є®в®а®Ґ ЇаЁЎмсв Ї®в®Є. + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв ®ЇаҐ¤Ґ«Ёвм, Ї®¤¤Ґа¦Ёў овбп «Ё MSR ў 楫®¬, + Є®¬ ­¤®© cpuid. €­ зҐ ў®§­ЁЄ­Ґв 㦥 ¤агЈ®Ґ ЁбЄ«о祭ЁҐ ў п¤аҐ, + Є®в®а®Ґ ўбс а ў­® ЇаЁЎмсв Ї®в®Є. + +====================================================================== +===== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 11 - Ё­ЁжЁ «Ё§Ёа®ў вм Єгзг Їа®жҐбб . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ­ҐгбЇҐе + * Ё­ зҐ а §¬Ґа б®§¤ ­­®© ЄгзЁ +‡ ¬Ґз ­Ёп: + * ‚л§®ў дг­ЄжЁЁ Ё­ЁжЁ «Ё§ЁагҐв Єгзг, Ё§ Є®в®а®© ўЇ®б«Ґ¤бвўЁЁ ¬®¦­® + ўл¤Ґ«пвм Ё ®бў®Ў®¦¤ вм Ў«®ЄЁ Ї ¬пвЁ Ї®¤дг­ЄжЁп¬Ё 12 Ё 13. + ђ §¬Ґа ЄгзЁ а ўҐ­ а §¬Ґа㠢ᥩ бў®Ў®¤­®© Ї ¬пвЁ ЇаЁ«®¦Ґ­Ёп. + * ЏаЁ Ї®ўв®а­®¬ ўл§®ўҐ дг­ЄжЁЁ ⥬ ¦Ґ Їа®жҐбᮬ дг­ЄжЁп ўҐа­св + а §¬Ґа бгйҐбвўго饩 ЄгзЁ. + * Џ®б«Ґ б®§¤ ­Ёп ЄгзЁ ўл§®ўл дг­ЄжЁЁ 64 ЁЈ­®аЁаговбп. + +====================================================================== +========== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 12 - ўл¤Ґ«Ёвм Ў«®Є Ї ¬пвЁ. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ваҐЎгҐ¬л© а §¬Ґа ў Ў ©в е +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = гЄ § вҐ«м ­  ўл¤Ґ«Ґ­­л© Ў«®Є +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв Ё­ЁжЁ «Ё§Ёа®ў вм Єгзг Їа®жҐбб  ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11. + * ”г­ЄжЁп ўл¤Ґ«пҐв 楫®Ґ зЁб«® бва ­Ёж (4 ЉЎ) в Є, зв® д ЄвЁзҐбЄЁ© + а §¬Ґа ўл¤Ґ«Ґ­­®Ј® Ў«®Є  Ў®«миҐ Ё«Ё а ўҐ­ § Їа®иҐ­­®¬г. + +====================================================================== +========= ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 13 - ®бў®Ў®¤Ёвм Ў«®Є Ї ¬пвЁ. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  Ў«®Є Ї ¬пвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 1 - гбЇҐи­® + * eax = 0 - ­Ґг¤ з  +‡ ¬Ґз ­Ёп: + * Ѓ«®Є Ї ¬пвЁ ¤®«¦Ґ­ Ўлвм а ­ҐҐ ўл¤Ґ«Ґ­ Ї®¤дг­ЄжЁҐ© 12 + Ё«Ё Ї®¤дг­ЄжЁҐ© 20. + +====================================================================== +==================== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 14 ======================= +===== Ћ¦Ё¤ вм Ї®«г祭Ёп бЁЈ­ « , ®в ¤агЈЁе ЇаЁ«®¦Ґ­Ё©/¤а ©ўҐа®ў. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 14 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа ¤«п Ё­д®а¬ жЁЁ (24 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв ecx, ᮤҐа¦Ёв б«Ґ¤гойго Ё­д®а¬ жЁо: + * +0: dword: Ё¤Ґ­вЁдЁЄ в®а Ї®б«Ґ¤гойЁе ¤ ­­ле бЁЈ­ «  + * +4: ¤ ­­лҐ ЇаЁ­пв®Ј® бЁЈ­ «  (20 Ў ©в), д®а¬ в Є®в®але + ®ЇаҐ¤Ґ«пҐвбп ЇҐаўл¬ dword-®¬ + +====================================================================== +== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 15 - гбв ­®ўЁвм ®Ўа Ў®взЁЄ ЁбЄ«о祭Ё© FPU. = +====================================================================== +“¤ «Ґ­  (ў ⥪г饩 ॠ«Ё§ жЁЁ Їа®бв® ў®§ўа й Ґв 0) +€бЇ®«м§®ў вм Ї®¤дг­ЄжЁЁ 24, 25 + +====================================================================== +=========== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 16 - § Јаг§Ёвм ¤а ©ўҐа. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 16 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ ¤а ©ўҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ­Ґг¤ з  + * Ё­ зҐ eax = ен­¤« ¤а ©ўҐа  +‡ ¬Ґз ­Ёп: + * …б«Ё ¤а ©ўҐа Ґйс ­Ґ § Ја㦥­, ®­ § Јаг¦ Ґвбп; + Ґб«Ё ¤а ©ўҐа 㦥 § Ја㦥­, ­ЁзҐЈ® ­Ґ ¬Ґ­пҐвбп. + * €¬п ¤а ©ўҐа  згўб⢨⥫쭮 Є ॣЁбваг бЁ¬ў®«®ў. + Њ ЄбЁ¬ «м­ п ¤«Ё­  Ё¬Ґ­Ё - 16 бЁ¬ў®«®ў, ўЄ«оз п § ўҐаи ойЁ© + ­г«Ґў®© бЁ¬ў®«, ®бв «м­лҐ бЁ¬ў®«л ЁЈ­®аЁаговбп. + * „а ©ўҐа б Ё¬Ґ­Ґ¬ ABC § Јаг¦ Ґвбп Ё§ д ©«  /rd/1/drivers/ABC.obj. + +====================================================================== +========== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 17 - гЇа ў«Ґ­ЁҐ ¤а ©ўҐа®¬. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 17 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  гЇа ў«пойго бвагЄвгаг: + * +0: dword: ен­¤« ¤а ©ўҐа  + * +4: dword: Є®¤ дг­ЄжЁЁ ¤а ©ўҐа  + * +8: dword: гЄ § вҐ«м ­  ўе®¤­лҐ ¤ ­­лҐ + * +12 = +0xC: dword: а §¬Ґа ўе®¤­ле ¤ ­­ле + * +16 = +0x10: dword: гЄ § вҐ«м ­  ўл室­лҐ ¤ ­­лҐ + * +20 = +0x14: dword: а §¬Ґа ўл室­ле ¤ ­­ле +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ®ЇаҐ¤Ґ«пҐвбп ¤а ©ўҐа®¬ +‡ ¬Ґз ­Ёп: + * Љ®¤л дг­ЄжЁ© Ё бвагЄвга  ўе®¤­ле/ўл室­ле ¤ ­­ле + ®ЇаҐ¤Ґ«повбп ¤а ©ўҐа®¬. + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ї®«г祭 ен­¤« ¤а ©ўҐа  Ї®¤дг­ЄжЁҐ© 16. + +====================================================================== +== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 18 - гбв ­®ўЁвм ®Ўа Ў®взЁЄ ЁбЄ«о祭Ё© SSE. = +====================================================================== +“¤ «Ґ­  (ў ⥪г饩 ॠ«Ё§ жЁЁ Їа®бв® ў®§ўа й Ґв 0) +€бЇ®«м§®ў вм Ї®¤дг­ЄжЁЁ 24, 25 + +====================================================================== +============= ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 19 - § Јаг§Ёвм DLL. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ї®«­л¬ Їгвс¬ Є DLL +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ­Ґг¤ з  + * Ё­ зҐ eax = гЄ § вҐ«м ­  в Ў«Ёжг нЄбЇ®ав  DLL +‡ ¬Ґз ­Ёп: + * ’ Ў«Ёж  нЄбЇ®ав  ЇаҐ¤бв ў«пҐв б®Ў®© ¬ ббЁў бвагЄвга Ї® 2 dword' , + § Є ­зЁў ойЁ©бп ­г«с¬. ЏҐаўл© dword ў бвагЄвгॠпҐвбп + гЄ § вҐ«Ґ¬ ­  Ё¬п дг­ЄжЁЁ, ўв®а®© ᮤҐа¦Ёв  ¤аҐб дг­ЄжЁЁ. + +====================================================================== +====== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 20 - ЇҐаҐа бЇаҐ¤Ґ«Ёвм Ў«®Є Ї ¬пвЁ. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 20 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®ўл© а §¬Ґа ў Ў ©в е + * edx = гЄ § вҐ«м ­  㦥 ўл¤Ґ«Ґ­­л© Ў«®Є Ї ¬пвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = гЄ § вҐ«м ­  ЇҐаҐа бЇаҐ¤Ґ«с­­л© Ў«®Є, 0 ЇаЁ ®иЁЎЄҐ +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв Ё­ЁжЁ «Ё§Ёа®ў вм Єгзг Їа®жҐбб  ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11. + * ”г­ЄжЁп ўл¤Ґ«пҐв 楫®Ґ зЁб«® бва ­Ёж (4 ЉЎ) в Є, зв® д ЄвЁзҐбЄЁ© + а §¬Ґа ўл¤Ґ«Ґ­­®Ј® Ў«®Є  Ў®«миҐ Ё«Ё а ўҐ­ § Їа®иҐ­­®¬г. + * …б«Ё edx=0, в® ўл§®ў дг­ЄжЁЁ нЄўЁў «Ґ­вҐ­ ўл¤Ґ«Ґ­Ёо Ї ¬пвЁ + Ї®¤дг­ЄжЁҐ© 12. ‚ Їа®вЁў­®¬ б«гз Ґ Ў«®Є Ї ¬пвЁ Ї®  ¤аҐбг edx + ¤®«¦Ґ­ Ўлвм а ­ҐҐ ўл¤Ґ«Ґ­ Ї®¤дг­ЄжЁҐ© 12 Ё«Ё + ®ЇЁблў Ґ¬®© Ї®¤дг­ЄжЁҐ©. + * …б«Ё ecx=0, в® дг­ЄжЁп ®бў®Ў®¦¤ Ґв Ў«®Є Ї ¬пвЁ Ї®  ¤аҐбг edx Ё + ў®§ўа й Ґв 0. + * ‘®¤Ґа¦Ё¬®Ґ Ї ¬пвЁ ўЇ«®вм ¤® ­ Ё¬Ґ­м襣® Ё§ бв а®Ј® Ё ­®ў®Ј® + а §¬Ґа®ў б®еа ­пҐвбп. + +====================================================================== +=== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 22 - ®вЄалвм Ё¬Ґ­®ў ­­го ®Ў« бвм Ї ¬пвЁ. == +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 22 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¬п ®Ў« бвЁ. Њ ЄбЁ¬г¬ 31 бЁ¬ў®«, ўЄ«оз п § ўҐаи ойЁ© ­®«м + * edx = а §¬Ґа ®Ў« бвЁ ў Ў ©в е ¤«п SHM_CREATE Ё SHM_OPEN_ALWAYS + * esi = д« ЈЁ ®вЄалвЁп Ё ¤®бвгЇ : + * SHM_OPEN = 0x00 - ®вЄалвм бгйҐбвўгойго ®Ў« бвм Ї ¬пвЁ. + …б«Ё ®Ў« бвм б в ЄЁ¬ Ё¬Ґ­Ґ¬ ­Ґ бгйҐбвўгҐв, + дг­ЄжЁп ўҐа­св Є®¤ ®иЁЎЄЁ 5. + * SHM_OPEN_ALWAYS = 0x04 - ®вЄалвм бгйҐбвўгойго Ё«Ё б®§¤ вм ­®ўго + ®Ў« бвм Ї ¬пвЁ. + * SHM_CREATE = 0x08 - б®§¤ вм ­®ўго ®Ў« бвм Ї ¬пвЁ. + …б«Ё ®Ў« бвм б в ЄЁ¬ Ё¬Ґ­Ґ¬ 㦥 бгйҐбвўгҐв, + дг­ЄжЁп ўҐа­св Є®¤ ®иЁЎЄЁ 10. + * SHM_READ = 0x00 - ¤®бвгЇ в®«мЄ® ­  з⥭ЁҐ + * SHM_WRITE = 0x01 - ¤®бвгЇ ­  з⥭ЁҐ Ё § ЇЁбм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = гЄ § вҐ«м ­  ®Ў« бвм Ї ¬пвЁ, 0 ЇаЁ ®иЁЎЄҐ + * ЇаЁ б®§¤ ­ЁЁ ­®ў®© ®Ў« бвЁ (SHM_CREATE Ё«Ё SHM_OPEN_ALWAYS): + edx = 0 - гбЇҐе, Ё­ зҐ - Є®¤ ®иЁЎЄЁ + * ЇаЁ ®вЄалвЁЁ бгйҐбвўго饩 ®Ў« бвЁ (SHM_OPEN Ё«Ё SHM_OPEN_ALWAYS): + edx = Є®¤ ®иЁЎЄЁ (ЇаЁ eax=0) Ё«Ё а §¬Ґа ®Ў« бвЁ ў Ў ©в е +Љ®¤л ®иЁЎ®Є: + * E_NOTFOUND = 5 + * E_ACCESS = 10 + * E_NOMEM = 30 + * E_PARAM = 33 +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв Ё­ЁжЁ «Ё§Ёа®ў вм Єгзг Їа®жҐбб  ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11. + * …б«Ё б®§¤ свбп ­®ў п ®Ў« бвм, в® д« ЈЁ ¤®бвгЇ  гбв ­ ў«Ёў ов + ¬ ЄбЁ¬ «м­лҐ Їа ў  ¤®бвгЇ  ¤«п ®бв «м­ле Їа®жҐбб®ў. Џ®ЇлвЄ  + ®вЄалвЁп ¤агЈЁ¬ Ї®в®Є®¬ б ­Ґа §аҐис­­л¬Ё Їа ў ¬Ё Їа®ў «Ёвбп + б Є®¤®¬ ®иЁЎЄЁ E_ACCESS. + * Џа®жҐбб, б®§¤ ўиЁ© ®Ў« бвм, ўбҐЈ¤  Ё¬ҐҐв ¤®бвгЇ ­  § ЇЁбм. + +====================================================================== +=== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 23 - § Єалвм Ё¬Ґ­®ў ­­го ®Ў« бвм Ї ¬пвЁ. == +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 23 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¬п ®Ў« бвЁ. Њ ЄбЁ¬г¬ 31 бЁ¬ў®«, ўЄ«оз п § ўҐаи ойЁ© ­®«м +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ЋЎ« бвм Ї ¬пвЁ дЁ§ЁзҐбЄЁ ®бў®Ў®¦¤ Ґвбп (б § Ўлў ­ЁҐ¬ ўбҐе ¤ ­­ле + Ё ўлбў®Ў®¦¤Ґ­ЁҐ¬ дЁ§ЁзҐбЄ®© Ї ¬пвЁ), Є®Ј¤  Ґс § Єа®ов + ўбҐ ®вЄалўиЁҐ Ї®в®ЄЁ. + * ЏаЁ § ўҐа襭ЁЁ Ї®в®Є  ®бў®Ў®¦¤ овбп ўбҐ ®вЄалвлҐ Ё¬ + ®Ў« бвЁ Ї ¬пвЁ. + +====================================================================== +==== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 24 - гбв ­®ўЁвм ®Ўа Ў®взЁЄ ЁбЄ«о祭Ё© === +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 24 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx =  ¤аҐб ­®ў®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© + * edx = ¬ бЄ  ®Ўа Ў влў Ґ¬ле ЁбЄ«о祭Ё© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax =  ¤аҐб бв а®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© (0, Ґб«Ё ­Ґ гбв ­®ў«Ґ­) + * ebx = ¬ бЄ  бв а®Ј® ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё© +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа ЎЁв  ў ¬ бЄҐ ЁбЄ«о祭Ё© ᮮ⢥вбвўгов ­®¬Ґаг ЁбЄ«о祭Ёп Ї® + бЇҐжЁдЁЄ жЁЁ ­  Їа®жҐбб®а (Intel-PC). ’ Є ­ ЇаЁ¬Ґа, ЁбЄ«о祭Ёп FPU + Ё¬Ґов ­®¬Ґа 16 (#MF),   SSE - 19 (#XF). + * ‚ ¤ ­­®© ॠ«Ё§ жЁЁ ЁЈ­®аЁагҐвбп § Їа®б ­  ЇҐаҐеў в ЁбЄ«о祭Ёп 7 + - бЁб⥬  ®Ўа Ў влў Ґв #NM б ¬®бв®п⥫쭮. + * Џ®«м§®ў вҐ«мбЄЁ© ®Ўа Ў®взЁЄ Ї®«гз Ґв ­®¬Ґа ЁбЄ«о祭Ёп Ї а ¬Ґв஬ + ў б⥪Ґ. Џ®н⮬㠯ࠢЁ«м­л© ўл室 Ё§ ®Ўа Ў®взЁЄ : RET 4. ‚®§ўа в + ЇаЁ н⮬ Їа®Ё§ў®¤Ёвбп ­  Є®¬ ­¤г, ўл§ў ўиго ЁбЄ«о祭ЁҐ. + * ЏаЁ ЇҐаҐ¤ зҐ гЇа ў«Ґ­Ёп ®Ўа Ў®взЁЄг ЁбЄ«о祭Ё©, бЎа блў Ґвбп + ᮮ⢥вбвўгойЁ© ЎЁв ў ¬ бЄҐ ЁбЄ«о祭Ё©. ‚®§­ЁЄ­®ўҐ­ЁҐ нв®Ј® ¦Ґ + ЁбЄ«о祭Ёп ў Ї®б«Ґ¤бвўЁЁ - ЇаЁўҐ¤Ґв Є default-®Ўа Ў®вЄҐ в Є®ў®Ј®. + Ђ Ё¬Ґ­­®: Є § ўҐа襭Ёо а Ў®вл ЇаЁ«®¦Ґ­Ёп, Ё«Ё ЇаЁ®бв ­®ўЄҐ б + ­®вЁдЁЄ жЁҐ© ®в« ¦Ёў о饬㠯ਫ®¦Ґ­Ёо. + * Џ®б«Ґ § ўҐа襭Ёп ЄаЁвЁзҐбЄЁе ¤Ґ©бвўЁ© ў ®Ўа Ў®взЁЄҐ Ї®«м§®ў вҐ«п, + ў®ббв ­®ў«Ґ­ЁҐ ЎЁв  ¬ бЄЁ ¤ ­­®Ј® ЁбЄ«о祭Ёп ¬®¦­® ᤥ« вм + Ї®¤дг­ЄжЁҐ© 25. ‘Ўа®б д« Ј®ў ЁбЄ«о祭Ё© ў ¬®¤г«пе FPU Ё XMM - + в Є¦Ґ ў®§« Ј Ґвбп ­  ®Ўа Ў®взЁЄ Ї®«м§®ў вҐ«п. + +====================================================================== += ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 25 - Ё§¬Ґ­Ґ­ЁҐ б®бв®п­Ёп  ЄвЁў­®бвЁ бЁЈ­ «  = +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 25 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа бЁЈ­ «  + * edx = §­ зҐ­ЁҐ гбв ­ ў«Ёў Ґ¬®©  ЄвЁў­®бвЁ (0/1) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = бв а®Ґ §­ зҐ­ЁҐ  ЄвЁў­®бвЁ бЁЈ­ «  (0/1) +‡ ¬Ґз ­Ёп: + * ‚ ⥪г饩 ॠ«Ё§ жЁЁ Ё§¬Ґ­пҐвбп в®«мЄ® ¬ бЄ  Ї®«м§®ў вҐ«мбЄ®Ј® + ®Ўа Ў®взЁЄ  ЁбЄ«о祭Ё©, гбв ­®ў«Ґ­­®Ј® Ї®¤дг­ЄжЁҐ© 24. ЏаЁ н⮬, + ­®¬Ґа бЁЈ­ «  ᮮ⢥вбвўгҐв ­®¬Ґаг ЁбЄ«о祭Ёп. + +====================================================================== +======================== ”г­ЄжЁп 69 - ®в« ¤Є . ======================= +====================================================================== +Џа®жҐбб ¬®¦Ґв § Јаг§Ёвм ¤агЈ®© Їа®жҐбб Є Є ®в« ¦Ёў Ґ¬л© гбв ­®ўЄ®© +ᮮ⢥вбвўго饣® ЎЁв  ЇаЁ ўл§®ўҐ Ї®¤дг­ЄжЁЁ 7 дг­ЄжЁЁ 70. +“ Їа®жҐбб  ¬®¦Ґв Ўлвм в®«мЄ® ®¤Ё­ ®в« ¤зЁЄ; ®¤Ё­ Їа®жҐбб ¬®¦Ґв +®в« ¦Ёў вм ­ҐбЄ®«мЄ® а §­ле. ‘Ёб⥬  㢥¤®¬«пҐв ®в« ¤зЁЄ ® б®ЎлвЁпе, +Їа®Ёб室пйЁе б ®в« ¦Ёў Ґ¬л¬ Їа®жҐбᮬ. ‘®®ЎйҐ­Ёп § ЇЁблў овбп ў ЎгдҐа, +®ЇаҐ¤Ґ«с­­л© Ї®¤дг­ЄжЁҐ© 0. +”®а¬ в б®®ЎйҐ­Ёп: + * +0: dword: Є®¤ б®®ЎйҐ­Ёп + * +4: dword: PID ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * +8: ¬®Јгв ЇаЁбгвбвў®ў вм ¤®Ї®«­ЁвҐ«м­лҐ ¤ ­­лҐ, + ®ЇаҐ¤Ґ«пҐ¬лҐ Є®¤®¬ б®®ЎйҐ­Ёп +Љ®¤л б®®ЎйҐ­Ё©: + * 1 = ЁбЄ«о祭ЁҐ + * ¤®Ї®«­ЁвҐ«м­® ЇҐаҐ¤ свбп dword-­®¬Ґа ЁбЄ«о祭Ёп + * Їа®жҐбб ЇаЁ®бв ­®ў«Ґ­ + * 2 = Їа®жҐбб § ўҐаиЁ«бп + * ЇаЁе®¤Ёв ЇаЁ «оЎ®¬ § ўҐа襭ЁЁ: Є Є зҐаҐ§ бЁб⥬­го дг­ЄжЁо -1, + в Є Ё ЇаЁ "гЎЁ©б⢥" «оЎл¬ ¤агЈЁ¬ Їа®жҐбᮬ + (ў ⮬ зЁб«Ґ б ¬Ё¬ ®в« ¤зЁЄ®¬) + * 3 = ®в« ¤®з­®Ґ ЁбЄ«о祭ЁҐ int 1 = #DB + * ¤®Ї®«­ЁвҐ«м­® ЇҐаҐ¤ свбп dword-®Ўа § ॣЁбва  DR6: + * ЎЁвл 0-3: ўлЇ®«­Ґ­® гб«®ўЁҐ ᮮ⢥вбвўго饩 в®зЄЁ ®бв ­®ў  + (гбв ­®ў«Ґ­­®© Ї®¤дг­ЄжЁҐ© 9) + * ЎЁв 14: ЁбЄ«о祭ЁҐ Їа®Ё§®и«® Ё§-§  ०Ё¬  + Ї®и Ј®ў®© ва ббЁа®ўЄЁ (гбв ­®ў«Ґ­ д« Ј TF) + * Їа®жҐбб ЇаЁ®бв ­®ў«Ґ­ +ЏаЁ § ўҐа襭ЁЁ ®в« ¤зЁЄ  ЇаЁЎЁў овбп ўбҐ ®в« ¦Ёў Ґ¬лҐ Їа®жҐббл. +…б«Ё ®в« ¤зЁЄ нв®Ј® ­Ґ е®зҐв, ®­ ¤®«¦Ґ­ ЇаҐ¤ў аЁвҐ«м­® ®вЄ«озЁвмбп +Ї®¤дг­ЄжЁҐ© 3. + +‚ᥠЇ®¤дг­ЄжЁЁ ЇаЁ¬Ґ­Ё¬л в®«мЄ® Є Їа®жҐбб ¬/Ї®в®Є ¬, § Їг饭­л¬ +Ё§ ⥪г饣® дг­ЄжЁҐ© 70 б гбв ­®ў«Ґ­­л¬ д« Ј®¬ ®в« ¤ЄЁ. +Ћв« ¤Є  ¬­®Ј®Ї®в®з­ле Їа®Ја ¬¬ Ї®Є  ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп. +Џ®«­л© бЇЁб®Є Ї®¤дг­ЄжЁ©: + * Ї®¤дг­ЄжЁп 0 - ®ЇаҐ¤Ґ«Ёвм ®Ў« бвм ¤ ­­ле ¤«п ®в« ¤®з­ле б®®ЎйҐ­Ё© + * Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 3 - ®вЄ«озЁвмбп ®в ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 4 - ЇаЁ®бв ­®ўЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є + * Ї®¤дг­ЄжЁп 5 - ў®§®Ў­®ўЁвм ўлЇ®«­Ґ­ЁҐ ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 6 - Їа®зЁв вм Ё§ Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў Ї ¬пвм ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 8 - § ўҐаиЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є + * Ї®¤дг­ЄжЁп 9 - гбв ­®ўЁвм/б­пвм  ЇЇ а в­го в®зЄг ®бв ­®ў  + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 0 ====================== +========= ЋЇаҐ¤Ґ«Ёвм ®Ў« бвм ¤ ­­ле ¤«п ®в« ¤®з­ле б®®ЎйҐ­Ё©. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м +”®а¬ в ®Ў« бвЁ ¤ ­­ле: + * +0: dword: N = а §¬Ґа ЎгдҐа  (­Ґ бзЁв п нв®Ј® § Ј®«®ўЄ ) + * +4: dword: § ­пв® ў ЎгдҐаҐ + * +8: N*byte: ЎгдҐа +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®«Ґ а §¬Ґа  ®ваЁж вҐ«м­®, ЎгдҐа бзЁв Ґвбп § Ў«®ЄЁа®ў ­­л¬ + Ё ЇаЁ Ї®бвгЇ«Ґ­ЁЁ ­®ў®Ј® б®®ЎйҐ­Ёп бЁб⥬  Ўг¤Ґв ¦¤ вм. + „«п бЁ­еа®­Ё§ жЁЁ ®Ўа ¬«п©вҐ ўбо а Ў®вг б ЎгдҐа®¬ ®ЇҐа жЁп¬Ё + Ў«®ЄЁа®ўЄЁ/а §Ў«®ЄЁа®ўЄЁ + neg [bufsize] + * „ ­­лҐ ў ЎгдҐаҐ ва Євговбп Є Є ¬ ббЁў н«Ґ¬Ґ­в®ў ЇҐаҐ¬Ґ­­®© ¤«Ё­л - + б®®ЎйҐ­Ё©. ”®а¬ в б®®ЎйҐ­Ёп гЄ § ­ ў ®ЎйҐ¬ ®ЇЁб ­ЁЁ. + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 1 ====================== +========= Џ®«гзЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + * edx = ¤«Ё­  бвагЄвгал Є®­вҐЄбв , ¤®«¦­® Ўлвм 0x28=40 Ў ©в + * esi = гЄ § вҐ«м ­  бвагЄвгаг Є®­вҐЄбв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в бвагЄвгал Є®­вҐЄбв : (FPU Ї®Є  ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп) + * +0: dword: eip + * +4: dword: eflags + * +8: dword: eax + * +12 = +0xC: dword: ecx + * +16 = +0x10: dword: edx + * +20 = +0x14: dword: ebx + * +24 = +0x18: dword: esp + * +28 = +0x1C: dword: ebp + * +32 = +0x20: dword: esi + * +36 = +0x24: dword: edi +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®в®Є ўлЇ®«­пҐв Є®¤ 0-Є®«мж , ў®§ўа й Ґвбп + б®бв®п­ЁҐ ॣЁбва®ў 3-Є®«мж . + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 2 ====================== +======== “бв ­®ўЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + * edx = ¤«Ё­  бвагЄвгал Є®­вҐЄбв , ¤®«¦­® Ўлвм 0x28=40 Ў ©в + * esi = гЄ § вҐ«м ­  бвагЄвгаг Є®­вҐЄбв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в бвагЄвгал Є®­вҐЄбв  гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 1. +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®в®Є ўлЇ®«­пҐв Є®¤ 0-Є®«мж , гбв ­ ў«Ёў Ґвбп + б®бв®п­ЁҐ ॣЁбва®ў 3-Є®«мж . + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 3 - ®вЄ«озЁвмбп ®в ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . = +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Їа®жҐбб Ўл« ЇаЁ®бв ­®ў«Ґ­, ®­ ў®§®Ў­®ў«пҐв ўлЇ®«­Ґ­ЁҐ. + +====================================================================== +==== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 4 - ЇаЁ®бв ­®ўЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа Їа®жҐбб  + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 5 ====================== +============ ‚®§®Ў­®ўЁвм ўлЇ®«­Ґ­ЁҐ ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 6 ====================== +============= Џа®зЁв вм Ё§ Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а + * edx = бЄ®«мЄ® Ў ©в зЁв вм + * esi =  ¤аҐб Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * edi = гЄ § вҐ«м ­  ЎгдҐа ¤«п ¤ ­­ле +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 ЇаЁ ®иЁЎЄҐ (­ҐўҐа­л© PID Ё«Ё ЎгдҐа) + * Ё­ зҐ eax = зЁб«® Їа®зЁв ­­ле Ў ©в (ў®§¬®¦­®, 0, + Ґб«Ё ў esi б«ЁиЄ®¬ Ў®«м讥 §­ зҐ­ЁҐ) +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== + ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў Ї ¬пвм ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а + * edx = бЄ®«мЄ® Ў ©в ЇЁб вм + * esi =  ¤аҐб Ї ¬пвЁ ў ®в« ¦Ёў Ґ¬®¬ Їа®жҐбᥠ+ * edi = гЄ § вҐ«м ­  ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 ЇаЁ ®иЁЎЄҐ (­ҐўҐа­л© PID Ё«Ё ЎгдҐа) + * Ё­ зҐ eax = зЁб«® § ЇЁб ­­ле Ў ©в (ў®§¬®¦­®, 0, + Ґб«Ё ў esi б«ЁиЄ®¬ Ў®«м讥 §­ зҐ­ЁҐ) +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 8 - § ўҐаиЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + * ”г­ЄжЁп  ­ «®ЈЁз­  Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 18 б ¤ўг¬п ®в«ЁзЁп¬Ё: + вॡгҐвбп ўлЇ®«­Ґ­ЁҐ ЇҐаў®Ј® § ¬Ґз ­Ёп Ё ЇаЁ­Ё¬ Ґвбп PID, +   ­Ґ ­®¬Ґа б«®в . + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 9 ====================== +============= “бв ­®ўЁвм/б­пвм  ЇЇ а в­го в®зЄг ®бв ­®ў . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + * dl = Ё­¤ҐЄб в®зЄЁ ®бв ­®ў , ®в 0 ¤® 3 ўЄ«озЁвҐ«м­® + * dh = д« ЈЁ: + * Ґб«Ё бв аиЁ© ЎЁв бЎа®иҐ­ - гбв ­®ўЁвм в®зЄг ®бв ­®ў : + * ЎЁвл 0-1 - гб«®ўЁҐ: + * 00 = в®зЄ  ®бв ­®ў  ­  ўлЇ®«­Ґ­ЁҐ + * 01 = в®зЄ  ®бв ­®ў  ­  § ЇЁбм + * 11 = в®зЄ  ®бв ­®ў  ­  з⥭ЁҐ/§ ЇЁбм + * ЎЁвл 2-3 - ¤«Ё­ ; ¤«п в®зҐЄ ®бв ­®ў  ­  ЁбЇ®«­Ґ­ЁҐ ¤®«¦­® Ўлвм + 00, ў Їа®вЁў­®¬ б«гз Ґ ®¤­® Ё§ + * 00 = Ў ©в + * 01 = б«®ў® + * 11 = ¤ў®©­®Ґ б«®ў® + * esi =  ¤аҐб в®зЄЁ ®бв ­®ў ; ¤®«¦Ґ­ Ўлвм ўла®ў­Ґ­ + ᮮ⢥вб⢥­­® ¤«Ё­Ґ (в.Ґ. ¤®«¦Ґ­ Ўлвм зсв­л¬ ¤«п + в®зҐЄ ®бв ­®ў  ­  б«®ў®, Єа вҐ­ 4 ¤«п ¤ў®©­®Ј® б«®ў ) + * Ґб«Ё бв аиЁ© ЎЁв гбв ­®ў«Ґ­ - бЎа®бЁвм в®зЄг ®бв ­®ў  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  ў® ўе®¤­ле ¤ ­­ле + * eax = 2 - (§ аҐ§ҐаўЁа®ў ­®, ­ЁЄ®Ј¤  ­Ґ ў®§ўа й Ґвбп + ў ⥪г饩 ॠ«Ё§ жЁЁ) б нвЁ¬ Ё­¤ҐЄб®¬ 㦥 гбв ­®ў«Ґ­  + Ј«®Ў «м­ п в®зЄ  ®бв ­®ў  +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + * ЂЇЇ а в­лҐ в®зЄЁ ®бв ­®ў  ॠ«Ё§говбп зҐаҐ§ DRx-ॣЁбвал + Їа®жҐбб®а , ®вбо¤  ўбҐ ®Ја ­ЁзҐ­Ёп. + * ”г­ЄжЁп ¬®¦Ґв ЇҐаҐгбв ­®ўЁвм а ­ҐҐ гбв ­®ў«Ґ­­го Ґ© ¦Ґ + в®зЄг ®бв ­®ў  (­ЁЄ Є ­Ґ б®®Ўй п ®Ў н⮬). + ‚Ґ¤ЁвҐ бЇЁб®Є гбв ­®ў«Ґ­­ле в®зҐЄ ®бв ­®ў  ў ®в« ¤зЁЄҐ. + * ‘а Ў влў ­ЁҐ в®зЄЁ ®бв ­®ў  § Є«оз Ґвбп ў ЈҐ­ҐаЁа®ў ­ЁЁ + ®в« ¤®з­®Ј® ЁбЄ«о祭Ёп #DB, ® Є®в®а®¬ бЁб⥬  б®®Ўй Ґв ®в« ¤зЁЄг. + * ’®зЄ  ®бв ­®ў  ­  § ЇЁбм Ё з⥭ЁҐ/§ ЇЁбм ба Ў влў Ґв Ї®б«Ґ + ўлЇ®«­Ґ­Ёп ўл§ў ўиҐ© Ґс Ё­бвагЄжЁЁ. + +====================================================================== += ”г­ЄжЁп 70 - а Ў®в  б д ©«®ў®© бЁб⥬®© б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. = +====================================================================== +Џ а ¬Ґвал: + * eax = 70 + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®; Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ў § ўЁбЁ¬®бвЁ ®в Ї®¤дг­ЄжЁЁ ¬®¦Ґв ў®§ўа й вмбп §­ зҐ­ЁҐ Ё + ў ¤агЈЁе ॣЁбва е +ЋЎйЁ© д®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ᬥ饭ЁҐ ў д ©«Ґ + * +8: dword: бв аиЁ© dword ᬥ饭Ёп (¤®«¦Ґ­ Ўлвм 0) Ё«Ё Ї®«Ґ д« Ј®ў + * +12 = +0xC: dword: а §¬Ґа + * +16 = +0x10: dword: гЄ § вҐ«м ­  ¤ ­­лҐ + * +20 = +0x14: n db: ASCIIZ-бва®Є  б Ё¬Ґ­Ґ¬ д ©«  + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +“в®з­Ґ­Ёп - ў ¤®Єг¬Ґ­в жЁЁ ­  ᮮ⢥вбвўгойго Ї®¤дг­ЄжЁо. +€¬п д ©«  ­Ґзгўб⢨⥫쭮 Є ॣЁбваг ЎгЄў. ђгббЄЁҐ ЎгЄўл ¤®«¦­л Ўлвм +§ ЇЁб ­л ў Є®¤Ёа®ўЄҐ cp866 (DOS). +”®а¬ в Ё¬Ґ­Ё д ©« : +/base/number/dir1/dir2/.../dirn/file, +Ј¤Ґ /base/number Ё¤Ґ­вЁдЁжЁагҐв гбва®©бвў®, ­  Є®в®а®¬ ЁйҐвбп д ©«: +®¤­® Ё§ + * /RD/1 = /RAMDISK/1 ¤«п ¤®бвгЇ  Є а ¬¤ЁбЄг + * /FD/1 = /FLOPPYDISK/1 ¤«п ¤®бвгЇ  Є ЇҐаў®¬г д«®ЇЇЁ-¤ЁбЄ®ў®¤г, + /FD/2 = /FLOPPYDISK/2 ¤«п ўв®а®Ј® д«®ЇЇЁ-¤ЁбЄ®ў®¤  + * /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«п ¤®бвгЇ  ᮮ⢥вб⢥­­® + Є ¦сбвЄЁ¬ ¤ЁбЄ ¬ ­  IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - ­®¬Ґа а §¤Ґ«  ­  ўлЎа ­­®¬ ўЁ­зҐбвҐаҐ, Ё§¬Ґ­пҐвбп ®в 1 ¤® 255 + (­  Є ¦¤®¬ Ё§ ўЁ­зҐбвҐа®ў ­г¬Ґа жЁп ­ зЁ­ Ґвбп б 1) + * /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«п ¤®бвгЇ  ᮮ⢥вб⢥­­® + Є CD ­  IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave) + * /SYS - ®ЇаҐ¤Ґ«пҐв бЁб⥬­го Ї ЇЄг; ЇаЁ ®Ўлз­®© § Јаг§ЄҐ бЁб⥬л + б ¤ЁбЄҐвл нЄўЁў «Ґ­в­® /RD/1 +ЏаЁ¬Ґал: + * '/rd/1/kernel.asm',0 + * '/HD0/1/kernel.asm',0 + * '/hd0/2/menuet/pics/tanzania.bmp',0 + * '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 + * '/sys/MySuperApp.ini',0 +„®бвгЇ­лҐ Ї®¤дг­ЄжЁЁ: + * Ї®¤дг­ЄжЁп 0 - з⥭ЁҐ д ©«  + * Ї®¤дг­ЄжЁп 1 - з⥭ЁҐ Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 2 - б®§¤ ­ЁҐ/ЇҐаҐ§ ЇЁбм д ©«  + * Ї®¤дг­ЄжЁп 3 - § ЇЁбм ў бгйҐбвўгойЁ© д ©« + * Ї®¤дг­ЄжЁп 4 - гбв ­®ўЄ  а §¬Ґа  д ©«  + * Ї®¤дг­ЄжЁп 5 - Ї®«г祭ЁҐ  ваЁЎгв®ў д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 6 - гбв ­®ўЄ   ваЁЎгв®ў д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 7 - § ЇгбЄ Їа®Ја ¬¬л + * Ї®¤дг­ЄжЁп 8 - г¤ «Ґ­ЁҐ д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 9 - б®§¤ ­ЁҐ Ї ЇЄЁ +„«п CD-ЇаЁў®¤®ў ў бўп§Ё б  ЇЇ а в­л¬Ё ®Ја ­ЁзҐ­Ёп¬Ё ¤®бвгЇ­л +в®«мЄ® Ї®¤дг­ЄжЁЁ 0,1,5 Ё 7, ўл§®ў ¤агЈЁе Ї®¤дг­ЄжЁ© § ўҐаиЁвбп +®иЁЎЄ®© б Є®¤®¬ 2. +ЏаЁ ЇҐаў®¬ ®Ўа йҐ­ЁЁ Ї®¤дг­ЄжЁ© 0,1,5,7 Є гбва®©бвў ¬ ATAPI +(CD Ё DVD) Їа®Ё§ў®¤Ёвбп Ў«®ЄЁа®ўЄ  агз­®Ј® гЇа ў«Ґ­Ёп ¬Ґе ­Ё§¬®¬ +«®вЄ . ќв® бўп§ ­® б ЄниЁа®ў ­ЁҐ¬ ¤ ­­ле, Ї®«г祭­ле ®в ЇаЁў®¤ . +ђ §Ў«®ЄЁа®ўЄ  ®бгйҐбвў«пҐвбп ЇаЁ ®Ўа йҐ­ЁЁ Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 24 +Є ᮮ⢥вбвўго饬г гбва®©бвўг. + +====================================================================== += ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 0 - з⥭ЁҐ д ©«  б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. = +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 0 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: Ї®§ЁжЁп ў д ©«Ґ (ў Ў ©в е) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­® Ї®¤ бв аиЁ© dword Ї®§ЁжЁЁ) + * +12 = +0xC: dword: бЄ®«мЄ® Ў ©в зЁв вм + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв § ЇЁб ­л ¤ ­­лҐ + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx = зЁб«® Їа®зЁв ­­ле Ў ©в Ё«Ё + -1=0xffffffff, Ґб«Ё д ©« ­Ґ ­ ©¤Ґ­ +‡ ¬Ґз ­Ёп: + * …б«Ё д ©« Є®­зЁ«бп а ­миҐ, 祬 Ўл« Їа®зЁв ­ Ї®б«Ґ¤­Ё© § Їа®иҐ­­л© + Ў«®Є, в® дг­ЄжЁп Їа®зЁв Ґв, бЄ®«мЄ® ᬮ¦Ґв, Ї®б«Ґ 祣® ўҐа­св + eax=6 (EOF). + * ”г­ЄжЁп ­Ґ Ї®§ў®«пҐв зЁв вм Ї ЇЄЁ + (ўҐа­свбп eax=10, access denied). + +====================================================================== += ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 1 - з⥭ЁҐ Ї ЇЄЁ б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. = +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 1 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: Ё­¤ҐЄб ­ з «м­®Ј® Ў«®Є  (бзЁв п б 0) + * +8: dword: Ї®«Ґ д« Ј®ў: + * ЎЁв 0 (¬ бЄ  1): ў Є Є®¬ д®а¬ вҐ ў®§ўа й вм Ё¬Ґ­ , + 0=ANSI, 1=UNICODE + * Їа®зЁҐ ЎЁвл § аҐ§ҐаўЁа®ў ­л Ё ¤®«¦­л Ўлвм гбв ­®ў«Ґ­л ў 0 + ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ + * +12 = +0xC: dword: бЄ®«мЄ® Ў«®Є®ў зЁв вм + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв § ЇЁб ­л + ¤ ­­лҐ, а §¬Ґа ЎгдҐа  ¤®«¦Ґ­ Ўлвм ­Ґ ¬Ґ­миҐ 32 + [+12]*560 Ў ©в + * +20 = +0x14: ASCIIZ-Ё¬п Ї ЇЄЁ, Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx = зЁб«® д ©«®ў, Ё­д®а¬ жЁп ® Є®в®але Ўл«  § ЇЁб ­  ў ЎгдҐа, + Ё«Ё -1=0xffffffff, Ґб«Ё Ї ЇЄ  ­Ґ ­ ©¤Ґ­  +‘вагЄвга  ЎгдҐа : + * +0: 32*byte: § Ј®«®ў®Є + * +32 = +0x20: n1*byte: Ў«®Є б Ё­д®а¬ жЁҐ© ® д ©«Ґ 1 + * +32+n1: n2*byte: Ў«®Є б Ё­д®а¬ жЁҐ© ® д ©«Ґ 2 + * ... +‘вагЄвга  § Ј®«®ўЄ : + * +0: dword: ўҐабЁп бвагЄвгал (⥪гй п ўҐабЁп = 1) + * +4: dword: Є®«ЁзҐбвў® а §¬Ґйс­­ле Ў«®Є®ў; ­Ґ Ў®«миҐ, 祬 § Їа®иҐ­® + ў Ї®«Ґ +12 Ё­д®а¬ жЁ®­­®© бвагЄвгал; ¬®¦Ґв Ўлвм ¬Ґ­миҐ, + Ґб«Ё ў Ї ЇЄҐ Є®­зЁ«Ёбм д ©«л (в® ¦Ґ б ¬®Ґ, зв® Ё ў ebx) + * +8: dword: ®ЎйҐҐ зЁб«® д ©«®ў ў Ї ЇЄҐ + * +12 = +0xC: 20*byte: § аҐ§ҐаўЁа®ў ­® (­г«Ё) +‘вагЄвга  Ў«®Є  ¤ ­­ле ўе®¤  Є в «®Ј  (Ѓ„‚Љ): + * +0: dword:  ваЁЎгвл д ©« : + * ЎЁв 0 (¬ бЄ  1): д ©« в®«мЄ® ¤«п з⥭Ёп + * ЎЁв 1 (¬ бЄ  2): д ©« пў«пҐвбп бЄалвл¬ + * ЎЁв 2 (¬ бЄ  4): д ©« пў«пҐвбп бЁб⥬­л¬ + * ЎЁв 3 (¬ бЄ  8): нв® ­Ґ д ©«,   ¬ҐвЄ  ⮬  + (­  § ¤ ­­®¬ а §¤Ґ«Ґ ўбваҐз Ґвбп ­Ґ Ў®«ҐҐ ®¤­®Ј® а §  Ё + в®«мЄ® ў Є®а­Ґў®© Ї ЇЄҐ) + * ЎЁв 4 (¬ бЄ  0x10): нв® Ї ЇЄ  + * ЎЁв 5 (¬ бЄ  0x20): д ©« ­Ґ  аеЁўЁа®ў «бп - ¬­®ЈЁҐ Їа®Ја ¬¬л +  аеЁў жЁЁ Ё¬Ґов ®ЇжЁо, Ї® Є®в®а®©  аеЁўЁаговбп в®«мЄ® д ©«л + б гбв ­®ў«Ґ­­л¬ нвЁ¬ ЎЁв®¬, Ї®б«Ґ 祣® нв®в ЎЁв бЎа блў Ґвбп - + нв® ¬®¦Ґв Ўлвм Ї®«Ґ§­® ¤«п  ўв®¬ вЁзҐбЄ®Ј® б®§¤ ­Ёп + backup- аеЁў®ў, ЁЎ® ЇаЁ § ЇЁбЁ ЎЁв ®Ўлз­® гбв ­ ў«Ёў Ґвбп + (­Ґ ў Kolibri, Їа ў¤ ) + * +4: byte: вЁЇ ¤ ­­ле Ё¬Ґ­Ё: + (б®ўЇ ¤ Ґв б ЎЁв®¬ 0 д« Ј®ў Ё­д®а¬ жЁ®­­®© бвагЄвгал) + * 0 = ASCII = 1-Ў ©в­®Ґ ЇаҐ¤бв ў«Ґ­ЁҐ Є ¦¤®Ј® бЁ¬ў®«  + * 1 = UNICODE = 2-Ў ©в­®Ґ ЇаҐ¤бв ў«Ґ­ЁҐ Є ¦¤®Ј® бЁ¬ў®«  + * +5: 3*byte: § аҐ§ҐаўЁа®ў ­® (­г«Ё) + * +8: 4*byte: ўаҐ¬п б®§¤ ­Ёп д ©«  + * +12 = +0xC: 4*byte: ¤ в  б®§¤ ­Ёп д ©«  + * +16 = +0x10: 4*byte: ўаҐ¬п Ї®б«Ґ¤­ҐЈ® ¤®бвгЇ  (з⥭ЁҐ Ё«Ё § ЇЁбм) + * +20 = +0x14: 4*byte: ¤ в  Ї®б«Ґ¤­ҐЈ® ¤®бвгЇ  + * +24 = +0x18: 4*byte: ўаҐ¬п Ї®б«Ґ¤­Ґ© ¬®¤ЁдЁЄ жЁЁ + * +28 = +0x1C: 4*byte: ¤ в  Ї®б«Ґ¤­Ґ© ¬®¤ЁдЁЄ жЁЁ + * +32 = +0x20: qword: а §¬Ґа д ©«  ў Ў ©в е (¤® 16777216 ’Ў) + * +40 = +0x28: Ё¬п + * ¤«п д®а¬ в  ASCII: ¬ ЄбЁ¬ «м­ п ¤«Ё­  Ё¬Ґ­Ё 263 бЁ¬ў®«  + (263 Ў ©в ), Ў ©в Ї®б«Ґ Ё¬Ґ­Ё Ё¬ҐҐв §­ зҐ­ЁҐ 0 + * ¤«п д®а¬ в  UNICODE: ¬ ЄбЁ¬ «м­ п ¤«Ё­  Ё¬Ґ­Ё 259 бЁ¬ў®«®ў + (518 Ў ©в), ¤ў  Ў ©в  Ї®б«Ґ Ё¬Ґ­Ё Ё¬Ґов §­ зҐ­ЁҐ 0 +”®а¬ в ўаҐ¬Ґ­Ё: + * +0: byte: ᥪ㭤л + * +1: byte: ¬Ё­гвл + * +2: byte: з бл + * +3: byte: § аҐ§ҐаўЁа®ў ­® (0) + * ­ ЇаЁ¬Ґа, 23.59.59 § ЇЁблў Ґвбп Є Є (ў hex) 3B 3B 17 00 +”®а¬ в ¤ вл: + * +0: byte: ¤Ґ­м + * +1: byte: ¬Ґбпж + * +2: word: Ј®¤ + * ­ ЇаЁ¬Ґа, 25.11.1979 § ЇЁблў Ґвбп Є Є (ў hex) 19 0B BB 07 +‡ ¬Ґз ­Ёп: + * …б«Ё ў Ѓ„‚Љ ЇаЁбгвбвўгҐв Ё¬п ў ASCII, в® ¤«Ё­  Ѓ„‚Љ б®бв ў«пҐв + 304 Ў ©в , Ґб«Ё ў UNICODE - 560 Ў ©в. ‡­ зҐ­ЁҐ ¤«Ё­л ўла ў­Ґ­® + ­  楫®Ґ Єа в­®Ґ 16 Ў ©в + (¤«п г᪮७Ёп ®Ўа Ў®вЄЁ ў Єни-Ї ¬пвЁ CPU). + * ЏҐаўл© бЁ¬ў®« Ї®б«Ґ Ё¬Ґ­Ё ­г«Ґў®© (ASCIIZ-бва®Є ). „ «м­Ґ©иЁҐ + ¤ ­­лҐ ᮤҐа¦ в ¬гб®а. + * …б«Ё д ©«л ў Ї ЇЄҐ Є®­зЁ«Ёбм а ­миҐ, 祬 Ўл«® Їа®зЁв ­® + § Їа®иҐ­­®Ґ Є®«ЁзҐбвў®, в® дг­ЄжЁп Їа®зЁв Ґв, бЄ®«мЄ® ᬮ¦Ґв, + Ї®б«Ґ 祣® ўҐа­св eax=6 (EOF). + * ‹оЎ п Ї ЇЄ  ­  ¤ЁбЄҐ, Єа®¬Ґ Є®а­Ґў®©, ᮤҐа¦Ёв ¤ў  бЇҐжЁ «м­ле + ўе®¤  "." Ё "..", Ё¤Ґ­вЁдЁжЁагойЁе ᮮ⢥вб⢥­­® б ¬г Ї ЇЄг Ё + தЁвҐ«мбЄго Ї ЇЄг. + * ”г­ЄжЁп Ї®§ў®«пҐв в Є¦Ґ зЁв вм ўЁавг «м­лҐ Ї ЇЄЁ "/", "/rd", + "/fd", "/hd[n]", ЇаЁ н⮬  ваЁЎгвл Ї®¤Ї Ї®Є Ї®« Ј овбп а ў­л¬Ё + 0x10,   ўаҐ¬Ґ­  Ё ¤ вл ®Ў­г«Ґ­л. Ђ«мвҐа­ вЁў­л© бЇ®б®Ў Ї®«г祭Ёп + Ё­д®а¬ жЁЁ ®Ў ®Ў®а㤮ў ­ЁЁ - Ї®¤дг­ЄжЁп 11 дг­ЄжЁЁ 18. + +====================================================================== +====================== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 2 ====================== +======== ‘®§¤ ­ЁҐ/ЇҐаҐ§ ЇЁбм д ©«  б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 2 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +12 = +0xC: dword: бЄ®«мЄ® Ў ©в ЇЁб вм + * +16 = +0x10: dword: гЄ § вҐ«м ­  ¤ ­­лҐ + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx = зЁб«® § ЇЁб ­­ле Ў ©в (ў®§¬®¦­®, 0) +‡ ¬Ґз ­Ёп: + * …б«Ё д ©« б в ЄЁ¬ Ё¬Ґ­Ґ¬ ­Ґ бгйҐбвў®ў «, ®­ б®§¤ свбп; Ґб«Ё + бгйҐбвў®ў «, в® ЇҐаҐ§ ЇЁблў Ґвбп. + * …б«Ё бў®Ў®¤­®Ј® ¬Ґбв  ­  ¤ЁбЄҐ ­Ґ¤®бв в®з­®, в® дг­ЄжЁп § ЇЁиҐв, + бЄ®«мЄ® ᬮ¦Ґв, Ї®б«Ґ 祣® ўҐа­св Є®¤ ®иЁЎЄЁ 8. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +====================== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 3 ====================== +======== ‡ ЇЁбм ў бгйҐбвўгойЁ© д ©« б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 3 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: Ї®§ЁжЁп ў д ©«Ґ (ў Ў ©в е) + * +8: dword: бв аиЁ© dword Ї®§ЁжЁЁ (¤®«¦Ґ­ Ўлвм 0 ¤«п FAT) + * +12 = +0xC: dword: бЄ®«мЄ® Ў ©в ЇЁб вм + * +16 = +0x10: dword: гЄ § вҐ«м ­  ¤ ­­лҐ + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx = зЁб«® § ЇЁб ­­ле Ў ©в (ў®§¬®¦­®, 0) +‡ ¬Ґз ­Ёп: + * ” ©« ¤®«¦Ґ­ 㦥 бгйҐбвў®ў вм, Ё­ зҐ ўҐа­свбп eax=5. + * …¤Ё­б⢥­­л¬ १г«мв в®¬ § ЇЁбЁ 0 Ў ©в пў«пҐвбп гбв ­®ўЄ  ў +  ваЁЎгв е д ©«  ¤ вл/ўаҐ¬Ґ­Ё ¬®¤ЁдЁЄ жЁЁ Ё ¤®бвгЇ  ў ⥪гйго. + * …б«Ё ­ з «м­ п Ё/Ё«Ё Є®­Ґз­ п Ї®§ЁжЁп ўл室Ёв §  ЇаҐ¤Ґ«л д ©«  + (§  ЁбЄ«о祭ЁҐ¬ ЇаҐ¤л¤г饣® б«гз п), д ©« а биЁапҐвбп ¤® + ­Ґ®Ўе®¤Ё¬®Ј® а §¬Ґа  ­г«Ґўл¬Ё бЁ¬ў®« ¬Ё. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +========= ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 4 - гбв ­®ўЄ  а §¬Ґа  д ©« . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 4 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ¬« ¤иЁ© dword ­®ў®Ј® а §¬Ґа  д ©«  + * +8: dword: бв аиЁ© dword ­®ў®Ј® а §¬Ґа  д ©«  + (¤®«¦Ґ­ Ўлвм 0 ¤«п FAT) + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * …б«Ё ­®ўл© а §¬Ґа д ©«  ¬Ґ­миҐ бв а®Ј®, д ©« гᥪ Ґвбп. …б«Ё + ­®ўл© а §¬Ґа Ў®«миҐ бв а®Ј®, д ©« а биЁапҐвбп ­г«Ґўл¬Ё бЁ¬ў®« ¬Ё. + …б«Ё ­®ўл© а §¬Ґа а ўҐ­ бв а®¬г, Ґ¤Ё­б⢥­­л¬ १г«мв в®¬ ўл§®ў  + пў«пҐвбп гбв ­®ўЄ  ¤ вл/ўаҐ¬Ґ­Ё ¬®¤ЁдЁЄ жЁЁ Ё ¤®бвгЇ  ў ⥪гйЁҐ. + * …б«Ё бў®Ў®¤­®Ј® ¬Ґбв  ­  ¤ЁбЄҐ ­Ґ¤®бв в®з­® ¤«п а биЁаҐ­Ёп д ©« , + в® дг­ЄжЁп а биЁаЁв ­ бЄ®«мЄ® ў®§¬®¦­®, Ї®б«Ґ 祣® ўҐа­св + Є®¤ ®иЁЎЄЁ 8. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +=== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 5 - Ї®«г祭ЁҐ Ё­д®а¬ жЁЁ ® д ©«Ґ/Ї ЇЄҐ. === +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 5 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа, Єг¤  Ўг¤гв § ЇЁб ­л ¤ ­­лҐ + (40 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +€­д®а¬ жЁп ® д ©«Ґ ў®§ўа й Ґвбп ў д®а¬ вҐ Ѓ„‚Љ +(Ў«®Є  ¤ ­­ле ўе®¤  Є в «®Ј ), гЄ § ­­®¬ ў ®ЇЁб ­ЁЁ +Ї®¤дг­ЄжЁЁ 1, ­® ЎҐ§ Ё¬Ґ­Ё д ©«  +(в® Ґбвм ЇҐаўлҐ 40 = 0x28 Ў ©в). +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв ўЁавг «м­лҐ Ї ЇЄЁ вЁЇ  /, /rd Ё + Є®а­ҐўлҐ Ї ЇЄЁ вЁЇ  /rd/1. + +====================================================================== +===== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 6 - гбв ­®ўЄ   ваЁЎгв®ў д ©« /Ї ЇЄЁ. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 6 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа б  ваЁЎгв ¬Ё (32 Ў ©в ) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +ЂваЁЎгвл д ©«  - ЇҐаўлҐ 32 Ў ©в  ў Ѓ„‚Љ (Ў«®ЄҐ ¤ ­­ле ўе®¤  Є в «®Ј ), +д®а¬ в Є®в®а®Ј® гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 1 +(в® Ґбвм ЎҐ§ Ё¬Ґ­Ё Ё а §¬Ґа  д ©« ). ЂваЁЎгв д ©«/Ї ЇЄ /¬ҐвЄ  ⮬  +(ЎЁвл 3,4 ў dword'Ґ +0) ­Ґ ¬Ґ­пҐвбп. +Ѓ ©в +4 (д®а¬ в Ё¬Ґ­Ё) ЁЈ­®аЁагҐвбп. +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв ўЁавг «м­лҐ Ї ЇЄЁ вЁЇ  /, /rd Ё + Є®а­ҐўлҐ Ї ЇЄЁ вЁЇ  /rd/1. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +============ ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 7 - § ЇгбЄ Їа®Ја ¬¬л. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 7 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: Ї®«Ґ д« Ј®ў: + * ЎЁв 0: § ЇгбвЁвм Їа®жҐбб Є Є ®в« ¦Ёў Ґ¬л© + * ®бв «м­лҐ ЎЁвл § аҐ§ҐаўЁа®ў ­л Ё ¤®«¦­л Ўлвм гбв ­®ў«Ґ­л ў 0 + * +8: dword: 0 Ё«Ё гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ї а ¬Ґва ¬Ё + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax > 0 - Їа®Ја ¬¬  § Ја㦥­ , eax ᮤҐа¦Ёв PID + * eax < 0 - Їа®Ё§®и«  ®иЁЎЄ , -eax ᮤҐа¦Ёв + Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Љ®¬ ­¤­ п бва®Є  ¤®«¦­  § Є ­зЁў вмбп бЁ¬ў®«®¬ б Є®¤®¬ 0 + (ASCIIZ-бва®Є ); гзЁвлў овбп «ЁЎ® ўбҐ бЁ¬ў®«л ¤® § ўҐаи о饣® ­г«п + ўЄ«озЁвҐ«м­®, «ЁЎ® ЇҐаўлҐ 256 бЁ¬ў®«®ў, ў § ўЁбЁ¬®бвЁ ®в в®Ј®, + зв® ¬Ґ­миҐ. + * …б«Ё Їа®жҐбб § ЇгбЄ Ґвбп Є Є ®в« ¦Ёў Ґ¬л©, ®­ б®§¤ свбп + ў § ¬®а®¦Ґ­­®¬ б®бв®п­ЁЁ; ¤«п § ЇгбЄ  ЁбЇ®«м§г©вҐ + Ї®¤дг­ЄжЁо 5 дг­ЄжЁЁ 69. + +====================================================================== +========== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 8 - г¤ «Ґ­ЁҐ д ©« /Ї ЇЄЁ. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 8 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + * Њ®¦­® г¤ «пвм в®«мЄ® ЇгбвлҐ Ї ЇЄЁ (Ї®ЇлвЄ  г¤ «Ґ­Ёп ­ҐЇгбв®© Ї ЇЄЁ + ЇаЁўҐ¤св Є ®иЁЎЄҐ б Є®¤®¬ 10, "¤®бвгЇ § ЇаҐйс­"). + +====================================================================== +============= ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 9 - б®§¤ ­ЁҐ Ї ЇЄЁ. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 70 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 9 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +8: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +12 = +0xC: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +16 = +0x10: dword: 0 (§ аҐ§ҐаўЁа®ў ­®) + * +20 = +0x14: ASCIIZ-Ё¬п Ї ЇЄЁ, Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ Ї ЇЄЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + * ђ®¤ЁвҐ«мбЄ п Ї ЇЄ  ¤®«¦­  㦥 бгйҐбвў®ў вм. + * …б«Ё Ї ЇЄ  㦥 бгйҐбвўгҐв, дг­ЄжЁп § ўҐаиЁвбп гбЇҐи­® (eax=0). + +====================================================================== +=== ”г­ЄжЁп 71, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм § Ј®«®ў®Є ®Є­  Їа®Ја ¬¬л. == +====================================================================== +Џ а ¬Ґвал: + * eax = 71 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx =  ¤аҐб бва®ЄЁ § Ј®«®ўЄ  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‘ва®Є  § Ј®«®ўЄ  ¤®«¦­  Ўлвм ў д®а¬ вҐ ASCIIZ. ‚ § Ј®«®ўЄҐ + ®в®Ўа ¦ Ґвбп ­Ґ Ў®«ҐҐ 255 бЁ¬ў®«®ў ­Ґ§ ўЁбЁ¬® ®в Ї®«­®© ¤«Ё­л + бва®ЄЁ. + * —в®Ўл гЎа вм § Ј®«®ў®Є, ЇҐаҐ¤ ©вҐ NULL ў ecx. + +====================================================================== +================ ”г­ЄжЁп 72 - Ї®б« вм б®®ЎйҐ­ЁҐ ®Є­г. ================ +====================================================================== + +--- Џ®¤дг­ЄжЁп 1 - Ї®б« вм б®®ЎйҐ­ЁҐ б Ї а ¬Ґв஬  ЄвЁў­®¬г ®Є­г. ---- +Џ а ¬Ґвал: + * eax = 72 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Є®¤ б®ЎлвЁп: 2 Ё«Ё 3 + * edx = Є®¤ Є« ўЁиЁ ¤«п ecx=2, Ё¤Ґ­вЁдЁЄ в®а Є­®ЇЄЁ ¤«п ecx=3 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ЎгдҐа § Ї®«­Ґ­ + +====================================================================== +========== ”г­ЄжЁп -1 - § ўҐаиЁвм ўлЇ®«­Ґ­ЁҐ Ї®в®Є /Їа®жҐбб  ========= +====================================================================== +Џ а ¬Ґвал: + * eax = -1 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв ­Ё §­ зҐ­Ёп, ­Ё гЇа ў«Ґ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Їа®жҐбб пў­® ­Ґ б®§¤ ў « Ї®в®Є®ў, в® г ­ҐЈ® Ґбвм в®«мЄ® + ®¤Ё­ Ї®в®Є, § ўҐа襭ЁҐ Є®в®а®Ј® ЇаЁў®¤Ёв Є § ўҐа襭Ёо Їа®жҐбб . + * …б«Ё ⥪гйЁ© Ї®в®Є - Ї®б«Ґ¤­Ё© ў Їа®жҐббҐ, в® ҐЈ® § ўҐа襭ЁҐ + в Є¦Ґ ЇаЁў®¤Ёв Є § ўҐа襭Ёо Їа®жҐбб . + * ќв  дг­ЄжЁп § ўҐаи Ґв ⥪гйЁ© Ї®в®Є. „агЈ®© Ї®в®Є ¬®¦­® ЇаЁЎЁвм + ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 18. + +====================================================================== +=========================== ‘ЇЁб®Є б®ЎлвЁ© =========================== +====================================================================== +ЋзҐаҐ¤­®Ґ б®ЎлвЁҐ ¬®¦­® Ї®«гзЁвм ўл§®ў®¬ ®¤­®© Ё§ дг­ЄжЁ© 10 +(®¦Ё¤ вм б®ЎлвЁп), 11 (Їа®ўҐаЁвм ЎҐ§ ®¦Ё¤ ­Ёп), 23 +(®¦Ё¤ вм ў вҐзҐ­ЁҐ § ¤ ­­®Ј® ўаҐ¬Ґ­Ё). +ќвЁ дг­ЄжЁЁ ў®§ўа й ов в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, +гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® ЇҐаўлҐ ваЁ, 祣® +ўЇ®«­Ґ ¤®бв в®з­® ¤«п ¬­®ЈЁе ЇаЁ«®¦Ґ­Ё©. +Љ®¤л б®ЎлвЁ©: + * 1 = б®®ЎйҐ­ЁҐ ® ЇҐаҐаЁб®ўЄҐ (бЎа блў Ґвбп ЇаЁ ўл§®ўҐ дг­ЄжЁЁ 0) + * 2 = ­ ¦ в  Є« ўЁи  ­  Є« ўЁ вгॠ(Ї®бвгЇ Ґв, в®«мЄ® Є®Ј¤  ®Є­® +  ЄвЁў­®) Ё«Ё ­ ¦ в  "Ј®апз п Є« ўЁи "; + бЎа блў Ґвбп, Є®Ј¤  ўбҐ Є« ўЁиЁ Ё§ ЎгдҐа  бзЁв ­л дг­ЄжЁҐ© 2 + * 3 = ­ ¦ в  Є­®ЇЄ , ®ЇаҐ¤Ґ«с­­ п а ­ҐҐ дг­ЄжЁҐ© 8 (Ё«Ё Є­®ЇЄ  + § ЄалвЁп, б®§¤ ­­ п ­Ґпў­® дг­ЄжЁҐ© 0; Є­®ЇЄ  ¬Ё­Ё¬Ё§ жЁЁ + ®Ўа Ў влў Ґвбп бЁб⥬®© Ё ® ­Ґ© б®®ЎйҐ­Ёп ­Ґ ЇаЁе®¤Ёв; + Ї®бвгЇ Ґв, в®«мЄ® Є®Ј¤  ®Є­®  ЄвЁў­®; бЎа блў Ґвбп, Є®Ј¤  ўбҐ + Є­®ЇЄЁ Ё§ ЎгдҐа  бзЁв ­л дг­ЄжЁҐ© 17) + * 4 = § аҐ§ҐаўЁа®ў ­® (ў ⥪г饩 ॠ«Ё§ жЁЁ ­ЁЄ®Ј¤  ­Ґ ЇаЁе®¤Ёв ¤ ¦Ґ + ЇаЁ а §¬ бЄЁа®ўЄҐ дг­ЄжЁҐ© 40) + * 5 = ЇҐаҐаЁб®ўлў Ґвбп д®­ а Ў®зҐЈ® бв®«  (бЎа блў Ґвбп +  ўв®¬ вЁзҐбЄЁ Ї®б«Ґ ЇҐаҐаЁб®ўЄЁ, в Є зв® Ґб«Ё ў® ўаҐ¬п ЇҐаҐаЁб®ўЄЁ + д®­  Їа®Ја ¬¬  ­Ґ ¦¤св Ё ­Ґ Їа®ўҐапҐв б®ЎлвЁп, в® нв®Ј® б®ЎлвЁп + ®­  ­Ґ § ¬ҐвЁв) + * 6 = б®ЎлвЁҐ ®в ¬лиЁ (зв®-в® б«гзЁ«®бм - ­ ¦ вЁҐ ­  Є­®ЇЄг ¬лиЁ + Ё«Ё ЇҐаҐ¬ҐйҐ­ЁҐ; бЎа блў Ґвбп ЇаЁ Їа®з⥭ЁЁ) + * 7 = Їа®Ё§®и«® б®ЎлвЁҐ IPC (ᬮваЁ дг­ЄжЁо 60 - Inter Process + Communication; бЎа блў Ґвбп ЇаЁ Їа®з⥭ЁЁ) + * 8 = Їа®Ё§®и«® бҐвҐў®Ґ б®ЎлвЁҐ (бЎа блў Ґвбп ЇаЁ Їа®з⥭ЁЁ; + ᬮваЁ а Ў®вг б бҐвмо) + * 9 = Їа®Ё§®и«® ®в« ¤®з­®Ґ б®ЎлвЁҐ (бЎа блў Ґвбп ЇаЁ Їа®з⥭ЁЁ; + ᬮваЁ ®в« ¤®з­го Ї®¤бЁб⥬г) + * 16..31 = Їа®Ё§®и«® б®ЎлвЁҐ б ᮮ⢥вбвўгойЁ¬ IRQ + (16=IRQ0, 31=IRQ15) (бЎа блў Ґвбп ЇаЁ бзЁвлў ­ЁЁ ўбҐе ¤ ­­ле IRQ) + +====================================================================== +==================== Љ®¤л ®иЁЎ®Є д ©«®ў®© бЁб⥬л ==================== +====================================================================== + * 0 = гбЇҐи­® + * 1 = ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  Ё/Ё«Ё а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  (Ї®¤дг­ЄжЁп¬Ё + 7, 8 дг­ЄжЁЁ 21) + * 2 = дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п ¤ ­­®© д ©«®ў®© бЁб⥬л + * 3 = ­ҐЁ§ўҐбв­ п д ©«®ў п бЁб⥬  + * 4 = § аҐ§ҐаўЁа®ў ­®, ­ЁЄ®Ј¤  ­Ґ ў®§ўа й Ґвбп ў ⥪г饩 ॠ«Ё§ жЁЁ + * 5 = д ©« ­Ґ ­ ©¤Ґ­ + * 6 = д ©« § Є®­зЁ«бп + * 7 = гЄ § вҐ«м ў­Ґ Ї ¬пвЁ ЇаЁ«®¦Ґ­Ёп + * 8 = ¤ЁбЄ § Ї®«­Ґ­ + * 9 = в Ў«Ёж  FAT а §аг襭  + * 10 = ¤®бвгЇ § ЇаҐйс­ + * 11 = ®иЁЎЄ  гбва®©бвў  +ЏаЁ § ЇгбЄҐ Їа®Ја ¬¬л ў®§¬®¦­л в Є¦Ґ б«Ґ¤гойЁҐ Є®¤л ®иЁЎ®Є: + * 30 = 0x1E = ­Ґ¤®бв в®з­® Ї ¬пвЁ + * 31 = 0x1F = д ©« ­Ґ пў«пҐвбп ЁбЇ®«­Ё¬л¬ + * 32 = 0x20 = б«ЁиЄ®¬ ¬­®Ј® Їа®жҐбб®ў diff --git a/kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt b/kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt new file mode 100644 index 000000000..19e2f2b1a --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/docs/sysfuncs.txt @@ -0,0 +1,4529 @@ +SYSTEM FUNCTIONS of OS Kolibri 0.7.5.0 + +Number of the function is located in the register eax. +The call of the system function is executed by "int 0x40" command. +All registers except explicitly declared in the returned value, + including eflags, are preserved. + + +====================================================================== +============== Function 0 - define and draw the window. ============== +====================================================================== +Defines an application window. Draws a frame of the window, header and +working area. For skinned windows defines standard close and minimize +buttons. +Parameters: + * eax = 0 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = 0xXYRRGGBB, where: + * Y = style of the window: + * Y=0 - type I - fixed-size window + * Y=1 - only define window area, draw nothing + * Y=2 - type II - variable-size window + * Y=3 - skinned window + * Y=4 - skinned fixed-size window + * other possible values (from 5 up to 15) are reserved, + function call with such Y is ignored + * RR, GG, BB = accordingly red, green, blue components of a color + of the working area of the window (are ignored for style Y=2) + * X = DCBA (bits) + * A = 1 - window has caption; for styles Y=3,4 caption string + must be passed in edi, for other styles use + subfunction 1 of function 71 + * B = 1 - coordinates of all graphics primitives are relative to + window client area + * C = 1 - don't fill working area on window draw + * D = 0 - normal filling of the working area, 1 - gradient + The following parameters are intended for windows + of a type I and II, and ignored for styles Y=1,3: + * esi = 0xXYRRGGBB - color of the header + * RR, GG, BB define color + * Y=0 - usual window, Y=1 - unmovable window + * X defines a gradient of header: X=0 - no gradient, + X=8 - usual gradient, + for windows of a type II X=4 - negative gradient + * other values of X and Y are reserved + * edi = 0x00RRGGBB - color of the frame +Returned value: + * function does not return value +Remarks: + * Position and sizes of the window are installed by the first + call of this function and are ignored at subsequent; to change + position and/or sizes of already created window use function 67. + * For windows with styles Y=3,4 and caption (A=1) caption string + is set by the first call of this function and is ignored + at subsequent (strictly speaking, is ignored after a call to + subfunction 2 of function 12 - end redraw); to change caption of + already created window use subfunction 1 of function 71. + * If the window has appropriate styles, position and/or sizes can be + changed by user. Current position and sizes can be obtained + by function 9. + * The window must fit on the screen. If the transferred + coordinates and sizes do not satisfy to this condition, + appropriate coordinate (or, probably, both) is considered as zero, + and if it does not help too, the appropriate size + (or, probably, both) is installed in a size of the screen. + + Further let us designate xpos,ypos,xsize,ysize - values passed + in ebx,ecx. The coordinates are resulted concerning + the left upper corner of the window, which, thus, is set as (0,0), + coordinates of the right lower corner essence (xsize,ysize). + * The sizes of the window are understood in sence of coordinates + of the right lower corner. This concerns all other functions too. + It means, that the real sizes are on 1 pixel more. + * The window of type I looks as follows: + * draw external frame of color indicated in edi, 1 pixel in width + * draw header - rectangle with the left upper corner (1,1) and + right lower (xsize-1,min(25,ysize)) color indicated in esi + (taking a gradient into account) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (1,21) and right lower + (xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color + indicated in edx (taking a gradient into account) + * if A=1 and caption has been already set by subfunction 1 + of function 71, it is drawn in the corresponding place of header + * The window of style Y=1 looks as follows: + * completely defined by the application + * The window of type II looks as follows: + * draw external frame of width 1 pixel with the "shaded" color + edi (all components of the color decrease twice) + * draw intermediate frame of width 3 pixels with color edi + * draw internal frame of width 1 pixel with the "shaded" color edi + * draw header - rectangle with the left upper corner (4,4) + and right lower (xsize-4,min(20,ysize)) color, indicated in esi + (taking a gradient into account) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (5,20) and right lower + (xsize-5,ysize-5) with color indicated in edx + (taking a gradient into account) + * if A=1 and caption has been already set by subfunction 1 + of function 71, it is drawn in the corresponding place of header + * The skinned window looks as follows: + * draw external frame of width 1 pixel + with color 'outer' from the skin + * draw intermediate frame of width 3 pixel + with color 'frame' from the skin + * draw internal frame of width 1 pixel + with color 'inner' from the skin + * draw header (on bitmaps from the skin) in a rectangle + (0,0) - (xsize,_skinh-1) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (5,_skinh) and right lower + (xsize-5,ysize-5) with color indicated in edx + (taking a gradient into account) + * define two standard buttons: close and minimize + (see function 8) + * if A=1 and edi contains (nonzero) pointer to caption string, + it is drawn in place in header defined in the skin + * value _skinh is accessible as the result of call + subfunction 4 of function 48 + +====================================================================== +================ Function 1 - put pixel in the window. =============== +====================================================================== +Parameters: + * eax = 1 - function number + * ebx = x-coordinate (relative to the window) + * ecx = y-coordinate (relative to the window) + * edx = 0x00RRGGBB - color of a pixel + edx = 0x01xxxxxx - invert color of a pixel + (low 24 bits are ignored) +Returned value: + * function does not return value + +====================================================================== +============ Function 2 - get the code of the pressed key. =========== +====================================================================== +Takes away the code of the pressed key from the buffer. +Parameters: + * eax = 2 - function number +Returned value: + * if the buffer is empty, function returns eax=1 + * if the buffer is not empty, function returns al=0, + ah=code of the pressed key, high word of eax is zero + * if there is "hotkey", function returns al=2, + ah=scancode of the pressed key (0 for control keys), + high word of eax contains a status of control keys at the moment + of pressing a hotkey +Remarks: + * There is a common system buffer of the pressed keys + by a size of 120 bytes, organized as queue. + * There is one more common system buffer on 120 "hotkeys". + * If the application with the inactive window calls this function, + the buffer of the pressed keys is considered to be empty. + * By default this function returns ASCII-codes; to switch + to the scancodes mode (and back) use function 66. + However, hotkeys are always notificated as scancodes. + * To find out, what keys correspond to what codes, start + the application keyascii and scancode. + * Scancodes come directly from keyboard and are fixed; + ASCII-codes turn out with usage of the conversion tables, + which can be set by subfunction 2 of function 21 + and get by subfunction 2 of function 26. + * As a consequence, ASCII-codes take into account current + keyboard layout (rus/en) as opposed to scancodes. + * This function notifies only about those hotkeys, which were + defined by this thread by subfunction 4 of function 66. + +====================================================================== +==================== Function 3 - get system time. =================== +====================================================================== +Parameters: + * eax = 3 - function number +Returned value: + * eax = 0x00SSMMHH, where HH:MM:SS = Hours:Minutes:Seconds + * each item is BCD-number, for example, + for time 23:59:59 function returns 0x00595923 +Remarks: + * See also subfunction 9 of function 26 - get time from + the moment of start of the system; it is more convenient, because + returns simply DWORD-value of the time counter. + * System time can be set by function 22. + +====================================================================== +============ Function 4 - draw text string in the window. ============ +====================================================================== +Parameters: + * eax = 4 - function number + * ebx = [coordinate on axis x]*65536 + [coordinate on axis y] + * ecx = 0xX0RRGGBB, where + * RR, GG, BB specify text color + * X=ABnn (bits): + * nn specifies the used font: 0=system monospaced, + 1=system font of variable width + * A=0 - output esi characters, A=1 - output ASCIIZ-string + * B=1 - fill background with the color edi + * edx = pointer to the beginning of the string + * esi = for A=0 length of the string, must not exceed 255; + for A=1 is ignored +Returned value: + * function does not return value +Remarks: + * First system font is read out at loading from the file char.mt, + second - from char2.mt. + * Both fonts have height 9 pixels, width of the monospaced font + is equal to 6 pixels. + +====================================================================== +========================= Function 5 - delay. ======================== +====================================================================== +Delays execution of the program on the given time. +Parameters: + * eax = 5 - function number + * ebx = time in the 1/100 of second +Returned value: + * function does not return value +Remarks: + * Passing ebx=0 does not transfer control to the next process + and does not make any operations at all. If it is really required + to transfer control to the next process (to complete a current + time slice), use subfunction 1 of function 68. + +====================================================================== +============== Function 6 - read the file from ramdisk. ============== +====================================================================== +Parameters: + * eax = 6 - function number + * ebx = pointer to the filename + * ecx = number of start block, beginning from 1; + ecx=0 - read from the beginning of the file (same as ecx=1) + * edx = number of blocks to read; + edx=0 - read one block (same as edx=1) + * esi = pointer to memory area for the data +Returned value: + * eax = file size in bytes, if the file was successfully read + * eax = -1, if the file was not found +Remarks: + * This function is out-of-date; function 70 allows + to fulfil the same operations with the extended possibilities. + * Block = 512 bytes. + * For reading all file you can specify the certainly large value + in edx, for example, edx = -1; but in this case be ready that + the program will "fall", if the file will appear too large and can + not be placed in the program memory. + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +=============== Function 7 - draw image in the window. =============== +====================================================================== +Paramters: + * eax = 7 - function number + * ebx = pointer to the image in the format BBGGRRBBGGRR... + * ecx = [size on axis x]*65536 + [size on axis y] + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] +Returned value: + * function does not return value +Remarks: + * Coordinates of the image are coordinates of the upper left corner + of the image relative to the window. + * Size of the image in bytes is 3*xsize*ysize. + +====================================================================== +=============== Function 8 - define/delete the button. =============== +====================================================================== +Parameters for button definition: + * eax = 8 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = 0xXYnnnnnn, where: + * nnnnnn = identifier of the button + * high (31st) bit of edx is cleared + * if 30th bit of edx is set - do not draw the button + * if 29th bit of edx is set - do not draw a frame + at pressing the button + * esi = 0x00RRGGBB - color of the button +Parameters for button deleting: + * eax = 8 - function number + * edx = 0x80nnnnnn, where nnnnnn - identifier of the button +Returned value: + * function does not return value +Remarks: + * Sizes of the button must be more than 0 and less than 0x8000. + * For skinned windows definition of the window + (call of 0th function) creates two standard buttons - + for close of the window with identifier 1 and + for minimize of the window with identifier 0xffff. + * The creation of two buttons with same identifiers is admitted. + * The button with the identifier 0xffff at pressing is interpreted + by the system as the button of minimization, the system handles + such pressing independently, not accessing to the application. + In rest it is usual button. + * Total number of buttons for all applications is limited to 4095. + +====================================================================== +============ Function 9 - information on execution thread. =========== +====================================================================== +Parameters: + * eax = 9 - function number + * ebx = pointer to 1-Kb buffer + * ecx = number of the slot of the thread + ecx = -1 - get information on the current thread +Returned value: + * eax = maximum number of the slot of a thread + * buffer pointed to by ebx contains the following information: + * +0: dword: usage of the processor (how many time units + per second leaves on execution of this thread) + * +4: word: position of the window of thread in the window stack + * +6: word: (has no relation to the specified thread) + number of the thread slot, which window has in the window stack + position ecx + * +8: word: reserved + * +10 = +0xA: 11 bytes: name of the process + (name of corresponding executable file in the format 8+3) + * +21 = +0x15: byte: reserved, this byte is not changed + * +22 = +0x16: dword: address of the process in memory + * +26 = +0x1A: dword: size of used memory - 1 + * +30 = +0x1E: dword: identifier (PID/TID) + * +34 = +0x22: dword: coordinate of the thread window on axis x + * +38 = +0x26: dword: coordinate of the thread window on axis y + * +42 = +0x2A: dword: size of the thread window on axis x + * +46 = +0x2E: dword: size of the thread window on axis y + * +50 = +0x32: word: status of the thread slot: + * 0 = thread is running + * 1 = thread is suspended + * 2 = thread is suspended while waiting for event + * 3 = thread is terminating as a result of call to function -1 + or under duress as a result of call to subfunction 2 + of function 18 or termination of the system + * 4 = thread is terminating as a result of exception + * 5 = thread waits for event + * 9 = requested slot is free, all other information on the slot + is not meaningful + * +52 = +0x34: word: reserved, this word is not changed + * +54 = +0x36: dword: coordinate of the client area on axis x + * +58 = +0x3A: dword: coordinate of the client area on axis y + * +62 = +0x3E: dword: width of the client area + * +66 = +0x42: dword: height of the client area + * +70 = +0x46: byte: state of the window - bitfield + * bit 0 (mask 1): window is maximized + * bit 1 (mask 2): window is minimized to panel + * bit 2 (mask 4): window is rolled up +Remarks: + * Slots are numbered starting from 1. + * Returned value is not a total number of threads, because there + can be free slots. + * When process is starting, system automatically creates + execution thread. + * Function gives information on the thread. Each process has + at least one thread. One process can create many threads, + in this case each thread has its own slot and the fields + +10, +22, +26 in these slots coincide. + Applications have no common way to define whether two threads + belong to one process. + * The active window - window on top of the window stack - + receives the messages on a keyboard input. For such window + the position in the window stack coincides with returned value. + * Slot 1 corresponds to special system thread, for which: + * the window is in the bottom of the window stack, the fields + +4 and +6 contain value 1 + * name of the process - "OS/IDLE" (supplemented by spaces) + * address of the process in memory is 0, size of used memory is + 16 Mb (0x1000000) + * PID=1 + * coordinates and sizes of the window and the client area are by + convention set to 0 + * status of the slot is always 0 (running) + * the execution time adds of time leaving on operations itself + and idle time in waiting for interrupt (which can be got by call + to subfunction 4 of function 18). + * Beginning from slot 2, the normal applications are placed. + * The normal applications are placed in memory at the address + 0x60400000 (kernel constant 'std_application_base_address'). + There is no intersection, as each process has its own page table. + * At creation of the thread it is assigned the slot + in the system table and identifier (Process/Thread IDentifier = + PID/TID), which do not vary with time for given thread. + After completion of the thread its slot can be anew used + for another thread. The thread identifier can not be assigned + to other thread even after completion of this thread. + Identifiers, assigned to new threads, grow monotonously. + * If the thread has not yet defined the window by call to + function 0, the position and the sizes + of its window are considered to be zero. + * Coordinates of the client area are relative to the window. + * At the moment only the part of the buffer by a size + 71 = 0x37 bytes is used. Nevertheless it is recommended to use + 1-Kb buffer for the future compatibility, in the future + some fields can be added. + +====================================================================== +==================== Function 10 - wait for event. =================== +====================================================================== +If the message queue is empty, waits for appearance of the message +in queue. In this state thread does not consume CPU time. +Then reads out the message from queue. + +Parameters: + * eax = 10 - function number +Returned value: + * eax = event (see the list of events) +Remarks: + * Those events are taken into account only which enter into + a mask set by function 40. By default it is + redraw, key and button events. + * To check, whether there is a message in queue, use function 11. + To wait for no more than given time, use function 23. + +====================================================================== +=============== Function 11 - check for event, no wait. ============== +====================================================================== +If the message queue contains event, function reads out +and return it. If the queue is empty, function returns 0. +Parameters: + * eax = 11 - function number +Returned value: + * eax = 0 - message queue is empty + * else eax = event (see the list of events) +Remarks: + * Those events are taken into account only, which enter into + a mask set by function 40. By default it is + redraw, key and button events. + * To wait for event, use function 10. + To wait for no more than given time, use function 23. + +====================================================================== +=============== Function 12 - begin/end window redraw. =============== +====================================================================== + +---------------- Subfunction 1 - begin window redraw. ---------------- +Parameters: + * eax = 12 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value + +----------------- Subfunction 2 - end window redraw. ----------------- +Parameters: + * eax = 12 - function number + * ebx = 2 - subfunction number +Returned value: + * function does not return value +Remarks: + * Subfunction 1 deletes all buttons defined with + function 8, they must be defined again. + +====================================================================== +============ Function 13 - draw a rectangle in the window. =========== +====================================================================== +Parameters: + * eax = 13 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = color 0xRRGGBB or 0x80RRGGBB for gradient fill +Returned value: + * function does not return value +Remarks: + * Coordinates are understood as coordinates of the left upper corner + of a rectangle relative to the window. + +====================================================================== +=================== Function 14 - get screen size. =================== +====================================================================== +Parameters: + * eax = 14 - function number +Returned value: + * eax = [xsize]*65536 + [ysize], where + * xsize = x-coordinate of the right lower corner of the screen = + horizontal size - 1 + * ysize = y-coordinate of the right lower corner of the screen = + vertical size - 1 +Remarks: + * See also subfunction 5 of function 48 - get sizes of + working area of the screen. + +====================================================================== +== Function 15, subfunction 1 - set a size of the background image. == +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 1 - subfunction number + * ecx = width of the image + * edx = height of the image +Returned value: + * function does not return value +Remarks: + * Before calling subfunctions 2 and 5 you should call this function + to set image size! + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get size of the background image - + subfunction 1 of function 39. + +====================================================================== +=== Function 15, subfunction 2 - put pixel on the background image. == +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 2 - subfunction number + * ecx = offset + * edx = color of a pixel 0xRRGGBB +Returned value: + * function does not return value +Remarks: + * Offset for a pixel with coordinates (x,y) is calculated as + (x+y*xsize)*3. + * If the given offset exceeds size set by subfunction 1, + the call is ignored. + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get pixel on the background image - + subfunction 2 of function 39. + +====================================================================== +=========== Function 15, subfunction 3 - redraw background. ========== +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 3 - subfunction number +Returned value: + * function does not return value + +====================================================================== +== Function 15, subfunction 4 - set drawing mode for the background. = +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 4 - subfunction number + * ecx = drawing mode: + * 1 = tile + * 2 = stretch +Returned value: + * function does not return value +Remarks: + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get drawing mode of the background - + subfunction 4 of function 39. + +====================================================================== +===================== Function 15, subfunction 5 ===================== +============ Put block of pixels on the background image. ============ +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 5 - subfunction number + * ecx = pointer to the data in the format BBGGRRBBGGRR... + * edx = offset in data of the background image + * esi = size of data in bytes = 3 * number of pixels +Returned value: + * function does not return value +Remarks: + * Offset and size are not checked for correctness. + * Color of each pixel is stored as 3-bytes value BBGGRR. + * Pixels of the background image are written sequentially + from left to right, from up to down. + * Offset of pixel with coordinates (x,y) is (x+y*xsize)*3. + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + +====================================================================== +===================== Function 15, subfunction 6 ===================== +======== Map background data to the address space of process. ======== +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 6 - subfunction number +Returned value: + * eax = pointer to background data, 0 if error +Remarks: + * Mapped data are available for read and write. + * Size of background data is 3*xsize*ysize. The system blocks + changes of background sizes while process works with mapped data. + * Color of each pixel is stored as 3-bytes value BBGGRR. + * Pixels of the background image are written sequentially + from left to right, from up to down. + +====================================================================== +===== Function 15, subfunction 7 - close mapped background data. ===== +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 7 - subfunction number + * ecx = pointer to mapped data +Returned value: + * eax = 1 - success, 0 - error + +====================================================================== +=============== Function 16 - save ramdisk on a floppy. ============== +====================================================================== +Parameters: + * eax = 16 - function number + * ebx = 1 or ebx = 2 - on which floppy save +Returned value: + * eax = 0 - success + * eax = 1 - error + +====================================================================== +======= Function 17 - get the identifier of the pressed button. ====== +====================================================================== +Takes away the code of the pressed button from the buffer. +Parameters: + * eax = 17 - function number +Returned value: + * if the buffer is empty, function returns eax=1 + * if the buffer is not empty: + * high 24 bits of eax contain button identifier (in particular, + ah contains low byte of the identifier; if all buttons have + the identifier less than 256, ah is enough to distinguish) + * al = 0 - the button was pressed with left mouse button + * al = bit corresponding to used mouse button otherwise +Remarks: + * "Buffer" keeps only one button, at pressing the new button the + information about old is lost. + * The call of this function by an application with inactive window + will return answer "buffer is empty". + * Returned value for al corresponds to the state of mouse buttons + as in subfunction 2 of function 37 at the beginning + of button press, excluding lower bit, which is cleared. + +====================================================================== += Function 18, subfunction 2 - terminate process/thread by the slot. = +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 2 - subfunction number + * ecx = number of the slot of process/thread +Returned value: + * function does not return value +Remarks: + * It is impossible to terminate system thread OS/IDLE (with + number of the slot 1), + it is possible to terminate any normal process/thread. + * See also subfunction 18 - terminate + process/thread by the identifier. + +====================================================================== +===================== Function 18, subfunction 3 ===================== +============= Make active the window of the given thread. ============ +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 3 - subfunction number + * ecx = number of the thread slot +Returned value: + * function does not return value +Remarks: + * If correct, but nonexistent slot is given, + some window is made active. + * To find out, which window is active, use subfunction 7. + +====================================================================== +===================== Function 18, subfunction 4 ===================== +=========== Get counter of idle time units per one second. =========== +====================================================================== +Idle time units are units, in which the processor stands idle +in waiting for interrupt (in the command 'hlt'). + +Parameters: + * eax = 18 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = value of the counter of idle time units per one second + +====================================================================== +========== Function 18, subfunction 5 - get CPU clock rate. ========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = clock rate (modulo 2^32 clock ticks = 4GHz) + +====================================================================== + Function 18, subfunction 6 - save ramdisk to the file on hard drive. +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 6 - subfunction number + * ecx = pointer to the full path to file + (for example, "/hd0/1/kolibri/kolibri.img") +Returned value: + * eax = 0 - success + * else eax = error code of the file system +Remarks: + * All folders in the given path must exist, otherwise function + returns value 5, "file not found". + +====================================================================== +=========== Function 18, subfunction 7 - get active window. ========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = number of the active window + (number of the slot of the thread with active window) +Remarks: + * Active window is at the top of the window stack and receives + messages on all keyboard input. + * To make a window active, use subfunction 3. + +====================================================================== +== Function 18, subfunction 8 - disable/enable the internal speaker. = +====================================================================== +If speaker sound is disabled, all calls to subfunction 55 of +function 55 are ignored. If speaker sound is enabled, +they are routed on builtin speaker. + +------------------- Subsubfunction 1 - get status. ------------------- +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 1 - number of the subsubfunction +Returned value: + * eax = 0 - speaker sound is enabled; 1 - disabled + +----------------- Subsubfunction 2 - toggle status. ------------------ +Toggles states of disable/enable. +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 2 - number of the subsubfunction +Returned value: + * function does not return value + +====================================================================== +== Function 18, subfunction 9 - system shutdown with the parameter. == +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 9 - subfunction number + * ecx = parameter: + * 2 = turn off computer + * 3 = reboot computer + * 4 = restart the kernel from the file 'kernel.mnt' on ramdisk +Returned value: + * at incorrect ecx the registers do not change (i.e. eax=18) + * by correct call function always returns eax=0 + as the tag of success +Remarks: + * Do not rely on returned value by incorrect call, it can be + changed in future versions of the kernel. + +====================================================================== +===== Function 18, subfunction 10 - minimize application window. ===== +====================================================================== +Minimizes the own window. +Parameters: + * eax = 18 - function number + * ebx = 10 - subfunction number +Returned value: + * function does not return value +Remarks: + * The minimized window from the point of view of function 9 + keeps position and sizes. + * Restoring of an application window occurs at its activation by + subfunction 3. + * Usually there is no necessity to minimize/restire a window + obviously: minimization of a window is carried out by the system + at pressing the minimization button (for skinned windows + it is defined automatically by function 0, + for other windows it can be defined manually by function 8), + restore of a window is done by the application '@panel'. + +====================================================================== + Function 18, subfunction 11 - get information on the disk subsystem. +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 11 - subfunction number + * ecx = type of the table: + * 1 = short version, 10 bytes + * 2 = full version, 65536 bytes + * edx = pointer to the buffer (in the application) for the table +Returned value: + * function does not return value +Format of the table: short version: + * +0: byte: information about FDD's (drives for floppies), + AAAABBBB, where AAAA gives type of the first drive, BBBB - + of the second regarding to the following list: + * 0 = there is no drive + * 1 = 360Kb, 5.25'' + * 2 = 1.2Mb, 5.25'' + * 3 = 720Kb, 3.5'' + * 4 = 1.44Mb, 3.5'' + * 5 = 2.88Mb, 3.5'' (such drives are not used anymore) + For example, for the standard configuration from one 1.44-drive + here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B: + the value is 24h. + * +1: byte: information about hard disks and CD-drives, AABBCCDD, + where AA corresponds to the controller IDE0, ..., DD - IDE3: + * 0 = device is absent + * 1 = hard drive + * 2 = CD-drive + For example, in the case HD on IDE0 and CD on IDE2 + this field contains 48h. + * +2: 4 db: number of the retrieved partitions on hard disks + at accordingly IDE0,...,IDE3. + If the hard disk on IDEx is absent, appropriate byte is zero, + otherwise it shows number of the recognized partitions, which + can be not presented (if the drive is not formatted or if + the file system is not supported). Current version of the kernel + supports only FAT16, FAT32 and NTFS for hard disks. + * +6: 4 db: reserved +Format of the table: full version: + * +0: 10 db: same as for the short version + * +10: 100 db: data for the first partition + * +110: 100 db: data for the second partition + * ... + * +10+100*(n-1): 100 db: data for the last partition +The partitions are located as follows: at first sequentially all +recoginzed partitions on HD on IDE0 (if present), +then on HD on IDE1 (if present) and so on up to IDE3. +Format of the information about partition +(at moment only FAT is supported): + * +0: dword: first physical sector of the partition + * +4: dword: last physical sector of the partition + (belongs to the partition) + * +8: byte: file system type: + 16=FAT16, 32=FAT32, 1=NTFS + * other data are dependent on file system, are modified with + kernel modifications and therefore are not described +Remarks: + * The short table can be used for obtaining the information about + available devices. + +====================================================================== +========== Function 18, subfunction 13 - get kernel version. ========= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 13 - subfunction number + * ecx = pointer to the buffer (not less than 16 bytes), where + the information will be placed +Returned value: + * function does not return value +Structure of the buffer: +db a,b,c,d for version a.b.c.d +db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 +dd REV - kernel SVN revision number +For Kolibri 0.7.1.0 kernel: +db 0,7,0,0 +db 2 +dd 638 + +====================================================================== +======= Function 18, subfunction 14 - wait for screen retrace. ======= +====================================================================== +Waits for the beginning of retrace of the scanning ray of the screen +monitor. +Parameters: + * eax = 18 - function number + * ebx = 14 - subfunction number +Returned value: + * eax = 0 as the tag of success +Remarks: + * Function is intended only for active high-efficiency graphics + applications; is used for smooth output of a graphics. + +====================================================================== +== Function 18, subfunction 15 - center mouse cursor on the screen. == +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 15 - subfunction number +Returned value: + * eax = 0 as the tag of success + +====================================================================== +========= Function 18, subfunction 16 - get size of free RAM. ======== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 16 - subfunction number +Returned value: + * eax = size of free memory in kilobytes + +====================================================================== +======== Function 18, subfunction 17 - get full amount of RAM. ======= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 17 - subfunction number +Returned value: + * eax = total size of existing memory in kilobytes + +====================================================================== +===================== Function 18, subfunction 18 ==================== +============= Terminate process/thread by the identifier. ============ +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 18 - subfunction number + * ecx = identifer of process/thread (PID/TID) +Returned value: + * eax = 0 - success + * eax = -1 - error (process is not found or is system) +Remarks: + * It is impossible to terminate system thread OS/IDLE (identifier + 1), it is possible to terminate any normal process/thread. + * See also subfunction 2 - terminate + process/thread by given slot. + +====================================================================== +======== Function 18, subfunction 19 - get/set mouse features. ======= +====================================================================== + +---------------- Subsubfunction 0 - get mouse speed. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 0 - subsubfunction number +Returned value: + * eax = current mouse speed + +---------------- Subsubfunction 1 - set mouse speed. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 1 - subsubfunction number + * edx = new value for speed +Returned value: + * function does not return value + +---------------- Subsubfunction 2 - get mouse delay. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 2 - subsubfunction number +Returned value: + * eax = current mouse delay + +---------------- Subsubfunction 3 - set mouse delay. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 3 - subsubfunction number + * edx = new value for mouse delay +Returned value: + * function does not return value + +----------- Subsubfunction 4 - set mouse pointer position. ----------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 4 - subsubfunction number + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] +Returned value: + * function does not return value + +-------- Subsubfunction 5 - simulate state of mouse buttons. --------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 5 - subsubfunction number + * edx = information about emulated state of mouse buttons: + (same as return value in subfunction 2 of function 37) + * bit 0 is set = left button is pressed + * bit 1 is set = right button is pressed + * bit 2 is set = middle button is pressed + * bit 3 is set = 4th button is pressed + * bit 4 is set = 5th button is pressed +Returned value: + * function does not return value +Remarks: + * It is recommended to set speed of the mouse (in subsubfunction 1) + from 1 up to 9. The installed value is not inspected by the kernel + code, so set it carefully, at incorrect value the cursor + can "freeze". Speed of the mouse can be regulated through the + application SETUP. + * Recommended delay of the mouse (in subsubfunction 3) = 10. Lower + value is not handled by COM mice. At the very large values the + movement of the mouse on 1 pixel is impossible and the cursor will + jump on the value of installed speed (subsubfunction 1). The + installed value is not inspected by the kernel code. + Mouse delay can be regulated through the application SETUP. + * The subsubfunction 4 does not check the passed value. Before + its call find out current screen resolution (with function 14) + and check that the value of position is inside the limits of the + screen. + +====================================================================== +======== Function 18, subfunction 20 - get information on RAM. ======= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 20 - subfunction number + * ecx = pointer to the buffer for information (36 bytes) +Returned value: + * eax = total size of existing RAM in pages + or -1 if error has occured + * buffer pointed to by ecx contains the following information: + * +0: dword: total size of existing RAM in pages + * +4: dword: size of free RAM in pages + * +8: dword: number of page faults (exceptions #PF) + in applications + * +12: dword: size of kernel heap in bytes + * +16: dword: free in kernel heap in bytes + * +20: dword: total number of memory blocks in kernel heap + * +24: dword: number of free memory blocks in kernel heap + * +28: dword: size of maximum free block in kernel heap + (reserved) + * +32: dword: size of maximum allocated block in kernel heap + (reserved) + +====================================================================== +===================== Function 18, subfunction 21 ==================== +======== Get slot number of process/thread by the identifier. ======== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 21 - subfunction number + * ecx = identifer of process/thread (PID/TID) +Returned value: + * eax = 0 - error (invalid identifier) + * otherwise eax = slot number + +====================================================================== +===================== Function 18, subfunction 22 ==================== +============== Operations with window of another thread. ============= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 22 - subfunction number + * ecx = operation type: + * 0 = minimize window of the thread with given slot number + * 1 = minimize window of the thread with given identifier + * 2 = restore window of the thread with given slot number + * 3 = restore window of the thread with given identifier + * edx = parameter (slot number or PID/TID) +Returned value: + * eax = 0 - success + * eax = -1 - error (invalid identifier) +Remarks: + * The thread can minimize its window with subfunction 10. + * One can restore and activate window simultaneously with + subfunction 3 (which requires slot number). + +====================================================================== +==================== Function 20 - MIDI interface. =================== +====================================================================== + +----------------------- Subfunction 1 - reset ------------------------ +Parameters: + * eax = 20 - function number + * ebx = 1 - subfunction number + +-------------------- Subfunction 2 - output byte --------------------- +Parameters: + * eax = 20 - function number + * ebx = 2 - subfunction number + * cl = byte for output +Returned value (is the same for both subfunctions): + * eax = 0 - success + * eax = 1 - base port is not defined +Remarks: + * Previously the base port must be defined by + subfunction 1 of function 21. + +====================================================================== +======== Function 21, subfunction 1 - set MPU MIDI base port. ======== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 1 - subfunction number + * ecx = number of base port +Returned value + * eax = 0 - success + * eax = -1 - erratic number of a port +Remarks: + * Number of a port must satisfy to conditions 0x100<=ecx<=0xFFFF. + * The installation of base is necessary for function 20. + * To get base port use subfunction 1 of function 26. + +====================================================================== +========== Function 21, subfunction 2 - set keyboard layout. ========= +====================================================================== +Keyboard layout is used to convert keyboard scancodes to ASCII-codes, +which will be read by function 2. +Parameters: + * eax = 21 - function number + * ebx = 2 - subfunction number + * ecx = which layout to set: + * 1 = normal layout + * 2 = layout at pressed Shift + * 3 = layout at pressed Alt + * edx = pointer to layout - table of length 128 bytes +Or: + * ecx = 9 + * dx = country identifier (1=eng, 2=fi, 3=ger, 4=rus) +Returned value: + * eax = 0 - success + * eax = 1 - incorrect parameter +Remarks: + * If Alt is pressed, the layout with Alt is used; + if Alt is not pressed, but Shift is pressed, + the layout with Shift is used; + if Alt and Shift are not pressed, but Ctrl is pressed, the normal + layout is used and then from the code is subtracted 0x60; + if no control key is pressed, the normal layout is used. + * To get layout and country identifier use + subfunction 2 of function 26. + * Country identifier is global system variable, which is not used + by the kernel itself; however the application '@panel' displays + the corresponding icon. + * The application @panel switches layouts on user request. + +====================================================================== +============== Function 21, subfunction 3 - set CD base. ============= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 3 - subfunction number + * ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Returned value: + * eax = 0 +Remarks: + * CD base is used by function 24. + * To get CD base use subfunction 3 of function 26. + +====================================================================== +========== Function 21, subfunction 5 - set system language. ========= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 5 - subfunction number + * ecx = system language (1=eng, 2=fi, 3=ger, 4=rus) +Returned value: + * eax = 0 +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon. + * Function does not check for correctness, as the kernel does not + use this variable. + * To get system language use subfunction 5 of function 26. + +====================================================================== +============== Function 21, subfunction 7 - set HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +syntax /HD in obsolete function 58; at usage of modern syntax +/HD0,/HD1,/HD2,/HD3 base is set automatically. +Parameters: + * eax = 21 - function number + * ebx = 7 - subfunction number + * ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Returned value: + * eax = 0 +Remarks: + * Any application at any time can change the base. + * Do not change base, when any application works with hard disk. + If you do not want system bugs. + * To get HD base use subfunction 7 of function 26. + * It is also necessary to define used partition of hard disk by + subfunction 8. + +====================================================================== +========= Function 21, subfunction 8 - set used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete syntax /HD and obsolete function 58; +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +base and partition are set automatically. +Parameters: + * eax = 21 - function number + * ebx = 8 - subfunction number + * ecx = HD partition (beginning from 1) +Return value: + * eax = 0 +Remarks: + * Any application at any time can change partition. + * Do not change partition when any application works with hard disk. + If you do not want system bugs. + * To get used partition use subfunction 8 of function 26. + * There is no correctness checks. + * To get the number of partitions of a hard disk use + subfunction 11 of function 18. + * It is also necessary to define used HD base by subfunction 7. + +====================================================================== + Function 21, subfunction 11 - enable/disable low-level access to HD. +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 11 - subfunction number + * ecx = 0/1 - disable/enable +Returned value: + * eax = 0 +Remarks: + * Is used in LBA-read (subfunction 8 of function 58). + * The current implementation uses only low bit of ecx. + * To get current status use subfunction 11 of function 26. + +====================================================================== + Function 21, subfunction 12 - enable/disable low-level access to PCI. +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 12 - subfunction number + * ecx = 0/1 - disable/enable +Returned value: + * eax = 0 +Remarks: + * Is used in operations with PCI bus (function 62). + * The current implementation uses only low bit of ecx. + * To get current status use subfunction 12 of function 26. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 1 =========== +======== Initialize + get information on the driver vmode.mdr. ======= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 1 - number of the driver function + * edx = pointer to 512-bytes buffer +Returned value: + * if driver is not loaded + (never happens in the current implementation): + * eax = -1 + * ebx, ecx destroyed + * if driver is loaded: + * eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high) + - signature + * ebx = current frequency of the scanning (in Hz) + * ecx destroyed + * buffer pointed to by edx is filled +Format of the buffer: + * +0: 32*byte: driver name, "Trans VideoDriver" + (without quotes, supplemented by spaces) + * +32 = +0x20: dword: driver version (version x.y is encoded as + y*65536+x), for the current implementation is 1 (1.0) + * +36 = +0x24: 7*dword: reserved (0 in the current implementation) + * +64 = +0x40: 32*word: list of supported videomodes (each word + is number of a videomode, after list itself there are zeroes) + * +128 = +0x80: 32*(5*word): list of supported frequences of the + scannings for videomodes: for each videomode listed in the + previous field up to 5 supported frequences are given + (unused positions contain zeroes) +Remarks: + * Function initializes the driver (if it is not initialized yet) + and must be called first, before others (otherwise they will do + nothing and return -1). + * The current implementation supports only one frequency + of the scanning on videomode. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 2 =========== +================ Get information on current videomode. =============== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 2 - number of the driver function +Returned value: + * eax = -1 - driver is not loaded or not initialized; + ebx,ecx are destroyed + * eax = [width]*65536 + [height] + * ebx = frequency of the vertical scanning (in Hz) + * ecx = number of current videomode +Remarks: + * Driver must be initialized by call to + driver function 1. + * If only screen sizes are required, it is more expedient to use + function 14 taking into account that it + returns sizes on 1 less. + +====================================================================== +=== Function 21, subfunction 13, subsubfunction 3 - set videomode. === +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 3 - number of the driver function + * edx = [scanning frequency]*65536 + [videomode number] +Returned value: + * eax = -1 - driver is not loaded, not initialized or + an error has occured + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by driver function 1. + * The videomode number and frequency must be in the table + returned by driver function 1. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 4 =========== +================== Return to the initial videomode. ================== +====================================================================== +Returns the screen to the videomode set at system boot. +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 4 - number of the driver function +Returned value: + * eax = -1 - driver is not loaded or not initialized + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by call to driver function 1. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 5 =========== +===== Increase/decrease the size of the visible area of monitor. ===== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 5 - number of the driver function + * edx = 0/1 - decrease/increase horizontal size on 1 position + * edx = 2/3 - is not supported in the current implementation; + is planned as decrease/increase vertical size on 1 position +Returned value: + * eax = -1 - driver is not loaded or not initialized + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by call to driver function 1. + * Function influences only the physical size of the screen image; + the logical size (number of pixels) does not change. + +====================================================================== +================= Function 22 - set system date/time. ================ +====================================================================== +Parameters: + * eax = 22 - function number + * ebx = 0 - set time + * ecx = 0x00SSMMHH - time in the binary-decimal code (BCD): + * HH=hour 00..23 + * MM=minute 00..59 + * SS=second 00..59 + * ebx = 1 - set date + * ecx = 0x00DDMMYY - date in the binary-decimal code (BCD): + * DD=day 01..31 + * MM=month 01..12 + * YY=year 00..99 + * ebx = 2 - set day of week + * ecx = 1 for Sunday, ..., 7 for Saturday + * ebx = 3 - set alarm clock + * ecx = 0x00SSMMHH +Returned value: + * eax = 0 - success + * eax = 1 - incorrect parameter + * eax = 2 - CMOS-battery was unloaded +Remarks: + * Value of installation of day of week seems to be doubtful, + as it a little where is used + (day of week can be calculated by date). + * Alarm clock can be set on operation in the given time every day. + But there is no existing system function to disable it. + * Operation of alarm clock consists in generation IRQ8. + * Generally CMOS supports for alarm clock set of value 0xFF + as one of parameters and it means that the appropriate parameter + is ignored. But current implementation does not allow this + (will return 1). + * Alarm clock is a global system resource; the set of + an alarm clock cancels automatically the previous set. + However, at moment no program uses it. + +====================================================================== +============= Function 23 - wait for event with timeout. ============= +====================================================================== +If the message queue is empty, waits for new message in the queue, +but no more than given time. Then reads out a message from the queue. + +Parameters: + * eax = 23 - function number + * ebx = timeout (in 1/100 of second) +Returned value: + * eax = 0 - the message queue is empty + * otherwise eax = event (see the list of events) +Remarks: + * Only those events are taken into account, which enter into + the mask set by function 40. By default it is + redraw, key and button events. + * To check for presence of a message in the queue use function 11. + To wait without timeout use function 10. + * Transmission ebx=0 results in immediate returning eax=0. + * Current implementation returns immediately with eax=0, + if the addition of ebx with the current value of time counter + makes 32-bit overflow. + +====================================================================== +======== Function 24, subfunction 1 - begin to play CD-audio. ======== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 1 - subfunction number + * ecx = 0x00FRSSMM, where + * MM = starting minute + * SS = starting second + * FR = starting frame +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Remarks: + * Previously CD base must be defined by the call to + subfunction 3 of function 21. + * One second includes 75 frames, one minute includes 60 seconds. + * The function is asynchronous (returns control, when play begins). + +====================================================================== +======= Function 24, subfunction 2 - get information on tracks. ====== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 2 - subfunction number + * ecx = pointer to the buffer for the table + (maximum 8*64h+4 bytes=100 tracks) +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Remarks: + * The format of the table with tracks information is the same as + for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h). + Function returns addresses in MSF. + * Previously CD base port must be set by call to + subfunction 3 of function 21. + * Function returns information only about no more than 100 + first tracks. In most cases it is enough. + +====================================================================== +========== Function 24, subfunction 3 - stop play CD-audio. ========== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Remarks: + * Previously CD base port must be defined by call to + subfunction 3 of function 21. + +====================================================================== +======= Function 24, subfunction 4 - eject tray of disk drive. ======= +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 4 - subfunction number + * ecx = position of CD/DVD-drive + (from 0=Primary Master to 3=Secondary Slave) +Returned value: + * function does not return value +Remarks: + * The function is supported only for ATAPI devices (CD and DVD). + * When the tray is being ejected, + manual control of tray is unlocked. + * When the tray is being ejected, the code clears the cache for + corresponding device. + * An example of usage of the function is the application CD_tray. + +====================================================================== +======== Function 24, subfunction 5 - load tray of disk drive. ======= +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 5 - subfunction number + * ecx = position of CD/DVD-drive + (from 0=Primary Master to 3=Secondary Slave) +Returned value: + * function does not return value +Remarks: + * The function is supported only for ATAPI devices (CD and DVD). + * An example of usage of the function is the application CD_tray. + +====================================================================== +======== Function 26, subfunction 1 - get MPU MIDI base port. ======== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = port number +Parameters: + * To set base port use subfunction 1 of function 21. + +====================================================================== +========== Function 26, subfunction 2 - get keyboard layout. ========= +====================================================================== +The keyboard layout is used to convert keyboard scancodes to +ASCII-codes for function 2. +Parameters: + * eax = 26 - function number + * ebx = 2 - subfunction number + * ecx = what layout to get: + * 1 = normal layout + * 2 = layout with pressed Shift + * 3 = layout with pressed Alt + * edx = pointer to the 128-bytes buffer, where the layout will be + copied +Returned value: + * function does not return value +Or: + * eax = 26 - function number + * ebx = 2 - subfunction number + * ecx = 9 +Returned value: + * eax = country identifier (1=eng, 2=fi, 3=ger, 4=rus) +Remarks: + * If Alt is pressed, the layout with Alt is used; + if Alt is not pressed, but Shift is pressed, + the layout with Shift is used; + if Alt and Shift are not pressed, but Ctrl is pressed, the normal + layout is used and then from the code is subtracted 0x60; + if no control key is pressed, the normal layout is used. + * To set layout and country identifier use + subfunction 2 of function 21. + * Country identifier is global system variable, which is not used + by the kernel itself; however the application '@panel' displays + the corresponding icon (using this function). + * The application @panel switches layouts on user request. + +====================================================================== +============== Function 26, subfunction 3 - get CD base. ============= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Remarks: + * CD base is used by function 24. + * To set CD base use subfunction 3 of function 21. + +====================================================================== +========== Function 26, subfunction 5 - get system language. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = system language (1=eng, 2=fi, 3=ger, 4=rus) +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon (using this function). + * To set system language use subfunction 5 of function 21. + +====================================================================== +============== Function 26, subfunction 7 - get HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +syntax /HD in obsolete function 58; at usage of modern syntax +/HD0,/HD1,/HD2,/HD3 base is set automatically. +Parameters: + * eax = 26 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Remarks: + * Any application in any time can change HD base. + * To set base use subfunction 7 of function 21. + * To get used partition of hard disk use subfunction 8. + +====================================================================== +========= Function 26, subfunction 8 - get used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete syntax /HD in obsolete function 58; +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +base and partition are set automatically. +Parameters: + * eax = 26 - function number + * ebx = 8 - subfunction number +Returned value: + * eax = HD partition (beginning from 1) +Remarks: + * Any application in any time can change partition. + * To set partition use subfunction 8 of function 21. + * To get number of partitions on a hard disk use + subfunction 11 of function 18. + * To get base of used hard disk, use subfunction 7. + +====================================================================== +=== Function 26, subfunction 9 - get the value of the time counter. == +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = number of 1/100s of second, past from the system boot time +Remarks: + * Counter takes modulo 2^32, that correspond to a little more + than 497 days. + * To get system time use function 3. + +====================================================================== +===================== Function 26, subfunction 11 ==================== +========== Find out whether low-level HD access is enabled. ========== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 11 - subfunction number +Returned value: + * eax = 0/1 - disabled/enabled +Remarks: + * Is used in LBA read (subfunction 8 of function 58). + * To set current state use subfunction 11 of function 21. + +====================================================================== +===================== Function 26, subfunction 12 ==================== +========== Find out whether low-level PCI access is enabled. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 12 - subfunction number +Returned value: + * eax = 0/1 - disabled/enabled +Remarks: + * Is used by operations with PCI bus (function 62). + * The current implementation uses only low bit of ecx. + * To set the current state use subfunction 12 of function 21. + +====================================================================== +=================== Function 29 - get system date. =================== +====================================================================== +Parameters: + * eax = 29 - function number +Returned value: + * eax = 0x00DDMMYY, where + (binary-decimal coding, BCD, is used) + * YY = two low digits of year (00..99) + * MM = month (01..12) + * DD = day (01..31) +Remarks: + * To set system date use function 22. + +====================================================================== +============= Function 30 - work with the current folder. ============ +====================================================================== + +--------- Subfunction 1 - set current folder for the thread. --------- +Parameters: + * eax = 30 - function number + * ebx = 1 - subfunction number + * ecx = pointer to ASCIIZ-string with the path to new current folder +Returned value: + * function does not return value + +--------- Subfunction 2 - get current folder for the thread. --------- +Parameters: + * eax = 30 - function number + * ebx = 2 - subfunction number + * ecx = pointer to buffer + * edx = size of buffer +Returned value: + * eax = size of the current folder's name (including terminating 0) +Remarks: + * If the buffer is too small to hold all data, only first (edx-1) + bytes are copied and than terminating 0 is inserted. + +====================================================================== +=============== Function 32 - delete file from ramdisk. ============== +====================================================================== +Parameters: + * eax = 32 - function number + * ebx = pointer to the filename +Returned value: + * eax = 0 - success; otherwise file system error code +Remarks: + * This function is obsolete; function 58 allows to fulfill + the same operations with the extended possibilities. + * The current implementation returns only values 0(success) and + 5(file not found). + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +================ Function 33 - write file to ramdisk. ================ +====================================================================== +Parameters: + * eax = 33 - function number + * ebx = pointer to the filename + * ecx = pointer to data for writing + * edx = number of bytes for writing + * should be set esi=0 +Returned value: + * eax = 0 - success, otherwise file system error code +Remarks: + * This function is obsolete; function 70 allows to fulfil + the same operations with extended possibilities. + * If esi contains non-zero value and selected file already exists, + one more file with the same name will be created. + * Otherwise file will be overwritten. + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +======= Function 35 - read the color of a pixel on the screen. ======= +====================================================================== +Parameters: + * eax = 35 + * ebx = y*xsize+x, where + * (x,y) = coordinates of a pixel (beginning from 0) + * xsize = horizontal screen size +Returned value: + * eax = color 0x00RRGGBB +Remarks: + * To get screen sizes use function 14. Pay attention, + that it subtracts 1 from both sizes. + * There is also direct access (without any system calls) + to videomemory through the selector gs. To get parameters of + the current videomode, use function 61. + +====================================================================== +=================== Function 36 - read screen area. ================== +====================================================================== +Paramters: + * eax = 36 - function number + * ebx = pointer to the previously allocated memory area, + where will be placed the image in the format BBGGRRBBGGRR... + * ecx = [size on axis x]*65536 + [size on axis y] + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] +Returned value: + * function does not return value +Remarks: + * Coordinates of the image are coordinates of the upper left corner + of the image relative to the screen. + * Size of the image in bytes is 3*xsize*ysize. + +====================================================================== +=================== Function 37 - work with mouse. =================== +====================================================================== + +---------- Subfunction 0 - screen coordinates of the mouse ----------- +Parameters: + * eax = 37 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = x*65536 + y, (x,y)=coordinates of the mouse pointer + (beginning from 0) + +-- Subfunction 1 - coordinates of the mouse relative to the window --- +Parameters: + * eax = 37 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = x*65536 + y, (x,y)=coordinates of the mouse pointer + relative to the application window (beginning from 0) +Remarks: + * The value is calculated by formula (x-xwnd)*65536 + (y-ywnd). + If y>=ywnd, the low word is non-negative and contains + relative y-coordinate, and the high word - relative x-coordinate + (with correct sign). Otherwise the low word is negative and still + contains relative y-coordinate, and to the high word + 1 should be added. + +------------ Subfunction 2 - pressed buttons of the mouse ------------ +Parameters: + * eax = 37 - function number + * ebx = 2 - subfunction number +Returned value: + * eax contains information on the pressed mouse buttons: + * bit 0 is set = left button is pressed + * bit 1 is set = right button is pressed + * bit 2 is set = middle button is pressed + * bit 3 is set = 4th button is pressed + * bit 4 is set = 5th button is pressed + * other bits are cleared + +-------------------- Subfunction 4 - load cursor --------------------- +Parameters: + * eax = 37 - function number + * ebx = 4 - subfunction number + * dx = data source: + * dx = LOAD_FROM_FILE = 0 - data in a file + * ecx = pointer to full path to the cursor file + * the file must be in the format .cur, which is standard for + MS Windows, at that of the size 32*32 pixels + * dx = LOAD_FROM_MEM = 1 - data of file are already loaded in memory + * ecx = pointer to data of the cursor file + * the data format is the same as in the previous case + * dx = LOAD_INDIRECT = 2 - data in memory + * ecx = pointer to cursor image in the format ARGB 32*32 pixels + * edx = 0xXXYY0002, where + * XX = x-coordinate of cursor hotspot + * YY = y-coordinate + * 0 <= XX, YY <= 31 +Returned value: + * eax = 0 - failed + * otherwise eax = cursor handle + +--------------------- Subfunction 5 - set cursor --------------------- +Sets new cursor for the window of the current thread. +Parameters: + * eax = 37 - function number + * ebx = 5 - subfunction number + * ecx = cursor handle +Returned value: + * eax = handle of previous cursor +Remarks: + * If the handle is incorrect, the function restores the default + cursor (standard arrow). In particular, ecx=0 restores it. + +------------------- Subfunction 6 - delete cursor -------------------- +Parameters: + * eax = 37 - function number + * ebx = 6 - subfunction number + * ecx = cursor handle +Returned value: + * eax destroyed +Remarks: + * The cursor must be loaded previously by the current thread + (with the call to subfunction 4). The function does not delete + system cursors and cursors, loaded by another applications. + * If the active cursor (set by subfunction 5) is deleted, + the system restores the default cursor (standard arrow). + +------------------ Subfunction 7 - get scroll data ------------------- +Parameters: + * eax = 37 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = [horizontal offset]*65536 + [vertical offset] +Remarks: + * Scroll data is available for active window only. + * Values are zeroed after reading. + * Values are signed. + +====================================================================== +====================== Function 38 - draw line. ====================== +====================================================================== +Parameters: + * eax = 38 - function number + * ebx = [start coordinate on axis x]*65536 + + [end coordinate on axis x] + * ecx = [start coordinate on axis y]*65536 + + [end coordinate on axis y] + * edx = 0x00RRGGBB - color + edx = 0x01xxxxxx - draw inversed line + (low 24 bits are ignored) +Returned value: + * function does not return value +Remarks: + * Coordinates are relative to the window. + * End point is also drawn. + +====================================================================== +== Function 39, subfunction 1 - get a size of the background image. == +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = [width]*65536 + [height] +Remarks: + * There is a pair function to set sizes of background image - + subfunction 1 of function 15. After which it is necessary, + of course, anew to define image. + +====================================================================== +== Function 39, subfunction 2 - get pixel from the background image. = +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 2 - subfunction number + * ecx = offset +Returned value: + * eax = 0x00RRGGBB - pixel color, if offset is valid + (less than 0x160000-16) + * eax = 2 otherwise +Remarks: + * Do not rely on returned value for invalid offsets, it may be + changed in future kernel versions. + * Offset for pixel with coordinates (x,y) + is calculated as (x+y*xsize)*3. + * There is a pair function to set pixel on the background image - + subfunction 2 of function 15. + +====================================================================== +== Function 39, subfunction 4 - get drawing mode for the background. = +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = 1 - tile + * eax = 2 - stretch +Remarks: + * There is a pair function to set drawing mode - + subfunction 4 of function 15. + +====================================================================== +=========== Function 40 - set the mask for expected events. ========== +====================================================================== +The mask for expected events affects function working with events +10, 11, 23 - they notify only about events allowed by this mask. +Parameters: + * eax = 40 - function number + * ebx = mask: bit i corresponds to event i+1 (see list of events) + (set bit permits notice on event) +Returned value: + * eax = previous value of mask +Remarks: + * Default mask (7=111b) enables nofices about redraw, + keys and buttons. This is enough for many applications. + * Events prohibited in the mask are saved anyway, when come; + they are simply not informed with event functions. + * Event functions take into account the mask on moment of + function call, not on moment of event arrival. + +====================================================================== +==================== Function 41 - get IRQ owner. ==================== +====================================================================== +Parameters: + * eax = 41 - function number + * ebx = IRQ number, 0..15 +Returned value: + * eax = owner PID + * eax = 0, if there is no owner + * eax = -1 for incorrect ebx + +====================================================================== +================== Function 42 - work with IRQ data. ================= +====================================================================== +When an IRQ occurs, the system reads data from ports indicated +earlier by function 44 and writes this data to +internal buffer. This function reads out data from that buffer. + +--------------------- Subfunction 0 - read data ---------------------- +Parameters: + * eax = 42 - function number + * bl = IRQ number, 0..15 + * bh = 0 - subfunction number + * rest of ebx must be zeroed + * ecx = pointer to a buffer with size not less than 4000 bytes +Returned value: (use value of eax to distinguish) + * if the thread is not IRQ owner + (or IRQ number is incorrect): eax = -1 + * if there is no data: eax = 0 + * if all is ok: + eax = size of data read (in bytes) + +------------- Subfunction 1 - get size of data in buffer ------------- +Parameters: + * eax = 42 - function number + * bl = IRQ number, 0..15 + * bh = 0 - subfunction number + * rest of ebx must be zeroed +Returned value: + * if the thread is not IRQ owner + (or IRQ number is incorrect): eax = -1 + * otherwise eax = size of data in buffer +Remarks: + * Previously the thread must reserve indicated IRQ for itself + by function 45. + * The size of data buffer is 4000 bytes, on overflow + "fresh" data cease to be written in the buffer. + +====================================================================== +================ Function 43 - input/output to a port. =============== +====================================================================== + +------------------------ Output data to port ------------------------- +Parameters: + * eax = 43 - function number + * bl = byte for output + * ecx = port number 0xnnnn (from 0 to 0xFFFF) +Returned value: + * eax = 0 - success + * eax = 1 - the thread has not reserved the selected port + +------------------------ Input data from port ------------------------ +Parameters: + * eax = 43 - function number + * ebx is ignored + * ecx = 0x8000nnnn, where nnnn = port number (from 0 to 0xFFFF) +Returned value: + * eax = 0 - success, thus ebx = entered byte + * eax = 1 - the thread has not reserved the selected port +Remarks: + * Previously the thread must reserve the selected port + for itself by function 46. + * Instead of call to this function it is better to use + processor instructions in/out - this is much + faster and a bit shorter and easier. + +====================================================================== +=========== Function 44 - define operations at IRQ arrival. ========== +====================================================================== +At IRQ arrival the system can read the data from ports defined +by this function and write these data to internal buffer, whence +they can be read by функцией 42. +Parameters: + * eax = 44 - function number + * ebx = pointer to the array of structures each describing one port: + * +0: word: 0 means end of array, otherwise port number + * +2: byte: reserved (ignored) + * +3: byte: 1=read byte from this port, 2=read word + * ecx = IRQ number, 0..15 +Returned value: + * eax = 0 - success + * eax = 1 - the thread is not owner of selected IRQ +Remarks: + * Previously the thread must reserve for itself selected IRQ + by function 45. + * First 16 ports are considered only. + * The current implementation considers incorrect value of field +3 + as a signal to terminate IRQ processing. + +====================================================================== +=================== Function 45 - reserve/free IRQ. ================== +====================================================================== +Parameters: + * eax = 45 - function number + * ebx = 0 - reserve, 1 = free + * ecx = IRQ number, 0..15 +Returned value: + * eax = 0 - success + * eax = 1 - error (invalid IRQ number + or attempt to reserve not free IRQ + or to free IRQ, not reserved by this thread) +Remarks: + * IRQ reservation is required for functions 42 and 44. + * Only one thread can reserve the specific IRQ. + * IRQs, handled by the system itself, are reserved by the system + (thread 1) at booting. + * When a thread terminates, all reserved by it IRQs + are freed automatically. + +====================================================================== +====== Function 46 - reserve/free a group of input/output ports. ===== +====================================================================== +To work with reserved ports an application can access directly by +commands in/out (recommended way) and can use function 43 +(not recommended way). +Parameters: + * eax = 46 - function number + * ebx = 0 - reserve, 1 - free + * ecx = start port number + * edx = end port number (inclusive) +Returned value: + * eax = 0 - success + * eax = 1 - error +Remarks: + * For ports reservation: an error occurs if and only if + one from the following condition satisfies: + * start port is more than end port; + * the selected range contains incorrect port number + (correct are from 0 to 0xFFFF); + * limit for the total number of reserved areas is exceeded + (maximum 255 are allowed); + * the selected range intersects with any of earlier reserved + * For ports free: an error is an attempt to free range, + that was not earlier reserved by this function + (with same ecx,edx). + * If an error occurs (for both cases) function performs no action. + * At booting the system reserves for itself ports + 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (inclusively). + * When a thread terminates, all reserved by it ports + are freed automatically. + +====================================================================== +============= Function 47 - draw a number in the window. ============= +====================================================================== +Parameters: + * eax = 47 - function number + * ebx = parameters of conversion number to text: + * bl = 0 - ecx contains number + * bl = 1 - ecx contains pointer to dword/qword-number + * bh = 0 - display in decimal number system + * bh = 1 - display in hexadecimal system + * bh = 2 - display in binary system + * bits 16-21 = how many digits to display + * bits 22-29 reserved and must be set to 0 + * bit 30 set = display qword (64-bit) number (must be bl=1) + * bit 31 set = do not display leading zeroes of the number + * ecx = number (if bl=0) or pointer (if bl=1) + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] + * esi = 0xX0RRGGBB: + * RR, GG, BB specify the color + * X = ABnn (bits) + * nn = font (0/1) + * A is ignored + * B=1 - fill background with the color edi +Returned value: + * function does not return value +Remarks: + * The given length must not exceed 60. + * The exactly given amount of digits is output. If number is small + and can be written by smaller amount of digits, it is supplemented + by leading zeroes; if the number is big and can not be written by + given amount of digits, extra digits are not drawn. + * Parameters of fonts are shown in the description of function 4 + (text output). + +====================================================================== +========= Function 48, subfunction 0 - apply screen settings. ======== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 0 - subfunction number + * ecx = 0 - reserved +Returned value: + * function does not return value +Remarks: + * Function redraws the screen after parameters change by + subfunctions 1 and 2. + * Function call without prior call to one of indicated subfunctions + is ignored. + * Function call with nonzero ecx is ignored. + +====================================================================== +=========== Function 48, subfunction 1 - set button style. =========== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 1 - subfunction number + * ecx = button style: + * 0 = flat + * 1 = 3d +Returned value: + * function does not return value +Remarks: + * After call to this function one should redraw the screen by + subfunction 0. + * Button style influences only to their draw of function 8. + +====================================================================== +====== Function 48, subfunction 2 - set standard window colors. ====== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 2 - subfunction number + * ecx = pointer to the color table + * edx = size of the color table + (must be 40 bytes for future compatibility) +Format of the color table is shown in description of subfunction 3. +Returned value: + * function does not return value +Remarks: + * After call to this function one should redraw the screen by + subfunction 0. + * Table of standard colors influences only to applications, + which receive this table obviously (by subfunction 3) + and use it (specifying colors from it to drawing functions). + * Table of standard colors is included in skin and is installed + anew with skin installation (by subfunction 8). + * Color table can be viewed/changed interactively with + the application 'desktop'. + +====================================================================== +====== Function 48, subfunction 3 - get standard window colors. ====== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 3 - subfunction number + * ecx = pointer to the buffer with size edx bytes, + where table will be written + * edx = size of color table + (must be 40 bytes for future compatibility) +Returned value: + * function does not return value +Format of the color table: +each item is dword-value for color 0x00RRGGBB + * +0: dword: frames - color of frame + * +4: dword: grab - color of header + * +8: dword: grab_button - color of button on header bar + * +12 = +0xC: dword: grab_button_text - color of text on button + on header bar + * +16 = +0x10: dword: grab_text - color of text on header + * +20 = +0x14: dword: work - color of working area + * +24 = +0x18: dword: work_button - color of button in working area + * +28 = +0x1C: dword: work_button_text - color of text on button + in working area + * +32 = +0x20: dword: work_text - color of text in working area + * +36 = +0x24: dword: work_graph - color of graphics in working area +Remarks: + * Structure of the color table is described in the standard + include file 'macros.inc' as 'system_colors'; for example, + it is possible to write: + sc system_colors ; variable declaration + ... ; somewhere one must call + ; this function with ecx=sc + mov ecx, [sc.work_button_text] ; read text color on + ; buttin in working area + * A program itself desides to use or not to use color table. + For usage program must simply at calls to drawing functions select + color taken from the table. + * At change of the table of standard colors (by subfunction 2 with + the subsequent application of changes by subfunction 0 or + at skin set by subfunction 8) the system sends to all windows + redraw message (the event with code 1). + * Color table can be viewed/changed interactively with + the application 'desktop'. + +====================================================================== +============ Function 48, subfunction 4 - get skin height. =========== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = skin height +Remarks: + * Skin height is defined as the height of a header + of skinned windows. + * See also general structure of window in the description + of function 0. + +====================================================================== +======== Function 48, subfunction 5 - get screen working area. ======= +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +Remarks: + * The screen working area defines position and coordinates of + a maximized window. + * The screen working area in view of normal work is all screen + without system panel (the application '@panel'). + * (left,top) are coordinates of the left upper corner, + (right,bottom) are coordinates of the right lower one. + Thus the size of working area on x axis can be calculated by + formula right-left+1, on y axis - by formula bottom-right+1. + * See also function 14, + to get sizes of all screen. + * There is a pair function to set working area - subfunction 6. + +====================================================================== +======== Function 48, subfunction 6 - set screen working area. ======= +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 6 - subfunction number + * ecx = [left]*65536 + [right] + * edx = [top]*65536 + [bottom] +Returned value: + * function does not return value +Remarks: + * The screen working area defines position and coordinates of + a maximized window. + * This function is used only by the application '@panel', + which set working area to all screen without system panel. + * (left,top) are coordinates of the left upper corner, + (right,bottom) are coordinates of the right lower one. + Thus the size of working area on x axis can be calculated by + formula right-left+1, on y axis - by formula bottom-right+1. + * If 'left'>='right', x-coordinate of working area is not changed. + If 'left'<0, 'left' will not be set. If 'right' is greater than or + equal to screen width, 'right' will not be set. + Similarly on y axis. + * See also function 14, + to get sizes of all screen. + * There is a pair function to get working area - subfunction 5. + * This function redraws the screen automatically, + updating coordinates and sizes of maximized windows. + The system sends to all windows redraw message (the event 1). + +====================================================================== +=========== Function 48, subfunction 7 - get skin margins. =========== +====================================================================== +Returns the area of a header of a skinned window, intended for +a text of a header. +Parameters: + * eax = 48 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +Remarks: + * An application decides itself to use or not to use this function. + * It is recommended to take into account returned value + of this function for choice of a place for drawing header text + (by function 4) or a substitute of header text + (at the discretion of an application). + +====================================================================== +============= Function 48, subfunction 8 - set used skin. ============ +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 8 - subfunction number + * ecx = pointer to a block for function 58, in + which the fields of intermediate buffer and file name are filled +Returned value: + * eax = 0 - success + * otherwise eax = file system error code; if file does not + contain valid skin, function returns error 3 + (unknown file system). +Remarks: + * After successful skin loading the system sends to all windows + redraw message (the event 1). + * At booting the system reads skin from file 'default.skn' + on ramdisk. + * User can change the skin statically by creating hisself + 'default.skn' or dynamically with the application 'desktop'. + +====================================================================== +=========== Function 49 - Advanced Power Management (APM). =========== +====================================================================== +Parameters: + * eax = 49 - function number + * dx = number of the APM function + (analogue of ax in APM specification) + * bx, cx = parameters of the APM function +Returned value: + * 16-bit registers ax, bx, cx, dx, si, di and carry flag CF + are set according to the APM specification + * high halves of 32-bit registers eax, ebx, ecx, + edx, esi, edi are destroyed +Remarks: + * APM 1.2 specification is described in the document + "Advanced Power Management (APM) BIOS Specification" + (Revision 1.2), available at + http://www.microsoft.com/whdc/archive/amp_12.mspx; + besides it is included in famous Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). + +====================================================================== +=================== Function 50 - set window shape. ================== +====================================================================== +Normal windows have rectangular shape. This function can give to +a window any shape. The shape is given by a set of points inside +the base rectangle belonging to a window. Position and coordinates +of the base rectangle are set by function 0 +and changed by function 67. + +--------------------------- Set shape data --------------------------- +Parameters: + * eax = 50 - function number + * ebx = 0 - subfunction number + * ecx = pointer to shape data (array of bytes 0/1) +Returned value: + * function does not return value + +-------------------------- Set shape scale --------------------------- +Parameters: + * eax = 50 - function number + * ebx = 1 - subfunction number + * ecx sets a scale: each byte of data defines + (2^scale)*(2^scale) pixels +Returned value: + * function does not return value +Remarks: + * Default scale is 0 (scale factor is 1). If in the shape data + one byte corresponds to one pixel, there is no necessity + to set scale. + * Let's designate xsize = window width (in pixels), ysize = height; + pay attention, that they are one pixel more than defined by + functions 0, 67. + * On definition of scale xsize and ysize must be divisible + on 2^scale. + * Byte of data on offset 'a' must be 0/1 and defines belonging + to a window of square with the side 2^scale (if scale=0, + this is one pixel) and coordinates of the left upper corner + (a mod (xsize shr scale), a div (xsize shr scale)) + * Data size: (xsize shr scale)*(ysize shr scale). + * Data must be presented in the memory and not change + after set of shape. + * The system views the shape data at every window redraw by + function 0. + * The call of subfunction 0 with NULL pointer results in return + to the rectangular shape. + +====================================================================== +==================== Function 51 - create thread. ==================== +====================================================================== +Parameters: + * eax = 51 - function number + * ebx = 1 - unique subfunction + * ecx = address of thread entry point (starting eip) + * edx = pointer to thread stack (starting esp) +Returned value: + * eax = -1 - error (there is too many threads) + * otherwise eax = TID - thread identifier + + +====================================================================== +=== Function 52, subfunction 0 - get network driver configuration. === +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = configuration dword +Remarks: + * Configuration dword can be set by subfunction 2. + * The kernel does not use this variable. The value of this + variable and working with it subfunctions 0 and 2 is represented + doubtful. + +====================================================================== +========= Function 52, subfunction 1 - get local IP-address. ========= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = IP-address (4 bytes) +Remarks: + * Local IP-address is set by subfunction 3. + +====================================================================== +=== Function 52, subfunction 2 - set network driver configuration. === +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 2 - subfunction number + * ecx = configuration dword; if low 7 bits derivate the number 3, + function [re-]initializes Ethernet-card, otherwise + Ethernet turns off +Returned value: + * if Ethernet-interface is not requested, function returns eax=2, + but this can be changed in future kernel versions + * if Ethernet-interface is requested, eax=0 means error + (absence of Ethernet-card), and nonzero value - success +Remarks: + * Configuration dword can be read by subfunction 0. + * The kernel does not use this variable. The value of this + variable, subfunction 0 and part of subfunction 2, which set it, + is represented doubtful. + +====================================================================== +========= Function 52, subfunction 3 - set local IP-address. ========= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 3 - subfunction number + * ecx = IP-address (4 bytes) +Returned value: + * the current implementation returns eax=3, but this can be changed + in future versions +Remarks: + * Local IP-address can be get by subfunction 1. + +====================================================================== += Function 52, subfunction 6 - add data to the stack of input queue. = +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 6 - subfunction number + * edx = data size + * esi = data pointer +Returned value: + * eax = -1 - error + * eax = 0 - success +Remarks: + * This function is intended only for slow network drivers + (PPP, SLIP). + * Data size must not exceed 1500 bytes, though function + performs no checks on correctness. + +====================================================================== + Function 52, subfunction 8 - read data from the network output queue. +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 8 - subfunction number + * esi = pointer to 1500-byte buffer +Returned value: + * eax = number of read bytes (in the current implementation + either 0 = no data or 1500) + * data was copied in buffer +Remarks: + * This function is intended only for slow network drivers + (PPP, SLIP). + +====================================================================== +============ Function 52, subfunction 9 - get gateway IP. ============ +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = gateway IP (4 bytes) + +====================================================================== +=========== Function 52, subfunction 10 - get subnet mask. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 10 - subfunction number +Returned value: + * eax = subnet mask + +====================================================================== +============ Function 52, subfunction 11 - set gateway IP. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 11 - subfunction number + * ecx = gateway IP (4 bytes) +Returned value: + * the current implementation returns eax=11, but this can be changed + in future versions + +====================================================================== +=========== Function 52, subfunction 12 - set subnet mask. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 12 - subfunction number + * ecx = subnet mask +Returned value: + * the current implementation returns eax=12, but this can be changed + in future versions + +====================================================================== +============== Function 52, subfunction 13 - get DNS IP. ============= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 13 - subfunction number +Returned value: + * eax = DNS IP (4 bytes) + +====================================================================== +============== Function 52, subfunction 14 - set DNS IP. ============= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 14 - subfunction number + * ecx = DNS IP (4 bytes) +Returned value: + * the current implementation returns eax=14, but this can be changed + in future versions + +====================================================================== +======== Function 52, subfunction 15 - get local MAC address. ======== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 15 - subfunction number + * ecx = 0 - read first 4 bytes, + ecx = 4 - read last 2 bytes +Returned value: + * for ecx=0: eax = first 4 bytes of MAC address + * for ecx=4: ax = last 2 bytes of MAC address, + high half of eax is destroyed + * for other ecx: eax = -1 indicates an error + +====================================================================== +============ Function 53, subfunction 0 - open UDP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 0 - subfunction number + * ecx = local port (only low word is taken into account), + ecx = 0 - let the system choose a port + * edx = remote port (only low word is taken into account) + * esi = remote IP +Returned value: + * eax = -1 = 0xFFFFFFFF - error; ebx destroyed + * eax = socket handle (some number which unambiguously identifies + socket and have sense only for the system) - success; + ebx destroyed + +====================================================================== +=========== Function 53, subfunction 1 - close UDP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 1 - subfunction number + * ecx = socket handle +Returned value: + * eax = -1 - incorrect handle + * eax = 0 - success + * ebx destroyed +Remarks: + * The current implementation does not close automatically all + sockets of a thread at termination. In particular, one should not + kill a thread with many opened sockets - there will be an outflow + of resources. + +====================================================================== +============== Function 53, subfunction 2 - poll socket. ============= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 2 - subfunction number + * ecx = socket handle +Returned value: + * eax = number of read bytes, 0 for incorrect handle + * ebx destroyed + +====================================================================== +========= Function 53, subfunction 3 - read byte from socket. ======== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 3 - subfunction number + * ecx = socket handle +Returned value: + * if there is no read data or handle is incorrect: eax=0, bl=0, + other bytes of ebx are destroyed + * if there are read data: eax=number of rest bytes + (possibly 0), bl=read byte, other bytes of ebx are destroyed + +====================================================================== +========== Function 53, subfunction 4 - write to UDP-socket. ========= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 4 - subfunction number + * ecx = socket handle + * edx = number of bytes to write + * esi = pointer to data to write +Returned value: + * eax = 0xffffffff - error (invalid handle or not enough memory) + * eax = 0 - success + * ebx destroyed +Remarks: + * Number of bytes to write must not exceed 1500-28, though + the appropriate check is not made. + +====================================================================== +============ Function 53, subfunction 5 - open TCP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 5 - subfunction number + * ecx = local port (only low word is taken into account), + ecx = 0 - let the system choose a port + * edx = remote port (only low word is taken into account) + * esi = remote IP + * edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1 +Returned value: + * eax = -1 = 0xFFFFFFFF - error; ebx destroys + * eax = socket handle (some number which unambiguously identifies + socket and have sense only for the system) - success; + ebx destroyed + +====================================================================== +========= Function 53, subfunction 6 - get TCP-socket status. ======== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 6 - subfunction number + * ecx = socket handle +Returned value: + * eax = 0 for incorrect handle or socket status: one of + * TCB_LISTEN = 1 + * TCB_SYN_SENT = 2 + * TCB_SYN_RECEIVED = 3 + * TCB_ESTABLISHED = 4 + * TCB_FIN_WAIT_1 = 5 + * TCB_FIN_WAIT_2 = 6 + * TCB_CLOSE_WAIT = 7 + * TCB_CLOSING = 8 + * TCB_LAST_ASK = 9 + * TCB_TIME_WAIT = 10 + * TCB_CLOSED = 11 + * ebx destroyed + +====================================================================== +========== Function 53, subfunction 7 - write to TCP-socket. ========= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 7 - subfunction number + * ecx = socket handle + * edx = number of bytes to write + * esi = pointer to data to write +Returned value: + * eax = 0xffffffff - error (invalid handle or not enough memory) + * eax = 0 - success + * ebx destroyed +Remarks: + * Number of bytes to write must not exceed 1500-40, though + the appropriate check is not made. + +====================================================================== +=========== Function 53, subfunction 8 - close TCP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 8 - subfunction number + * ecx = socket handle +Returned value: + * eax = -1 - error (invalid handle or + not enough memory for socket close packet) + * eax = 0 - success + * ebx destroyed +Remarks: + * The current implementation does not close automatically all + sockets of a thread at termination. In particular, one should not + kill a thread with many opened sockets - there will be an outflow + of resources. + +====================================================================== +=== Function 53, subfunction 9 - check whether local port is free. === +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 9 - subfunction number + * ecx = local port number (low 16 bits are used only) +Returned value: + * eax = 0 - port is used + * eax = 1 - port is free + * ebx destroyed + +====================================================================== +===== Function 53, subfunction 10 - query Ethernet cable status. ===== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 10 - subfunction number +Returned value: + * al = -1 - a network driver is not loaded or + does not support this function + * al = 0 - Ethernet cable is unplugged + * al = 1 - Ethernet cable is plugged + * ebx destroyed +Remarks: + * The current kernel implementation supports this function + only for RTL8139 network cards. + +====================================================================== +======= Function 53, subfunction 11 - read network stack data. ======= +====================================================================== +Paramters: + * eax = 53 - function number + * ebx = 11 - subfunction number + * ecx = socket handle + * edx = pointer to buffer + * esi = number of bytes to read; + * esi = 0 - read all data (maximum 4096 bytes) +Returned value: + * eax = number of bytes read (0 for incorrect handle) + * ebx destroyed + +====================================================================== += Function 53, subfunction 255 - debug information of network driver. +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 255 - subfunction number + * ecx = type of requested information (see below) +Returned value: + * eax = requested information + * ebx destroyed +Possible values for ecx: + * 100: length of queue 0 (empty queue) + * 101: length of queue 1 (ip-out queue) + * 102: length of queue 2 (ip-in queue) + * 103: length of queue 3 (net1out queue) + * 200: number of items in the ARP table + * 201: size of the ARP table (in items) (20 for current version) + * 202: read item at edx of the ARP table to the temporary buffer, + whence 5 following types take information; + in this case eax is not defined + * 203: IP-address saved by type 202 + * 204: high dword of MAC-address saved by type 202 + * 205: low word of MAC-address saved by type 202 + * 206: status word saved by type 202 + * 207: ttl word saved by type 202 + * 2: total number of received IP-packets + * 3: total number of transferred IP-packets + * 4: total number of dumped received packets + * 5: total number of received ARP-packets + * 6: status of packet driver, 0=inactive, nonzero=active + +====================================================================== + Function 55, subfunction 55 - begin to play data on built-in speaker. +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 55 - subfunction number + * esi = pointer to data +Returned value: + * eax = 0 - success + * eax = 55 - error (speaker is off or busy) +Data is an array of items with variable length. +Format of each item is defined by first byte: + * 0 = end of data + * 1..0x80 = sets sound duration on 1/100 of second; sound note + is defined by immediate value of frequency + * following word (2 bytes) contains frequency divider; + frequency is defined as 1193180/divider + * 0x81 = invalid + * 0x82..0xFF = note is defined by octave and number: + * duration in 1/100 of second = (first byte)-0x81 + * there is one more byte; + * (second byte)=0xFF - delay + * otherwise it looks like a*0x10+b, where b=number of the note in + an octave from 1 to 12, a=number of octave (beginning from 0) +Remarks: + * Speaker play can be disabled/enabled by + subfunction 8 of function 18. + * Function returns control, having informed the system + an information on request. Play itself goes independently from + the program. + * The data must be kept in the memory at least up to the end + of play. + +====================================================================== +======================= Function 57 - PCI BIOS. ====================== +====================================================================== +Parameters: + * eax = 57 - function number + * ebp corresponds to al in PCI BIOS specification + * other registers are set according to PCI BIOS specification +Returned value: + * CF is undefined + * other registers are set according to PCI BIOS specification +Remarks: + * Many effects of this function can be also achieved with + corresponding subfunctions of function 62. + * The function calls PCI32 BIOS extension, documented e.g. in + http://alpha1.dyns.net/files/PCI/bios21.pdf. + * If BIOS does not support this extension, its behavior is emulated + (through kernel-mode analogues of subfunctions of function 62). + +====================================================================== +================ Function 58 - work with file system. ================ +====================================================================== +Parameters: + * eax = 58 + * ebx = pointer to the information structure +Returned value: + * eax = 0 - success; otherwise file system error code + * some subfunctions return value in other registers too +General format of the information structure: + * +0: dword: subfunction number + * +4: dword: number of block + * +8: dword: size + * +12 = +0xC: dword: pointer to data + * +16 = +0x10: dword: pointer to a memory for system operations + (4096 bytes) + * +20 = +0x14: n db: ASCIIZ-string with the file name +Specifications - in documentation on the appropriate subfunction. +Filename is case-insensitive for latin letters, russian letters +must be capital. +Format of filename: +/base/number/dir1/dir2/.../dirn/file, +where /base/number identifies device, on which file is located: +one of + * /RD/1 = /RAMDISK/1 to access ramdisk + * /FD/1 = /FLOPPYDISK/1 to access first floppy drive, + /FD/2 = /FLOPPYDISK/2 to access second one + * /HD/x = /HARDDISK/x - obsolete variant of access to hard disk + (in this case base is defined by subfunction 7 of function 21), + x - partition number (beginning from 1) + * /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices + IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - partition number on the selected hard drive, varies from 1 + to 255 (on each hard drive the indexing starts from 1) +Remarks: + * In the first two cases it is also possible to use FIRST + instead of 1, SECOND instead of 2, but it is not recommended + for convenience of transition to the future extensions. + * Limitation n<=39 is imposed. + * Names of folders and file dir1,...,dirn,file must have the + format 8.3: name no more than 8 characters, dot, extension no + more than 3 characters. Trailing spaces are ignored, no other + spaces is allowed. If name occupies equally 8 characters, + dot may be omitted (though it is not recommended to use this + feature for convenience of transition to the future extensions). + * This function does not support folders on ramdisk. +Examples: + * '/RAMDISK/FIRST/KERNEL.ASM',0 + '/rd/1/kernel.asm',0 + * '/HD0/1/kernel.asm',0 + * '/hd0/1/menuet/pics/tanzania.bmp',0 +Existing subfunctions: + * subfunction 0 - read file/folder + * subfunction 8 - LBA-read from device + * subfunction 15 - get file system information + +====================================================================== +=========== Function 58, subfunction 0 - read file/folder. =========== +====================================================================== +Parameters: + * eax = 58 + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 0 = subfunction number + * +4: dword: first block to read (beginning from 0) + * +8: dword: amount of blocks to read + * +12 = +0xC: dword: pointer to buffer for data + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = file size (in bytes) or -1=0xffffffff, if file was not found +Remarks: + * Block size is 512 bytes. + * This function is obsolete, for reading files use subfunction 0 + of function 70, for reading folders - subfunction 1 of + function 70. + * Function can read contents of a folder. Only FAT file system is + supported. The format of FAT-folder is described + in any FAT documentation. + * Size of a folder is determined by size of FAT clusters chain. + * If file was ended before last requested block was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * Function can read root folders /rd/1,/fd/x,/hd[n]/x, but + in the first two cases the current implementation does not follow + to the declared rules: + for /rd/1: + * if one want to read 0 blocks, function considers, + that he requested 1; + * if one requests more than 14 blocks or starting block is + not less than 14, function returns eax=5 (not found) и ebx=-1; + * size of ramdisk root folder is 14 blocks, + 0x1C00=7168 байт; but function returns ebx=0 + (except of the case of previous item); + * strangely enough, it is possible to read 14th block (which + generally contains a garbage - I remind, the indexing begins + from 0); + * if some block with the number not less than 14 was requested, + function returns eax=6(EOF); otherwise eax=0. + For /fd/x: + * if the start block is not less than 14, function returns + eax=5 (not found) and ebx=0; + * note that format of FAT12 allows floppies with the root size + more or less than 14 blocks; + * check for length is not performed; + * if data was successful read, function returns + eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1. + * The function handles reading of special folders /,/rd,/fd,/hd[n]; + but the result does not correspond to expected (on operations with + normal files/folders), does not follow the declared rules, + may be changed in future versions of the kernel and consequently + is not described. To obtain the information about the equipment + use subfunction 11 of function 18 or + read corresponding folder with subfunction 1 of function 70. + +====================================================================== +========= Function 58, subfunction 8 - LBA-read from device. ========= +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 8 = subfunction number + * +4: dword: number of block to read (beginning from 0) + * +8: dword: ignored (set to 1) + * +12 = +0xC: dword: pointer to buffer for data (512 bytes) + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of + /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, + 1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3. + Instead of digits it is allowed, though not recommended for + convenience of transition to future extensions, to use + 'first','second','third','fourth'. +Returned value: + * for device name /hd/xxx, where xxx is not in the list above: + * eax = ebx = 1 + * for invalid device name (except for the previous case): + * eax = 5 + * ebx does not change + * if LBA-access is disabled by subfunction 11 of function 21: + * eax = 2 + * ebx destroyed + * for ramdisk: attempt to read block outside ramdisk + (18*2*80 blocks) results in + * eax = 3 + * ebx = 0 + * for successful read: + * eax = ebx = 0 +Remarks: + * Block size is 512 bytes; function reads one block. + * Do not depend on returned value, it can be changed + in future versions. + * Function requires that LBA-access to devices is enabled by + subfunction 11 of function 21. To check this one can use + subfunction 11 of function 26. + * LBA-read of floppy is not supported. + * Function reads data on physical hard drive; if for any reason + data of the concrete partition are required, application must + define starting sector of this partition (either directly + through MBR, or from the full structure returned by + подфункцией 11 функции 18). + * Function does not check error code of hard disk, so request of + nonexisting sector reads something (most probably it will be + zeroes, but this is defined by device) and this is considered + as success (eax=0). + +====================================================================== +==== Function 58, subfunction 15 - get information on file system. === +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 15 = subfunction number + * +4: dword: ignored + * +8: dword: ignored + * +12 = +0xC: dword: ignored + * +16 = +0x10: dword: ignored + * +20 = +0x14: (only second character is checked) + /rd=/RAMDISK or /hd=/HARDDISK +Returned value: + * if the second character does not belong to set {'r','R','h','H'}: + * eax = 3 + * ebx = ecx = dword [fileinfo] = 0 + * for ramdisk: + * eax = 0 (success) + * ebx = total number of clusters = 2847 + * ecx = number of free clusters + * dword [fileinfo] = cluster size = 512 + * for hard disk: base and partition are defined by subfunctions + 7 and 8 of function 21: + * eax = 0 (success) + * ebx = total number of clusters + * ecx = number of free clusters + * dword [fileinfo] = cluster size (in bytes) +Remarks: + * Be not surprised to strange layout of 4th returned parameter + - when this code was writing, at system calls application got + only registers eax,ebx,ecx (from pushad-structure transmitted + as argument to the system function). Now it is corrected, so, + probably, it is meaningful to return cluster size in edx, while + this function is not used yet. + * There exists also subfunction 11 of function 18, + which returns information on file system. From the full table + of disk subsystem it is possible to deduce cluster size (there + it is stored in sectors) and total number of clusters + for hard disks. + +====================================================================== +========== Function 60 - Inter Process Communication (IPC). ========== +====================================================================== +IPC is used for message dispatching from one process/thread to +another. Previously it is necessary to agree how to interpret +the concrete message. + +----------- Subfunction 1 - set the area for IPC receiving ----------- +Is called by process-receiver. +Parameters: + * eax = 60 - function number + * ebx = 1 - subfunction number + * ecx = pointer to the buffer + * edx = size of the buffer +Returned value: + * eax = 0 - always success +Format of IPC-buffer: + * +0: dword: if nonzero, buffer is considered locked; + lock/unlock the buffer, when you work with it and need that + buffer data are not changed from outside (no new messages) + * +4: dword: occupied place in the buffer (in bytes) + * +8: first message + * +8+n: second message + * ... +Format of a message: + * +0: dword: PID of sender + * +4: dword: message length (not including this header) + * +8: n*byte: message data + +------------------ Subfunction 2 - send IPC message ------------------ +Is called by process-sender. +Parameters: + * eax = 60 - function number + * ebx = 2 - subfunction number + * ecx = PID of receiver + * edx = pointer to the message data + * esi = message length (in bytes) +Returned value: + * eax = 0 - success + * eax = 1 - the receiver has not defined buffer for IPC messages + (can be, still have no time, + and can be, this is not right process) + * eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit + * eax = 3 - overflow of IPC-buffer of the receiver + * eax = 4 - process/thread with such PID does not exist +Remarks: + * Immediately after writing of IPC-message to the buffer the system + sends to the receiver the event with code 7 (see event codes). + +====================================================================== +==== Function 61 - get parameters for the direct graphics access. ==== +====================================================================== +The data of the graphics screen (the memory area which displays +screen contents) are accessible to a program directly, without +any system calls, through the selector gs: + mov eax, [gs:0] +places in eax the first dword of the buffer, which contains +information on color of the left upper point (and, possibly, colors +of several following). + mov [gs:0], eax +by work in VESA modes with LFB sets color of the left upper point +(and, possibly, colors of several following). +To interpret the data of graphics screen program needs to know +some parameters, returning by this function. +Remarks: + * Graphics parameters changes very seldom at work, + namely, only in cases, when user works with the application VRR. + * At videomode change the system redraws all windows (event + with code 1) and redraws the background (event 5). + Same events occur in other cases too, which meet much more often, + than videomode change. + * By operation in videomodes with LFB the selector gs points to + LFB itself, so reading/writing on gs result directly in + change of screen contents. By operation in videomodes without + LFB gs points to some data area in the kernel, and all functions + of screen output fulfil honesty double operation on writing + directly to the screen and writing to this buffer. In result + at reading contents of this buffer the results correspond to + screen contents (with, generally speaking, large color + resolution), and writing is ignored. + One exception is the mode 320*200, for which main loop of the + system thread updates the screen according to mouse movements. + +------------------------- Screen resolution -------------------------- +Parameters: + * eax = 61 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = [resolution on x axis]*65536 + [resolution on y axis] +Remarks: + * One can use function 14 paying attention that + it returns sizes on 1 pixel less. It is fully equivalent way. + +---------------------- Number of bits per pixel ---------------------- +Parameters: + * eax = 61 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = number of bits per pixel (24 or 32) + +-------------------- Number of bytes per scanline -------------------- +Parameters: + * eax = 61 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = number of bytes occupied by one scanline + (horizontal line on the screen) + +====================================================================== +===== Function 62, subfunction 0 - get version of PCI-interface. ===== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 0 - subfunction number +Returned value: + * eax = -1 - PCI access is disabled; otherwise + * ah.al = version of PCI-interface (ah=version, al=subversion) + * high word of eax is zeroed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * If PCI BIOS is not supported, the value of ax is undefined. + +====================================================================== +==== Function 62, subfunction 1 - get number of the last PCI-bus. ==== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 1 - subfunction number +Returned value: + * eax = -1 - access to PCI is disabled; otherwise + * al = number of the last PCI-bus; other bytes of eax are destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * If PCI BIOS is not supported, the value of ax is undefined. + +====================================================================== +===================== Function 62, subfunction 2 ===================== +===== Get mechanism of addressing to the PCI configuration space. ==== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 2 - subfunction number +Returned value: + * eax = -1 - access to PCI is disabled; otherwise + * al = mechanism (1 or 2); other bytes of eax are destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Addressing mechanism is selected depending on + equipment characteristics. + * Subfunctions of read and write work automatically + with the selected mechanism. + +====================================================================== +======== Function 62, subfunctions 4,5,6 - read PCI-register. ======== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 4 - read byte + * bl = 5 - read word + * bl = 6 - read dword + * bh = number of PCI-bus + * ch = dddddfff, where ddddd = number of the device on the bus, + fff = function number of device + * cl = number of register (must be even for bl=5, + divisible by 4 for bl=6) +Returned value: + * eax = -1 - error (access to PCI is disabled or parameters + are not supported); otherwise + * al/ax/eax (depending on requested size) contains the data; + the other part of register eax is destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Access mechanism 2 supports only 16 devices on a bus and ignores + function number. To get access mechanism use subfunction 2. + * Some registers are standard and exist for all devices, some are + defined by the concrete device. The list of registers of the + first type can be found e.g. in famous + Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); + registers of the second type must be listed + in the device documentation. + +====================================================================== +====== Function 62, subfunctions 8,9,10 - write to PCI-register. ===== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 8 - write byte + * bl = 9 - write word + * bl = 10 - write dword + * bh = number of PCI-bus + * ch = dddddfff, where ddddd = number of the device on the bus, + fff = function number of device + * cl = number of register (must be even for bl=9, + divisible by 4 for bl=10) + * dl/dx/edx (depending on requested size) contatins + the data to write +Returned value: + * eax = -1 - error (access to PCI is disabled or parameters + are not supported) + * eax = 0 - success +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Access mechanism 2 supports only 16 devices on a bus and ignores + function number. To get access mechanism use subfunction 2. + * Some registers are standard and exist for all devices, some are + defined by the concrete device. The list of registers of the + first type can be found e.g. in famous Interrupt List by + Ralf Brown; registers of the second type must be listed + in the device documentation. + +====================================================================== +============== Function 63 - work with the debug board. ============== +====================================================================== +The debug board is the global system buffer (with the size +1024 bytes), to which any program can write (generally speaking, +arbitrary) data and from which other program can read these data. +By the agreement written data are text strings interpreted as +debug messages on a course of program execution. The kernel in +some situations also writes to the debug board information on +execution of some functions; by the agreement kernel messages +begins from the prefix "K : ". +For view of the debug board the application 'board' was created, +which reads data from the buffer and displays them in its window. +'board' interpretes the sequence of codes 13,10 as newline. +A character with null code in an end of line is not necessary, +but also does not prevent. +Because debugger has been written, the value of the debug board +has decreased, as debugger allows to inspect completely a course of +program execution without any efforts from the direction of program +itself. Nevertheless in some cases the debug board is still useful. + +----------------------------- Write byte ----------------------------- +Parameters: + * eax = 63 - function number + * ebx = 1 - subfunction number + * cl = data byte +Returned value: + * function does not return value +Remarks: + * Byte is written to the buffer. Buffer size is 512 bytes. + At buffer overflow all obtained data are lost. + * For output to the debug board of more complicated objects + (strings, numbers) it is enough to call this function in cycle. + It is possible not to write the appropriate code manually and use + file 'debug.inc', which is included into the distributive. + +----------------------------- Read byte ------------------------------ +Takes away byte from the buffer. +Parameters: + * eax = 63 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = ebx = 0 - the buffer is empty + * eax = byte, ebx = 1 - byte was successfully read + +====================================================================== +============== Function 64 - resize application memory. ============== +====================================================================== +Parameters: + * eax = 64 - function number + * ebx = 1 - unique subfunction + * ecx = new memory size +Returned value: + * eax = 0 - success + * eax = 1 - not enough memory +Remarks: + * There is another way to dynamically allocate/free memory - + subfunctions 11, 12, 13 of function 68. + * The function cannot be used together with 68.11, 68.12, 68.13. + The function call will be ignored after creation of process heap + with function 68.11. + +====================================================================== +======== Function 65 - draw image with palette in the window. ======== +====================================================================== +Parameters: + * eax = 65 - function number + * ebx = pointer to the image + * ecx = [size on axis x]*65536 + [size on axis y] + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] + * esi = number of bits per pixel, must be 1,2,4,8,15,16,24 or 32 + * edi = pointer to palette (2 to the power esi colors 0x00RRGGBB); + ignored when esi > 8 + * ebp = offset of next row data relative to previous row data +Returned value: + * function does not return value +Remarks: + * Coordinates of the image are coordinates of the upper left corner + of the image relative to the window. + * Format of image with 1 bit per pixel: each byte of image + (possibly excluding last bytes in rows), contains information on + the color of 8 pixels, MSB corresponds to first pixel. + * Format of image with 2 bits per pixel: each byte of image + (possibly excluding last bytes in rows), contains information on + the color of 4 pixels, two MSBs correspond to first pixel. + * Format of image with 4 bits per pixel: each byte of image + excluding last bytes in rows (if width is odd) contains + information on the color of 2 pixels, high-order tetrad + corresponds to first pixel. + * Format of image with 8 bits per pixel: each byte of image is + index in the palette. + * Format of image with 15 bits per pixel: the color of each pixel + is coded as (bit representation) 0RRRRRGGGGGBBBBB - 5 bits per + each color. + * Format of image with 16 bits per pixel: the color of each pixel + is coded as RRRRRGGGGGGBBBBB (5+6+5). + * Format of image with 24 bits per pixel: the color of each pixel + is coded as 3 bytes - sequentially blue, green, red components. + * Format of image with 32 bits per pixel: similar to 24, but + one additional ignored byte is present. + * The call to function 7 is equivalent to call to this function + with esi=24, ebp=0. + +====================================================================== +================== Function 66 - work with keyboard. ================= +====================================================================== +The input mode influences results of reading keys by function 2. +When a program loads, ASCII input mode is set for it. + +-------------- Subfunction 1 - set keyboard input mode. -------------- +Parameters: + * eax = 66 - function number + * ebx = 1 - subfunction number + * ecx = mode: + * 0 = normal (ASCII-characters) + * 1 = scancodes +Returned value: + * function does not return value + +-------------- Subfunction 2 - get keyboard input mode. -------------- +Parameters: + * eax = 66 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = current mode + +------------ Subfunction 3 - get status of control keys. ------------- +Parameters: + * eax = 66 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = bit mask: + * bit 0 (mask 1): left Shift is pressed + * bit 1 (mask 2): right Shift is pressed + * bit 2 (mask 4): left Ctrl is pressed + * bit 3 (mask 8): right Ctrl is pressed + * bit 4 (mask 0x10): left Alt is pressed + * bit 5 (mask 0x20): right Alt is pressed + * bit 6 (mask 0x40): CapsLock is on + * bit 7 (mask 0x80): NumLock is on + * bit 8 (mask 0x100): ScrollLock is on + * other bits are cleared + +-------------- Subfunction 4 - set system-wide hotkey. --------------- +When hotkey is pressed, the system notifies only those applications, +which have installed it; the active application (which receives +all normal input) does not receive such keys. +The notification consists in sending event with the code 2. +Reading hotkey is the same as reading normal key - by function 2. +Parameters: + * eax = 66 - function number + * ebx = 4 - subfunction number + * cl determines key scancode; + use cl=0 to give combinations such as Ctrl+Shift + * edx = 0xXYZ determines possible states of control keys: + * Z (low 4 bits) determines state of LShift and RShift: + * 0 = no key must be pressed; + * 1 = exactly one key must be pressed; + * 2 = both keys must be pressed; + * 3 = must be pressed LShift, but not RShift; + * 4 = must be pressed RShift, but not LShift + * Y - similar for LCtrl and RCtrl; + * X - similar for LAlt and RAlt +Returned value: + * eax=0 - success + * eax=1 - too mant hotkeys (maximum 256 are allowed) +Remarks: + * Hotkey can work either at pressing or at release. Release + scancode of a key is more on 128 than pressing scancode + (i.e. high bit is set). + * Several applications can set the same combination; + all such applications will be informed on pressing + such combination. + +-------------- Subfunction 5 - delete installed hotkey. -------------- +Parameters: + * eax = 66 - function number + * ebx = 5 - subfunction number + * cl = scancode of key and edx = 0xXYZ the same as in subfunction 4 +Returned value: + * eax = 0 - success + * eax = 1 - there is no such hotkey +Remarks: + * When a process/thread terminates, all hotkey installed by it are + deleted. + * The call to this subfunction does not affect other applications. + If other application has defined the same combination, it will + still receive notices. + +====================================================================== +========= Function 67 - change position/sizes of the window. ========= +====================================================================== +Parameters: + * eax = 67 - function number + * ebx = new x-coordinate of the window + * ecx = new y-coordinate of the window + * edx = new x-size of the window + * esi = new y-size of the window +Returned value: + * function does not return value +Remarks: + * The value -1 for a parameter means "do not change"; e.g. to move + the window without resizing it is possible to specify edx=esi=-1. + * Previously the window must be defined by function 0. + It sets initial coordinates and sizes of the window. + * Sizes of the window are understood in sense of function 0, + that is one pixel less than real sizes. + * The function call for maximized windows is simply ignored. + * For windows of appropriate styles position and/or sizes can be + changed by user; current position and sizes can be obtained by + call to function 9. + * The function sends to the window redraw event (with the code 1). + +====================================================================== +====== Function 68, subfunction 0 - get the task switch counter. ===== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = number of task switches from the system booting + (modulo 2^32) + +====================================================================== +======= Function 68, subfunction 1 - switch to the next thread. ====== +====================================================================== +The function completes the current time slice allocated to the +thread and switches to the next. (Which thread in which process +will be next, is unpredictable). Later, when execution queue +will reach the current thread, execution will be continued. +Parameters: + * eax = 68 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value + +====================================================================== +============= Function 68, subfunction 2 - cache + rdpmc. ============ +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 2 - subfunction number + * ecx = required action: + * ecx = 0 - enable instruction 'rdpmc' + (ReaD Performance-Monitoring Counters) for applications + * ecx = 1 - find out whether cache is disabled/enabled + * ecx = 2 - enable cache + * ecx = 3 - disable cache +Returned value: + * for ecx=0: + * eax = the value of cr4 + * for ecx=1: + * eax = (cr0 and 0x60000000): + * eax = 0 - cache is on + * eax <> 0 - cache is off + * for ecx=2 and ecx=3: + * function does not return value + +====================================================================== +=========== Function 68, subfunction 3 - read MSR-register. ========== +====================================================================== +MSR = Model Specific Register; the complete list of MSR-registers +of a processor is included to the documentation on it (for example, +IA-32 Intel Architecture Software Developer's Manual, +Volume 3, Appendix B); each processor family has its own subset +of the MSR-registers. +Parameters: + * eax = 68 - function number + * ebx = 3 - subfunction number + * ecx is ignored + * edx = MSR address +Returned value: + * ebx:eax = high:low dword of the result +Remarks: + * If ecx contains nonexistent or not implemented for this processor + MSR, processor will generate an exception in the kernel, which + will kill the thread. + * Previously it is necessary to check, whether MSRs are supported + as a whole, with the instruction 'cpuid'. Otherwise processor + will generate other exception in the kernel, which will anyway + kill the thread. + +====================================================================== +========= Function 68, subfunction 4 - write to MSR-register. ======== +====================================================================== +MSR = Model Specific Register; the complete list of MSR-registers +of a processor is included to the documentation on it (for example, +IA-32 Intel Architecture Software Developer's Manual, +Volume 3, Appendix B); each processor family has its own subset +of the MSR-registers. +Parameters: + * eax = 68 - function number + * ebx = 4 - subfunction number + * ecx is ignored + * edx = MSR address + * esi:edi = high:low dword +Returned value: + * function does not return value +Remarks: + * If ecx contains nonexistent or not implemented for this processor + MSR, processor will generate an exception in the kernel, which + will kill the thread. + * Previously it is necessary to check, whether MSRs are supported + as a whole, with the instruction 'cpuid'. Otherwise processor + will generate other exception in the kernel, which will anyway + kill the thread. + +====================================================================== +======= Function 68, subfunction 11 - initialize process heap. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 11 - subfunction number +Returned value: + * eax = 0 - failed + * otherwise size of created heap +Remarks: + * The function call initializes heap, from which one can in future + allocate and free memory blocks with subfunctions 12 and 13. + Heap size is equal to total amount of free application memory. + * The second function call from the same process results in + returning the size of the existing heap. + * After creation of the heap calls to function 64 will be ignored. + +====================================================================== +======== Function 68, subfunction 12 - allocate memory block. ======== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 12 - subfunction number + * ecx = required size in bytes +Returned value: + * eax = pointer to the allocated block +Remarks: + * Before this call one must initialize process heap by call to + subfunction 11. + * The function allocates an integer number of pages (4 Kb) in such + way that the real size of allocated block is more than or equal to + requested size. + +====================================================================== +========== Function 68, subfunction 13 - free memory block. ========== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 13 - subfunction number + * ecx = pointer to the memory block +Returned value: + * eax = 1 - success + * eax = 0 - failed +Remarks: + * The memory block must have been allocated by subfunction 12 + or subfunction 20. + +====================================================================== +===================== Function 68, subfunction 14 ==================== +====== Waiting delivering of signal from another program/driver ====== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 14 - subfunction number + * ecx = pointer to the buffer for information (24 bytes) +Returned value: + * buffer pointed to by ecx contains the following information: + * +0: dword: identifier for underlying data of signal + * +4: data of signal (20 bytes), format of which is defining by + first dword + +====================================================================== +====== Function 68, subfunction 15 - set FPU exception handler. ====== +====================================================================== +Deleted (in current implementation only 0 is returned). +Using subfunctions 24, 25 is true. + +====================================================================== +============= Function 68, subfunction 16 - load driver. ============= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 16 - subfunction number + * ecx = pointer to ASCIIZ-string with driver name +Returned value: + * eax = 0 - failed + * otherwise eax = driver handle +Remarks: + * If the driver was not loaded yet, it is loaded; + if the driver was loaded yet, nothing happens. + * Driver name is case-sensitive. + Maximum length of the name is 16 characters, including + terminating null character, the rest is ignored. + * Driver ABC is loaded from file /rd/1/drivers/ABC.obj. + +====================================================================== +============ Function 68, subfunction 17 - driver control. =========== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 17 - subfunction number + * ecx = pointer to the control structure: + * +0: dword: handle of driver + * +4: dword: code of driver function + * +8: dword: pointer to input data + * +12 = +0xC: dword: size of input data + * +16 = +0x10: dword: pointer to output data + * +20 = +0x14: dword: size of output data +Returned value: + * eax = error code + 0 - successful call + -1 - any error. + -2, -3, -4, etc. reserved for kernel error codes + 1, 2, 3, etc driver specific error codes +Remarks: + * Function codes and the structure of input/output data + are defined by driver. + * Previously one must obtain driver handle by subfunction 16. + +====================================================================== +====== Function 68, subfunction 18 - set SSE exception handler. ====== +====================================================================== +Deleted (in current implementation only 0 is returned). +Using subfunctions 24, 25 is true. + +====================================================================== +=============== Function 68, subfunction 19 - load DLL. ============== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 19 - subfunction number + * ecx = pointer to ASCIIZ-string with the full path to DLL +Returned value: + * eax = 0 - failed + * otherwise eax = pointer to DLL export table +Remarks: + * Export table is an array of structures of 2 dword's, terminated + by zero. The first dword in structure points to function name, + the second dword contains address of function. + +====================================================================== +======= Function 68, subfunction 20 - reallocate memory block. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 20 - subfunction number + * ecx = new size in bytes + * edx = pointer to already allocated block +Returned value: + * eax = pointer to the reallocated block, 0 = error +Remarks: + * Before this call one must initialize process heap by call to + subfunction 11. + * The function allocates an integer number of pages (4 Kb) in such + way that the real size of allocated block is more than or equal to + requested size. + * If edx=0, the function call is equivalent to memory allocation + with subfunction 12. Otherwise the block at edx + must be allocated earlier with subfunction 12 or this subfunction. + * If ecx=0, the function frees memory block at edx and returns 0. + * The contents of the block are unchanged up to the shorter of + the new and old sizes. + +====================================================================== +====== Function 68, subfunction 24 - set new exceptions handler ====== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 24 - subfunction number + * ecx = address of the new exception handler + * edx = the mask of processing exceptions +Returned value: + * eax = address of the old exception handler (0, if it was not set) + * ebx = the old mask of exception handler +Remarks: + * Bit number in mask of exceptions is correspond to exception number + by CPU-specification (Intel-PC). For example, FPU-exception have + number 16 (#MF), and SSE-exception - 19 (#XF) + * The current implementation ignore the inquiry for hook of 7 + exception - system process #NM by one's own. + * User handler get exception number in stack parameter. So, correct + exit from handler is: RET 4. Return from handler is to the same + instruction, that was cause the exception + * When control is transfering to user handler, corresponding bit in + exception mask is clearing. Rising this exception in consequence + - reduce to default-handling. Exactly: terminating the application, + or suspending with debug-notify to owner. + * After completion of critical operations in user handler, it may be + rising corresponding bit in exception mask by using subfunction 25 + Clearing exceptions flags in FPU and/or XMM modules - is + responsibility of user handler too. + +====================================================================== +==== Function 68, subfunction 25 - change state of signal activity === +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 25 - subfunction number + * ecx = signal number + * edx = value of activity (0/1) +Returned value: + * eax = value of old activity for this signal (0/1) +Remarks: + * In current implementation, it is changed only exception mask for + user exception handler, wich was previously set by subfunction 24. + At that, number of signal correspond to exception number. + +====================================================================== +====================== Fucntion 69 - debugging. ====================== +====================================================================== +A process can load other process as debugged by set of corresponding +bit by call to subfunction 7 of function 70. +A process can have only one debugger; one process can debug some +others. The system notifies debugger on events occuring with +debugged process. Messages are written to the buffer defined by +subfunction 0. +Format of a message: + * +0: dword: message code + * +4: dword: PID of debugged process + * +8: there can be additional data depending on message code +Message codes: + * 1 = exception + * in addition dword-number of the exception is given + * process is suspended + * 2 = process has terminated + * comes at any termination: both through the system function -1, + and at "murder" by any other process (including debugger itself) + * 3 = debug exception int 1 = #DB + * in addition dword-image of the register DR6 is given: + * bits 0-3: condition of the corresponding breakpoint (set by + subfunction 9) is satisfied + * бит 14: exception has occured because of the trace mode + (flag TF is set TF) + * process is suspended +When debugger terminates, all debugged processes are killed. +If debugger does not want this, it must previously detach by +subfunction 3. + +All subfunctions are applicable only to processes/threads started +from the current by function 70 with set debugging flag. +Debugging of multithreaded programs is not supported yet. +The full list of subfunctions: + * subfunction 0 - define data area for debug messages + * subfunction 1 - get contents of registers of debugged thread + * subfunction 2 - set contents of registers of debugged thread + * subfunction 3 - detach from debugged process + * subfunction 4 - suspend debugged thread + * subfunction 5 - resume debugged thread + * subfunction 6 - read from the memory of debugged process + * subfunction 7 - write to the memory of debugged process + * subfunction 8 - terminate debugged thread + * subfunction 9 - set/clear hardware breakpoint + +====================================================================== += Function 69, subfunction 0 - define data area fror debug messages. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 0 - subfunction number + * ecx = pointer +Format of data area: + * +0: dword: N = buffer size (not including this header) + * +4: dword: occupied place + * +8: N*byte: buffer +Returned value: + * function does not return value +Remarks: + * If the size field is negative, the buffer is considered locked + and at arrival of new message the system will wait. + For synchronization frame all work with the buffer by operations + lock/unlock + neg [bufsize] + * Data in the buffer are considered as array of items with variable + length - messages. Format of a message is explained in + general description. + +====================================================================== +===================== Function 69, subfunction 1 ===================== +============ Get contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 1 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes + * esi = pointer to context structure +Returned value: + * function does not return value +Format of context structure: (FPU is not supported yet) + * +0: dword: eip + * +4: dword: eflags + * +8: dword: eax + * +12 = +0xC: dword: ecx + * +16 = +0x10: dword: edx + * +20 = +0x14: dword: ebx + * +24 = +0x18: dword: esp + * +28 = +0x1C: dword: ebp + * +32 = +0x20: dword: esi + * +36 = +0x24: dword: edi +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===================== Function 69, subfunction 2 ===================== +============ Set contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 2 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes +Returned value: + * function does not return value +Format of context structure is shown in the description of +subfunction 1. +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===== Function 69, subfunction 3 - detach from debugged process. ===== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 3 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * If the process was suspended, it resumes execution. + +====================================================================== +======== Function 69, subfunction 4 - suspend debugged thread. ======= +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 4 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======== Function 69, subfunction 5 - resume debugged thread. ======== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 5 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== += Fucntion 69, subfunction 6 - read from memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 6 - subfunction number + * ecx = identifier + * edx = number of bytes to read + * esi = address in the memory of debugged process + * edi = pointer to buffer for data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of read bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +== Function 69, subfunction 7 - write to memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 7 - subfunction number + * ecx = identifier + * edx = number of bytes to write + * esi = address of memory in debugged process + * edi = pointer to data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of written bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======= Function 69, subfunction 8 - terminate debugged thread. ====== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 8 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * The function is similar to subfunction 2 of function 18 + with two differences: it requires first remark and + accepts PID rather than slot number. + +====================================================================== +===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 9 - subfunction number + * ecx = thread identifier + * dl = index of breakpoint, from 0 to 3 inclusively + * dh = flags: + * if high bit is cleared - set breakpoint: + * bits 0-1 - condition: + * 00 = breakpoint on execution + * 01 = breakpoint on read + * 11 = breakpoint on read/write + * bits 2-3 - length; for breakpoints on exception it must be + 00, otherwise one of + * 00 = byte + * 01 = word + * 11 = dword + * esi = breakpoint address; must be aligned according to + the length (i.e. must be even for word breakpoints, + divisible by 4 for dword) + * if high bit is set - clear breakpoint +Returned value: + * eax = 0 - success + * eax = 1 - error in the input data + * eax = 2 - (reserved, is never returned in the current + implementation) a global breakpoint with that index is already set +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * Hardware breakpoints are implemented through DRx-registers of + the processor, all limitations results from this. + * The function can reinstall the breakpoint, previously set + by it (and it does not inform on this). + Carry on the list of set breakpoints in the debugger. + * Breakpoints generate debug exception #DB, on which the system + notifies debugger. + * Breakpoints on write and read/write act after + execution of the caused it instruction. + +====================================================================== +==== Function 70 - work with file system with long names support. ==== +====================================================================== +Parameters: + * eax = 70 + * ebx = pointer to the information structure +Returned value: + * eax = 0 - success; otherwise file system error code + * some subfunctions return value in other registers too +General format of the information structure: + * +0: dword: subfunction number + * +4: dword: file offset + * +8: dword: high dword of offset (must be 0) or flags field + * +12 = +0xC: dword: size + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: n db: ASCIIZ-string with the filename + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with the filename +Specifications - in documentation on the appropriate subfunction. +Filename is case-insensitive. Russian letters must be written in +the encoding cp866 (DOS). +Format of filename: +/base/number/dir1/dir2/.../dirn/file, +where /base/number identifies device, on which file is located: +one of + * /RD/1 = /RAMDISK/1 to access ramdisk + * /FD/1 = /FLOPPYDISK/1 to access first floppy drive, + /FD/2 = /FLOPPYDISK/2 to access second one + * /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices + IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - partition number on the selected hard drive, varies from 1 + to 255 (on each hard drive the indexing starts from 1) + * /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to + CD on IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave) + * /SYS means system folder; with the usual boot (from floppy) + is equivalent to /RD/1 +Examples: + * '/rd/1/kernel.asm',0 + * '/HD0/1/kernel.asm',0 + * '/hd0/2/menuet/pics/tanzania.bmp',0 + * '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 + * '/sys/MySuperApp.ini',0 +Available subfunctions: + * subfunction 0 - read file + * subfunction 1 - read folder + * subfunction 2 - create/rewrite file + * subfunction 3 - write to existing file + * subfunction 4 - set file size + * subfunction 5 - get attributes of file/folder + * subfunction 6 - set attributes of file/folder + * subfunction 7 - start application + * subfunction 8 - delete file/folder + * subfunction 9 - create folder +For CD-drives due to hardware limitations only subfunctions +0,1,5 and 7 are available, other subfunctions return error +with code 2. +At the first call of subfunctions 0,1,5,7 to ATAPI devices +(CD and DVD) the manual control of tray is locked due to caching +drive data. Unlocking is made when subfunction 4 of function 24 +is called for corresponding device. + +====================================================================== +=== Function 70, subfunction 0 - read file with long names support. == +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 0 = subfunction number + * +4: dword: file offset (in bytes) + * +8: dword: 0 (reserved for high dword of offset) + * +12 = +0xC: dword: number of bytes to read + * +16 = +0x10: dword: pointer to buffer for data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of read bytes or -1=0xffffffff if file was not found +Remarks: + * If file was ended before last requested block was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * The function does not allow to read folder (returns eax=10, + access denied). + +====================================================================== +== Function 70, subfunction 1 - read folder with long names support. = +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 1 = subfunction number + * +4: dword: index of starting block (beginning from 0) + * +8: dword: flags field: + * bit 0 (mask 1): in what format to return names, + 0=ANSI, 1=UNICODE + * other bits are reserved and must be set to 0 for the future + compatibility + * +12 = +0xC: dword: number of blocks to read + * +16 = +0x10: dword: pointer to buffer for data, buffer size + must be not less than 32 + [+12]*560 bytes + * +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of files, information on which was written to + the buffer, or -1=0xffffffff, if folder was not found +Structure of the buffer: + * +0: 32*byte: header + * +32 = +0x20: n1*byte: block with information on file 1 + * +32+n1: n2*byte: block with information on file 2 + * ... +Structure of header: + * +0: dword: version of structure (current is 1) + * +4: dword: number of placed blocks; is not greater than requested + in the field +12 of information structure; can be less, if + there are no more files in folder (the same as in ebx) + * +8: dword: total number of files in folder + * +12 = +0xC: 20*byte: reserved (zeroed) +Structure of block of data for folder entry (BDFE): + * +0: dword: attributes of file: + * bit 0 (mask 1): file is read-only + * bit 1 (mask 2): file is hidden + * bit 2 (mask 4): file is system + * bit 3 (mask 8): this is not a file but volume label + (for one partition meets no more than once and + only in root folder) + * bit 4 (mask 0x10): this is a folder + * bit 5 (mask 0x20): file was not archived - many archivation + programs have an option to archive only files with this bit set, + and after archiving this bit is cleared - it can be useful + for automatically creating of backup-archives as at writing + this bit is usually set + * +4: byte: type of name data: + (coincides with bit 0 of flags in the information structure) + * 0 = ASCII = 1-byte representation of each character + * 1 = UNICODE = 2-byte representation of each character + * +5: 3*byte: reserved (zero) + * +8: 4*byte: time of file creation + * +12 = +0xC: 4*byte: date of file creation + * +16 = +0x10: 4*byte: time of last access (read or write) + * +20 = +0x14: 4*byte: date of last access + * +24 = +0x18: 4*byte: time of last modification + * +28 = +0x1C: 4*byte: date of last modification + * +32 = +0x20: qword: file size in bytes (up to 16777216 Tb) + * +40 = +0x28: name + * for ASCII format: maximum length is 263 characters + (263 bytes), byte after the name has value 0 + * for UNICODE format: maximum length is 259 characters + (518 bytes), 2 bytes after the name have value 0 +Time format: + * +0: byte: seconds + * +1: byte: minutes + * +2: byte: hours + * +3: byte: reserved (0) + * for example, 23.59.59 is written as (in hex) 3B 3B 17 00 +Date format: + * +0: byte: day + * +1: byte: month + * +2: word: year + * for example, 25.11.1979 is written as (in hex) 19 0B BB 07 +Remarks: + * If BDFE contains ASCII name, the length of BDFE is 304 bytes, + if UNICODE name - 560 bytes. Value of length is aligned + on 16-byte bound (to accelerate processing in CPU cache). + * First character after a name is zero (ASCIIZ-string). The further + data contain garbage. + * If files in folder were ended before requested number was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * Any folder on the disk, except for root, contains two special + entries "." and "..", identifying accordingly the folder itself + and the parent folder. + * The function allows also to read virtual folders "/", "/rd", + "/fd", "/hd[n]", thus attributes of subfolders are set to 0x10, + and times and dates are zeroed. An alternative way to get the + equipment information - subfunction 11 of function 18. + +====================================================================== +===================== Function 70, subfunction 2 ===================== +============ Create/rewrite file with long names support. ============ +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 2 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: number of bytes to read + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of written bytes (possibly 0) +Remarks: + * If a file with given name did not exist, it is created; + if it existed, it is rewritten. + * If there is not enough free space on disk, the function will + write as many as can and then return error code 8. + * The function is not supported for CD (returns error code 2). + +====================================================================== +===================== Function 70, subfunction 3 ===================== +=========== Write to existing file with long names support. ========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 3 = subfunction number + * +4: dword: file offset (in bytes) + * +8: dword: high dword of offset (must be 0 for FAT) + * +12 = +0xC: dword: number of bytes to write + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of written bytes (possibly 0) +Remarks: + * The file must already exist, otherwise function returns eax=5. + * The only result of write 0 bytes is update in the file attributes + date/time of modification and access to the current date/time. + * If beginning and/or ending position is greater than file size + (except for the previous case), the file is expanded to needed + size with zero characters. + * The function is not supported for CD (returns error code 2). + +====================================================================== +============ Function 70, subfunction 4 - set end of file. =========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 4 = subfunction number + * +4: dword: low dword of new file size + * +8: dword: high dword of new file size (must be 0 for FAT) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * If the new file size is less than old one, file is truncated. + If the new size is greater than old one, file is expanded with + characters with code 0. If the new size is equal to old one, + the only result of call is set date/time of modification and + access to the current date/time. + * If there is not enough free space on disk for expansion, the + function will expand to maximum possible size and then return + error code 8. + * The function is not supported for CD (returns error code 2). + +====================================================================== +==== Function 70, subfunction 5 - get information on file/folder. ==== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 5 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: pointer to buffer for data (40 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Information on file is returned in the BDFE format (block of data +for folder entry), explained in the description of +subfunction 1, but without filename +(i.e. only first 40 = 0x28 bytes). +Remarks: + * The function does not support virtual folders such as /, /rd and + root folders like /rd/1. + +====================================================================== +===== Function 70, subfunction 6 - set attributes of file/folder. ==== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 6 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: pointer to buffer with attributes (32 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +File attributes are first 32 bytes in BDFE (block of data +for folder entry), explained in the description of subfunction 1 +(that is, without name and size of file). Attribute +file/folder/volume label (bits 3,4 in dword +0) is not changed. +Byte +4 (name format) is ignored. +Remarks: + * The function does not support virtual folders such as /, /rd and + root folders like /rd/1. + * The function is not supported for CD (returns error code 2). + +====================================================================== +=========== Function 70, subfunction 7 - start application. ========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 7 = subfunction number + * +4: dword: flags field: + * бит 0: start process as debugged + * other bits are reserved and must be set to 0 + * +8: dword: 0 or pointer to ASCIIZ-string with parameters + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax > 0 - program is loaded, eax contains PID + * eax < 0 - an error has occured, -eax contains + file system error code + * ebx destroyed +Remarks: + * Command line must be terminated by the character with the code 0 + (ASCIIZ-string); function takes into account either all characters + up to terminating zero inclusively or first 256 character + regarding what is less. + * If the process is started as debugged, it is created in + the suspended state; to run use subfunction 5 of function 69. + +====================================================================== +========== Function 70, subfunction 8 - delete file/folder. ========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 8 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * The function is not supported for CD (returns error code 2). + * The function can delete only empty folders (attempt to delete + nonempty folder results in error with code 10, "access denied"). + +====================================================================== +============= Function 70, subfunction 9 - create folder. ============ +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 9 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with folder name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * The function is not supported for CD (returns error code 2). + * The parent folder must already exist. + * If target folder already exists, function returns success (eax=0). + +====================================================================== +========== Function 71, subfunction 1 - set window caption. ========== +====================================================================== +Parameters: + * eax = 71 - function number + * ebx = 1 - subfunction number + * ecx = pointer to caption string +Returned value: + * function does not return value +Remarks: + * String must be in the ASCIIZ-format. Disregarding real string + length, no more than 255 characters are drawn. + * Pass NULL in ecx to remove caption. + +====================================================================== +=============== Function 72 - send message to a window. ============== +====================================================================== + +- Subfunction 1 - send message with parameter to the active window. -- +Parameters: + * eax = 72 - function number + * ebx = 1 - subfunction number + * ecx = event code: 2 or 3 + * edx = parameter: key code for ecx=2, button identifier for ecx=3 +Returned value: + * eax = 0 - success + * eax = 1 - buffer is full + +====================================================================== +=============== Function -1 - terminate thread/process =============== +====================================================================== +Parameters: + * eax = -1 - function number +Returned value: + * function does not return neither value nor control +Remarks: + * If the process did not create threads obviously, it has only + one thread, which termination results in process termination. + * If the current thread is last in the process, its termination + also results in process terminates. + * This function terminates the current thread. Other thread can be + killed by call to subfunction 2 of function 18. + +====================================================================== +=========================== List of events =========================== +====================================================================== +Next event can be retrieved by the call of one from functions 10 +(to wait for event), 11 (to check without waiting), 23 +(to wait during the given time). +These functions return only those events, which enter into a mask set +by function 40. By default it is first three, +there is enough for most applications. +Codes of events: + * 1 = redraw event (is reset by call to function 0) + * 2 = key on keyboard is pressed (acts, only when the window is + active) or hotkey is pressed; is reset, when all keys from + the buffer are read out by function 2 + * 3 = button is pressed, defined earlier by function 8 + (or close button, created implicitly by function 0; + minimize button is handled by the system and sends no message; + acts, only when the window is active; + is reset when all buttons from the buffer + are read out by function 17) + * 4 = reserved (in current implementation never comes even after + unmasking by function 40) + * 5 = the desktop background is redrawed (is reset automatically + after redraw, so if in redraw time program does not wait and + does not check events, it will not remark this event) + * 6 = mouse event (something happened - button pressing or moving; + is reset at reading) + * 7 = IPC event (see function 60 - + Inter Process Communication; is reset at reading) + * 8 = network event (is reset at reading) + * 9 = debug event (is reset at reading; see + debug subsystem) + * 16..31 = event with appropriate IRQ + (16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data) + +====================================================================== +=================== Error codes of the file system =================== +====================================================================== + * 0 = success + * 1 = base and/or partition of a hard disk is not defined + (by subfunctions 7, 8 of function 21) + * 2 = function is not supported for the given file system + * 3 = unknown file system + * 4 = reserved, is never returned in the current implementation + * 5 = file not found + * 6 = end of file, EOF + * 7 = pointer lies outside of application memory + * 8 = disk is full + * 9 = FAT table is destroyed + * 10 = access denied + * 11 = device error +Application start functions can return also following errors: + * 30 = 0x1E = not enough memory + * 31 = 0x1F = file is not executable + * 32 = 0x20 = too many processes diff --git a/kernel/tags/kolibri0.7.7.0/drivers/codec.inc b/kernel/tags/kolibri0.7.7.0/drivers/codec.inc new file mode 100644 index 000000000..f79102f69 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/codec.inc @@ -0,0 +1,283 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +AD_LOSEL equ BIT5 +AD_HPSEL equ BIT10 + +align 4 +proc detect_codec + locals + codec_id dd ? + endl + + stdcall codec_read, dword 0x7C + shl eax, 16 + mov [codec_id], eax + + stdcall codec_read, dword 0x7E + or eax, [codec_id] + + mov [codec.chip_id], eax + and eax, 0xFFFFFF00 + + mov edi, codecs +@@: + mov ebx, [edi] + test ebx, ebx + jz .unknown + + cmp eax, ebx + jne .next + mov eax, [edi+4] + mov [codec.ac_vendor_ids], eax + mov esi, eax + call SysMsgBoardStr + stdcall detect_chip, [edi+8] + + ret +.next: + add edi, 12 + jmp @B +.unknown: + mov [codec.ac_vendor_ids], ac_unknown + mov [codec.chip_ids], chip_unknown + + mov esi, chip_unknown + call SysMsgBoardStr + mov eax, [codec.chip_id] + call dword2str + call SysMsgBoardStr + ret +endp + +align 4 +proc detect_chip stdcall, chip_tab:dword + + mov eax, [codec.chip_id] + and eax, 0xFF + + mov edi, [chip_tab] +@@: + mov ebx, [edi] + cmp ebx, 0xFF + je .unknown + + cmp eax,ebx + jne .next + mov eax, [edi+4] + mov [codec.chip_ids], eax + mov esi, eax + call SysMsgBoardStr + ret +.next: + add edi, 8 + jmp @b +.unknown: + mov [codec.chip_ids], chip_unknown + mov esi, chip_unknown + call SysMsgBoardStr + mov eax, [codec.chip_id] + call dword2str + call SysMsgBoardStr + ret +endp + +align 4 +proc setup_codec + + xor eax, eax + stdcall codec_write, dword CODEC_AUX_VOL + + mov eax, 0x0B0B + stdcall codec_write, dword CODEC_MASTER_VOL_REG + + mov ax, 0x08 + stdcall codec_write, dword 0x0C + + mov ax, 0x0808 + stdcall codec_write, dword CODEC_PCM_OUT_REG + + mov ax, 0x0808 + stdcall codec_write, dword 0x10 + + mov ax, 0x0808 + stdcall codec_write, dword 0x12 + + mov ax, 0x0808 + stdcall codec_write, dword 0x16 + + + stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG + and eax, 0FFFFh - BIT1 ; clear DRA (BIT1) + or eax, BIT0 ; set VRA (BIT0) + stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG + + stdcall set_sample_rate, dword 48000 + +.init_error: + xor eax, eax ; exit with error + ret +endp + + +; param +; eax= volume -10000 - 0 for both channels + +align 4 +set_master_vol: + cmp eax, 0 + jl @F + xor eax, eax + jmp .set +@@: + cmp eax, -9450 + jg .set + mov eax, -9450 ;clamp into 6 bits +.set: + cdq + mov ebx, -150 + idiv ebx + mov ah, al + stdcall codec_write, dword CODEC_MASTER_VOL_REG + xor eax, eax + ret + +align 4 +proc get_master_vol stdcall, pvol:dword + + stdcall codec_read, dword CODEC_MASTER_VOL_REG + and eax, 0x3F + imul eax, -150 + mov ebx, [pvol] + mov [ebx], eax + xor eax, eax + ret +endp + +align 4 +proc set_sample_rate stdcall, rate:dword + mov eax, [rate] + stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG + ret +endp + +patch_AD: + stdcall codec_read, 0x76 + or ax, BIT5+BIT10 + stdcall codec_write, 0x76 + ret + + + +align 16 +ac_unknown db 'unknown manufacturer',13,10,0 +ac_Realtek db 'Realtek Semiconductor',13,10,0 +ac_Analog db 'Analog Devices',13,10,0 +ac_CMedia db 'C-Media Electronics',13,10,0 +ac_Cirrus db 'Cirrus Logic',13,10,0 + +chip_unknown db 'unknown codec id ', 0 + +CHIP_ANALOG equ 0x41445300 +CHIP_REALTEK equ 0x414C4700 +CHIP_CMEDIA equ 0x434D4900 +CHIP_CIRRUS equ 0x43525900 + +align 16 +codecs dd CHIP_ANALOG, ac_Analog, chips_Analog + dd CHIP_CMEDIA, ac_CMedia, chips_CMedia + dd CHIP_REALTEK,ac_Realtek, chips_Realtek + dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus + dd 0 + +align 16 +chips_Analog dd 0x03, chip_AD1819 + dd 0x40, chip_AD1881 + dd 0x48, chip_AD1881A + dd 0x60, chip_AD1884 + dd 0x61, chip_AD1886 + dd 0x62, chip_AD1887 + dd 0x63, chip_AD1886A + dd 0x70, chip_AD1980 + dd 0x75, chip_AD1985 + dd 0xFF + +chips_Realtek: + dd 0x20, chip_ALC650 + dd 0x21, chip_ALC650D + dd 0x22, chip_ALC650E + dd 0x23, chip_ALC650F + dd 0x60, chip_ALC655 + dd 0x80, chip_ALC658 + dd 0x81, chip_ALC658D + dd 0x90, chip_ALC850 + dd 0xFF + +chips_CMedia dd 0x41, chip_CM9738 + dd 0x61, chip_CM9739 + dd 0x69, chip_CM9780 + dd 0x78, chip_CM9761 + dd 0x82, chip_CM9761 + dd 0x83, chip_CM9761 + dd 0xFF + +chips_Cirrus dd 0x00, chip_CS4297 + dd 0x10, chip_CS4297A + dd 0x20, chip_CS4298 + dd 0x28, chip_CS4294 + dd 0x30, chip_CS4299 + dd 0x34, chip_CS4299D + dd 0x48, chip_CS4201 + dd 0x58, chip_CS4205 + dd 0x60, chip_CS4291 + dd 0x70, chip_CS4202 + dd 0xFF + + +align 16 +;Analog Devices +chip_AD1819 db 'AD1819 ',0dh,0ah,00h +chip_AD1881 db 'AD1881 ',0dh,0ah,00h +chip_AD1881A db 'AD1881A',0dh,0ah,00h +chip_AD1884 db 'AD1885 ',0dh,0ah,00h +chip_AD1885 db 'AD1885 ',0dh,0ah,00h +chip_AD1886 db 'AD1886 ',0dh,0ah,00h +chip_AD1886A db 'AD1886A',0dh,0ah,00h +chip_AD1887 db 'AD1887 ',0dh,0ah,00h +chip_AD1980 db 'AD1980 ',0dh,0ah,00h +chip_AD1985 db 'AD1985 ',0dh,0ah,00h + +;Realtek +chip_ALC650 db 'ALC650 ',0dh,0ah,00h +chip_ALC650D db 'ALC650D',0dh,0ah,00h +chip_ALC650E db 'ALC650E',0dh,0ah,00h +chip_ALC650F db 'ALC650F',0dh,0ah,00h +chip_ALC655 db 'ALC655 ',0dh,0ah,00h +chip_ALC658 db 'ALC658 ',0dh,0ah,00h +chip_ALC658D db 'ALC658D',0dh,0ah,00h +chip_ALC850 db 'ALC850 ',0dh,0ah,00h + +;CMedia +chip_CM9738 db 'CMI9738', 0dh,0ah,0 +chip_CM9739 db 'CMI9739', 0dh,0ah,0 +chip_CM9780 db 'CMI9780', 0dh,0ah,0 +chip_CM9761 db 'CMI9761', 0dh,0ah,0 + +;Cirrus +chip_CS4297 db 'CS4297',13,10,0 +chip_CS4297A db 'CS4297A',13,10,0 +chip_CS4298 db 'CS4298',13,10,0 +chip_CS4294 db 'CS4294',13,10,0 +chip_CS4299 db 'CS4299',13,10,0 +chip_CS4299D db 'CS4299D',13,10,0 +chip_CS4201 db 'CS4201',13,10,0 +chip_CS4205 db 'CS4205',13,10,0 +chip_CS4291 db 'CS4291',13,10,0 +chip_CS4202 db 'CS4202',13,10,0 + + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/com_mouse.asm b/kernel/tags/kolibri0.7.7.0/drivers/com_mouse.asm new file mode 100644 index 000000000..4996aae18 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/com_mouse.asm @@ -0,0 +1,382 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Includes source code by Kulakov Vladimir Gennadievich. ;; +;; Modified by Mario79 and Rus. ;; +;; 02.12.2009 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;driver sceletone + +format MS COFF + +DEBUG equ 0 + +include 'proc32.inc' +include 'imports.inc' + +API_VERSION equ 5 ;debug + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +public START +public version + + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +STRIDE equ 4 ;size of row in devices table + +SRV_GETVERSION equ 0 + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit +.entry: + ;Detect_COM_Mouse: +if DEBUG + mov esi, msgInit + call Boot_Log +end if + mov bx, 0x3f8 + call MSMouseSearch + cmp AL,'M' + jne @f + ;mov [com1_mouse_detected],1 + ;mov [irq_owner+4*4], 1 ; IRQ4 owner is System + + mov dx, bx + inc dx ; 0x3f8 + 1 + mov al, 1 + out dx, al + + stdcall AttachIntHandler, 4, irq4_handler, dword 0 +if DEBUG + test eax, eax + jne .label1 + + mov esi, msg_error_attach_int_handler + call Boot_Log +end if + .label1: +; mov eax, 0 +; mov ebx, 0x3F8 +; mov ecx, 0x3FF + xor ebx,ebx + mov ecx, 0x3F8 + mov edx, 0x3FF + call ReservePortArea + +if DEBUG + cmp eax, 1 + jne .go + + mov esi, msg_error_reserve_ports + call Boot_Log + + .go: + mov esi,boot_setmouse_type + call Boot_Log +end if + @@: + mov bx, 0x2f8 + call MSMouseSearch + cmp AL,'M' + jne .resume + ;mov [com2_mouse_detected],1 + ;mov [irq_owner+3*4], 1 ; IRQ3 owner is System + + stdcall AttachIntHandler, 3, irq3_handler, dword 0 + +; mov eax, 0 +; mov ebx, 0x2F8 +; mov ecx, 0x3F8 + xor ebx,ebx + mov ecx, 0x2F8 + mov edx, 0x3F8 + + call ReservePortArea +if DEBUG + cmp eax, 1 + jne @f + + mov esi, msg_error_reserve_ports + call Boot_Log + @@: + + mov esi,boot_setmouse_type + 22 + call Boot_Log +end if + .resume: + + stdcall RegService, my_service, service_proc +if DEBUG + test eax, eax + jne @f + + mov esi, msg_exit + call Boot_Log +end if + @@: + ret +.fail: +.exit: +if DEBUG + mov esi, msg_exit + call Boot_Log +end if + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov ebx, [ioctl] + mov eax, [ebx+io_code] + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [ebx+output] + cmp [ebx+out_size], 4 + jne .fail + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: +.fail: + or eax, -1 + ret +endp + +align 4 +MSMouseSearch: + ; ПОИСК МЫШИ ЧЕРЕЗ COM-ПОРТЫ +MouseSearch: + ; Устанавливаем скорость + ; приема/передачи 1200 бод + ; in bx COM Port Base Address + mov DX, bx + add DX,3 + in AL,DX + or AL,80h ;установить бит DLAB + out DX,AL + mov DX, bx + mov AL,60h ;1200 бод + out DX,AL + inc DX + mov AL,0 + out DX,AL + ; Установить длину слова 7 бит, 1 стоповый бит, + ; четность не контролировать + mov DX, bx + add DX,3 + mov AL,00000010b + out DX,AL + ; Запретить все прерывани + mov dx, bx + inc dx + mov AL,0 + out DX,AL +; Проверить, что устройство подключено и являетс +; мышью типа MSMouse + ; Отключить питание мыши и прерывани + mov DX, bx + add EDX,4 ;регистр управления модемом + mov AL,0 ;сбросить DTR, RTS и OUT2 + out DX,AL + ; Ожидать 5 "тиков" (0,2 с) + mov ecx, 0xFFFF + loop $ + ; Включить питание мыши + mov al, 1 + out dx, al + mov ecx, 0xFFFF + loop $ + ; Очистить регистр данных + mov dx, bx + in AL,DX + add edx, 4 + mov AL, 1011b ;установить DTR и RTS и OUT2 + out DX,AL + mov ecx, 0x1FFFF +; Цикл опроса порта +WaitData: + ; Ожидать еще 10 "тиков" + dec ecx +; cmp ecx,0 + jz NoMouse + ; Проверить наличие идентификационного байта + mov DX, bx + add DX,5 + in AL,DX + test AL,1 ;Данные готовы? + jz WaitData + ; Ввести данные + mov DX, bx + in AL,DX +NoMouse: + ret + +align 4 +irq3_handler: + mov dx, 0x2f8 + mov esi, com2_mouse + jmp irq_handler + +align 4 +irq4_handler: + mov dx, 0x3f8 + mov esi, com1_mouse + +irq_handler: + +; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h) + add edx, 5 ; xFDh + in al, dx + test al, 1 ; Данные готовы? + jz .Error +; Ввести данные + sub edx, 5 + in al, dx +; Сбросить старший незначащий бит + and al, 01111111b + +; Определить порядковый номер принимаемого байта + cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2 + ja .Error + jz .ThirdByte + jp .SecondByte +; Сохранить первый байт данных +.FirstByte: + test al, 1000000b ; Первый байт посылки? + jz .Error + mov [esi+COM_MOUSE_DATA.FirstByte], al + inc [esi+COM_MOUSE_DATA.MouseByteNumber] + jmp .EndMouseInterrupt +; Сохранить второй байт данных +.SecondByte: + test al, 1000000b + jnz .Error + mov [esi+COM_MOUSE_DATA.SecondByte], al + inc [esi+COM_MOUSE_DATA.MouseByteNumber] + jmp .EndMouseInterrupt +; Сохранить третий байт данных +.ThirdByte: + test al, 1000000b + jnz .Error + mov [esi+COM_MOUSE_DATA.ThirdByte], al + mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 +; (Пакет данных от мыши принят полностью). +; Записать новое значение состояния кнопок мыши + mov al, [esi+COM_MOUSE_DATA.FirstByte] + mov ah, al + shr al, 3 + and al, 2 + shr ah, 5 + and ah, 1 + add al, ah + movzx eax, al + mov [BTN_DOWN], eax + +; Прибавить перемещение по X к координате X + mov al, [esi+COM_MOUSE_DATA.FirstByte] + shl al, 6 + or al, [esi+COM_MOUSE_DATA.SecondByte] + + cbw + movzx eax, ax + mov [MOUSE_X], eax + +; Прибавить перемещение по Y к координате Y + mov al, [esi+COM_MOUSE_DATA.FirstByte] + and al, 00001100b + shl al, 4 + or al, [esi+COM_MOUSE_DATA.ThirdByte] + + cbw + movzx eax, ax + neg eax + mov [MOUSE_Y], eax + + stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0 + + jmp .EndMouseInterrupt + +.Error: +; Произошел сбой в порядке передачи информации от +; мыши, обнулить счетчик байтов пакета данных + + mov [esi+COM_MOUSE_DATA.MouseByteNumber],0 +.EndMouseInterrupt: + + ret + +;all initialized data place here + +align 4 + +struc COM_MOUSE_DATA { +; Номер принимаемого от мыши байта + .MouseByteNumber db ? +; Трехбайтовая структура данных, передаваемая мышью + .FirstByte db ? + .SecondByte db ? + .ThirdByte db ? + ;.timer_ticks_com dd ? +} +virtual at 0 + COM_MOUSE_DATA COM_MOUSE_DATA +end virtual + +com1_mouse COM_MOUSE_DATA +com2_mouse COM_MOUSE_DATA + +MOUSE_X dd 0 +MOUSE_Y dd 0 +BTN_DOWN dd 0 + +COMPortBaseAddr dw 3F8h + + + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +my_service db 'COM_Mouse',0 ;max 16 chars include zero + +if DEBUG +msgInit db 'Preved bugoga!',13,10,0 +boot_setmouse_type db 'Detected - COM1 mouse',13,10,0 + db 'Detected - COM2 mouse',13,10,0 +msg_error_reserve_ports db 'Error reserving ports!',13,10,0 +msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0 +msg_exit db 'Exit!',13,10,0 +end if + +section '.data' data readable writable align 16 + +;all uninitialized data place here + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/ensoniq.asm b/kernel/tags/kolibri0.7.7.0/drivers/ensoniq.asm new file mode 100644 index 000000000..d5fe56fc3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/ensoniq.asm @@ -0,0 +1,1177 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;alpha version + +format MS COFF + +DEBUG equ 1 + + +include 'proc32.inc' +include 'imports.inc' + +REMAP_IRQ equ 0 + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010101000b + +IRQ_LINE equ 0 + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x16 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +OS_BASE equ 0x80000000 +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgDetect + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + + end if + call init_controller + test eax, eax + jz .fail + + jmp .fail ;force fail + + if DEBUG + mov esi, msgInitCodec + call SysMsgBoardStr + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call SysMsgBoardStr + + mov esi, [codec.chip_ids] + call SysMsgBoardStr + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + + call create_primary_buff + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail + + stdcall AttachIntHandler, ebx, ac97_irq, dword 0 + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + stdcall get_master_vol, ebx + ret +;@@: +; cmp eax, DEV_GET_INFO +; jne @F +; mov ebx, [edi+output] +; stdcall get_dev_info, ebx +; ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call SysMsgBoardStr +; end if + + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 ;0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + + mov ebx, 0xC0002000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr ;eax + and ebx, 0xFFF + add eax, ebx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B + +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp ebx, 0x1274 + jne @F + mov [ctrl.vendor_ids], msgEnsoniq + ret +@@: + mov [ctrl.vendor_ids], 0 ;something wrong ? + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc init_controller + + mov esi, msgPCIcmd + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + call dword2str + call SysMsgBoardStr + + mov esi, msgIObase + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 +; and eax, -16 + mov [ctrl.ctrl_io_base], eax + + call dword2str + call SysMsgBoardStr + + mov esi, msgIRQline + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + call dword2str + call SysMsgBoardStr + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_ICH + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + + call dword2str + call SysMsgBoardStr + + test eax, CTRL_ST_CREADY + jnz .ready + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call SysMsgBoardStr + end if + + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if + + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + xor eax, eax + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 1000000 ; wait 1 s + call StallExec + + mov eax, 2 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +play: + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + xor eax, eax + ret + +align 4 +stop: + mov edx, PCM_OUT_CR_REG + mov ax, 0x0 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + xor eax, eax + ret + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +codec_io_r16: + add edx, [ctrl.codec_io_base] + in ax, dx + ret + +align 4 +codec_io_w16: + add edx, [ctrl.codec_io_base] + out dx, ax + ret + +align 4 +ctrl_io_r8: + add edx, [ctrl.ctrl_io_base] + in al, dx + ret + +align 4 +ctrl_io_r16: + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret + +align 4 +ctrl_io_r32: + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret + +align 4 +ctrl_io_w8: + add edx, [ctrl.ctrl_io_base] + out dx, al + ret + +align 4 +ctrl_io_w16: + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret + +align 4 +ctrl_io_w32: + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret + + +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH + dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH + dd 0 ;terminator + +version dd 0x00040004 + +msgEnsoniq db 'Ensonic 1371',13,10,0 +msgVibra128 db 'Sound Blaster AudioPCI Vibra 128',13,10,0 + +sz_sound_srv db 'SOUND',0 + +msgDetect db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 +msgPCIcmd db 'PCI command ',0 +msgIObase db 'IO base ',0 +msgIRQline db 'IRQ line ',0 + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 + + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/imports.inc b/kernel/tags/kolibri0.7.7.0/drivers/imports.inc new file mode 100644 index 000000000..df1ee70f0 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/imports.inc @@ -0,0 +1,89 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +macro kernel_export [name]{ +forward + if used name + if DEBUG + display 'uses: ',`name,#13,#10 + end if + extrn name + end if +} +; all exported kernel functions and data + + +kernel_export \ + RegService,\ + GetService,\ + ServiceHandler,\ + AttachIntHandler,\ + GetIntHandler,\ + FpuSave,\ + FpuRestore,\ + ReservePortArea,\ + Boot_Log,\ +\ + PciApi,\ + PciRead32,\ + PciRead16,\ + PciRead8,\ + PciWrite8,\ + PciWrite16,\ + PciWrite32,\ +\ + AllocPage,\ + AllocPages,\ + FreePage,\ + MapPage,\ + MapSpace,\ + MapIoMem,\ + GetPgAddr,\ + CommitPages,\ + ReleasePages,\ +\ + AllocKernelSpace,\ + FreeKernelSpace,\ + KernelAlloc,\ + KernelFree,\ + UserAlloc,\ + UserFree,\ + Kmalloc,\ + Kfree,\ + CreateRingBuffer,\ +\ + GetPid,\ + CreateObject,\ + DestroyObject,\ + CreateEvent,\ + RaiseEvent,\ + WaitEvent,\ + DestroyEvent,\ + ClearEvent,\ +\ + LoadCursor,\ + SelectHwCursor,\ + SetHwCursor,\ + HwCursorRestore,\ + HwCursorCreate,\ +\ + SysMsgBoardStr,\ + SysMsgBoardChar,\ + GetCurrentTask,\ + LoadFile,\ + SendEvent,\ + SetMouseData,\ + Sleep,\ + GetTimerTicks,\ +\ + strncat,\ + strncpy,\ + strncmp,\ + strnlen,\ + strchr,\ + strrchr,\ +\ + LFBAddress diff --git a/kernel/tags/kolibri0.7.7.0/drivers/infinity.asm b/kernel/tags/kolibri0.7.7.0/drivers/infinity.asm new file mode 100644 index 000000000..bcfbe909d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/infinity.asm @@ -0,0 +1,1306 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Serge 2006-2008 +; email: infinity_sound@mail.ru + +format MS COFF + +DEBUG equ 1 + + +include 'proc32.inc' +include 'main.inc' +include 'imports.inc' + + +CURRENT_API equ 0x0101 ;1.01 +COMPATIBLE_API equ 0x0100 ;1.00 + +API_VERSION equ (COMPATIBLE_API shl 16) or CURRENT_API +SOUND_VERSION equ CURRENT_API + + +FORCE_MMX equ 0 ;set to 1 to force use mmx or +FORCE_MMX_128 equ 0 ;integer sse2 extensions + ;and reduce driver size + +;USE_SSE equ 0 + +USE_SSE2_MIXER equ 0 ;floating point mixer. Disabled by default + +OS_BASE equ 0x80000000 + +CAPS_SSE2 equ 26 +PG_SW equ 0x003 + +public START +public service_proc +public version + +RT_INP_EMPTY equ 0xFF000001 +RT_OUT_EMPTY equ 0xFF000002 +RT_INP_FULL equ 0xFF000003 +RT_OUT_FULL equ 0xFF000004 + +EVENT_WATCHED equ 0x10000000 +EVENT_SIGNALED equ 0x20000000 +MANUAL_RESET equ 0x40000000 +MANUAL_DESTROY equ 0x80000000 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit + + stdcall GetService, szSound + test eax, eax + jz .fail + mov [hSound], eax + + stdcall KernelAlloc, 16*512 + test eax, eax + jz .out_of_mem + mov [mix_buff], eax + + mov eax, str.fd-FD_OFFSET + mov [str.fd], eax + mov [str.bk], eax + +if FORCE_MMX + if FORCE_MMX_128 + display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 + stop + end if + mov [mix_2_core], mmx_mix_2 + mov [mix_3_core], mmx_mix_3 + mov [mix_4_core], mmx_mix_4 +end if + +if FORCE_MMX_128 + if FORCE_MMX + display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 + stop + end if + mov [mix_2_core], mmx128_mix_2 + mov [mix_3_core], mmx128_mix_3 + mov [mix_4_core], mmx128_mix_4 +end if + +if 0 + +if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect + mov eax, 1 + cpuid + bt edx, CAPS_SSE2 + jc .mmx128 + ;old 64-bit mmx + mov [mix_2_core], mmx_mix_2 + mov [mix_3_core], mmx_mix_3 + mov [mix_4_core], mmx_mix_4 + jmp @F +.mmx128: ;128-bit integer sse2 extensions + mov [mix_2_core], mmx128_mix_2 + mov [mix_3_core], mmx128_mix_3 + mov [mix_4_core], mmx128_mix_4 +@@: +end if + +end if + stdcall set_handler, [hSound], new_mix + mov [eng_state], SND_STOP + stdcall RegService, szInfinity, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if +.exit: + xor eax, eax + ret + +.out_of_mem: + if DEBUG + mov esi, msgMem + call SysMsgBoardStr + end if + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + + cmp eax, SRV_GETVERSION + jne @F + mov eax, [edi+output] + cmp [edi+out_size], 4 + jne .fail + mov eax, [eax] + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: + cmp eax, SND_CREATE_BUFF + jne @F + mov ebx, [edi+input] + stdcall CreateBuffer,[ebx],[ebx+4] + mov edi, [ioctl] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx], ebx + ret +@@: + mov ebx, [edi+input] + mov edx, [ebx] + + cmp [edx+STREAM.magic], 'WAVE' + jne .fail + + cmp [edx+STREAM.size], STREAM_SIZE + jne .fail + + cmp eax, SND_DESTROY_BUFF + jne @F + mov eax, edx + call DestroyBuffer ;edx= stream + ret +@@: + cmp eax, SND_SETFORMAT + jne @F + stdcall SetFormat,edx,[ebx+4] + ret +@@: + cmp eax, SND_GETFORMAT + jne @F + + movzx eax, word [edx+STREAM.format] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx], eax + xor eax, eax + ret +@@: + cmp eax, SND_RESET + jne @F + stdcall ResetBuffer,edx,[ebx+4] + ret +@@: + cmp eax, SND_SETPOS + jne @F + stdcall SetBufferPos,edx,[ebx+4] + ret +@@: + cmp eax, SND_GETPOS + jne @F + stdcall GetBufferPos, edx + mov edi, [ioctl] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx], ebx + ret +@@: + cmp eax, SND_SETBUFF + jne @F + mov eax, [ebx+4] + stdcall set_buffer, edx,eax,[ebx+8],[ebx+12] + ret +@@: + cmp eax, SND_SETVOLUME + jne @F + stdcall SetBufferVol,edx,[ebx+4],[ebx+8] + ret +@@: + cmp eax, SND_GETVOLUME + jne @F + + mov eax, [edi+output] + mov ecx, [eax] + mov eax, [eax+4] + stdcall GetBufferVol,edx,ecx,eax + ret +@@: + cmp eax, SND_SETPAN + jne @F + stdcall SetBufferPan,edx,[ebx+4] + ret +@@: + cmp eax, SND_GETPAN + jne @F + mov eax, [edx+STREAM.pan] + mov ebx, [edi+output] + mov ebx, [ebx] + mov [ebx], eax + xor eax, eax + ret +@@: + cmp eax, SND_OUT + jne @F + + mov eax, [ebx+4] + stdcall wave_out, edx,eax,[ebx+8] + ret +@@: + cmp eax, SND_PLAY + jne @F + + stdcall play_buffer, edx,[ebx+4] + ret +@@: + cmp eax, SND_STOP + jne @F + + stdcall stop_buffer, edx + ret +@@: + cmp eax, SND_GETBUFFSIZE + jne @F + mov eax, [edx+STREAM.in_size] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx], eax + xor eax, eax + ret +@@: + cmp eax, SND_GETFREESPACE + jne @F + + test [edx+STREAM.format], PCM_OUT + jz .fail + + mov ebx, [edx+STREAM.in_free] + mov ecx, [edi+output] + mov [ecx], ebx + xor eax, eax + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc CreateBuffer stdcall, format:dword, size:dword + locals + str dd ? + ring_size dd ? + ring_pages dd ? + endl + + mov eax, [format] + cmp ax, PCM_1_8_8 + ja .fail + + test eax, PCM_OUT + jnz .test_out + test eax, PCM_RING + jnz .test_ring +;staic + test eax, PCM_STATIC + jz .test_out ;use PCM_OUT as default format + jmp .test_ok +.test_out: + test eax, PCM_RING+PCM_STATIC + jnz .fail + or [format], PCM_OUT ;force set + jmp .test_ok +.test_ring: + test eax, PCM_OUT+PCM_STATIC + jnz .fail +.test_ok: + + call GetPid + mov ebx, eax + mov eax, STREAM_SIZE + + call CreateObject + test eax, eax + jz .fail + mov [str], eax + + mov ebx, [format] + mov [eax+STREAM.format], ebx + + xor ecx, ecx + movzx ebx, bx + cmp ebx, 19 + jb @f + mov ecx, 0x80808080 +@@: + mov [eax+STREAM.r_silence], ecx + + shl ebx, 2 + lea ebx, [ebx+ebx*2] ;ebx*=12 + + mov ecx, [resampler_params+ebx] + mov edx, [resampler_params+ebx+4] + mov esi, [resampler_params+ebx+8] + + mov [eax+STREAM.r_size],ecx + mov [eax+STREAM.r_dt], edx + mov [eax+STREAM.resample], esi + xor ecx, ecx + mov [eax+STREAM.l_vol], ecx + mov [eax+STREAM.r_vol], ecx + mov dword [eax+STREAM.l_amp], 0x7FFF7FFF + mov [eax+STREAM.pan], ecx + + test [format], PCM_STATIC + jnz .static + +; ring and waveout + + mov ebx, 0x10000 + test [format], PCM_RING + jz .waveout + + mov ebx, [eax+STREAM.r_size] + add ebx, 4095 + and ebx, -4096 + add ebx, ebx +.waveout: + mov [ring_size], ebx + mov eax, ebx + shr ebx, 12 + mov [ring_pages], ebx + + stdcall CreateRingBuffer, eax, PG_SW + + mov edi, [str] + mov ecx, [ring_size] + mov [edi+STREAM.in_base], eax + mov [edi+STREAM.in_size], ecx + add eax, 128 + ; sub ecx, 128 + mov [edi+STREAM.in_wp], eax + mov [edi+STREAM.in_rp], eax + mov [edi+STREAM.in_count], 0 + + mov [edi+STREAM.in_free], ecx + add eax, ecx + mov [edi+STREAM.in_top], eax + + jmp .out_buff +.static: + mov ecx, [size] + add ecx, 128 ;resampler required + mov [eax+STREAM.in_size], ecx + stdcall KernelAlloc, ecx + + mov edi, [str] + mov [edi+STREAM.in_base], eax + add eax, 128 + mov [edi+STREAM.in_wp], eax + mov [edi+STREAM.in_rp], eax + mov ebx, [size] + mov [edi+STREAM.in_count], ebx + mov [edi+STREAM.in_free], ebx + add eax, ebx + mov [edi+STREAM.in_top], eax + +.out_buff: + stdcall AllocKernelSpace, dword 128*1024 + + mov edi, [str] + mov [edi+STREAM.out_base], eax + mov [edi+STREAM.out_wp], eax + mov [edi+STREAM.out_rp], eax + mov [edi+STREAM.out_count], 0 + add eax, 64*1024 + mov [edi+STREAM.out_top], eax + + stdcall AllocPages, dword 64/4 + mov edi, [str] + mov ebx, [edi+STREAM.out_base] + mov ecx, 16 + or eax, PG_SW + push eax + push ebx + call CommitPages ;eax, ebx, ecx + mov ecx, 16 + pop ebx + pop eax + add ebx, 64*1024 + call CommitPages ;double mapped + + mov edi, [str] + mov ecx, [edi+STREAM.in_top] + mov edi, [edi+STREAM.in_base] + sub ecx, edi + xor eax, eax + shr ecx, 2 + cld + rep stosd + + mov edi, [str] + mov edi, [edi+STREAM.out_base] + mov ecx, (64*1024)/4 + rep stosd + + xor esi, esi + mov ecx, MANUAL_DESTROY + call CreateEvent + + mov ebx, [str] + mov [ebx+STREAM.notify_event], eax + mov [ebx+STREAM.notify_id], edx + + mov [ebx+STREAM.magic], 'WAVE' + mov [ebx+STREAM.destroy], DestroyBuffer.destroy + mov [ebx+STREAM.size], STREAM_SIZE + mov [ebx+STREAM.flags], SND_STOP + + pushf + cli + mov eax, str.fd-FD_OFFSET + mov edx, [eax+STREAM.str_fd] + mov [ebx+STREAM.str_fd], edx + mov [ebx+STREAM.str_bk], eax + mov [eax+STREAM.str_fd], ebx + mov [edx+STREAM.str_bk], ebx + popf + + xor eax, eax + ret +.fail: + xor ebx, ebx + or eax, -1 + ret +endp + +;param +; eax= buffer handle + +align 4 +DestroyBuffer: + .handle equ esp ;local + + mov [eax+STREAM.flags], SND_STOP +.destroy: + push eax + + pushfd + cli + mov ebx, [eax+STREAM.str_fd] + mov ecx, [eax+STREAM.str_bk] + mov [ebx+STREAM.str_bk], ecx + mov [ecx+STREAM.str_fd], ebx + popf + + stdcall KernelFree, [eax+STREAM.in_base] + mov eax, [.handle] + stdcall KernelFree, [eax+STREAM.out_base] + + pop eax ;restore stack + call DestroyObject ;eax= stream + xor eax, eax + ret +.fail: + or eax, -1 + ret +restore .handle + +align 4 +proc SetFormat stdcall, str:dword, format:dword + + cmp word [format], PCM_1_8_8 + ja .fail + + mov edx, [str] + mov [edx+STREAM.flags], SND_STOP + + test [edx+STREAM.format], PCM_RING + jnz .fail + +; mov eax,[edx+STREAM.out_base] +; mov [edx+STREAM.out_wp], eax +; mov [edx+STREAM.out_rp], eax +; mov [edx+STREAM.out_count], 0 + + movzx eax, word [format] + mov word [edx+STREAM.format], ax + + xor ebx, ebx + cmp eax, 19 + jb @f + mov ebx, 0x80808080 +@@: + mov [edx+STREAM.r_silence], ebx + + shl eax, 2 + lea eax, [eax+eax*2] ;eax*=12 + + mov edi, [resampler_params+eax] + mov ecx, [resampler_params+eax+4] + mov ebx, [resampler_params+eax+8] + + mov [edx+STREAM.r_size],edi + mov [edx+STREAM.r_dt], ecx + mov [edx+STREAM.resample], ebx + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; for static buffers only +; use waveout for streams + +align 4 +proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_OUT + jnz .fail + + mov esi, [src] + mov edi, [offs] + add edi, [edx+STREAM.in_base] + add edi, 128 + + cmp edi, [edx+STREAM.in_top] + jae .fail + + mov ecx, [size] + lea ebx, [ecx+edi] + sub ebx, [edx+STREAM.in_top] + jb @F + sub ecx, ebx +@@: + shr ecx, 2 + cld + rep movsd + xor eax,eax + ret +.fail: + or eax, -1 + ret +endp + +; for stream buffers only + +align 4 +proc wave_out stdcall, str:dword,src:dword,size:dword + locals + state_saved dd ? + fpu_state rb 528 + endl + + mov edx, [str] + mov eax, [edx+STREAM.format] + test eax, PCM_OUT + jz .fail + + cmp ax, PCM_ALL + je .fail + + mov esi,[src] + test esi, esi + jz .fail + + cmp esi, OS_BASE + jae .fail + + mov [state_saved], 0 + +.main_loop: + mov edx, [str] + + mov ebx, [size] + test ebx, ebx + jz .done + + cmp [edx+STREAM.flags], SND_STOP + jne .fill + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + + mov ecx, [edx+STREAM.in_size] + sub ecx, 128 + mov [edx+STREAM.in_wp], edi + mov [edx+STREAM.in_rp], edi + mov [edx+STREAM.in_count], 0 + mov [edx+STREAM.in_free], ecx + + mov eax,[edx+STREAM.out_base] + mov [edx+STREAM.out_wp], eax + mov [edx+STREAM.out_rp], eax + mov [edx+STREAM.out_count], 0 +.fill: + cli + + mov ecx, [edx+STREAM.in_free] + test ecx, ecx + jz .wait + + cmp ecx, ebx + jbe @F + + mov ecx, ebx +@@: + sub [size], ecx + add [edx+STREAM.in_count], ecx + sub [edx+STREAM.in_free], ecx + + shr ecx, 2 + mov edi, [edx+STREAM.in_wp] + mov esi, [src] + cld + rep movsd + + mov [src], esi + cmp edi, [edx+STREAM.in_top] + jb @F + sub edi, [edx+STREAM.in_size] +@@: + mov [edx+STREAM.in_wp], edi + + cmp [edx+STREAM.out_count], 32768 + jae .skip + + cmp [state_saved], 0 + jne @F + lea eax, [fpu_state+15] + and eax, -16 + call FpuSave + mov [state_saved], 1 +@@: + stdcall refill, edx + +.skip: + sti + mov edx, [str] + mov [edx+STREAM.flags], SND_PLAY + cmp [eng_state], SND_PLAY + je .main_loop + + stdcall dev_play, [hSound] + mov [eng_state], SND_PLAY + jmp .main_loop +.wait: + sti + mov edx, [str] + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call WaitEvent ;eax ebx + jmp .main_loop +.done: + cmp [state_saved], 1 + jne @F + + lea eax, [fpu_state+15] + and eax, -16 + call FpuRestore +@@: + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; both static and stream +; reset all but not clear buffers + + +; flags reserved +; RESET_INPUT equ 1 ;reserved reset and clear input buffer +; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer +; RESET_ALL equ 3 + + +align 4 +proc ResetBuffer stdcall, str:dword, flags:dword + + mov edx, [str] + mov [edx+STREAM.flags], SND_STOP + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + + mov [edx+STREAM.in_wp], edi + mov [edx+STREAM.in_rp], edi + + test [edx+STREAM.flags], PCM_STATIC + jnz .static + mov [edx+STREAM.in_count], 0 + jmp @F +.static: + mov eax, [edx+STREAM.in_size] + mov [edx+STREAM.in_count], eax +@@: + + mov eax, [edx+STREAM.in_size] + sub eax, 128 + mov [edx+STREAM.in_free], eax + + xor eax, eax + mov ebx,[edx+STREAM.out_base] + mov [edx+STREAM.out_wp], ebx + mov [edx+STREAM.out_rp], ebx + mov [edx+STREAM.out_count], eax + ret +.fail: + or eax, -1 + ret +endp + +; for static buffers only + +align 4 +proc SetBufferPos stdcall, str:dword, pos:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_STATIC + jz .fail + + mov [edx+STREAM.flags], SND_STOP + + mov eax, [pos] + add eax, [edx+STREAM.in_base] + mov ebx, [edx+STREAM.in_top] + add eax, 128 + + cmp eax, ebx + jae .fail + + mov [edx+STREAM.in_rp], eax + sub ebx, eax + mov [edx+STREAM.in_count], ebx + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +align 4 +proc GetBufferPos stdcall, str:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_STATIC + jz .fail + + mov ebx, [edx+STREAM.in_rp] + sub ebx, [edx+STREAM.in_base] + sub ebx, 128 + xor eax, eax + ret +.fail: + xor ebx,ebx + or eax, -1 + ret +endp + +; both + +align 4 +proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword + + mov edx, [str] + stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan] + ret +endp + +proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword + locals + _600 dd ? + _32767 dd ? + state rb 108 + endl + + mov [_600], 0x44160000 ;600.0 + mov [_32767], 32767 + + lea ebx, [state] + fnsave [ebx] + + movq mm0, qword [l_vol] + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movq qword [l_vol], mm0 + movq qword [edx+STREAM.l_vol], mm0 + + movd mm1,[pan] + pminsw mm1, qword [pan_max] + pmaxsw mm1, qword [vol_min] + movd [edx+STREAM.pan], mm1 + + cmp word [edx+STREAM.pan], 0 + jl @F + + psubsw mm0,mm1 + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movd [l_vol],mm0 + jmp .calc_amp +@@: + punpckhdq mm0,mm0 + paddsw mm0,mm1 + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movd [r_vol], mm0 +.calc_amp: + emms + fild word [l_vol] + + call .calc + + fistp word [edx+STREAM.l_amp] + fstp dword [edx+STREAM.l_amp_f] + fstp st0 + + fild word [r_vol] + + call .calc + + fistp word [edx+STREAM.r_amp] + fstp dword [edx+STREAM.r_amp_f] + fstp st0 + + fnclex + lea ebx, [state] + frstor [ebx] + + xor eax, eax + inc eax + ret +.calc: + fdiv dword [_600] + fld st0 + frndint + fxch st1 + fsub st, st1 + f2xm1 + fld1 + faddp st1, st0 + fscale + fld st0 + fimul dword [_32767] + ret 0 +endp + +align 4 +proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword + + mov edx, [str] + mov eax, [p_lvol] + movsx ecx, word [edx+STREAM.l_vol] + mov [eax], ecx + + mov eax, [p_rvol] + movsx ecx, word [edx+STREAM.r_vol] + mov [eax], ecx + xor eax, eax + ret +endp + +align 4 +proc SetBufferPan stdcall, str:dword,pan:dword + + mov edx, [str] + stdcall set_vol_param,[edx+STREAM.l_vol],\ + [edx+STREAM.r_vol],[pan] + ret +endp + +; for static and ring buffers only + +align 4 +proc play_buffer stdcall, str:dword, flags:dword + + mov ebx, [str] + mov eax, [ebx+STREAM.format] + test eax, PCM_OUT + jnz .fail + + cmp ax, PCM_ALL + je .fail + + mov [ebx+STREAM.flags], SND_PLAY + cmp [eng_state], SND_PLAY + je .done + + stdcall dev_play, [hSound] + mov [eng_state], SND_PLAY +.done: + test [flags], PLAY_SYNC + jz @F + + mov edx, [str] +.wait: + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call WaitEvent ;eax ebx + + mov edx, [str] + cmp [edx+STREAM.flags], SND_STOP + jne .wait +@@: + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; for static and ring buffers only + +align 4 +proc stop_buffer stdcall, str:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_STATIC+PCM_RING + jz .fail + + mov [edx+STREAM.flags], SND_STOP + +; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 + + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call ClearEvent ;eax ebx + + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; param +; eax= mix_list + +align 4 +do_mix_list: + + xor edx, edx + mov esi, str.fd-FD_OFFSET + mov ebx, [esi+STREAM.str_fd] +@@: + cmp ebx, esi + je .done + + cmp [ebx+STREAM.magic], 'WAVE' + jne .next + + cmp [ebx+STREAM.size], STREAM_SIZE + jne .next + + cmp [ebx+STREAM.flags], SND_PLAY; + jne .next + + mov ecx, [ebx+STREAM.out_count] + test ecx, ecx + jnz .l1 + + test [ebx+STREAM.format], PCM_RING + jnz .next + mov [ebx+STREAM.flags], SND_STOP + jmp .next +.l1: + cmp ecx, 512 + jae .add_buff + + mov edi, [ebx+STREAM.out_rp] + add edi, ecx + sub ecx, 512 + neg ecx + push eax + xor eax, eax + cld + rep stosb + pop eax + + mov [ebx+STREAM.out_count], 512 + +.add_buff: + mov ecx, [ebx+STREAM.out_rp] + mov [eax],ecx + +if USE_SSE2_MIXER + mov edi, dword [ebx+STREAM.l_amp_f] + mov [eax+4], edi + mov edi, dword [ebx+STREAM.r_amp_f] + mov [eax+8], edi +else + mov edi, dword [ebx+STREAM.l_amp] + mov [eax+4], edi +end if + add [ebx+STREAM.out_rp], 512 + sub [ebx+STREAM.out_count], 512 + + add eax, 12 + inc edx +.next: + mov ebx, [ebx+STREAM.str_fd] + jmp @B +.done: + mov eax, edx + ret + +align 4 +prepare_playlist: + + xor edx, edx + mov [play_count], edx + mov esi, str.fd-FD_OFFSET + mov edi, [esi+STREAM.str_fd] +@@: + cmp edi, esi + je .done + + cmp [edi+STREAM.magic], 'WAVE' + jne .next + + cmp [edi+STREAM.size], STREAM_SIZE + jne .next + + cmp [edi+STREAM.flags], SND_PLAY; + jne .next + + mov [play_list+edx], edi + inc [play_count] + add edx, 4 +.next: + mov edi, [edi+STREAM.str_fd] + jmp @B +.done: + ret + +align 4 +proc set_handler stdcall, hsrv:dword, handler_proc:dword + locals + handler dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + lea ecx, [handler_proc] + xor ebx, ebx + + mov [handler], eax + mov [io_code], DEV_CALLBACK + mov [input], ecx + mov [inp_size], 4 + mov [output], ebx + mov [out_size], 0 + + lea eax, [handler] + stdcall ServiceHandler, eax + ret +endp + +align 4 +proc dev_play stdcall, hsrv:dword + locals + handle dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + xor ebx, ebx + + mov [handle], eax + mov [io_code], DEV_PLAY + mov [input], ebx + mov [inp_size], ebx + mov [output], ebx + mov [out_size], ebx + + lea eax, [handle] + stdcall ServiceHandler, eax + ret +endp + +if 0 +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + +end if + +include 'mixer.asm' +include 'mix_mmx.inc' +include 'mix_sse2.inc' + +;if USE_SSE +; include 'mix_sse.inc' +;end if + +align 16 +resampler_params: + ;r_size r_dt resampler_func + dd 0,0,0 ; 0 PCM_ALL + dd 16384, 0, copy_stream ; 1 PCM_2_16_48 + dd 8192, 0, m16_stereo ; 2 PCM_1_16_48 + + dd 16384, 30109, resample_2 ; 3 PCM_2_16_44 + dd 8192, 30109, resample_1 ; 4 PCM_1_16_44 + + dd 16384, 21846, resample_2 ; 5 PCM_2_16_32 + dd 8192, 21846, resample_1 ; 6 PCM_1_16_32 + + dd 16384, 16384, resample_2 ; 7 PCM_2_16_24 + dd 8192, 16384, resample_1 ; 8 PCM_1_16_24 + + dd 8192, 15052, resample_2 ; 9 PCM_2_16_22 + dd 4096, 15052, resample_1 ;10 PCM_1_16_22 + + dd 8192, 10923, resample_2 ;11 PCM_2_16_16 + dd 4096, 10923, resample_1 ;12 PCM_1_16_16 + + dd 8192, 8192, resample_2 ;13 PCM_2_16_12 + dd 4096, 8192, resample_1 ;14 PCM_1_16_12 + + dd 4096, 7527, resample_2 ;15 PCM_2_16_11 + dd 2048, 7527, resample_1 ;16 PCM_1_16_11 + + dd 4096, 5462, resample_2 ;17 PCM_2_16_8 + dd 2048, 5462, resample_1 ;18 PCM_1_16_8 + + dd 16384, 0, s8_stereo ;19 PCM_2_8_48 + dd 8192, 0, m8_stereo ;20 PCM_1_8_48 + + dd 8192, 30109, resample_28 ;21 PCM_2_8_44 + dd 4096, 30109, resample_18 ;22 PCM_1_8_44 + + dd 8192, 21846, resample_28 ;23 PCM_2_8_32 + dd 4096, 21846, resample_18 ;24 PCM_1_8_32 + + dd 8192, 16384, resample_28 ;25 PCM_2_8_24 + dd 4096, 16384, resample_18 ;26 PCM_1_8_24 + + dd 4096, 15052, resample_28 ;27 PCM_2_8_22 + dd 2048, 15052, resample_18 ;28 PCM_1_8_22 + + dd 4096, 10923, resample_28 ;29 PCM_2_8_16 + dd 2048, 10923, resample_18 ;30 PCM_1_8_16 + + dd 4096, 8192, resample_28 ;31 PCM_2_8_12 + dd 2048, 8192, resample_18 ;32 PCM_1_8_12 + + dd 2048, 7527, resample_28 ;33 PCM_2_8_11 + dd 1024, 7527, resample_18 ;34 PCM_1_8_11 + + dd 2048, 5462, resample_28 ;35 PCM_2_8_8 + dd 1024, 5462, resample_18 ;36 PCM_1_8_8 + +m7 dw 0x8000,0x8000,0x8000,0x8000 +mm80 dq 0x8080808080808080 +mm_mask dq 0xFF00FF00FF00FF00 + +vol_max dd 0x00000000,0x00000000 +vol_min dd 0x0000D8F0,0x0000D8F0 +pan_max dd 0x00002710,0x00002710 + +;stream_map dd 0xFFFF ; 16 +version dd (5 shl 16) or SOUND_VERSION + +szInfinity db 'INFINITY',0 +szSound db 'SOUND',0 + +if DEBUG +msgFail db 'Sound service not loaded',13,10,0 +msgPlay db 'Play buffer',13,10,0 +msgStop db 'Stop',13,10,0 +msgUser db 'User callback',13,10,0 +msgMem db 'Not enough memory',13,10,0 +msgDestroy db 'Destroy sound buffer', 13,10,0 +msgWaveout db 'Play waveout', 13,10,0 +msgSetVolume db 'Set volume',13,10,0 +end if + +section '.data' data readable writable align 16 + +play_list rd 16 +mix_input rd 16 +play_count rd 1 +hSound rd 1 +eng_state rd 1 +mix_buff rd 1 +mix_buff_map rd 1 +str.fd rd 1 +str.bk rd 1 + +mix_2_core rd 1 +mix_3_core rd 1 +mix_4_core rd 1 diff --git a/kernel/tags/kolibri0.7.7.0/drivers/main.inc b/kernel/tags/kolibri0.7.7.0/drivers/main.inc new file mode 100644 index 000000000..67198c304 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/main.inc @@ -0,0 +1,164 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Serge 2006-2008 +; email: infinity_sound@mail.ru + + +PLAY_SYNC equ 0x80000000 + +PCM_ALL equ 0 + +PCM_OUT equ 0x08000000 +PCM_RING equ 0x10000000 +PCM_STATIC equ 0x20000000 +PCM_FLOAT equ 0x40000000 ;reserved +PCM_FILTER equ 0x80000000 ;reserved + +PCM_2_16_48 equ 1 +PCM_1_16_48 equ 2 + +PCM_2_16_44 equ 3 +PCM_1_16_44 equ 4 + +PCM_2_16_32 equ 5 +PCM_1_16_32 equ 6 + +PCM_2_16_24 equ 7 +PCM_1_16_24 equ 8 + +PCM_2_16_22 equ 9 +PCM_1_16_22 equ 10 + +PCM_2_16_16 equ 11 +PCM_1_16_16 equ 12 + +PCM_2_16_12 equ 13 +PCM_1_16_12 equ 14 + +PCM_2_16_11 equ 15 +PCM_1_16_11 equ 16 + +PCM_2_16_8 equ 17 +PCM_1_16_8 equ 18 + +PCM_2_8_48 equ 19 +PCM_1_8_48 equ 20 + +PCM_2_8_44 equ 21 +PCM_1_8_44 equ 22 + +PCM_2_8_32 equ 23 +PCM_1_8_32 equ 24 + +PCM_2_8_24 equ 25 +PCM_1_8_24 equ 26 + +PCM_2_8_22 equ 27 +PCM_1_8_22 equ 28 + +PCM_2_8_16 equ 29 +PCM_1_8_16 equ 30 + +PCM_2_8_12 equ 31 +PCM_1_8_12 equ 32 + +PCM_2_8_11 equ 33 +PCM_1_8_11 equ 34 + +PCM_2_8_8 equ 35 +PCM_1_8_8 equ 36 + +SRV_GETVERSION equ 0 +SND_CREATE_BUFF equ 1 +SND_DESTROY_BUFF equ 2 +SND_SETFORMAT equ 3 +SND_GETFORMAT equ 4 +SND_RESET equ 5 +SND_SETPOS equ 6 +SND_GETPOS equ 7 +SND_SETBUFF equ 8 +SND_OUT equ 9 +SND_PLAY equ 10 +SND_STOP equ 11 +SND_SETVOLUME equ 12 +SND_GETVOLUME equ 13 +SND_SETPAN equ 14 +SND_GETPAN equ 15 +SND_GETBUFFSIZE equ 16 +SND_GETFREESPACE equ 17 + +struc STREAM +{ + .magic dd ? ;'WAVE' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .size dd ? + .str_fd dd ? + .str_bk dd ? + .device dd ? + .format dd ? + .flags dd ? + + .out_base dd ? + .out_wp dd ? + .out_rp dd ? + .out_count dd ? + .out_top dd ? ;16*4 + + .r_size dd ? + .r_dt dd ? + .r_silence dd ? + .resample dd ? + .l_vol dd ? + .r_vol dd ? + .l_amp dw ? + .r_amp dw ? + .pan dd ? + .l_amp_f dd ? ;float point left + .r_amp_f dd ? ;float point right + + .in_base dd ? + .in_size dd ? + .in_wp dd ? + .in_rp dd ? + .in_count dd ? + .in_free dd ? + .in_top dd ? + + .notify_event dd ? + .notify_id dd ? +} + +STREAM_SIZE equ 36*4 +FD_OFFSET equ 24 + +virtual at 0 + STREAM STREAM +end virtual + +struc WAVE_HEADER +{ .riff_id dd ? + .riff_size dd ? + .riff_format dd ? + + .fmt_id dd ? + .fmt_size dd ? + .format_tag dw ? + .channels dw ? + .freq dd ? + .bytes_sec dd ? + .block_align dw ? + .bits_sample dw ? + + .data_id dd ? + .data_size dd ? +} + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/mix_mmx.inc b/kernel/tags/kolibri0.7.7.0/drivers/mix_mmx.inc new file mode 100644 index 000000000..5778cc823 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/mix_mmx.inc @@ -0,0 +1,247 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; params +; edi= output +; eax= input stream 1 +; ebx= input stream 2 + +if used mmx_mix_2 + +align 4 +mmx_mix_2: + movq mm0, [eax] + movq mm1, [eax+8] + movq mm2, [eax+16] + movq mm3, [eax+24] + movq mm4, [eax+32] + movq mm5, [eax+40] + movq mm6, [eax+48] + movq mm7, [eax+56] + + paddsw mm0, [ebx] + movq [edi], mm0 + paddsw mm1,[ebx+8] + movq [edi+8], mm1 + paddsw mm2, [ebx+16] + movq [edi+16], mm2 + paddsw mm3, [ebx+24] + movq [edi+24], mm3 + paddsw mm4, [ebx+32] + movq [edi+32], mm4 + paddsw mm5, [ebx+40] + movq [edi+40], mm5 + paddsw mm6, [ebx+48] + movq [edi+48], mm6 + paddsw mm7, [ebx+56] + movq [edi+56], mm7 + + movq mm0, [eax+64] + movq mm1, [eax+72] + movq mm2, [eax+80] + movq mm3, [eax+88] + movq mm4, [eax+96] + movq mm5, [eax+104] + movq mm6, [eax+112] + movq mm7, [eax+120] + + paddsw mm0, [ebx+64] + movq [edi+64], mm0 + paddsw mm1, [ebx+72] + movq [edi+72], mm1 + paddsw mm2, [ebx+80] + movq [edi+80], mm2 + paddsw mm3, [ebx+88] + movq [edi+88], mm3 + paddsw mm4, [ebx+96] + movq [edi+96], mm4 + paddsw mm5, [ecx+104] + movq [edx+104], mm5 + paddsw mm6, [ebx+112] + movq [edi+112], mm6 + paddsw mm7, [ebx+120] + movq [edi+120], mm7 + ret + +align 4 +mmx_mix_3: + movq mm0, [eax] + movq mm1, [eax+8] + movq mm2, [eax+16] + movq mm3, [eax+24] + movq mm4, [eax+32] + movq mm5, [eax+40] + movq mm6, [eax+48] + movq mm7, [eax+56] + + paddsw mm0, [ebx] + paddsw mm1, [ebx+8] + paddsw mm2, [ebx+16] + paddsw mm3, [ebx+24] + paddsw mm4, [ebx+32] + paddsw mm5, [ebx+40] + paddsw mm6, [ebx+48] + paddsw mm7, [ebx+56] + paddsw mm0, [ecx] + movq [edi], mm0 + paddsw mm1,[ecx+8] + movq [edi+8], mm1 + paddsw mm2, [ecx+16] + movq [edi+16], mm2 + paddsw mm3, [ecx+24] + movq [edi+24], mm3 + paddsw mm4, [ecx+32] + movq [edi+32], mm4 + paddsw mm5, [ecx+40] + movq [edi+40], mm5 + paddsw mm6, [ecx+48] + movq [edi+48], mm6 + paddsw mm7, [ecx+56] + movq [edi+56], mm7 + + movq mm0, [eax+64] + movq mm1, [eax+72] + movq mm2, [eax+80] + movq mm3, [eax+88] + movq mm4, [eax+96] + movq mm5, [eax+104] + movq mm6, [eax+112] + movq mm7, [eax+120] + paddsw mm0, [ebx+64] + paddsw mm1, [ebx+72] + paddsw mm2, [ebx+80] + paddsw mm3, [ebx+88] + paddsw mm4, [ebx+96] + paddsw mm5, [ebx+104] + paddsw mm6, [ebx+112] + paddsw mm7, [ebx+120] + paddsw mm0, [ecx+64] + movq [edi+64], mm0 + paddsw mm1, [ecx+72] + movq [edi+72], mm1 + paddsw mm2, [ecx+80] + movq [edi+80], mm2 + paddsw mm3, [ecx+88] + movq [edi+88], mm3 + paddsw mm4, [ecx+96] + movq [edi+96], mm4 + paddsw mm5, [ecx+104] + movq [edi+104], mm5 + paddsw mm6, [ecx+112] + movq [edi+112], mm6 + paddsw mm7, [ecx+120] + movq [edi+120], mm7 + ret + +align 4 +mmx_mix_4: + + movq mm0, [eax] + movq mm2, [eax+8] + movq mm4, [eax+16] + movq mm6, [eax+24] + movq mm1, [ebx] + movq mm3, [ebx+8] + movq mm5, [ebx+16] + movq mm7, [ebx+24] + paddsw mm0, [ecx] + paddsw mm2, [ecx+8] + paddsw mm4, [ecx+16] + paddsw mm6, [ecx+24] + paddsw mm1, [edx] + paddsw mm3, [edx+8] + paddsw mm5, [edx+16] + paddsw mm7, [edx+24] + + paddsw mm0, mm1 + movq [edi], mm0 + paddsw mm2, mm3 + movq [edi+8], mm2 + paddsw mm4, mm5 + movq [edi+16], mm4 + paddsw mm5, mm6 + movq [edi+24], mm6 + + movq mm0, [eax+32] + movq mm2, [eax+40] + movq mm4, [eax+48] + movq mm6, [eax+56] + movq mm1, [ebx+32] + movq mm3, [ebx+40] + movq mm5, [ebx+48] + movq mm7, [ebx+56] + paddsw mm0, [ecx+32] + paddsw mm2, [ecx+40] + paddsw mm4, [ecx+48] + paddsw mm6, [ecx+56] + paddsw mm1, [edx+32] + paddsw mm3, [edx+40] + paddsw mm5, [edx+48] + paddsw mm7, [edx+56] + + paddsw mm0, mm1 + movq [edi+32], mm0 + paddsw mm2, mm2 + movq [edi+40], mm2 + paddsw mm4, mm5 + movq [edi+48], mm4 + paddsw mm6, mm7 + movq [edi+56], mm6 + + movq mm0, [eax+64] + movq mm2, [eax+72] + movq mm4, [eax+80] + movq mm6, [eax+88] + movq mm1, [ebx+64] + movq mm3, [ebx+72] + movq mm5, [ebx+80] + movq mm7, [ebx+88] + paddsw mm0, [ecx+64] + paddsw mm2, [ecx+72] + paddsw mm4, [ecx+80] + paddsw mm6, [ecx+88] + paddsw mm1, [edx+64] + paddsw mm3, [edx+72] + paddsw mm5, [edx+80] + paddsw mm7, [edx+88] + + paddsw mm0, mm1 + movq [edi+64], mm0 + paddsw mm2, mm3 + movq [edi+72], mm2 + paddsw mm4, mm5 + movq [edi+80], mm4 + paddsw mm6, mm5 + movq [edi+88], mm7 + + movq mm0, [eax+96] + movq mm2, [eax+104] + movq mm4, [eax+112] + movq mm6, [eax+120] + movq mm1, [ebx+96] + movq mm3, [ebx+104] + movq mm5, [ebx+112] + movq mm7, [ebx+120] + paddsw mm0, [ecx+96] + paddsw mm2, [ecx+104] + paddsw mm4, [ecx+112] + paddsw mm6, [ecx+120] + paddsw mm1, [edx+96] + paddsw mm3, [edx+104] + paddsw mm5, [edx+112] + paddsw mm7, [edx+120] + paddsw mm0, mm1 + movq [eax+96], mm0 + paddsw mm2, mm3 + movq [edi+104], mm2 + paddsw mm4, mm5 + movq [edi+112], mm4 + paddsw mm6, mm7 + movq [edi+120], mm6 + ret + +end if diff --git a/kernel/tags/kolibri0.7.7.0/drivers/mix_sse2.inc b/kernel/tags/kolibri0.7.7.0/drivers/mix_sse2.inc new file mode 100644 index 000000000..aa450a61f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/mix_sse2.inc @@ -0,0 +1,145 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +if used mmx128_mix_2 + +align 4 +mmx128_mix_2: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + + movaps xmm0, [eax] + movaps xmm1, [eax+16] + movaps xmm2, [eax+32] + movaps xmm3, [eax+48] + movaps xmm4, [eax+64] + movaps xmm5, [eax+80] + movaps xmm6, [eax+96] + movaps xmm7, [eax+112] + + paddsw xmm0, [ebx] + movaps [edi], xmm0 + paddsw xmm1,[ebx+16] + movaps [edi+16], xmm1 + paddsw xmm2, [ebx+32] + movaps [edi+32], xmm2 + paddsw xmm3, [ebx+48] + movaps [edi+48], xmm3 + paddsw xmm4, [ebx+64] + movaps [edi+64], xmm4 + paddsw xmm5, [ebx+80] + movaps [edi+80], xmm5 + paddsw xmm6, [ebx+96] + movaps [edi+96], xmm6 + paddsw xmm7, [ebx+112] + movaps [edi+112], xmm7 + ret + +align 4 +mmx128_mix_3: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + prefetcht1 [ecx+128] + + movaps xmm0, [eax] + movaps xmm1, [eax+16] + movaps xmm2, [eax+32] + movaps xmm3, [eax+48] + movaps xmm4, [eax+64] + movaps xmm5, [eax+80] + movaps xmm6, [eax+96] + movaps xmm7, [eax+112] + + paddsw xmm0, [ebx] + paddsw xmm1, [ebx+16] + paddsw xmm2, [ebx+32] + paddsw xmm3, [ebx+48] + paddsw xmm4, [ebx+64] + paddsw xmm5, [ebx+80] + paddsw xmm6, [ebx+96] + paddsw xmm7, [ebx+112] + + paddsw xmm0, [ecx] + movaps [edi], xmm0 + paddsw xmm1, [ecx+16] + movaps [edi+16], xmm1 + paddsw xmm2, [ecx+32] + movaps [edi+32], xmm2 + paddsw xmm3, [ecx+48] + movaps [edi+48], xmm3 + paddsw xmm4, [ecx+64] + movaps [edi+64], xmm4 + paddsw xmm5, [ecx+80] + movaps [edi+80], xmm5 + paddsw xmm6, [ecx+96] + movaps [edi+96], xmm6 + paddsw xmm7, [ecx+112] + movaps [edi+112], xmm7 + ret + +align 4 +mmx128_mix_4: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + prefetcht1 [ecx+128] + prefetcht1 [edx+128] + + movaps xmm0, [eax] + movaps xmm2, [eax+16] + movaps xmm4, [eax+32] + movaps xmm6, [eax+48] + movaps xmm1, [ebx] + movaps xmm3, [ebx+16] + movaps xmm5, [ebx+32] + movaps xmm7, [ebx+48] + + paddsw xmm0, [ecx] + paddsw xmm2, [ecx+16] + paddsw xmm4, [ecx+32] + paddsw xmm6, [ecx+48] + paddsw xmm1, [edx] + paddsw xmm3, [edx+16] + paddsw xmm5, [edx+32] + paddsw xmm7, [edx+48] + + paddsw xmm0, xmm1 + movaps [edi], xmm0 + paddsw xmm2, xmm3 + movaps [edi+16], xmm2 + paddsw xmm4, xmm5 + movaps [edi+32], xmm4 + paddsw xmm6, xmm7 + movaps [edi+48], xmm6 + + movaps xmm0, [eax+64] + movaps xmm2, [eax+80] + movaps xmm4, [eax+96] + movaps xmm6, [eax+112] + + movaps xmm1, [ebx+64] + movaps xmm3, [ebx+80] + movaps xmm5, [ebx+96] + movaps xmm7, [ebx+112] + paddsw xmm0, [ecx+64] + paddsw xmm2, [ecx+80] + paddsw xmm4, [ecx+96] + paddsw xmm6, [ecx+112] + + paddsw xmm1, [edx+64] + paddsw xmm3, [edx+80] + paddsw xmm5, [edx+96] + paddsw xmm7, [edx+112] + paddsw xmm0, xmm1 + movaps [edi+64], xmm0 + paddsw xmm2, xmm3 + movaps [edi+80], xmm2 + paddsw xmm4, xmm5 + movaps [edi+96], xmm4 + paddsw xmm6, xmm7 + movaps [edi+112], xmm6 + ret +end if diff --git a/kernel/tags/kolibri0.7.7.0/drivers/mixer.asm b/kernel/tags/kolibri0.7.7.0/drivers/mixer.asm new file mode 100644 index 000000000..f825ef461 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/mixer.asm @@ -0,0 +1,1262 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru + + +align 4 + +mix_list rd 32*3 + +align 4 +proc new_mix stdcall, output:dword + locals + main_count rd 1 + fpu_state rb 528 ;512+16 + endl + + mov [main_count], 32 + call prepare_playlist + cmp [play_count], 0 + je .clear + + lea eax, [fpu_state+16] + and eax, -16 ;must be 16b aligned + call FpuSave + + call update_stream +.mix: + lea eax, [mix_list] + call do_mix_list + test eax, eax + je .done + +if USE_SSE2_MIXER + + cmp eax, 1 + ja @F + ;use fast path + mov edi, [output] + lea edx, [mix_list] + call mix_fast + jmp .next +@@: + cmp eax, 2 + ja @F + + mov edi, [output] + lea edx, [mix_list] + call mix_fast_2_stream + jmp .next +@@: + +end if + + lea ebx, [mix_list] + stdcall mix_all, [output], ebx, eax +.next: + add [output], 512 + dec [main_count] + jnz .mix +.exit: + lea eax, [fpu_state+16] + and eax, -16 + call FpuRestore + ret +.done: + mov ecx, [main_count] + shl ecx, 7 ;ecx*= 512/4 + + mov edi, [output] + xor eax, eax + cld + rep stosd + jmp .exit +.clear: + mov edi, [output] + mov ecx, 4096 + xor eax, eax + cld + rep stosd + ret +endp + +align 4 +proc update_stream + locals + stream_index dd ? + event rd 6 + endl + + mov [stream_index], 0 +.l1: + mov edx, [stream_index] + mov esi, [play_list+edx*4] + + mov eax, [esi+STREAM.out_rp] + cmp eax, [esi+STREAM.out_top] + jb @f + sub eax, 64*1024 +@@: + mov [esi+STREAM.out_rp], eax + + cmp [esi+STREAM.out_count], 16384 + ja .skip + + test [esi+STREAM.format], PCM_RING + jnz .ring + + stdcall refill, esi +.skip: + inc [stream_index] + dec [play_count] + jnz .l1 + ret +.ring: + stdcall refill_ring, esi + jmp .skip +endp + +align 4 +proc refill stdcall, str:dword + locals + r_size rd 1 + endl + + mov ebx, [str] + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @F + sub edi, 0x10000 + mov [ebx+STREAM.out_wp], edi +@@: + mov eax, [ebx+STREAM.in_count] + test eax, eax + jz .done + + mov ecx, [ebx+STREAM.r_size] + cmp eax, ecx + jle @F + + mov eax, ecx +@@: + mov ecx, eax + cmp word [ebx+STREAM.format], PCM_1_16_8 + ja @F + + shr eax, 1 ;two channles +@@: + test [ebx+STREAM.format], 1 ;even formats mono + jz @F + + shr eax, 1 ;eax= samples +@@: + shl eax, 15 ;eax*=32768 =r_end + + mov [r_size], ecx + + mov esi, [ebx+STREAM.in_rp] + mov edi, [ebx+STREAM.out_wp] + + stdcall [ebx+STREAM.resample], edi, esi, \ + [ebx+STREAM.r_dt], ecx, eax + + mov ebx, [str] + + add [ebx+STREAM.out_count], eax; + add [ebx+STREAM.out_wp], eax; + + mov eax, [ebx+STREAM.in_rp] + mov ecx, [r_size] + add eax, ecx + add [ebx+STREAM.in_free], ecx + sub [ebx+STREAM.in_count], ecx + + cmp eax, [ebx+STREAM.in_top] + jb @f + + sub eax, [ebx+STREAM.in_size] +@@: + mov [ebx+STREAM.in_rp], eax + +.done: + mov eax, [ebx+STREAM.notify_event] + test eax, eax + jz .exit + + mov ebx, [ebx+STREAM.notify_id] + mov edx, EVENT_WATCHED + xor esi, esi + call RaiseEvent ;eax, ebx, edx, esi +.exit: + ret +endp + +align 4 +proc refill_ring stdcall, str:dword + locals + event rd 6 + endl + + mov ebx, [str] + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @F + sub edi, 0x10000 + mov [ebx+STREAM.out_wp], edi +@@: + mov ecx, [ebx+STREAM.r_size] + mov eax, ecx + cmp word [ebx+STREAM.format], PCM_1_16_8 + ja @F + + shr eax, 1 ;two channles +@@: + test [ebx+STREAM.format], 1 ;even formats mono + jz @F + + shr eax, 1 ;eax= samples +@@: + shl eax, 15 ;eax*=32768 =r_end + + mov esi, [ebx+STREAM.in_rp] + mov edi, [ebx+STREAM.out_wp] + + stdcall [ebx+STREAM.resample], edi, esi, \ + [ebx+STREAM.r_dt], ecx, eax + + mov ebx, [str] + + add [ebx+STREAM.out_count], eax; + add [ebx+STREAM.out_wp], eax; + + mov eax, [ebx+STREAM.in_rp] + mov ecx, [ebx+STREAM.r_size] + add eax, ecx + add [ebx+STREAM.in_free], ecx + sub [ebx+STREAM.in_count], ecx + + cmp eax, [ebx+STREAM.in_top] + jb @f + + sub eax, [ebx+STREAM.in_size] +@@: + mov [ebx+STREAM.in_rp], eax + + sub eax, [ebx+STREAM.in_base] + sub eax, 128 + lea esi, [event] + + mov dword [esi], RT_INP_EMPTY + mov dword [esi+4], 0 + mov dword [esi+8], ebx + mov dword [esi+12], eax + + mov eax, [ebx+STREAM.notify_event] + test eax, eax + jz .exit + + mov ebx, [ebx+STREAM.notify_id] + xor edx, edx + call RaiseEvent ;eax, ebx, edx, esi +.exit: + ret +endp + +if USE_SSE2_MIXER + +align 4 +proc mix_all stdcall, dest:dword, list:dword, count:dword + + mov edi, [dest] + mov ebx, 32 +.mix: + mov edx, [list] + mov ecx, [count] + + mov eax, [edx] + + movdqa xmm1, [eax] + movss xmm2, [edx+4] + movss xmm3, [edx+8] + + punpcklwd xmm0, xmm1 + punpckhwd xmm1, xmm1 + + shufps xmm2, xmm3, 0 + shufps xmm2, xmm2, 0x88 + + psrad xmm0, 16 + psrad xmm1, 16 + cvtdq2ps xmm0, xmm0 + cvtdq2ps xmm1, xmm1 + mulps xmm0, xmm2 + mulps xmm1, xmm2 + +.mix_loop: + add dword [edx], 16 + add edx, 12 + dec ecx + jz @F + + mov eax, [edx] + + movdqa xmm3, [eax] + movss xmm4, [edx+4] + movss xmm5, [edx+8] + + punpcklwd xmm2, xmm3 + punpckhwd xmm3, xmm3 + + shufps xmm4, xmm5, 0 + shufps xmm4, xmm4, 0x88 + + psrad xmm2, 16 + psrad xmm3, 16 + + cvtdq2ps xmm2, xmm2 + cvtdq2ps xmm3, xmm3 + + mulps xmm2, xmm4 + mulps xmm3, xmm4 + addps xmm0, xmm2 + addps xmm1, xmm3 + + jmp .mix_loop +@@: + cvtps2dq xmm0, xmm0 + cvtps2dq xmm1, xmm1 + packssdw xmm0, xmm0 + packssdw xmm1, xmm1 + punpcklqdq xmm0, xmm1 + movntdq [edi], xmm0 + + add edi, 16 + dec ebx + jnz .mix + + ret +endp + +; param +; edi = dest +; edx = mix_list + +align 4 +mix_fast: + + mov ebx, 32 + mov eax, [edx] + + movss xmm2, [edx+4] ; vol Lf + movss xmm3, [edx+8] ; vol Rf + shufps xmm2, xmm3, 0 ; Rf Rf Lf Lf + shufps xmm2, xmm2, 0x88 ; volume level Rf Lf Rf Lf +.mix: + movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w + add eax, 16 + punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w + punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w + + psrad xmm0, 16 ; R1d L1d R0d L0d + psrad xmm1, 16 ; R3d L3d R2d L2d + + cvtdq2ps xmm0, xmm0 ; time to use all power + cvtdq2ps xmm1, xmm1 ; of the dark side + + mulps xmm0, xmm2 ; R1f' L1f' R0f' L0f' + mulps xmm1, xmm2 ; R3f' L3f' R2f' L2f' + + cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' + cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' + packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' + packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' + punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' + movntdq [edi], xmm0 + + add edi, 16 + dec ebx + jnz .mix + + ret + +align 4 +mix_fast_2_stream: + + mov ebx, 32 + mov eax, [edx] + + movss xmm4, [edx+4] ; vol Lf + movss xmm5, [edx+8] ; vol Rf + mov ecx, [edx+12] + + movss xmm6, [edx+16] ; vol Lf + movss xmm7, [edx+20] ; vol Rf + + shufps xmm4, xmm5, 0 ; Rf Rf Lf Lf + shufps xmm4, xmm4, 0x88 ; volume level Rf Lf Rf Lf + + shufps xmm6, xmm7, 0 ; Rf Rf Lf Lf + shufps xmm6, xmm6, 0x88 ; volume level Rf Lf Rf Lf + +.mix: + movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w + movdqa xmm3, [ecx] ; R3w L3w R2w L2w R1w L1w R0w L0w + + add eax, 16 + add ecx, 16 + + punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w + punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w + + psrad xmm0, 16 ; R1d L1d R0d L0d + psrad xmm1, 16 ; R3d L3d R2d L2d + + cvtdq2ps xmm0, xmm0 ; time to use all power + cvtdq2ps xmm1, xmm1 ; of the dark side + + mulps xmm0, xmm4 ; R1f' L1f' R0f' L0f' + mulps xmm1, xmm4 ; R3f' L3f' R2f' L2f' + + punpcklwd xmm2, xmm3 ; R1w R1w L1w L1W R0w R0w L0w L0w + punpckhwd xmm3, xmm3 ; R3w R3w L3w L3w R2w R2w L2w L2w + + psrad xmm2, 16 ; R1d L1d R0d L0d + psrad xmm3, 16 ; R3d L3d R2d L2d + + cvtdq2ps xmm2, xmm2 ; time to use all power + cvtdq2ps xmm3, xmm3 ; of the dark side + + mulps xmm2, xmm6 ; R1f' L1f' R0f' L0f' + mulps xmm3, xmm6 ; R3f' L3f' R2f' L2f' + + addps xmm0, xmm2 + addps xmm1, xmm3 + + cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' + cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' + packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' + packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' + punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' + movntdq [edi], xmm0 + + add edi, 16 + dec ebx + jnz .mix + + ret + +else ; fixed point mmx version + +align 4 +proc mix_all stdcall, dest:dword, list:dword, count:dword + + mov edi, [dest] + mov ebx, 64 +.mix: + mov edx, [list] + mov ecx, [count] + + mov eax, [edx] + + movq mm0, [eax] + + movd mm1, [edx+4] + punpckldq mm1,mm1 + pmulhw mm0, mm1 + psllw mm0, 1 + +.mix_loop: + add dword [edx], 8 + add edx, 12 + dec ecx + jz @F + + mov eax, [edx] + movq mm1, [eax] + movd mm2, [edx+4] + punpckldq mm2,mm2 + pmulhw mm1, mm2 + psllw mm1, 1 + paddsw mm0, mm1 + jmp .mix_loop +@@: + movq [edi], mm0 + add edi, 8 + dec ebx + jnz .mix + + ret +endp + +end if + + +align 4 +proc resample_1 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + +; dest equ esp+8 +; src equ esp+12 +; r_dt equ esp+16 +; r_size equ esp+20 +; r_end equ esp+24 + + mov edi, [dest] + mov edx, [src] + sub edx, 32*2 + mov eax, 16 + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movsx ebp, word [esi] + movsx esi, word [esi+2] + mov ebx, 32768 + imul esi, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+esi+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add eax, [esp+16] + cmp eax, [esp+24] + jb .l1 + + mov ebp, esp + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_18 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + + mov edi, [dest] + mov edx, [src] + sub edx, 32 + + mov esi, 16 + +align 4 +.l1: + mov ecx, esi + mov eax, esi + and ecx, 0x7FFF + shr eax, 15 + lea eax, [edx+eax] + + mov bx, word [eax] + sub bh, 0x80 + sub bl, 0x80 + movsx eax, bh + shl eax,8 + movsx ebp, bl + shl ebp,8 + mov ebx, 32768 + imul eax, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+eax+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add esi, [esp+16] + cmp esi, [esp+24] + jb .l1 + + mov ebp, esp + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc copy_stream stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov ecx, [r_size] + mov eax, ecx + shr ecx, 2 + mov esi, [src] + mov edi, [dest] + cld + rep movsd + ret +endp + +align 4 +proc resample_2 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edx, [src] + sub edx, 32*4 + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*4] + + movq mm0, [esi] + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ;0x8000 + + psubw mm3, mm2 ; ;0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_28 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edx, [src] + sub edx, 32*2 + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + movq mm7,[mm80] + movq mm6,[mm_mask] + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movq mm0, [esi] + psubb mm0,mm7 + punpcklbw mm0,mm0 + pand mm0,mm6 + + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ; // 0x8000 + + psubw mm3, mm2 ; // 0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + + sub edi, [dest] + mov eax, edi + ret +endp + + +proc m16_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx,8 +@@: + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +align 4 +proc s8_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 7 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +proc m8_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 6 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + add eax, eax + ret +endp + +align 4 +proc alloc_mix_buff + + bsf eax, [mix_buff_map] + jnz .find + xor eax, eax + ret +.find: + btr [mix_buff_map], eax + shl eax, 9 + add eax, [mix_buff] + ret +endp + +align 4 +proc m16_s_mmx + + movq mm0, [esi] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+48], mm0 + movq [edi+56], mm1 + + movq mm0, [esi+32] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+64], mm0 + movq [edi+72], mm1 + + movq mm0, [esi+40] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+80], mm0 + movq [edi+88], mm1 + + + movq mm0, [esi+48] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+96], mm0 + movq [edi+104], mm1 + + movq mm0, [esi+56] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+112], mm0 + movq [edi+120], mm1 + + ret +endp + +align 4 +proc s8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+48], mm0 + movq [edi+56], mm1 + + ret + +endp + +align 4 +proc m8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi], mm0 + movq [edi+8], mm2 + movq [edi+16], mm1 + movq [edi+24], mm3 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi+32], mm0 + movq [edi+40], mm2 + movq [edi+48], mm1 + movq [edi+56], mm3 + + ret +endp + +align 4 +proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword + + mov edi, [output] + mov eax, [str0] + mov ebx, [str1] + mov esi, 128 + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + ret +endp + +align 4 +proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword + + mov edi, [output] + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov esi, 128 + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + ret +endp + +align 4 +proc mix_4_1 stdcall, str0:dword, str1:dword,\ + str2:dword, str3:dword + + local output:DWORD + + call alloc_mix_buff + and eax, eax + jz .err + + mov [output], eax + + mov edi, eax + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov edx, [str3] + mov esi, 128 + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + mov eax, [output] + ret +.err: + xor eax, eax + ret +endp + + +align 4 +proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ + str2:dword, str3:dword + + mov edi, [output] + + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov edx, [str3] + mov esi, 128 + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + ret +endp + +align 4 +proc copy_mem stdcall, output:dword, input:dword + + mov edi, [output] + mov esi, [input] + mov ecx, 0x80 +.l1: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + loop .l1 + + ret +endp + +proc memcpy +@@: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + dec ecx + jnz @B + ret +endp + +if 0 + +align 4 +proc new_mix stdcall, output:dword + locals + mixCounter dd ? + mixIndex dd ? + streamIndex dd ? + inputCount dd ? + main_count dd ? + blockCount dd ? + mix_out dd ? + endl + + call prepare_playlist + + cmp [play_count], 0 + je .exit + call FpuSave + mov [main_count], 32; +.l00: + mov [mix_buff_map], 0x0000FFFF; + xor eax, eax + mov [mixCounter], eax + mov [mixIndex],eax + mov [streamIndex], eax; + mov ebx, [play_count] + mov [inputCount], ebx +.l0: + mov ecx, 4 +.l1: + mov ebx, [streamIndex] + mov esi, [play_list+ebx*4] + mov eax, [esi+STREAM.work_read] + add [esi+STREAM.work_read], 512 + + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixCounter] + inc [mixIndex] + inc [streamIndex] + dec [inputCount] + jz .m2 + + dec ecx + jnz .l1 + + cmp [mixCounter], 4 + jnz .m2 + + stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12] + sub [mixIndex],4 + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixIndex] + mov [mixCounter], 0 + + cmp [inputCount], 0 + jnz .l0 +.m2: + cmp [mixIndex], 1 + jne @f + stdcall copy_mem, [output], [mix_input] + jmp .m3 +@@: + cmp [mixIndex], 2 + jne @f + stdcall mix_2_1, [output], [mix_input], [mix_input+4] + jmp .m3 +@@: + cmp [mixIndex], 3 + jne @f + stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8] + jmp .m3 +@@: + stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12] +.m3: + add [output],512 + + dec [main_count] + jnz .l00 + + call update_stream + emms + call FpuRestore + ret +.exit: + mov edi, [output] + mov ecx, 0x1000 + xor eax, eax + cld + rep stosd + ret +endp + +end if diff --git a/kernel/tags/kolibri0.7.7.0/drivers/proc32.inc b/kernel/tags/kolibri0.7.7.0/drivers/proc32.inc new file mode 100644 index 000000000..23c56b03c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/proc32.inc @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ 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/tags/kolibri0.7.7.0/drivers/sb16/CONFIG.INC b/kernel/tags/kolibri0.7.7.0/drivers/sb16/CONFIG.INC new file mode 100644 index 000000000..322fccfbc --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sb16/CONFIG.INC @@ -0,0 +1,50 @@ +;flags------------------------------------------------------------ +DEBUG equ 1 ;show messages at debug board +use_cli_sti equ 1 ;driver become more stable (theoretically) + +;constants-------------------------------------------------------- +API_VERSION equ 0 ;debug + +OS_BASE equ 0x80000000 +new_app_base equ 0x0 +PROC_BASE equ (OS_BASE+0x080000) +SB16Buffer equ (OS_BASE+0x2A0000) +SB16_Status equ (OS_BASE+0x2B0000) +DMAPage equ ((SB16Buffer-OS_BASE) shr 16) + +SB16Buffer0 equ SB16Buffer +SB16Buffer1 equ (SB16Buffer+16384) +SB16Buffer2 equ (SB16Buffer+(2*16384)) +SB16Buffer3 equ (SB16Buffer+(3*16384)) + +sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect +sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect + +small_buffer equ 32768 +full_buffer equ 65536 +sb_buffer_size equ small_buffer ; FIX ring buffer overlapped events issue; full_buffer + +__supported_buffer_sizes fix + +if ~(sb_buffer_size in __supported_buffer_sizes) +display 13,10,'unsupported buffer size was selected, check config.inc',13,10 +stop +end if + +sb_out_rate equ 48000 +;time constant for cards older than SB16 +sb_tc equ (256-(1000000/(sb_out_rate*2))) + +SRV_GETVERSION equ 0 +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sb16/README.TXT b/kernel/tags/kolibri0.7.7.0/drivers/sb16/README.TXT new file mode 100644 index 000000000..7f82babac --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sb16/README.TXT @@ -0,0 +1,72 @@ +Nable 21.05.2008. +This driver is my contribution (or donation) to KolibriOS. This is provided +AS IS in hope it'll be useful, but WITHOUT ANY WARRANTY! No responcibility +for any hardware damage or data loss. Use at your own risk! + +;------------------------------------------------------------------------------- +;Changelog: +;------------------------------------------------------------------------------- +v0.2 - DEV_SET(GET)_MASTERVOL functions are unlocked and implemented. + +v0.1 - first release. + +;------------------------------------------------------------------------------- +;Tiny FAQ for sound driver by Nable for SB16 sound card. +;------------------------------------------------------------------------------- + +;What is it?-------------------------------------------------------------------- + As you may know there is a sound subsystem ('INFINITY') in KolibriOS. +This subsystem includes mixer and separate interface for soundplayer +program and driver, so player application don't need to know what soundcard +is installed and how to cope with it, all work with card do the driver. +Before this time there were drivers only for AC97 integrated sound, but I +don't have such at home and if I would upgrade my computer with a newest +hardware, with 100% probability integrated sound will be HD Codec, nowadays +AC97 is not actual (2008 year is at calendar). But I'm not planning to upgrade +my computer so much now (and in next 5-6 years), writing the driver for my PCI +ESS Maestro1 card is difficult for me (may be some time later), so I decided +to write a driver for SB16. At first it is easy, there are many working +examples for DOS, there are heaps of good documentation and as an ISA device +SB16 can be programmed through I/O ports (about 5 ports are used), that is +more easy than PCI access. Now, enough lirics, lets go to physics :-) + If you still don't understand what stuff is it, I'll tell this in brief: +with this driver you can play MP3 and WAV music (using AC97SND player) and +sounds (some games and DOSBOX can produce sound output through sound +subsystem) in KolibriOS. + +;Yeah! I need sound in Kolibri and I have SB16 card. Whats then?---------------- + At first copy my SOUND.OBJ to /sys/drivers at your Kolibri system. Note, +that if you have AC97 card and it's driver started - then new driver won't +run until reboot. Then run BOARD and go to 'user' tab. Then try to run +AC97SND player. At BOARD you will see the following (if you had a proper +card): +|----------------------------| +|detecting hardware... | <- detector startup message +|DSP found at port 220h | <- if you have a proper card, it'll be +|DSP version 4.13 - SB16 | autodetected. Numbers may be different. +|failed to attach IRQ5 | <- don't mention. Old kernels reserve IRQ5 +|owner's handler: 0x80D74284 | see below how to fix it. +|----------------------------| + At first, note that DSP version must be 4.xx or higher. Older cards are not +supported in this first release, maybe some time later. If nothing detected +but PNP/BIOS or some other OS detects your card - I'm sorry, it's perverted +PNP card like OPTi16, that is like HD Codec - until you init it through +PCI->ISA bridge (HD Codec of course through PCI->PCI bridge), map it, etc, +you can't use it in any way. I'd rather write a PCI device driver, than +for this extreme perversion. If your card detected and has a proper version +but you see 'failed to attach IRQ' - delete stroke 'mov [irq_owner+4*5],1' from the +file kernel.asm of your kernel source, save it, rebuild kernel, copy new +kernel to /sys/ (did you rename 'kernel' to 'kernel.mnt'? You should do it), +restart kernel (Ctrl+Alt+F12, Home). THE EASIER WAY IS TO USE A NEWER KERNEL, +since SVN802 it's fixed. +Now everything should be OK. + +;It works for a part of the second and then stops, but system doesn't hang------ +Go to 'config.inc' of my driver and change 'sb_irq_num' value from 5 to 7. +Then save, rebuild driver (compile 'sound.asm'), put 'sound' to /sys/drivers/ +(you need to rename file 'sound' to 'sound.obj'), restart kernel and try again +to produce sound. + +;------------------------------------------------------------------------------- +Ask your questions at KolibriOS forum: board.kolibrios.org +I'll try to answer you if possible. \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sb16/SB16.INC b/kernel/tags/kolibri0.7.7.0/drivers/sb16/SB16.INC new file mode 100644 index 000000000..40f03ba4e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sb16/SB16.INC @@ -0,0 +1,297 @@ +;-------------------------------- +; program dma +;-------------------------------- +sb_set_dma: + mov ebx,[sound_dma] + lea eax,[ebx+4] ;mask required channel + cmp bl,4 + ja .use_second_dma_controller + jb @f +.dma_setup_error: +if DEBUG + mov esi,msgErrDMAsetup + call SysMsgBoardStr +end if + mov dword[esp],START.stop + ret +@@: +if use_cli_sti + cli ;here to minimize time with disabled ints +end if + out 0xA,al ;mask required channel + + xor eax,eax + out 0xC,al ;clear byte pointer flip-flop register + + lea eax,[ebx+0x58] ;auto-init mode for channel (ebx) + out 0xB,al ;DMA channel 0-3 mode register + + movzx edx,byte[ebx+dma_table] ;page register + mov al,DMAPage + out dx,al + + lea edx,[ebx*2] ;DMA channel 0-3 base address + + mov al,0 ;LSB is 0 + out dx,al + +; mov al,0 ;MSB is 0 too + out dx,al + + inc edx ;DMA channel 0-3 byte count + + mov al,((sb_buffer_size-1) and 0xff) + out dx,al + + mov al,((sb_buffer_size-1) shr 8) ;it is the same + out dx,al + + mov eax,ebx ;unmask DMA channel + out 0xA,al + +if use_cli_sti + sti +end if + ret + +.use_second_dma_controller: + cmp bl,7 + ja .dma_setup_error + + sub bl,4 + sub al,4 +if use_cli_sti + cli ;here to minimize time with disabled ints +end if + out 0xD4,al ;mask required channel + + xor eax,eax + out 0xD8,al ;clear byte pointer flip-flop register + + lea eax,[ebx+0x58] ;auto-init mode for channel (ebx+4) + out 0xD6,al ;DMA channel 4-7 mode register + + movzx edx,byte[ebx+dma_table+4] ;page register + mov al,DMAPage + out dx,al + + lea edx,[ebx*4+0xC0] ;DMA channel 4-7 base address + + mov al,0 ;LSB is 0 ;for 16bit DMA this contains + out dx,al ;A1-A8 lines of address bus, A0 is zero + +; mov al,0 ;MSB is 0 too ;for 16bit DMA this contains + out dx,al ;A9-A16 lines of address bus + + inc edx + inc edx ;DMA channel 4-7 16bit word count + + mov al,(((sb_buffer_size/2)-1) and 0xff) + out dx,al + + mov al,(((sb_buffer_size/2)-1) shr 8) + out dx,al + + mov eax,ebx ;unmask DMA channel + out 0xD4,al + +if use_cli_sti + sti +end if + ret +;------------------------------------------------------------------------------- +; out byte to SB DSP's write port +;------------------------------------------------------------------------------- +macro sb_out data_to_out { +@@: + in al,dx + test al,al ;is DSP busy? + js @b ;it's busy + mov al,data_to_out ;it's free + out dx,al +} +;------------------------------------------------------------------------------- +; stop playing +;------------------------------------------------------------------------------- +proc sb_stop + mov edx,[sb_base_port] + add dl,0xC + sb_out 0xD3 ;turn the speaker off + sb_out 0xDA ;exit 8bit DMA + sb_out 0xD9 ;exit 16bit DMA + ret +endp +;------------------------------------------------------------------------------- +; start playing +;------------------------------------------------------------------------------- +proc sb_play + and [int_flip_flop],0 + mov edx,[sb_base_port] + add dl,0xC + sb_out 0xD1 ;turn speaker on +; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported +; ;in this version +; mov ax,32767 ;(64k)/2-1 +;@@: ;out the low byte... +; in al,dx +; test al,al ;is DSP busy? +; js @b ;it's busy +; out dx,al + +; mov al,ah ;...then the high byte +;@@: +; in al,dx +; test al,al ;is DSP busy? +; js @b ;it's busy +; out dx,al + +; sb_out 0x1C ;auto-init 8bit playback + +; 0xBXh - 16 bit DMA mode +; |||| + sb_out 10110110b ;bCommand +; |||| +; |||+-reserved +; ||+--turn FIFO on (0 for off) +; |+---auto-init mode on (0 for off) +; +----A/D: 0-output, 1-input +; +------stereo on +; |+-----unsigned (1 for signed) +; || + sb_out 00110000b ;bMode +; || |||| +; ---------reserved +;wSize is a number of 16bit samples less 1. For auto-init mode each half +;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples + sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte + sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte + ret +endp +;------------------------------------------------------------------------------- +; reset DSP +;------------------------------------------------------------------------------- +proc sb_reset + and [int_flip_flop],0 + mov edx,[sb_base_port] + add dl,6 + mov al,1 ;start DSP reset + +if use_cli_sti + cli ;here to minimize time with disabled ints +end if + out dx,al + mov ecx,40 ;wait at least 3 microsec. +@@: + in al,dx + loop @b + + xor eax,eax ;stop DSP reset +if use_cli_sti + sti +end if + out dx,al + ret +endp + +;------------------------------------------------------------------------------- +; set the rate for playing, enable stereo +;------------------------------------------------------------------------------- +proc sb_setup + mov edx,[sb_base_port] + add dl,0xC + sb_out 40h ;set time constant, this is for old cards + sb_out sb_tc + + sb_out 41h ;set sound rate, this can only SB16 + sb_out (sb_out_rate shr 8) ;first high byte (MSB) + sb_out (sb_out_rate and 0xff) ;then low byte (LSB) + +; mov al,0xE ;for older cards, not supported in this version +; sub dl,(0xC-4) ;talk to SB's mixer +; out dx,al ;select this register of the mixer +; mov ecx,6 ;wait for the chip +;@@: +; in al,dx +; loop @b + +; inc edx ;now read the data port +; in al,dx +; or al,22h ;turn on stereo +; mov ah,al + +; mov al,0xE +; dec edx ;talk to SB's mixer +; out dx,al ;select this register of the mixer + +; mov ecx,6 ;wait for the chip +;@@: +; in al,dx +; loop @b + +; inc edx ;now send data to the data port +; mov al,ah +; out dx,al + +; dec edx +; mov ecx,35 ;wait for the chip +;@@: +; in al,dx +; loop @b + ret +endp + +;------------------------------------------------------------------------------- +; set master volume of SB mixer, note, not only SB16 but SBPro and older +; this is the first step to more full support for hardware +;------------------------------------------------------------------------------- +;in: eax in range [-10000;0] - master volume for _both_ channels +;note that x*3*17/2000 and x*3/2000*17 are not the same numbers, +;because we count in integers +proc sb_set_master_vol + mov [sb_master_vol],eax + add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL + lea eax,[eax+eax*2] ;*3 + mov ebx,2000 ;divisor + xor edx,edx + cmp byte[sb_DSP_version_int],4 + jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because + ;volume byte looks like that: 0xLR, where L - left + ;channel volume, R - right, 0<=R,L<=15 + div ebx + imul eax,17 + mov edx,[sb_base_port] + push eax ;here for optimisation + add dl,4 + mov al,0x22 ;write mixer register 0x22 + out dx,al + in al,dx ;wait for the chip ;6 + in al,dx ;wait for the chip ;5 + in al,dx ;wait for the chip ;4 + in al,dx ;wait for the chip ;3 + in al,dx ;wait for the chip ;2 + in al,dx ;wait for the chip ;1 + pop eax ;go! + inc edx + out dx,al + ret +@@: ;SB16's MAX_LEVEL is 255 + imul eax,17 + div ebx + mov edx,[sb_base_port] + push eax ;here for optimisation + add dl,4 + mov al,0x30 ;left speaker + out dx,al + pop eax ;<--+ + inc edx ; \/ + push eax ;here for optimisation + out dx,al ;write + dec edx + mov al,0x31 ;right speaker + out dx,al + pop eax + inc edx + out dx,al ;write + ret +endp +;------------------------------------------------------------------------------- diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sb16/sb16.asm b/kernel/tags/kolibri0.7.7.0/drivers/sb16/sb16.asm new file mode 100644 index 000000000..33a62da5d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sb16/sb16.asm @@ -0,0 +1,393 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + +include 'config.inc' + +;structs---------------------------------------------------------- +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +;something-------------------------------------------------------- +public START +public service_proc +public version + +include '..\proc32.inc' +include '..\imports.inc' + +section '.flat' code readable align 16 + +include 'sb16.inc' + +;------------------------------------------------------------------------------- +proc START stdcall, state:dword + cmp [state], 1 + jne .stop +.entry: + +if DEBUG + mov esi, msgInit + call SysMsgBoardStr +end if + + call detect ;returns DSP version or zero if + test eax,eax ;SB card not found + jz .exit + +if DEBUG + movzx eax,al ;major version + mov esi,sb_DSP_description + dec eax + jz .sb_say_about_found_dsp + mov dword[esi],'2.x ' + dec eax + jz .sb_say_about_found_dsp + mov dword[esi],'Pro ' + dec eax + jz .sb_say_about_found_dsp + mov dword[esi],'16 ' +.sb_say_about_found_dsp: + mov esi,msgDSPFound + call SysMsgBoardStr +end if +; xor eax,eax +; mov ebx,[sb_base_port] +; lea ecx,[ebx+0xF] + xor ebx,ebx + mov ecx,[sb_base_port] + lea edx,[ebx+0xF] + + call ReservePortArea ;these ports must be my! +if DEBUG + dec eax + jnz @f + mov esi,msgErrRsrvPorts + call SysMsgBoardStr +@@: +end if + + call sb_setup ;clock it, etc + + stdcall AttachIntHandler, sb_irq_num, sb_irq, 0 + +if DEBUG + test eax,eax + jnz @f + + mov esi,msgErrAtchIRQ + call SysMsgBoardStr + + stdcall GetIntHandler, sb_irq_num + call SysMsgBoardNum + + jmp .stop +@@: + mov esi,msgSucAtchIRQ + call SysMsgBoardStr +end if + stdcall RegService, my_service, service_proc + ret +.stop: + call sb_reset +.exit: + +if DEBUG + mov esi,msgExit + call SysMsgBoardStr +end if + + xor eax, eax + ret +endp +;------------------------------------------------------------------------------- + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + mov edi,[ioctl] + mov eax,[edi+io_code] + cmp eax,SRV_GETVERSION + jne @F + + mov eax,[edi+output] + cmp [edi+out_size],4 + jne .fail + mov [eax],dword API_VERSION + xor eax,eax + ret +@@: + cmp eax,DEV_PLAY + jne @f +if DEBUG + mov esi,msgPlay + call SysMsgBoardStr +end if + call sb_stop ;to play smth new we must stop smth old + + call pre_fill_data ;fill first and second half of the buffer + call pre_fill_data ; + + call sb_set_dma ;is it really needed here? Paranoia. + call sb_play + xor eax,eax ;set maximum volume + call sb_set_master_vol + xor eax,eax + ret +;@@: ;all this commented stuff in service proc +; cmp eax,DEV_STOP ;is never used. Mixer do this virtually, +; jne @f ;e.g. instead of stopping driver it +;if DEBUG ;outputs silence +; mov esi,msgStop +; call SysMsgBoardStr +;end if +; call sb_stop +; xor eax,eax +; ret +@@: + cmp eax,DEV_CALLBACK + jne @f +if DEBUG + mov esi,msgCallback + call SysMsgBoardStr +end if + mov edi,[edi+input] + mov eax,[edi] + mov [callback],eax +if DEBUG + call SysMsgBoardNum +end if + xor eax,eax + ret +@@: + cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock + jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it. + ;It doesn't use it _in current version_ - but in the future... + +if DEBUG + mov esi,msgSetVol + call SysMsgBoardStr +end if + mov eax,[edi+input] + mov eax,[eax] + call sb_set_master_vol + xor eax,eax + ret +@@: + cmp eax,DEV_GET_MASTERVOL + jne @F +if DEBUG + mov esi,msgGetVol + call SysMsgBoardStr +end if + mov eax,[edi+output] + mov edx,[sb_master_vol] + mov [eax],edx + xor eax,eax + ret + +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +;------------------------------------------------------------------------------- +align 4 +proc sb_irq + mov edx,[sb_base_port] ;tell the DSP that we have processed IRQ + add dl,0xF ;0xF for 16 bit sound, 0xE for 8 bit sound + in al,dx ;for non-stop sound + +pre_fill_data: + mov eax,int_flip_flop + not dword[eax] + mov eax,[eax] + test eax,eax + jns .fill_second_half + +if sb_buffer_size eq small_buffer + stdcall [callback],SB16Buffer0 ;for 32k buffer +else if sb_buffer_size eq full_buffer + stdcall [callback],SB16Buffer0 ;for 64k buffer + stdcall [callback],SB16Buffer1 ;for 64k buffer +end if + xor eax,eax + ret + +.fill_second_half: +if sb_buffer_size eq small_buffer + stdcall [callback],SB16Buffer1 ;for 32k buffer +else if sb_buffer_size eq full_buffer + stdcall [callback],SB16Buffer2 ;for 64k buffer + stdcall [callback],SB16Buffer3 ;for 64k buffer +end if + xor eax,eax + ret +endp +;------------------------------------------------------------------------------- +align 4 +proc detect +.sb_detect_next_port: +if DEBUG + inc dword[port_second_digit_num] +end if + mov edx,sb_base_port + add byte[edx],10h + cmp byte[edx],80h + jbe .sb_try_to_detect_at_specified_port +;error - no SB card detected +.sb_not_found_err: + xor eax, eax + ret + +.sb_try_to_detect_at_specified_port: + call sb_reset + add dl,8 + mov ecx,100 +.sb_check_port: + in al,dx + test al,al ;is DSP port ready to be read? + jns .sb_port_not_ready + + sub dl,4 + in al,dx ;check for AAh response + add dl,4 + cmp al,0xAA + jne .sb_port_not_ready +.sb_card_found: + and dl,0xF0 + add dl,0xC + sb_out 0xE1 ;get DSP version + add dl,2 +@@: + in al,dx + test al,al ;is DSP port ready to be read? + jns @b + sub dl,4 + in al,dx ;get major version + ror eax,16 + add dl,4 +@@: + in al,dx + test al,al ;is DSP port ready to be read? + jns @b + sub dl,4 + in al,dx ;get minor version + xor edx,edx + mov dl,10 + div dl + ror eax,16 + xor ah,ah + mov [sb_DSP_version_int],eax ;for internal usage +if DEBUG + add [sb_DSP_version],eax +end if + ret + +.sb_port_not_ready: + loop .sb_check_port ;100 retries (~100 microsec.) + jmp .sb_detect_next_port +endp +;------------------------------------------------------------------------------- +if DEBUG +proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi + mov ebx,eax + mov ecx,8 + mov esi,(number_to_out+1) +.1: + mov eax,ebx + and eax,0xF + add al,'0' + cmp al,(10+'0') + jb @f + add al,('A'-'0'-10) +@@: + mov [esi+ecx],al + shr ebx,4 + loop .1 + dec esi + call SysMsgBoardStr + ret +endp +end if +;all initialized data place here +align 4 +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +sb_base_port: dd 200h ;don't ask me why - see the code&docs + +sound_dma dd sb_dma_num + +;note that 4th DMA channel doesn't exist, it is used for cascade +;plugging the first DMA controler to the second +dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A + +my_service db 'SOUND',0 ;max 16 chars include zero + +if DEBUG +number_to_out db '0x00000000',13,10,0 + +msgInit db 'detecting hardware...',13,10,0 +msgExit db 'exiting... May be some problems found?',13,10,0 +msgPlay db 'start play',13,10,0 +;msgStop db 'stop play',13,10,0 +msgCallback db 'set_callback received from the mixer!',13,10 + db 'callback handler is: ',0 +msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10 + db 'owner',39,'s handler: ',0 +msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0') + db ' as hardcoded',13,10,0 +msgErrRsrvPorts db 'failed to reserve needed ports.',13,10 + db 'Driver may work unstable',13,10,0 +msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0 +msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0 +msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0 +;------------------------------------------------------------------------------- +msgDSPFound db 'DSP found at port 2' +label port_second_digit_num dword at $ + db '00h',13,10,'DSP version ' +sb_DSP_version: db '0.00 - SB' +sb_DSP_description: db 32,32,32,32,13,10,0 +;------------------------------------------------------------------------------- +end if + +section '.data' data readable writable align 16 +;all uninitialized data place here + +;pTempBuf rd 1 + +callback rd 1 + +int_flip_flop rd 1 + +sb_master_vol rd 1 + +sb_DSP_version_int rd 1 diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sceletone.asm b/kernel/tags/kolibri0.7.7.0/drivers/sceletone.asm new file mode 100644 index 000000000..4f9df29e5 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sceletone.asm @@ -0,0 +1,177 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;driver sceletone + +format MS COFF + +DEBUG equ 1 + +API_VERSION equ 0 ;debug + +include 'proc32.inc' +include 'imports.inc' + +OS_BASE equ 0; +new_app_base equ 0x60400000 +PROC_BASE equ OS_BASE+0x0080000 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +public START +public service_proc +public version + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +STRIDE equ 4 ;size of row in devices table + +SRV_GETVERSION equ 0 + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit +.entry: + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + stdcall RegService, my_service, service_proc + ret +.fail: +.exit: + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov ebx, [ioctl] + mov eax, [ebx+io_code] + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [ebx+output] + cmp [ebx+out_size], 4 + jne .fail + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc detect + locals + last_bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + + add edi, STRIDE + jmp @B +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret +endp + +DEVICE_ID equ 1234; pci device id +VENDOR_ID equ 5678; device vendor id + + +;all initialized data place here + +align 4 +devices dd (DEVICE_ID shl 16)+VENDOR_ID + dd 0 ;terminator + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +my_service db 'MY_SERVICE',0 ;max 16 chars include zero + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgFail db 'device not found',13,10,0 + +section '.data' data readable writable align 16 + +;all uninitialized data place here + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sis.asm b/kernel/tags/kolibri0.7.7.0/drivers/sis.asm new file mode 100644 index 000000000..b0a2e8bee --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sis.asm @@ -0,0 +1,1307 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + + +DEBUG equ 1 + +include 'proc32.inc' +include 'imports.inc' + +API_VERSION equ 0x01000100 +DEBUG_IRQ equ 0 + +USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices +IRQ_REMAP equ 0 +IRQ_LINE equ 0 + + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010100000b + +if USE_COM_IRQ +ATTCH_IRQ equ 0000111010111000b +end if + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_SIS equ 0x1039 +CTRL_SIS equ 0x7012 + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x18 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume +CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +SRV_GETVERSION equ 0 +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + + end if + + call init_controller + test eax, eax + jz .fail + + call init_codec + test eax, eax + jz .fail + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + call create_primary_buff + mov esi, msgDone + call SysMsgBoardStr + + if IRQ_REMAP + pushf + cli + + mov ebx, [ctrl.int_line] + in al, 0xA1 + mov ah, al + in al, 0x21 + test ebx, ebx + jz .skip + bts ax, bx ;mask old line +.skip + bts ax, IRQ_LINE ;mask new ine + out 0x21, al + mov al, ah + out 0xA1, al + ;remap IRQ + stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE + + mov dx, 0x4d0 ;8259 ELCR1 + in al, dx + bts ax, IRQ_LINE + out dx, al ;set level-triggered mode + mov [ctrl.int_line], IRQ_LINE + popf + mov esi, msgRemap + call SysMsgBoardStr + end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail_msg + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail_msg + + stdcall AttachIntHandler, ebx, ac97_irq, dword 0 +.reg: + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.fail_msg: + call SysMsgBoardStr + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [edi+output] + cmp [edi+out_size], 4 + jne .fail + + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + stdcall get_master_vol, ebx + ret +;@@: +; cmp eax, DEV_GET_INFO +; jne @F +; mov ebx, [edi+output] +; stdcall get_dev_info, ebx +; ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc ac97_irq + + if DEBUG_IRQ + mov esi, msgIRQ + call SysMsgBoardStr + end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x10 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 1 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + + mov ebx, 0xC0004000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr ;eax + and ebx, 0xFFF + add eax, ebx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + and eax, not 0x000000C0 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov [ctrl.vendor_ids], msg_SIS + + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + mov esi, msgPciCmd + call SysMsgBoardStr + call dword2str + call SysMsgBoardStr + + mov esi, msgPciStat + call SysMsgBoardStr + mov eax, [ctrl.pci_stat] + call dword2str + call SysMsgBoardStr + + mov esi, msgMixIsaIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + + call dword2str + call SysMsgBoardStr + + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + mov esi, msgCtrlIsaIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + + call dword2str + call SysMsgBoardStr + + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + mov esi, msgMixMMIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + call dword2str + call SysMsgBoardStr + + mov esi, msgCtrlMMIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + call dword2str + call SysMsgBoardStr +.default: + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF +@@: + mov [ctrl.int_line], eax + + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_SIS + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + push eax + call dword2str + call SysMsgBoardStr + pop eax + cmp eax, 0xFFFFFFFF + je .err + + test eax, CTRL_ST_CREADY + jnz .done ;;;;;.ready + + call reset_codec + test eax, eax + jz .err + +.ready: + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov eax, 5000 ; wait 5 ms + call StallExec + + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + je .done + + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.done: + mov eax, 2 ;force set 16-bit 2-channel PCM + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + mov eax, 5000 ; wait 5 ms + call StallExec + + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_CREADY + jnz .ok + + dec [counter] + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if +.fail: + stc + ret +.ok: + clc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + mov eax, 0x02 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 400000 ; wait 400 ms + call StallExec + + mov [counter], 16 ; total 20*100 ms = 2s +.wait: + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_CREADY + jnz .ok + + mov eax, 100000 ; wait 100 ms + call StallExec + + dec [counter] + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + +.fail: + stc + ret +.ok: + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +play: + xor eax, eax + mov [civ_val], eax + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + xor eax, eax + ret + +align 4 +stop: + mov edx, PCM_OUT_CR_REG + mov ax, 0x0 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + xor eax, eax + ret + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx, edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + +include "codec.inc" + +align 4 +devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS + dd 0 + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +msg_AC db '7012 AC97 controller',13,10, 0 +msg_SIS db 'Silicon Integrated Systems',13,10, 0 + +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +;msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +;msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer ...',0 +msgDone db 'done',13,10,0 +msgRemap db 'Remap IRQ',13,10,0 +;msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 +msgPciCmd db 'PCI command ',0 +msgPciStat db 'PCI status ',0 +msgCtrlIsaIo db 'controller io base ',0 +msgMixIsaIo db 'codec io base ',0 +msgCtrlMMIo db 'controller mmio base ',0 +msgMixMMIo db 'codec mmio base ',0 +msgIrqMap db 'AC97 irq map as ',0 + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 diff --git a/kernel/tags/kolibri0.7.7.0/drivers/sound.asm b/kernel/tags/kolibri0.7.7.0/drivers/sound.asm new file mode 100644 index 000000000..c77c9a964 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/sound.asm @@ -0,0 +1,1473 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + +DEBUG equ 1 + +include 'proc32.inc' +include 'imports.inc' + +API_VERSION equ 0x01000100 + +DEBUG_IRQ equ 0 + +USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices +IRQ_REMAP equ 0 +IRQ_LINE equ 0 + + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010100000b + +if USE_COM_IRQ +ATTCH_IRQ equ 0000111010111000b +end if + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +PCM_4 equ BIT20 +PCM_6 equ BIT21 + +VID_INTEL equ 0x8086 +VID_NVIDIA equ 0x10DE + +CTRL_ICH equ 0x2415 +CTRL_ICH0 equ 0x2425 +CTRL_ICH2 equ 0x2435 +CTRL_ICH3 equ 0x2445 +CTRL_ICH4 equ 0x24C5 +CTRL_ICH5 equ 0x24D5 +CTRL_ICH6 equ 0x266E +CTRL_ICH7 equ 0x27DE + +CTRL_NFORCE equ 0x01B1 +CTRL_NFORCE2 equ 0x006A +CTRL_NFORCE3 equ 0x00DA +CTRL_MCP04 equ 0x003A +CTRL_CK804 equ 0x0059 +CTRL_CK8 equ 0x008A +CTRL_CK8S equ 0x00EA +CTRL_MCP51 equ 0x026B + + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x16 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume +CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +SRV_GETVERSION equ 0 +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + + end if + + call init_controller + test eax, eax + jz .fail + + call init_codec + test eax, eax + jz .fail + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + call create_primary_buff + mov esi, msgDone + call SysMsgBoardStr + + if IRQ_REMAP + pushf + cli + + mov ebx, [ctrl.int_line] + in al, 0xA1 + mov ah, al + in al, 0x21 + test ebx, ebx + jz .skip + bts ax, bx ;mask old line +.skip + bts ax, IRQ_LINE ;mask new ine + out 0x21, al + mov al, ah + out 0xA1, al + ;remap IRQ + stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE + + mov dx, 0x4d0 ;8259 ELCR1 + in al, dx + bts ax, IRQ_LINE + out dx, al ;set level-triggered mode + mov [ctrl.int_line], IRQ_LINE + popf + mov esi, msgRemap + call SysMsgBoardStr + end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail_msg + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail_msg + + stdcall AttachIntHandler, ebx, ac97_irq, dword 0 +.reg: + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.fail_msg: + call SysMsgBoardStr + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [edi+output] + cmp [edi+out_size], 4 + jne .fail + + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + stdcall get_master_vol, ebx + ret +;@@: +; cmp eax, DEV_GET_INFO +; jne @F +; mov ebx, [edi+output] +; stdcall get_dev_info, ebx +; ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc ac97_irq + + if DEBUG_IRQ + mov esi, msgIRQ + call SysMsgBoardStr + end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x10; 0x10 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 ;0x1D + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 1 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 ;0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + + mov ebx, 0xC0002000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr ;eax + and ebx, 0xFFF + add eax, ebx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp edx, VID_INTEL + jne @F + mov [ctrl.vendor_ids], msg_Intel + ret +@@: + cmp edx, VID_NVIDIA + jne @F + mov [ctrl.vendor_ids], msg_NVidia + ret +@@: +.err: + xor eax, eax + mov [ctrl.vendor_ids], eax ;something wrong ? + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + mov esi, msgPciCmd + call SysMsgBoardStr + call dword2str + call SysMsgBoardStr + + mov esi, msgPciStat + call SysMsgBoardStr + mov eax, [ctrl.pci_stat] + call dword2str + call SysMsgBoardStr + + mov esi, msgMixIsaIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + + call dword2str + call SysMsgBoardStr + + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + mov esi, msgCtrlIsaIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + + call dword2str + call SysMsgBoardStr + + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + mov esi, msgMixMMIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + call dword2str + call SysMsgBoardStr + + mov esi, msgCtrlMMIo + call SysMsgBoardStr + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + call dword2str + call SysMsgBoardStr + +if 0 + +;;patch for some ugly BIOS ICH-ICH5 compatible + cmp [ctrl.vendor], VID_INTEL + jne .default + + mov esi, msgIrqMap + call SysMsgBoardStr + stdcall PciRead8, 0, 0xF8, 0x61 + and eax, 0xFF + call dword2str + call SysMsgBoardStr + btr eax, 7 ;when bit 7 set remap disabled + jnc @F + xor eax, eax + jmp @F +end if + +.default: + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF +@@: + mov [ctrl.int_line], eax + + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_ICH + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +align 4 +proc set_ICH4 + + stdcall MapIoMem,[ctrl.codec_mem_base],0x1000,PG_SW+PG_NOCACHE + mov [ctrl.codec_mem_base], eax + + stdcall MapIoMem,[ctrl.ctrl_mem_base],0x1000,PG_SW+PG_NOCACHE + mov [ctrl.ctrl_mem_base], eax + + mov [ctrl.codec_read16], codec_mem_r16 ;virtual + mov [ctrl.codec_write16], codec_mem_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + push eax + call dword2str + call SysMsgBoardStr + pop eax + cmp eax, 0xFFFFFFFF + je .err + + test eax, CTRL_ST_CREADY + jnz .ready + + call reset_codec + test eax, eax + jz .err + +.ready: + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov eax, 5000 ; wait 5 ms + call StallExec + + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .done + + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.done: + mov eax, 2 ;force set 16-bit 2-channel PCM + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + mov eax, 5000 ; wait 5 ms + call StallExec + + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call SysMsgBoardStr + end if + + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_CREADY + jnz .ok + + dec [counter] + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if +.fail: + stc + ret +.ok: + clc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + mov eax, 0x02 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 400000 ; wait 400 ms + call StallExec + + mov [counter], 16 ; total 20*100 ms = 2s +.wait: + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_CREADY + jnz .ok + + mov eax, 100000 ; wait 100 ms + call StallExec + + dec [counter] + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + +.fail: + stc + ret +.ok: + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +play: + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + xor eax, eax + ret + +align 4 +stop: + mov edx, PCM_OUT_CR_REG + mov ax, 0x0 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + xor eax, eax + ret + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEMORY MAPPED IO (os depended) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_mem_r16 + add edx, [ctrl.codec_mem_base] + mov ax, word [edx] + ret +endp + +align 4 +proc codec_mem_w16 + add edx, [ctrl.codec_mem_base] + mov word [edx], ax + ret +endp + +align 4 +proc ctrl_mem_r8 + add edx, [ctrl.ctrl_mem_base] + mov al, [edx] + ret +endp + +align 4 +proc ctrl_mem_r16 + add edx, [ctrl.ctrl_mem_base] + mov ax, [edx] + ret +endp + +align 4 +proc ctrl_mem_r32 + add edx, [ctrl.ctrl_mem_base] + mov eax, [edx] + ret +endp + +align 4 +proc ctrl_mem_w8 + add edx, [ctrl.ctrl_mem_base] + mov [edx], al + ret +endp + +align 4 +proc ctrl_mem_w16 + add edx, [ctrl.ctrl_mem_base] + mov [edx], ax + ret +endp + +align 4 +proc ctrl_mem_w32 + add edx, [ctrl.ctrl_mem_base] + mov [edx], eax + ret +endp + +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH + dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH + dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH + dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH + dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 + dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 + dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 + dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 + + dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH + dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH + dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH + dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH + dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH + dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH + dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH + dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH + + dd 0 ;terminator + + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +msg_ICH db '802801AA (ICH)', 13,10, 0 +msg_ICH0 db '802801AB (ICH0)', 13,10, 0 +msg_ICH2 db '802801BA (ICH2)', 13,10, 0 +msg_ICH3 db '802801CA (ICH3)', 13,10, 0 +msg_ICH4 db '802801DB (ICH4)', 13,10, 0 +msg_ICH5 db '802801EB (ICH5)', 13,10, 0 +msg_ICH6 db '802801FB (ICH6)', 13,10, 0 +msg_ICH7 db '802801GB (ICH7)', 13,10, 0 +msg_Intel db 'Intel ', 0 + +msg_NForce db 'NForce', 13,10, 0 +msg_NForce2 db 'NForce 2', 13,10, 0 +msg_NForce3 db 'NForce 3', 13,10, 0 +msg_MCP04 db 'NForce MCP04',13,10, 0 +msg_CK804 db 'NForce CK804',13,10, 0 +msg_CK8 db 'NForce CK8', 13,10, 0 +msg_CK8S db 'NForce CK8S', 13,10, 0 +msg_MCP51 db 'NForce MCP51',13,10, 0 + +msg_NVidia db 'NVidia', 0 + +szKernel db 'KERNEL', 0 +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +;msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +;msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer ...',0 +msgDone db 'done',13,10,0 +msgRemap db 'Remap IRQ',13,10,0 +;msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 +msgPciCmd db 'PCI command ',0 +msgPciStat db 'PCI status ',0 +msgCtrlIsaIo db 'controller io base ',0 +msgMixIsaIo db 'codec io base ',0 +msgCtrlMMIo db 'controller mmio base ',0 +msgMixMMIo db 'codec mmio base ',0 +msgIrqMap db 'AC97 irq map as ',0 + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 diff --git a/kernel/tags/kolibri0.7.7.0/drivers/uart.asm b/kernel/tags/kolibri0.7.7.0/drivers/uart.asm new file mode 100644 index 000000000..a445a74a8 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/uart.asm @@ -0,0 +1,976 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + +DEBUG equ 1 + +include 'proc32.inc' +include 'imports.inc' + + + +API_VERSION equ 0 +UART_VERSION equ API_VERSION + +PG_SW equ 0x003 +page_tabs equ 0xFDC00000 ;hack + +OS_BASE equ 0x80000000 +SLOT_BASE equ (OS_BASE+0x0080000) +TASK_COUNT equ (OS_BASE+0x0003004) +CURRENT_TASK equ (OS_BASE+0x0003000) + + +struc APPOBJ ;common object header +{ + .magic dd ? ; + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id +}; + +virtual at 0 + APPOBJ APPOBJ +end virtual + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +DEBUG equ 1 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 + +THR_REG equ 0; x3f8 ;transtitter/reciever +IER_REG equ 1; x3f9 ;interrupt enable +IIR_REG equ 2; x3fA ;interrupt info +LCR_REG equ 3; x3FB ;line control +MCR_REG equ 4; x3FC ;modem control +LSR_REG equ 5; x3FD ;line status +MSR_REG equ 6; x3FE ;modem status + +LCR_5BIT equ 0x00 +LCR_6BIT equ 0x01 +LCR_7BIT equ 0x02 +LCR_8BIT equ 0x03 +LCR_STOP_1 equ 0x00 +LCR_STOP_2 equ 0x04 +LCR_PARITY equ 0x08 +LCR_EVEN equ 0x10 +LCR_STICK equ 0x20 +LCR_BREAK equ 0x40 +LCR_DLAB equ 0x80 + +LSR_DR equ 0x01 ;data ready +LSR_OE equ 0x02 ;overrun error +LSR_PE equ 0x04 ;parity error +LSR_FE equ 0x08 ;framing error +LSR_BI equ 0x10 ;break interrupt +LSR_THRE equ 0x20 ;transmitter holding empty +LSR_TEMT equ 0x40 ;transmitter empty +LSR_FER equ 0x80 ;FIFO error + +FCR_EFIFO equ 0x01 ;enable FIFO +FCR_CRB equ 0x02 ;clear reciever FIFO +FCR_CXMIT equ 0x04 ;clear transmitter FIFO +FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins +FCR_FIFO_1 equ 0x00 ;1 byte trigger +FCR_FIFO_4 equ 0x40 ;4 bytes trigger +FCR_FIFO_8 equ 0x80 ;8 bytes trigger +FCR_FIFO_14 equ 0xC0 ;14 bytes trigger + +IIR_INTR equ 0x01 ;1= no interrupts + +IER_RDAI equ 0x01 ;reciever data interrupt +IER_THRI equ 0x02 ;transmitter empty interrupt +IER_LSI equ 0x04 ;line status interrupt +IER_MSI equ 0x08 ;modem status interrupt + +MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0 +MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0 +MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0 +MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr +MCR_LOOP equ 0x10 ;lopback mode + +MSR_DCTS equ 0x01 ;delta clear to send +MSR_DDSR equ 0x02 ;delta data set redy +MSR_TERI equ 0x04 ;trailinh edge of ring +MSR_DDCD equ 0x08 ;delta carrier detect + + +RATE_50 equ 0 +RATE_75 equ 1 +RATE_110 equ 2 +RATE_134 equ 3 +RATE_150 equ 4 +RATE_300 equ 5 +RATE_600 equ 6 +RATE_1200 equ 7 +RATE_1800 equ 8 +RATE_2000 equ 9 +RATE_2400 equ 10 +RATE_3600 equ 11 +RATE_4800 equ 12 +RATE_7200 equ 13 +RATE_9600 equ 14 +RATE_19200 equ 15 +RATE_38400 equ 16 +RATE_57600 equ 17 +RATE_115200 equ 18 + +COM_1 equ 1 +COM_2 equ 2 +COM_3 equ 3 +COM_4 equ 4 +COM_MAX equ 2 ;only two port supported + +COM_1_BASE equ 0x3F8 +COM_2_BASE equ 0x2F8 + +COM_1_IRQ equ 4 +COM_2_IRQ equ 3 + +UART_CLOSED equ 0 +UART_TRANSMIT equ 1 +UART_STOP equ 2 + +struc UART +{ + .lock dd ? + .base dd ? + .lcr_reg dd ? + .mcr_reg dd ? + .rate dd ? + .mode dd ? + .state dd ? + + .rcvr_buff dd ? + .rcvr_rp dd ? + .rcvr_wp dd ? + .rcvr_count dd ? + .rcvr_top dd ? + + .xmit_buff dd ? + .xmit_rp dd ? + .xmit_wp dd ? + .xmit_count dd ? + .xmit_free dd ? + .xmit_top dd ? +} +virtual at 0 + UART UART +end virtual + +UART_SIZE equ 18*4 + +struc CONNECTION +{ + .magic dd ? ;'CNCT' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .id dd ? ;reserved + .uart dd ? ;uart pointer +} + +virtual at 0 + CONNECTION CONNECTION +end virtual + +CONNECTION_SIZE equ 7*4 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + mov eax, UART_SIZE + call Kmalloc + test eax, eax + jz .fail + + mov [com1], eax + mov edi, eax + mov ecx, UART_SIZE/4 + xor eax, eax + cld + rep stosd + + mov eax, [com1] + mov [eax+UART.base], COM_1_BASE + + stdcall AllocKernelSpace, 32768 + + mov edi, [com1] + mov edx, eax + + mov [edi+UART.rcvr_buff], eax + add eax, 8192 + mov [edi+UART.rcvr_top], eax + add eax, 8192 + mov [edi+UART.xmit_buff], eax + add eax, 8192 + mov [edi+UART.xmit_top], eax + + call AllocPage + test eax, eax + jz .fail + + shr edx, 12 + or eax, PG_SW + mov [page_tabs+edx*4], eax + mov [page_tabs+edx*4+8], eax + + call AllocPage + test eax, eax + jz .fail + + or eax, PG_SW + mov [page_tabs+edx*4+4], eax + mov [page_tabs+edx*4+12], eax + + call AllocPage + test eax, eax + jz .fail + + or eax, PG_SW + mov [page_tabs+edx*4+16], eax + mov [page_tabs+edx*4+24], eax + + call AllocPage + test eax, eax + jz .fail + + or eax, PG_SW + mov [page_tabs+edx*4+20], eax + mov [page_tabs+edx*4+28], eax + + mov eax, [edi+UART.rcvr_buff] + invlpg [eax] + invlpg [eax+0x1000] + invlpg [eax+0x2000] + invlpg [eax+0x3000] + invlpg [eax+0x4000] + invlpg [eax+0x5000] + invlpg [eax+0x6000] + invlpg [eax+0x7000] + + mov eax, edi + call uart_reset.internal ;eax= uart + + stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0 + stdcall RegService, sz_uart_srv, service_proc + ret +.fail: +.stop: + xor eax, eax + ret +endp + + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +SRV_GETVERSION equ 0 +PORT_OPEN equ 1 +PORT_CLOSE equ 2 +PORT_RESET equ 3 +PORT_SETMODE equ 4 +PORT_GETMODE equ 5 +PORT_SETMCR equ 6 +PORT_GETMCR equ 7 +PORT_READ equ 8 +PORT_WRITE equ 9 + +align 4 +proc service_proc stdcall, ioctl:dword + + mov ebx, [ioctl] + mov eax, [ebx+io_code] + cmp eax, PORT_WRITE + ja .fail + + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [ebx+output] + cmp [ebx+out_size], 4 + jne .fail + mov [eax], dword UART_VERSION + xor eax, eax + ret +@@: + cmp eax, PORT_OPEN + jne @F + + cmp [ebx+out_size], 4 + jne .fail + + mov ebx, [ebx+input] + mov eax, [ebx] + call uart_open + mov ebx, [ioctl] + mov ebx, [ebx+output] + mov [ebx], ecx + ret +@@: + mov esi, [ebx+input] ;input buffer + mov edi, [ebx+output] + call [uart_func+eax*4] + ret +.fail: + or eax, -1 + ret + +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +; param +; esi= input buffer +; +0 connection +; +; retval +; eax= error code + +align 4 +uart_reset: + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail + + mov eax, [eax+CONNECTION.uart] + test eax, eax + jz .fail + +; set mode 2400 bod 8-bit +; disable DTR & RTS +; clear FIFO +; clear pending interrupts +; +; param +; eax= uart + +align 4 +.internal: + mov esi, eax + mov [eax+UART.state], UART_CLOSED + mov edx, [eax+UART.base] + add edx, MCR_REG + xor eax, eax + out dx, al ;clear DTR & RTS + + mov eax, esi + mov ebx, RATE_2400 + mov ecx, LCR_8BIT+LCR_STOP_1 + call uart_set_mode.internal + + mov edx, [esi+UART.base] + add edx, IIR_REG + mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14 + out dx, al +.clear_RB: + mov edx, [esi+UART.base] + add edx, LSR_REG + in al, dx + test eax, LSR_DR + jz @F + + mov edx, [esi+UART.base] + in al, dx + jmp .clear_RB +@@: + mov edx, [esi+UART.base] + add edx, IER_REG + mov eax,IER_RDAI+IER_THRI+IER_LSI + out dx, al +.clear_IIR: + mov edx, [esi+UART.base] + add edx, IIR_REG + in al, dx + test al, IIR_INTR + jnz .done + + shr eax, 1 + and eax, 3 + jnz @F + + mov edx, [esi+UART.base] + add edx, MSR_REG + in al, dx + jmp .clear_IIR +@@: + cmp eax, 1 + je .clear_IIR + + cmp eax, 2 + jne @F + + mov edx, [esi+UART.base] + in al, dx + jmp .clear_IIR +@@: + mov edx, [esi+UART.base] + add edx, LSR_REG + in al, dx + jmp .clear_IIR +.done: + mov edi, [esi+UART.rcvr_buff] + mov ecx, 8192/4 + xor eax, eax + + mov [esi+UART.rcvr_rp], edi + mov [esi+UART.rcvr_wp], edi + mov [esi+UART.rcvr_count], eax + + cld + rep stosd + + mov edi, [esi+UART.xmit_buff] + mov ecx, 8192/4 + + mov [esi+UART.xmit_rp], edi + mov [esi+UART.xmit_wp], edi + mov [esi+UART.xmit_count], eax + mov [esi+UART.xmit_free], 8192 + + rep stosd + ret ;eax= 0 +.fail: + or eax, -1 + ret + +; param +; esi= input buffer +; +0 connection +; +4 rate +; +8 mode +; +; retval +; eax= error code + +align 4 +uart_set_mode: + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail + + mov eax, [eax+CONNECTION.uart] + test eax, eax + jz .fail + + mov ebx, [esi+4] + mov ecx, [esi+8] + +; param +; eax= uart +; ebx= baud rate +; ecx= mode + +align 4 +.internal: + cmp ebx, RATE_115200 + ja .fail + + cmp ecx, LCR_BREAK + jae .fail + + mov [eax+UART.rate], ebx + mov [eax+UART.mode], ecx + + mov esi, eax + mov bx, [divisor+ebx*2] + + mov edx, [esi+UART.base] + push edx + add edx, LCR_REG + in al, dx + or al, 0x80 + out dx, al + + pop edx + mov al, bl + out dx, al + + inc dx + mov al, bh + out dx, al + + add edx, LCR_REG-1 + mov eax, ecx + out dx, al + xor eax, eax + ret +.fail: + or eax, -1 + ret + +; param +; esi= input buffer +; +0 connection +; +4 modem control reg valie +; +; retval +; eax= error code + +align 4 +uart_set_mcr: + + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail + + mov eax, [eax+CONNECTION.uart] + test eax, eax + jz .fail + + mov ebx, [esi+4] + + mov [eax+UART.mcr_reg], ebx + mov edx, [eax+UART.base] + add edx, MCR_REG + mov al, bl + out dx, al + xor eax, eax + ret +.fail: + or eax, -1 + ret + +; param +; eax= port +; +; retval +; ecx= connection +; eax= error code + +align 4 +uart_open: + dec eax + cmp eax, COM_MAX + jae .fail + + mov esi, [com1+eax*4] ;uart + push esi +.do_wait: + cmp dword [esi+UART.lock],0 + je .get_lock + ; call change_task + jmp .do_wait +.get_lock: + mov eax, 1 + xchg eax, [esi+UART.lock] + test eax, eax + jnz .do_wait + + mov eax, esi ;uart + call uart_reset.internal + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov ebx, [CURRENT_TASK+ebx+4] + mov eax, CONNECTION_SIZE + call CreateObject + pop esi ;uart + test eax, eax + jz .fail + + mov [eax+APPOBJ.magic], 'CNCT' + mov [eax+APPOBJ.destroy], uart_close.destroy + mov [eax+CONNECTION.uart], esi + mov ecx, eax + xor eax, eax + ret +.fail: + or eax, -1 + ret +restore .uart + +; param +; esi= input buffer + +align 4 +uart_close: + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail +.destroy: + push [eax+CONNECTION.uart] + call DestroyObject ;eax= object + pop eax ;eax= uart + test eax, eax + jz .fail + + mov [eax+UART.state], UART_CLOSED + mov [eax+UART.lock], 0 ;release port + xor eax, eax + ret +.fail: + or eax, -1 + ret + + +; param +; eax= uart +; ebx= baud rate + +align 4 +set_rate: + cmp ebx, RATE_115200 + ja .fail + + mov [eax+UART.rate], ebx + mov bx, [divisor+ebx*2] + + mov edx, [eax+UART.base] + add edx, LCR_REG + in al, dx + push eax + or al, 0x80 + out dx, al + + sub edx, LCR_REG + mov al, bl + out dx, al + + inc edx + mov al, bh + out dx, al + + pop eax + add edx, LCR_REG-1 + out dx, al +.fail: + ret + + +; param +; ebx= uart + +align 4 +transmit: + push esi + push edi + + mov edx, [ebx+UART.base] + + pushfd + cli + + mov esi, [ebx+UART.xmit_rp] + mov ecx, [ebx+UART.xmit_count] + test ecx, ecx + je .stop + + cmp ecx, 16 + jbe @F + mov ecx, 16 +@@: + sub [ebx+UART.xmit_count], ecx + add [ebx+UART.xmit_free], ecx + cld +@@: + lodsb + out dx, al + dec ecx + jnz @B + + cmp esi,[ebx+UART.xmit_top] + jb @F + sub esi, 8192 +@@: + mov [ebx+UART.xmit_rp], esi + + cmp [ebx+UART.xmit_count], 0 + je .stop + + mov [ebx+UART.state], UART_TRANSMIT + jmp @F +.stop: + mov [ebx+UART.state], UART_STOP +@@: + popfd + pop edi + pop esi + ret + + +; param +; esi= input buffer +; +0 connection +; +4 dst buffer +; +8 dst size +; edi= output buffer +; +0 bytes read + +; retval +; eax= error code + +align 4 +uart_read: + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail + + mov eax, [eax+CONNECTION.uart] + test eax, eax + jz .fail + + mov ebx, [esi+8] ;dst size + mov ecx, [eax+UART.rcvr_count] + cmp ecx, ebx + jbe @F + mov ecx, ebx +@@: + mov [edi], ecx ;bytes read + test ecx, ecx + jz .done + + push ecx + + mov edi, [esi+4] ;dst + mov esi, [eax+UART.rcvr_rp] + cld + rep movsb + pop ecx + + cmp esi, [eax+UART.rcvr_top] + jb @F + sub esi, 8192 +@@: + mov [eax+UART.rcvr_rp], esi + sub [eax+UART.rcvr_count], ecx +.done: + xor eax, eax + ret +.fail: + or eax, -1 + ret + +; param +; esi= input buffer +; +0 connection +; +4 src buffer +; +8 src size +; +; retval +; eax= error code + +align 4 +uart_write: + mov eax, [esi] + cmp [eax+APPOBJ.magic], 'CNCT' + jne .fail + + cmp [eax+APPOBJ.destroy], uart_close.destroy + jne .fail + + mov eax, [eax+CONNECTION.uart] + test eax, eax + jz .fail + + mov ebx, [esi+4] + mov edx, [esi+8] + +; param +; eax= uart +; ebx= src +; edx= count + +align 4 +.internal: + mov esi, ebx + mov edi, [eax+UART.xmit_wp] +.write: + test edx, edx + jz .fail +.wait: + cmp [eax+UART.xmit_free], 0 + jne .fill + + cmp [eax+UART.state], UART_TRANSMIT + je .wait + + mov ebx, eax + push edx + call transmit + pop edx + mov eax, ebx + jmp .write +.fill: + mov ecx, [eax+UART.xmit_free] + cmp ecx, edx + jbe @F + mov ecx, edx +@@: + push ecx + cld + rep movsb + pop ecx + sub [eax+UART.xmit_free], ecx + add [eax+UART.xmit_count], ecx + sub edx, ecx + jnz .wait +.done: + cmp edi, [eax+UART.xmit_top] + jb @F + sub edi, 8192 +@@: + mov [eax+UART.xmit_wp], edi + cmp [eax+UART.state], UART_TRANSMIT + je @F + mov ebx, eax + call transmit +@@: + xor eax, eax + ret +.fail: + or eax, -1 + ret + + +align 4 +com_2_isr: + mov ebx, [com2] + jmp com_1_isr.get_info +align 4 +com_1_isr: + mov ebx, [com1] +.get_info: + mov edx, [ebx+UART.base] + add edx, IIR_REG + in al, dx + + test al, IIR_INTR + jnz .done + + shr eax, 1 + and eax, 3 + + call [isr_action+eax*4] + jmp .get_info +.done: + ret + +align 4 +isr_line: + mov edx, [ebx+UART.base] + add edx, LSR_REG + in al, dx + ret + +align 4 +isr_recieve: + mov esi, [ebx+UART.base] + add esi, LSR_REG + mov edi, [ebx+UART.rcvr_wp] + xor ecx, ecx + cld +.read: + mov edx, esi + in al, dx + test eax, LSR_DR + jz .done + + mov edx, [ebx+UART.base] + in al, dx + stosb + inc ecx + jmp .read +.done: + cmp edi, [ebx+UART.rcvr_top] + jb @F + sub edi, 8192 +@@: + mov [ebx+UART.rcvr_wp], edi + add [ebx+UART.rcvr_count], ecx + ret + +align 4 +isr_modem: + mov edx, [ebx+UART.base] + add edx, MSR_REG + in al, dx + ret + + +align 4 +divisor dw 2304, 1536, 1047, 857, 768, 384 + dw 192, 96, 64, 58, 48, 32 + dw 24, 16, 12, 6, 3, 2, 1 + +align 4 +uart_func dd 0 ;SRV_GETVERSION + dd 0 ;PORT_OPEN + dd uart_close ;PORT_CLOSE + dd uart_reset ;PORT_RESET + dd uart_set_mode ;PORT_SETMODE + dd 0 ;PORT_GETMODE + dd uart_set_mcr ;PORT_SETMODEM + dd 0 ;PORT_GETMODEM + dd uart_read ;PORT_READ + dd uart_write ;PORT_WRITE + +isr_action dd isr_modem + dd transmit + dd isr_recieve + dd isr_line + +version dd (5 shl 16) or (UART_VERSION and 0xFFFF) + +sz_uart_srv db 'UART',0 + +align 4 + +com1 rd 1 +com2 rd 1 + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/usb/urb.inc b/kernel/tags/kolibri0.7.7.0/drivers/usb/urb.inc new file mode 100644 index 000000000..d3be5e75b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/usb/urb.inc @@ -0,0 +1,115 @@ + +struc URB +{ + .fd dd ? + .bk dd ? + .dev dd ? ; pointer to associated device + .pipe dd ? ; pipe information + .status dd ? ; non-ISO status + .transfer_flags dd ? ; URB_SHORT_NOT_OK | ... + .transfer_buffer dd ? ; associated data buffer + .transfer_dma dd ? ; dma addr for transfer_buffer + .transfer_buffer_length dd ? ; data buffer length + .actual_length dd ? ; actual transfer length + .setup_packet dd ? ; setup packet (control only) + .setup_dma dd ? ; dma addr for setup_packet + .start_frame dd ? ; start frame (ISO) + .number_of_packets dd ? ; number of ISO packets + .interval dd ? ; transfer interval + + .error_count dd ? ; number of ISO errors + .context dd ? ; context for completion + .complete dd ? ; (in) completion routine + .iso_frame_desc: +} + +virtual at 0 + URB URB +end virtual + + +struc REQ ;usb request +{ + .request_type db ? + .request db ? + .value dw ? + .index dw ? + .length dw ? +} + +virtual at 0 + REQ REQ +end virtual + +align 4 +proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\ + requesttype:dword, value:dword, index:dword,\ + data:dword, size:dword, timeout:dword + + locals + req REQ + endl + + lea eax, [req] + mov ecx, [request] + mov ebx, [requesttupe] + mov edx, [value] + mov esi, [index] + mov edi, [size] + + mov [eax+REQ.request_type], bl + mov [eax+REQ.request], cl + mov [eax+REQ.value], dx + mov [eax+REQ.index], si + mov [eax+REQ.length], di + + stdcall usb_internal_control_msg, [dev], [pipe],\ + eax, [data], [size], [timeout] + + ret +endp + + +; returns status (negative) or length (positive) +static int usb_internal_control_msg(struct usb_device *usb_dev, + unsigned int pipe, + struct usb_ctrlrequest *cmd, + void *data, int len, int timeout) +{ + struct urb *urb; + int retv; + int length; + + urb = usb_alloc_urb(0, GFP_NOIO); + if (!urb) + return -ENOMEM; + usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, + len, usb_api_blocking_completion, NULL); + + retv = usb_start_wait_urb(urb, timeout, &length); + if (retv < 0) + return retv; + else + return length; +} + + +void usb_fill_control_urb (struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + unsigned char *setup_packet, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete_fn, + void *context) +{ + + urb->dev = dev; + urb->pipe = pipe; + urb->setup_packet = setup_packet; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = buffer_length; + urb->complete = complete_fn; + urb->context = context; +} + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/usb/usb.asm b/kernel/tags/kolibri0.7.7.0/drivers/usb/usb.asm new file mode 100644 index 000000000..13cbd8133 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/usb/usb.asm @@ -0,0 +1,435 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;driver sceletone + +format MS COFF + +API_VERSION equ 0 ;debug + +include '../proc32.inc' +include '../imports.inc' +include 'urb.inc' + +struc UHCI +{ + .bus dd ? + .devfn dd ? + .io_base dd ? + .mm_base dd ? + .irq dd ? + .flags dd ? + .reset dd ? + .start dd ? + .stop dd ? + + .port_c_suspend dd ? + .resuming_ports dd ? + .rh_state dd ? + .rh_numports dd ? + .is_stopped dd ? + .dead dd ? + + .sizeof: +} + +virtual at 0 + UHCI UHCI +end virtual + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +struc TD ;transfer descriptor +{ + .link dd ? + .status dd ? + .token dd ? + .buffer dd ? + + .addr dd ? + .frame dd ? + .fd dd ? + .bk dd ? + .sizeof: +} + +virtual at 0 + TD TD +end virtual + +public START +public service_proc +public version + +DEBUG equ 1 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +STRIDE equ 4 ;size of row in devices table + +SRV_GETVERSION equ 0 + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit +.entry: + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call init + + stdcall RegService, my_service, service_proc + ret +.fail: +.exit: + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov ebx, [ioctl] + mov eax, [ebx+io_code] + cmp eax, SRV_GETVERSION + jne @F + + mov eax, [ebx+output] + cmp [ebx+out_size], 4 + jne .fail + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc detect + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + + add edi, STRIDE + jmp @B +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov eax, UHCI.sizeof + call Kmalloc + test eax, eax + jz .mem_fail + + mov ebx, [bus] + mov [eax+UHCI.bus], ebx + + mov ecx, [devfn] + mov [eax+UHCI.devfn], ecx + ret +.mem_fail: + if DEBUG + mov esi, msgMemFail + call SysMsgBoardStr + end if +.err: + xor eax, eax + ret +endp + +PCI_BASE equ 0x20 +USB_LEGKEY equ 0xC0 + +align 4 +proc init + locals + uhci dd ? + endl + + call detect + test eax, eax + jz .fail + + mov [uhci], eax + + stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE + and eax, 0xFFC0 + mov esi, [uhci] + mov [esi+UHCI.io_base], eax + + stdcall uhci_reset, esi + + stdcall finish_reset, [uhci] + +.fail: + if DEBUG + mov esi, msgDevNotFound + call SysMsgBoardStr + end if + ret +endp + +UHCI_USBINTR equ 4 ; interrupt register + +UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits +UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits + +UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit +UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset +UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode +UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag +UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable + +PORTSC0 equ 0x10 +PORTSC1 equ 0x12 + + +UHCI_RH_RESET equ 0 +UHCI_RH_SUSPENDED equ 1 +UHCI_RH_AUTO_STOPPED equ 2 +UHCI_RH_RESUMING equ 3 + +; In this state the HC changes from running to halted +; so it can legally appear either way. +UHCI_RH_SUSPENDING equ 4 + +; In the following states it's an error if the HC is halted. +; These two must come last. +UHCI_RH_RUNNING equ 5 ; The normal state +UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices + +UHCI_IS_STOPPED equ 9999 + +align 4 +proc uhci_reset stdcall, uhci:dword + mov esi, [uhci] + stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY + test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC) + jnz .reset + + mov edx, [esi+UHCI.io_base] + in ax, dx + test ax, UHCI_USBCMD_RUN + jnz .reset + + test ax, UHCI_USBCMD_CONFIGURE + jz .reset + + test ax, UHCI_USBCMD_EGSM + jz .reset + + add edx, UHCI_USBINTR + in ax, dx + test ax, not UHCI_USBINTR_RESUME + jnz .reset + ret +.reset: + stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC + + mov edx, [esi+UHCI.io_base] + mov ax, UHCI_USBCMD_HCRESET + out dx, ax + + xor eax, eax + out dx, ax + add edx, UHCI_USBINTR + out dx, ax + ret +endp + +proc finish_reset stdcall, uhci:dword + + mov esi, [uhci] + mov edx, [esi+UHCI.io_base] + add edx, PORTSC0 + xor eax, eax + out dx, ax + add edx, (PORTSC1-PORTSC0) + out dx, ax + + mov [esi+UHCI.port_c_suspend], eax + mov [esi+UHCI.resuming_ports], eax + mov [esi+UHCI.rh_state], UHCI_RH_RESET + mov [esi+UHCI.rh_numports], 2 + + mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED + ; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT; + ; uhci_to_hcd(uhci)->poll_rh = 0; + + mov [esi+UHCI.dead], eax ; Full reset resurrects the controller + + ret +endp + +proc insert_td stdcall, td:dword, frame:dword + + mov edi, [td] + mov eax, [frame] + and eax, -1024 + mov [edi+TD.frame], eax + + mov ebx, [framelist] + mov edx, [dma_framelist] + shl eax, 5 + + mov ecx, [eax+ebx] + test ecx, ecx + jz .empty + + mov ecx, [ecx+TD.bk] ;last TD + + mov edx, [ecx+TD.fd] + mov [edi+TD.fd], edx + mov [edi+TD.bk], ecx + mov [ecx+TD.fd], edi + mov [edx+TD.bk], edi + + mov eax, [ecx+TD.link] + mov [edi+TD.link], eax + mov ebx, [edi+TD.addr] + mov [ecx+TD.link], ebx + ret +.empty: + mov ecx, [eax+edx] + mov [edi+TD.link], ecx + mov [ebx+eax], edi + mov ecx, [edi+TD.addr] + mov [eax+edx], ecx + ret +endp + + +align 4 +proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\ + buf:dword, size:dword + + locals + count dd ? + endl + + mov esi, [buf] + mov ecx, [size] + xor eax, eax + cld + rep stosb + + mov [count], 3 +@@: + mov eax, [type] + shl eax, 8 + add eax, [index] + stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\ + USB_DIR_IN, eax,0,[buf], [size],\ + USB_CTRL_GET_TIMEOUT + test eax, eax + jz .next + cmp eax, -1 + je .next + jmp. ok +.next: + dec [count] + jnz @B + mov eax, -1 +.ok: + ret +endp + +DEVICE_ID equ 0x24D2 ; pci device id +VENDOR_ID equ 0x8086 ; device vendor id +QEMU_USB equ 0x7020 + +;all initialized data place here + +align 4 +devices dd (DEVICE_ID shl 16)+VENDOR_ID + dd (QEMU_USB shl 16)+VENDOR_ID + dd 0 ;terminator + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +my_service db 'UHCI',0 ;max 16 chars include zero + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgDevNotFound db 'device not found',13,10,0 +msgMemFail db 'Kmalloc failed', 10,10,0 +;msgFail db 'device not found',13,10,0 + +section '.data' data readable writable align 16 + +;all uninitialized data place here + diff --git a/kernel/tags/kolibri0.7.7.0/drivers/vmode.asm b/kernel/tags/kolibri0.7.7.0/drivers/vmode.asm new file mode 100644 index 000000000..9cb0427bb --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/drivers/vmode.asm @@ -0,0 +1,736 @@ +; +; MenuetOS Driver (vmode.mdr) +; Target: Vertical Refresh Rate programming and videomode changing +; +; Author: Trans <<<<<13>>>>> +; Date: 20.07.2003 +; +; Version: 1.0 +; OS: MenuetOS +; Compiler: FASM +; + +OS_BASE equ 0x80000000 + +use32 + +macro align value { rb (value-1) - ($ + value-1) mod value } + + org OS_BASE+0x0328000 + +headerstart=$ + +mdid db 'MDAZ' ; 4 byte id +mdhver dd 0x00 ; header version +mdcode dd MDSTART ; start of code +mdver dd 0x00000001 ; driver version (subversion*65536+version) +mdname db 'Trans VideoDriver' ; 32 bytes of full driver name + times (32-($-mdname)) db ' ' ; + +headerlen=$-headerstart + times (256-headerlen) db 0 ; reserved area for future + +MDSTART: ; start of driver code ( base_adr+256 bytes) +; ebx(=ecx in program): +; 1 - Get DriverInfo and Driver Initial Set +; 2 - Get Current Video Mode With Vertical Refresh Rate +; 3 - Change Video Mode +; 4 - Return at Start System Video Mode +; 5 - Change vertical and horizontal size of visible screen area +; 6 - Change Vert/Hor position visible area on screen (not complete yet) +; +; MAXF - ... +MAXF=5 + +;-------Main Manager------------- + pushad + cmp ebx,1 + jb mdvm_00 + cmp ebx,MAXF + ja mdvm_00 + shl ebx,2 + add ebx,mdvm_func_table + call dword [ebx] + mov [esp+28],eax + mov [esp+24],ecx + mov [esp+20],edx + mov [esp+16],ebx + popad + retn +mdvm_00: + popad + xor eax,eax + dec eax + retn + +; ------Drivers Functions---------- + +align 4 + +; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set +; +; IN: ecx (in app. edx) - pointer to 512-bytes info area in application +; OUT: +; +vm_info_init: + push ecx + cmp [mdrvm],dword 0 + jnz .vmii_00 + call vm_safe_reg + call vm_get_initial_videomode + mov eax,[initvm] + mov [currvm],eax + call vm_search_sys_func_table + call vm_get_cur_vert_rate + mov [initrr],eax + call vm_calc_pixelclock + call vm_calc_refrate + inc [mdrvm] +.vmii_00: + pop ecx + call vm_transfer_drv_info + mov ebx,dword [refrate] + mov eax,dword [mdid] ;dword [systlb] + retn + + +align 4 + +; EBX=2 (in applications ECX=2)- Get Current Video Mode +; +; OUT: eax = X_screen*65536+Y_screen +; ebx = current vertical rate +; ecx = current video mode (number) +vm_get_cur_mode: + cmp [mdrvm],dword 0 + jz .vmgcm_00 + call vm_get_cur_vert_rate + mov eax,[OS_BASE+0FE00h] + mov ebx,[OS_BASE+0FE04h] + shl eax,16 + add eax,ebx + add eax,00010001h + mov ebx,[refrate] + mov ecx,[currvm] + retn +.vmgcm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=3 (in applications ECX=3)- Change Video Mode +; +; IN: ecx = VertRate*65536+VideoMode +; OUT: eax = 0 if no error +; +vm_set_video_mode: + cmp [mdrvm],dword 0 + jz .vmsvm_00 + call vm_set_selected_mode +; xor eax,eax + retn +.vmsvm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=4 (in applications ECX=4)- Return at Start System Video Mode +; +; IN: +; OUT: eax = = 0 if no error +; +vm_restore_init_video_mode: + cmp [mdrvm],dword 0 + jz .vmrivm_00 + call vm_restore_reg + xor eax,eax + retn +.vmrivm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=5 (in applications ECX=5)- Change vertical and horizontal size +; of visible screen area +; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position +; = 2/3 - -/+ vertical size on 1 position (8 pixels) +; ^-^----- not complete yet +; OUT: eax = = 0 if no error +; +vm_change_screen_size: + cmp [mdrvm],dword 0 + jz .vmcss_00 + cmp cl,1 + ja .vmcss_01 + mov eax,ecx + call vm_inc_dec_width + xor eax,eax + retn +.vmcss_01: + and ecx,01h + mov eax,ecx +; call vm_inc_dec_high ; not complete yet + xor eax,eax + retn +.vmcss_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen +; +; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point +; = 2/3 - -/+ vertical position on 1 pixel +; ^-^----- not complete yet +; OUT: eax = 0 if no error +; +vm_change_position_screen: + cmp [mdrvm],dword 0 + jz .vmcps_00 + ; ... + xor eax,eax + retn +.vmcps_00: + xor eax,eax + dec eax + retn + + +;-----Drivers Subfunctions--------- + +; +; Searching i40 system functions pointer table in kernel area location +; +vm_search_sys_func_table: + push eax ; eax - current value + push ecx ; ecx - will be counter of equevalent value + push edx ; edx - last value + push esi ; esi - current address + xor ecx,ecx + mov esi,OS_BASE+010000h ; Start address of kernel location + lodsd + mov edx,eax + cld +.vmssft_00: + cmp esi,OS_BASE+30000h + ja .vmssft_03 + inc ecx + lodsd + cmp edx,eax + mov edx,eax + je .vmssft_00 + cmp ecx,128 + ja .vmssft_02 +.vmssft_01: + xor ecx,ecx + jmp .vmssft_00 +.vmssft_02: + cmp edx,0 + je .vmssft_01 + sub esi,256*4-1 + mov [systlb],esi + xor ecx,ecx +.vmssft_03_0: + inc ecx + lodsd + cmp edx,eax + mov edx,eax + jne .vmssft_03_0 + mov esi,dword [systlb] + cmp cx,60 + jae .vmssft_03 + add esi,256*4-4 + lodsb + mov edx,eax + jmp .vmssft_01 +.vmssft_03: + mov [systlb],esi + pop esi + pop edx + pop ecx + pop eax + retn + +; IN: +; OUT: eax= vertical rate in Hz +vm_get_cur_vert_rate: + push edx + push ebx + xor eax,eax + mov edx,eax + mov ebx,eax + mov dx,03DAh +.vmgcvt_00: + in al,dx + test al,8 + jz .vmgcvt_00 +.vmgcvt_01: + in al,dx + test al,8 + jnz .vmgcvt_01 + mov ebx,edx + rdtsc + mov edx,ebx + mov ebx,eax +.vmgcvt_02: + in al,dx + test al,8 + jz .vmgcvt_02 +.vmgcvt_03: + in al,dx + test al,8 + jnz .vmgcvt_03 + rdtsc + sub eax,ebx + mov ebx,eax + mov eax,[OS_BASE+0F600h] + xor edx,edx + div ebx + inc eax + mov [refrate],eax + pop ebx + pop edx + retn + +vm_calc_pixelclock: + push ebx + push edx + xor eax,eax + mov al,[_00] + add ax,5 + shl eax,3 + xor ebx,ebx + mov bl,[_06] + mov bh,[_07] + and bh,00100001b + btr bx,13 + jnc .vmcpc_00 + or bh,2 +.vmcpc_00: + xor edx,edx + mul ebx + xor edx,edx + mul [initrr] + mov [pclock],eax + pop edx + pop ebx + retn + +; +; Safe of initial CRTC state +; +vm_safe_reg: + push edx + push ebx + push ecx + push edi + cli + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh + out dx,al ; Clear protection bit + dec dx + xor ecx,ecx + mov cl,19h + xor bl,bl + mov edi,CRTCreg +.vmsr_00: + mov al,bl + out dx,al + inc dx + in al,dx + dec dx + stosb + inc bl + loop .vmsr_00 + sti + pop edi + pop ecx + pop ebx + pop edx + retn + +; +; Restore of initial CRTC state +; +vm_restore_reg: + push eax + push ebx + push edx + push esi + mov eax,[oldX] + mov [OS_BASE+0FE00h],eax + mov eax,[oldY] + mov [OS_BASE+0FE04h],eax + mov dx,03dah +.vmrr_00: + in al,dx + test al,8 + jnz .vmrr_00 +.vmrr_01: + in al,dx + test al,8 + jnz .vmrr_01 + cli + mov dx,03c4h + mov ax,0101h + out dx,ax + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh ; Clear Protection bit + out dx,al + dec dx + xor ecx,ecx + mov cl,19h + mov esi,CRTCreg + xor bl,bl +.vmrr_02: + lodsb + mov ah,al + mov al,bl + out dx,ax + inc bl + loop .vmrr_02 + sti +; call ref_screen + pop esi + pop edx + pop ecx + pop eax + retn + +; Calculate of possible vertical refrash rate +; (light version of function) +vm_calc_refrate: + push ebx + push ecx + push edx + push edi + push esi + mov eax,[pclock] + xor edx,edx + mov edi,_m1 + mov ebx,eax + mov ecx,(1696*1065) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(1344*804) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(1056*636) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(800*524) + div ecx + xor edx,edx + stosw + mov edi,_m1 + mov esi,edi + mov ecx,5*4 +.vmcrr_00: + lodsw + cmp ax,55 + jb .vmcrr_01 + stosw + loop .vmcrr_00 + pop esi + pop edi + pop edx + pop ecx + pop ebx + retn +.vmcrr_01: + xor ax,ax + stosw + loop .vmcrr_00 + pop esi + pop edi + pop edx + pop ecx + pop ebx + retn + +vm_get_initial_videomode: + push eax + mov eax,dword [OS_BASE+0FE00h] + mov [oldX],eax + mov eax,dword [OS_BASE+0FE04h] + mov [oldY],eax + mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode + and ax,01FFh + mov dword [initvm],eax + pop eax + retn + + +; IN: eax = 0/1 - -/+ 1 position of width +vm_inc_dec_width: + push ebx + push edx + mov ebx,eax + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh ; Clear Protection bit + out dx,al + dec dx + xor al,al + out dx,al + inc dx + in al,dx + dec al + cmp bl,0 + jnz .vmidr_00 + inc al + inc al +.vmidr_00: + out dx,al + pop edx + pop ebx + retn + +; +; Copy driver info to application area +; +; IN: ecx (in app. edx) - pointer to 512-bytes info area in application +; OUT: +vm_transfer_drv_info: + push ecx + push edi + push esi + mov eax,ecx + xor ecx,ecx + mov cl,32/4 + mov esi,mdname + mov edi,drvname + rep movsd + mov ecx,eax + mov eax,[mdver] + mov [drvver],eax + mov edi,[OS_BASE+3010h] + mov edi,[edi+10h] + add edi,ecx + mov esi,drvinfo + xor ecx,ecx + mov cx,512 + rep movsb + pop esi + pop edi + pop ecx + retn + + +; +; Set selected video mode +; (light version) +; +; IN: ecx = VertRate*65536+VideoMode +; +vm_set_selected_mode: + push edx + push ecx + push esi + ror ecx,16 + cmp cx,00h + je .vmssm_03 + rol ecx,16 + mov eax,ecx + shl eax,16 + shr eax,16 + mov [currvm],eax + cmp cx,112h + jne .vmssm_00 + mov esi,mode0 + mov ecx,639 + mov edx,479 + jmp .vmssm_st00 +.vmssm_00: + cmp cx,115h + jne .vmssm_01 + mov esi,mode1 + mov ecx,799 + mov edx,599 + jmp .vmssm_st00 +.vmssm_01: + cmp cx,118h + jne .vmssm_02 + mov esi,mode2 + mov ecx,1023 + mov edx,767 + jmp .vmssm_st00 +.vmssm_02: + cmp cx,11Bh + jne .vmssm_03 + mov esi,mode2 + mov ecx,1279 + mov edx,1023 + jmp .vmssm_st00 +.vmssm_03: + xor eax,eax + dec eax + pop esi + pop ecx + pop edx + retn +.vmssm_st00: + mov [OS_BASE+0FE00h],ecx + mov [OS_BASE+0FE04h],edx + cli + mov dx,03c4h + lodsw + out dx,ax + mov dx,03d4h + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh + out dx,al + dec dx + mov ecx,13 +.vmssm_st01: + lodsw + out dx,ax + loop .vmssm_st01 + sti + xor eax,eax + pop esi + pop ecx + pop edx + retn + + +;------------DATA AREA--------------- +align 4 + +mdvm_func_table: + dd MDSTART + dd vm_info_init, vm_get_cur_mode + dd vm_set_video_mode, vm_restore_init_video_mode + dd vm_change_screen_size, vm_change_position_screen + + +CRTCreg: +_00 db ? +_01 db ? +_02 db ? +_03 db ? +_04 db ? +_05 db ? +_06 db ? +_07 db ? +_08 db ? +_09 db ? +_0a db ? +_0b db ? +_0c db ? +_0d db ? +_0e db ? +_0f db ? +_10 db ? +_11 db ? +_12 db ? +_13 db ? +_14 db ? +_15 db ? +_16 db ? +_17 db ? +_18 db ? +_19 db ? + +align 4 + +oldX dd ? +oldY dd ? +initvm dd ? +currvm dd 0 +refrate dd 0 +initrr dd 0 +systlb dd 0 +pclock dd ? +mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init + + +drvinfo: +drvname: times 32 db ' ' +drvver dd 0 + times (32-($-drvver))/4 dd 0 +drvmode dw 011Bh,0118h,0115h,0112h + times (64-($-drvmode))/2 dw 00h +_m1 dw 0,0,0,0,0 +_m2 dw 0,0,0,0,0 +_m3 dw 0,0,0,0,0 +_m4 dw 0,0,0,0,0 +_m5 dw 0,0,0,0,0 + times (512-($-drvinfo)) db 0 +drvinfoend: + + +;1280x1024 - 11Bh +mode3: + dw 0101h + dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h + dw 0110h,8411h,0ff12h,0ff15h,2916h + +;1024x768 - 118h +mode2: + dw 0101h + dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h + dw 0310h,8911h,0ff12h,0ff15h,2516h + +;800x600 - 115h +mode1: + dw 0101h + dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h + dw 5910h,8d11h,5712h,5715h,7316h + +;640x480 - 112h, 12h +mode0: + dw 0101h + dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h + dw 0ea10h,8c11h,0df12h,0df15h,0c16h + +; 640x400 +;mymode0: +; dw 0101h +;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h +; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h + +; 640x800 +;mymode1: +; dw 0101h +; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h +; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h + + +DRVM_END: + diff --git a/kernel/tags/kolibri0.7.7.0/fdo.inc b/kernel/tags/kolibri0.7.7.0/fdo.inc new file mode 100644 index 000000000..787401aa7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fdo.inc @@ -0,0 +1,439 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +_esp equ esp + +; +; Formatted Debug Output (FDO) +; Copyright (c) 2005-2006, mike.dld +; Created: 2005-01-29, Changed: 2006-11-10 +; +; For questions and bug reports, mail to mike.dld@gmail.com +; +; Available format specifiers are: %s, %d, %u, %x (with partial width support) +; + +; to be defined: +; __DEBUG__ equ 1 +; __DEBUG_LEVEL__ equ 5 + +macro debug_func name { + if used name + name@of@func equ name +} + +macro debug_beginf { + align 4 + name@of@func: +} + +debug_endf fix end if + +macro DEBUGS _sign,[_str] { + common + local tp + tp equ 0 + match _arg:_num,_str \{ + DEBUGS_N _sign,_num,_arg + tp equ 1 + \} + match =0 _arg,tp _str \{ + DEBUGS_N _sign,,_arg + \} +} + +macro DEBUGS_N _sign,_num,[_str] { + common + pushf + pushad + local ..str,..label,is_str + is_str = 0 + forward + if _str eqtype '' + is_str = 1 + end if + common + if is_str = 1 + jmp ..label + ..str db _str,0 + ..label: +; add esp,4*8+4 +esp equ esp+4*8+4 + mov edx,..str +esp equ _esp +; sub esp,4*8+4 + else + mov edx,_str + end if + if ~_num eq + if _num eqtype eax + if _num in + 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 +esp equ esp+4*8+4 + if _num eq + mov eax,dword _dec + else if _num = 1 + if _sign = 1 + movsx eax,byte _dec + else + movzx eax,byte _dec + end if + else if _num = 2 + if _sign = 1 + movsx eax,word _dec + else + movzx eax,word _dec + end if + else + mov eax,dword _dec + end if +esp equ _esp +; sub esp,4*8+4 + end if + mov cl,_sign + call fdo_debug_outdec + popad + popf +} + +macro DEBUGH _sign,_hex { + local tp + tp equ 0 + match _arg:_num,_hex \{ + DEBUGH_N _sign,_num,_arg + tp equ 1 + \} + match =0 _arg,tp _hex \{ + DEBUGH_N _sign,,_arg + \} +} + +macro DEBUGH_N _sign,_num,_hex { + pushf + pushad + if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>) + 'Error: 1..8 are only allowed for precision in %x' + end if + if _hex eqtype eax + if _hex in + if ~_hex eq eax + mov eax,_hex + end if + mov edx,8 + else if _hex in + if ~_hex eq ax + movzx eax,_hex + end if + if (_num eq) + mov edx,4 + end if + else if _hex in + if ~_hex eq al + movzx eax,_hex + end if + if (_num eq) + mov edx,2 + end if + end if + else if _hex eqtype 0 + mov eax,_hex + else +; add esp,4*8+4 +esp equ esp+4*8+4 + mov eax,dword _hex +esp equ _esp +; sub esp,4*8+4 + end if + if ~_num eq + mov edx,_num + else + if ~_hex eqtype eax + mov edx,8 + end if + end if + call fdo_debug_outhex + popad + popf +} + +;----------------------------------------------------------------------------- + +debug_func fdo_debug_outchar +debug_beginf + pushad + movzx ebx,al + mov eax,1 + mov ecx,sys_msg_board + call ecx ; sys_msg_board + popad + ret +debug_endf + +debug_func fdo_debug_outstr +debug_beginf + mov eax,1 + .l1: dec esi + js .l2 + movzx ebx,byte[edx] + or bl,bl + jz .l2 + mov ecx,sys_msg_board + call ecx ; sys_msg_board + inc edx + jmp .l1 + .l2: ret +debug_endf + +debug_func fdo_debug_outdec +debug_beginf + or cl,cl + jz @f + or eax,eax + jns @f + neg eax + push eax + mov al,'-' + call fdo_debug_outchar + pop eax + @@: push 10 + pop ecx + push -'0' + .l1: xor edx,edx + div ecx + push edx + test eax,eax + jnz .l1 + .l2: pop eax + add al,'0' + jz .l3 + call fdo_debug_outchar + jmp .l2 + .l3: ret +debug_endf + +debug_func fdo_debug_outhex + __fdo_hexdigits db '0123456789ABCDEF' +debug_beginf + mov cl,dl + neg cl + add cl,8 + shl cl,2 + rol eax,cl + .l1: rol eax,4 + push eax + and eax,0x0000000F + mov al,[__fdo_hexdigits+eax] + call fdo_debug_outchar + pop eax + dec edx + jnz .l1 + ret +debug_endf + +;----------------------------------------------------------------------------- + +macro DEBUGF _level,_format,[_arg] { + common + if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__ + local ..f1,f2,a1,a2,c1,c2,c3,..lbl + _debug_str_ equ __debug_str_ # a1 + a1 = 0 + c2 = 0 + c3 = 0 + f2 = 0 + repeat ..lbl-..f1 + virtual at 0 + db _format,0,0 + load c1 word from %-1 + end virtual + if c1 = '%s' + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER S,a1,0,_arg + else if c1 = '%x' + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER H,a1,0,_arg + else if c1 = '%d' | c1 = '%u' + local c4 + if c1 = '%d' + c4 = 1 + else + c4 = 0 + end if + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER D,a1,c4,_arg + else if c1 = '\n' + c3 = c3 + 1 + end if + end repeat + virtual at 0 + db _format,0,0 + load c1 from f2-c2 + end virtual + if (c1<>0)&(f2<>..lbl-..f1-1) + DEBUGS 0,_debug_str_+f2-c2 + end if + virtual at 0 + ..f1 db _format,0 + ..lbl: + __debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3 + end virtual + end if +} + +macro __include_debug_strings dummy,[_id,_fmt,_len] { + common + local c1,a1,a2 + forward + if defined _len & ~_len eq + _id: + a1 = 0 + a2 = 0 + repeat _len + virtual at 0 + db _fmt,0,0 + load c1 word from %+a2-1 + end virtual + if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u') + db 0 + a2 = a2 + 1 + else if (c1='\n') + dw $0A0D + a1 = a1 + 1 + a2 = a2 + 1 + else + db c1 and 0x0FF + end if + end repeat + db 0 + end if +} + +macro DEBUGF_HELPER _letter,_num,_sign,[_arg] { + common + local num + num = 0 + forward + if num = _num + DEBUG#_letter _sign,_arg + end if + num = num+1 + common + _num = _num+1 +} + +macro include_debug_strings { + if __DEBUG__ = 1 + match dbg_str,__debug_strings \{ + __include_debug_strings dbg_str + \} + end if +} diff --git a/kernel/tags/kolibri0.7.7.0/fs/fat12.inc b/kernel/tags/kolibri0.7.7.0/fs/fat12.inc new file mode 100644 index 000000000..08e4858b7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/fat12.inc @@ -0,0 +1,2272 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; FAT12.INC ;; +;; (C) 2005 Mario79, License: GPL ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +n_sector dd 0 ; temporary save for sector value +flp_status dd 0 +clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write +path_pointer_flp dd 0 +pointer_file_name_flp dd 0 +save_root_flag db 0 +save_flag db 0 +root_read db 0 ; 0-necessary to load root, 1-not to load root +flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat +flp_number db 0 ; 1- Floppy A, 2-Floppy B +old_track db 0 ; old value track +flp_label rb 15 ; Label and ID of inserted floppy disk + +reserve_flp: + + cli + cmp [flp_status],0 + je reserve_flp_ok + + sti + call change_task + jmp reserve_flp + + reserve_flp_ok: + + push eax + mov eax,[CURRENT_TASK] + shl eax,5 + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] + mov [flp_status],eax + pop eax + sti + ret + + +floppy_fileread: +;---------------------------------------------------------------- +; +; fileread - sys floppy +; +; eax points to filename 11 chars - for root directory +; ebx first wanted block ; 1+ ; if 0 then set to 1 +; ecx number of blocks to read ; 1+ ; if 0 then set to 1 +; edx mem location to return data +; esi length of filename 12*X +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; 10 = access denied +;-------------------------------------------------------------- + + mov [save_flag],0 + mov [path_pointer_flp],edi + cmp esi,0 ; return ramdisk root + jne fr_noroot_1 + cmp ebx,224/16 + jbe fr_do_1 + mov eax,5 + mov ebx,0 + mov [flp_status],0 + ret + +fr_do_1: + push ebx ecx edx + call read_flp_root + pop edx ecx ebx + cmp [FDC_Status],0 + jne fdc_status_error_1 + mov edi,edx + dec ebx + shl ebx,9 + mov esi,FLOPPY_BUFF + add esi,ebx + shl ecx,9 + cld + rep movsb + xor eax,eax + xor ebx,ebx +; mov eax,0 ; ok read +; mov ebx,0 + mov [flp_status],eax + ret +fdc_status_error_1: + xor eax,eax + mov [flp_status],eax + mov eax,10 + or ebx,-1 + ret + +fr_noroot_1: + sub esp,32 + call expand_filename +frfloppy_1: + test ebx,ebx + jnz frfl5_1 + mov ebx,1 +frfl5_1: + test ecx,ecx + jnz frfl6_1 + mov ecx,1 +frfl6_1: + dec ebx + push eax + push eax ebx ecx edx esi edi + call read_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_3_1 + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],1 ; Сторона + mov [FDD_Sector],2 ; Сектор + call SeekTrack + mov dh,14 +l.20_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_3_1 + mov dl,16 + mov edi,FDD_BUFF + inc [FDD_Sector] +l.21_1: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifound_1 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + test dl,dl + jnz l.21_1 + dec dh + test dh,dh + jnz l.20_1 +fdc_status_error_3: + mov eax,5 ; file not found ? + or ebx,-1 + add esp,32+28 + mov [flp_status],0 + ret +fdc_status_error_3_2: + cmp [FDC_Status],0 + je fdc_status_error_3 +fdc_status_error_3_1: + add esp,32+28 + jmp fdc_status_error_1 + +fifound_1: + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + je fifound_2 + add edi,0xf + mov eax,[edi] + and eax,65535 + mov ebx,[path_pointer_flp] + add ebx,36 + call get_cluster_of_a_path_flp + jc fdc_status_error_3_2 + mov ebx,[ebx-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + jmp fifound_3 +fifound_2: + mov ebx,[edi-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + add edi,0xf + mov eax,[edi] +fifound_3: + and eax,65535 + mov [n_sector],eax ;eax=cluster +frnew_1: + add eax,31 ;bootsector+2*fat+filenames + cmp [esp+16],dword 0 ; wanted cluster ? + jne frfl7_1 + call read_chs_sector + cmp [FDC_Status],0 + jne fdc_status_error_5 + mov edi,[esp+8] + call give_back_application_data_1 + add [esp+8],dword 512 + dec dword [esp+12] ; last wanted cluster ? + cmp [esp+12],dword 0 + je frnoread_1 + jmp frfl8_1 +frfl7_1: + dec dword [esp+16] +frfl8_1: + mov edi,[n_sector] + shl edi,1 ;find next cluster from FAT + add edi,FLOPPY_FAT + mov eax,[edi] + and eax,4095 + mov edi,eax + mov [n_sector],edi + cmp edi,4095 ;eof - cluster + jz frnoread2_1 + cmp [esp+24],dword 512 ;eof - size + jb frnoread_1 + sub [esp+24],dword 512 + jmp frnew_1 + +read_chs_sector: + call calculate_chs + call ReadSectWithRetr + ret + +frnoread2_1: + cmp [esp+16],dword 0 ; eof without read ? + je frnoread_1 + mov [fdc_irq_func],fdc_null + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + mov eax,6 ; end of file + mov [flp_status],0 + ret + +frnoread_1: + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + xor eax,eax + mov [flp_status],eax + ret + +fdc_status_error_5: + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + jmp fdc_status_error_1 + +read_flp_root: + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_root_read + cmp [root_read],1 + je unnecessary_root_read + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],1 ; Сторона + mov [FDD_Sector],2 ; Сектор + mov edi,FLOPPY_BUFF + call SeekTrack +read_flp_root_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_root_read + push edi + call give_back_application_data_1 + pop edi + add edi,512 + inc [FDD_Sector] + cmp [FDD_Sector],16 + jne read_flp_root_1 + mov [root_read],1 +unnecessary_root_read: + popa + ret + + +read_flp_fat: + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_flp_fat + cmp [flp_fat],1 + je unnecessary_flp_fat + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],2 ; Сектор + mov edi,FLOPPY_BUFF + call SeekTrack +read_flp_fat_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat + push edi + call give_back_application_data_1 + pop edi + add edi,512 + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne read_flp_fat_1 + mov [FDD_Sector],1 + mov [FDD_Head],1 + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat + call give_back_application_data_1 + call calculatefatchain_flp + mov [root_read],0 + mov [flp_fat],1 +unnecessary_flp_fat: + popa + ret + +calculatefatchain_flp: + pushad + + mov esi,FLOPPY_BUFF + mov edi,FLOPPY_FAT + + fcnew_1: + mov eax,dword [esi] + mov ebx,dword [esi+4] + mov ecx,dword [esi+8] + mov edx,ecx + shr edx,4 ;8 ok + shr dx,4 ;7 ok + xor ch,ch + shld ecx,ebx,20 ;6 ok + shr cx,4 ;5 ok + shld ebx,eax,12 + and ebx,0x0fffffff ;4 ok + shr bx,4 ;3 ok + shl eax,4 + and eax,0x0fffffff ;2 ok + shr ax,4 ;1 ok + mov dword [edi],eax + add edi,4 + mov dword [edi],ebx + add edi,4 + mov dword [edi],ecx + add edi,4 + mov dword [edi],edx + add edi,4 + add esi,12 + + cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters + jnz fcnew_1 + + popad + ret + +check_label: + pushad + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],1 ; Сектор + call SetUserInterrupts + call FDDMotorON + call RecalibrateFDD + cmp [FDC_Status],0 + jne fdc_status_error + call SeekTrack + cmp [FDC_Status],0 + jne fdc_status_error + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error + mov esi,flp_label + mov edi,FDD_BUFF+39 + mov ecx,15 + cld + rep cmpsb + je same_label + mov [root_read],0 + mov [flp_fat],0 +same_label: + mov esi,FDD_BUFF+39 + mov edi,flp_label + mov ecx,15 + cld + rep movsb + popad + ret +fdc_status_error: + popad + ret + +save_flp_root: + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_root_save + cmp [root_read],0 + je unnecessary_root_save + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],1 ; Сторона + mov [FDD_Sector],2 ; Сектор + mov esi,FLOPPY_BUFF + call SeekTrack +save_flp_root_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_root_save + inc [FDD_Sector] + cmp [FDD_Sector],16 + jne save_flp_root_1 +unnecessary_root_save: + mov [fdc_irq_func],fdc_null + popa + ret + +save_flp_fat: + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + cmp [flp_fat],0 + je unnecessary_flp_fat_save + call restorefatchain_flp + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],2 ; Сектор + mov esi,FLOPPY_BUFF + call SeekTrack +save_flp_fat_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne save_flp_fat_1 + mov [FDD_Sector],1 + mov [FDD_Head],1 + call take_data_from_application_1 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + mov [root_read],0 +unnecessary_flp_fat_save: + mov [fdc_irq_func],fdc_null + popa + ret + + +restorefatchain_flp: ; restore fat chain + pushad + + mov esi,FLOPPY_FAT + mov edi,FLOPPY_BUFF + + fcnew2_1: + mov eax,dword [esi] + mov ebx,dword [esi+4] + shl ax,4 + shl eax,4 + shl bx,4 + shr ebx,4 + shrd eax,ebx,8 + shr ebx,8 + mov dword [edi],eax + add edi,4 + mov word [edi],bx + add edi,2 + add esi,8 + + cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT + jb fcnew2_1 + + mov esi,FLOPPY_BUFF ; duplicate fat chain + mov edi,FLOPPY_BUFF+0x1200 + mov ecx,0x1200/4 + cld + rep movsd + + popad + ret + + +save_chs_sector: + call calculate_chs + call WriteSectWithRetr + ret + +calculate_chs: + mov bl,[FDD_Track] + mov [old_track],bl + mov ebx,18 + xor edx,edx + div ebx + inc edx + mov [FDD_Sector],dl + xor edx,edx + mov ebx,2 + div ebx + mov [FDD_Track],al + mov [FDD_Head],0 + test edx,edx + jz no_head_2 + inc [FDD_Head] +no_head_2: + mov dl,[old_track] + cmp dl,[FDD_Track] + je no_seek_track_1 + call SeekTrack +no_seek_track_1: + ret + + +get_cluster_of_a_path_flp: +;--------------------------------------------------------- +; input : EBX = pointer to a path string +; (example: the path "/files/data/document" become +; "files......data.......document...0" +; '.' = space char +; '0' = char(0) (ASCII=0) !!! ) +; output : if (CARRY=1) -> ERROR in the PATH +; if (CARRY=0) -> EAX=cluster +;--------------------------------------------------------- + + push edx + mov edx,ebx + +search_end_of_path_flp: + cmp [save_flag],0 + jne search_end_of_path_flp_1 + cmp byte [edx],0 + je found_end_of_path_flp + jmp search_end_of_path_flp_2 +search_end_of_path_flp_1: + cmp byte [edx+12],0 + je found_end_of_path_flp +search_end_of_path_flp_2: + inc edx ; '/' + call analyze_directory_flp + jc directory_not_found_flp + + mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field + mov ax,[ebx+26] ; read the LOW 16bit cluster field + and eax,0xfff ;[fatMASK] + add edx,11 ; 8+3 (name+extension) + jmp search_end_of_path_flp + +found_end_of_path_flp: + inc edx + mov [pointer_file_name_flp],edx + pop edx + clc ; no errors + ret + +directory_not_found_flp: + pop edx + stc ; errors occour + ret + +analyze_directory_flp: +;-------------------------------- +; input : EAX = first cluster of the directory +; EBX = pointer to filename +; output : IF CARRY=0 EAX = sector where th file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,EDI,EDI not changed +; IF CARRY=1 +;-------------------------------- + push ebx ;[esp+16] + push ecx + push edx + push esi + push edi + + +adr56_flp: + mov [clust_tmp_flp],eax + add eax,31 + pusha + call read_chs_sector + popa + cmp [FDC_Status],0 + jne not_found_file_analyze_flp + + mov ecx,512/32 + mov ebx,FDD_BUFF + +adr1_analyze_flp: + mov esi,edx ;[esp+16] + mov edi,ebx + cld + push ecx + mov ecx,11 + rep cmpsb + pop ecx + je found_file_analyze_flp + + add ebx,32 + loop adr1_analyze_flp + + mov eax,[clust_tmp_flp] + shl eax,1 ;find next cluster from FAT + add eax,FLOPPY_FAT + mov eax,[eax] + and eax,4095 + cmp eax,0x0ff8 + jb adr56_flp +not_found_file_analyze_flp: + pop edi + pop esi + pop edx + pop ecx + add esp,4 + stc ;file not found + ret + +found_file_analyze_flp: + pop edi + pop esi + pop edx + pop ecx + add esp,4 + clc ;file found + ret + + +; \begin{diamond} +fat_find_lfn: +; in: esi->name +; [esp+4] = next +; [esp+8] = first +; [esp+C]... - possibly parameters for first and next +; out: CF=1 - file not found +; else CF=0, esi->next name component, edi->direntry + pusha + lea eax, [esp+0Ch+20h] + call dword [eax-4] + jc .reterr + sub esp, 262*2 ; reserve place for LFN + mov ebp, esp + push 0 ; for fat_get_name: read ASCII name +.l1: + call fat_get_name + jc .l2 + call fat_compare_name + jz .found +.l2: + lea eax, [esp+0Ch+20h+262*2+4] + call dword [eax-8] + jnc .l1 + add esp, 262*2+4 +.reterr: + stc + popa + ret +.found: + add esp, 262*2+4 +; if this is LFN entry, advance to true entry + cmp byte [edi+11], 0xF + jnz @f + lea eax, [esp+0Ch+20h] + call dword [eax-8] + jc .reterr +@@: + add esp, 8 ; CF=0 + push esi + push edi + popa + ret + +uglobal +; this is for delete support +fd_prev_sector dd ? +fd_prev_prev_sector dd ? +endg + +flp_root_next: + cmp edi, OS_BASE+0xD200-0x20 + jae @f + add edi, 0x20 + ret ; CF=0 +@@: +; read next sector + inc dword [eax] + cmp dword [eax], 14 + jae flp_root_first.readerr + push [fd_prev_sector] + pop [fd_prev_prev_sector] + push eax + mov eax, [eax] + add eax, 19-1 + mov [fd_prev_sector], eax + pop eax +flp_root_first: + mov eax, [eax] + pusha + add eax, 19 + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .readerr + mov edi, FDD_BUFF + ret ; CF=0 +.readerr: + stc + ret + +flp_rootmem_first: + mov edi, FLOPPY_BUFF + clc + ret +flp_rootmem_next: + add edi, 0x20 + cmp edi, FLOPPY_BUFF+14*0x200 + cmc +flp_rootmem_next_write: +flp_rootmem_begin_write: +flp_rootmem_end_write: + ret +flp_rootmem_extend_dir: + stc + ret + +flp_notroot_next: + cmp edi, OS_BASE+0xD200-0x20 + jae flp_notroot_next_sector + add edi, 0x20 + ret ; CF=0 +flp_notroot_next_sector: + push ecx + mov ecx, [eax] + push [fd_prev_sector] + pop [fd_prev_prev_sector] + add ecx, 31 + mov [fd_prev_sector], ecx + mov ecx, [(ecx-31)*2+FLOPPY_FAT] + and ecx, 0xFFF + cmp ecx, 2849 + jae flp_notroot_first.err2 + mov [eax], ecx + pop ecx +flp_notroot_first: + mov eax, [eax] + cmp eax, 2 + jb .err + cmp eax, 2849 + jae .err + pusha + add eax, 31 + call read_chs_sector + popa + mov edi, FDD_BUFF + cmp [FDC_Status], 0 + jnz .err + ret ; CF=0 +.err2: + pop ecx +.err: + stc + ret +flp_notroot_begin_write: + pusha + mov eax, [eax] + add eax, 31 + call read_chs_sector + popa + ret +flp_notroot_end_write: + pusha + mov eax, [eax] + add eax, 31 + call save_chs_sector + popa + ret +flp_notroot_next_write: + cmp edi, OS_BASE+0xD200 + jae @f + ret +@@: + call flp_notroot_end_write + jmp flp_notroot_next_sector +flp_notroot_extend_dir: +; find free cluster in FAT + pusha + xor eax, eax + mov edi, FLOPPY_FAT + mov ecx, 2849 + repnz scasw + jnz .notfound + mov word [edi-2], 0xFFF ; mark as last cluster + sub edi, FLOPPY_FAT + shr edi, 1 + dec edi + mov eax, [esp+28] + mov ecx, [eax] + mov [FLOPPY_FAT+ecx*2], di + mov [eax], edi + xor eax, eax + mov edi, FDD_BUFF + mov ecx, 128 + rep stosd + popa + call flp_notroot_end_write + mov edi, FDD_BUFF + clc + ret +.notfound: + popa + stc + ret + +fd_find_lfn: +; in: esi+ebp -> name +; out: CF=1 - file not found +; else CF=0 and edi->direntry, eax=directory cluster (0 for root) + push esi edi + push 0 + push flp_root_first + push flp_root_next +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found +.continue: + test byte [edi+11], 10h + jz .notfound + movzx eax, word [edi+26] ; cluster + mov [esp+8], eax + mov dword [esp+4], flp_notroot_first + mov dword [esp], flp_notroot_next + jmp .loop +.notfound: + add esp, 12 + pop edi esi + stc + ret +.found: + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp + jmp .continue +@@: + mov eax, [esp+8] + add eax, 31 + cmp dword [esp], flp_root_next + jnz @f + add eax, -31+19 +@@: + add esp, 16 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_FloppyRead - LFN variant for reading floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyRead: + call read_flp_fat + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 ; EOF +@@: + movzx edi, word [edi+26] +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + sub ebx, 512 + jae .skip + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err + lea eax, [FDD_BUFF+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx +.skip: + movzx edi, word [edi*2+FLOPPY_FAT] + jmp .new +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + jmp .reteof +.err: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + mov al, 11 + ret + +;---------------------------------------------------------------- +; +; fs_FloppyReadFolder - LFN variant for reading floppy folders +; +; esi points to filename +; ebx pointer to structure: 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyReadFolder: + call read_flp_fat + push edi + cmp byte [esi], 0 + jz .root + call fd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 ; do not allow read files + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + movzx eax, word [edi+26] + add eax, 31 + push 0 + jmp .doit +.root: + mov eax, 19 + push 14 +.doit: + push ecx ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + mov byte [edx], 1 ; version + mov esi, edi ; esi points to BDFE +.main_loop: + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .error + mov edi, FDD_BUFF + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + cmp edi, OS_BASE+0xD200 + jb .do_bdfe + pop eax + inc eax + dec byte [esp+262*2+12] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+FLOPPY_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+12], 0 +@@: + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .error + mov edi, FDD_BUFF + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec ebx + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + cmp edi, OS_BASE+0xD200 + jb .l1 + pop eax + inc eax + dec byte [esp+262*2+12] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+FLOPPY_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+12], 0 +@@: + jmp .main_loop +.error: + add esp, 262*2+4 + pop ebp ecx edi edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.done: + add esp, 262*2+4 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx edi edi + ret + +;---------------------------------------------------------------- +; +; fs_FloppyRewrite - LFN variant for writing sys floppy +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +@@: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +fsfrfe2: + popad +fsfrfe: + mov eax, 11 + xor ebx, ebx + ret + +fs_FloppyCreateFolder: + mov al, 1 + jmp fs_FloppyRewrite.common + +fs_FloppyRewrite: + xor eax, eax +.common: + cmp byte [esi], 0 + jz @b + call read_flp_fat + cmp [FDC_Status], 0 + jnz fsfrfe + pushad + xor edi, edi + push esi + test ebp, ebp + jz @f + mov esi, ebp +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea edi, [esi-1] + jmp @b +@@: + pop esi + test edi, edi + jnz .noroot + test ebp, ebp + jnz .hasebp + call read_flp_root + cmp [FDC_Status], 0 + jnz fsfrfe2 + push flp_rootmem_extend_dir + push flp_rootmem_end_write + push flp_rootmem_next_write + push flp_rootmem_begin_write + xor ebp, ebp + push ebp + push flp_rootmem_first + push flp_rootmem_next + jmp .common1 +.hasebp: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp], 0 + jz .ret1 + push ebp + xor ebp, ebp + call fd_find_lfn + pop esi + jc .notfound0 + jmp .common0 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [edi+1], 0 + jz .ret1 +; check existence + mov byte [edi], 0 + push edi + call fd_find_lfn + pop esi + mov byte [esi], '/' + jnc @f +.notfound0: + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + inc esi +.common0: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + movzx ebp, word [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 + cmp ebp, 2849 + jae .ret1 + push flp_notroot_extend_dir + push flp_notroot_end_write + push flp_notroot_next_write + push flp_notroot_begin_write + push ebp + push flp_notroot_first + push flp_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found + test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 28 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+28+28], 0 + jz @f + add esp, 28 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xchg ax, word [edi+26] ; start cluster + test eax, eax + jz .done1 +@@: + cmp eax, 0xFF8 + jae .done1 + lea edi, [FLOPPY_FAT + eax*2] ; position in FAT + xor eax, eax + xchg ax, [edi] + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 28 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+28 + popa + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+12+8+12+8] + mov [eax], ebp + call dword [eax-4] + pop eax + jnc .scan_dir +.fsfrfe3: + add esp, 8+8+12+28 + popad + mov eax, 11 + xor ebx, ebx + ret +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+12+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + cmp [FDC_Status], 0 + jnz .fsfrfe3 + push eax + lea eax, [esp+12+8+12+8] + call dword [eax+16] ; extend directory + pop eax + jnc .scan_dir + add esp, 8+8+12+28 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+8+8+12+8] + mov [esp+4], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+8] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+8] +; edi points to first entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + lea eax, [esp+8+8+12+8] + call dword [eax+4] ; begin write + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call fs_RamdiskRewrite.read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call fs_RamdiskRewrite.read_symbols + xor eax, eax + stosw + mov cl, 2 + call fs_RamdiskRewrite.read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+8] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +; lea eax, [esp+8+12+8] +; call dword [eax+12] ; end write +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + and word [edi+20], 0 ; high word of cluster + and word [edi+26], 0 ; low word of cluster - to be filled + and dword [edi+28], 0 ; file size - to be filled + cmp byte [esp+28+28], 0 + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov ecx, 32*2 + mov edx, edi +.doit: + lea eax, [esp+8] + call dword [eax+12] ; flush directory + push ecx + push edi + push 0 + mov esi, edx + test ecx, ecx + jz .done + mov ecx, 2849 + mov edi, FLOPPY_FAT + push 0 ; first cluster +.write_loop: +; allocate new cluster + xor eax, eax + repnz scasw + mov al, ERROR_DISK_FULL + jnz .ret + dec edi + dec edi + + mov eax, edi + sub eax, FLOPPY_FAT + + shr eax, 1 ; eax = cluster + mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp+4] + cmp dword [esp], 0 + jz .first + stosw + jmp @f +.first: + mov [esp], eax +@@: + mov edi, [esp+4] + inc ecx +; write data + push ecx edi + mov ecx, 512 + cmp dword [esp+20], ecx + jae @f + mov ecx, [esp+20] +@@: + mov edi, FDD_BUFF + cmp byte [esp+24+28+28], 0 + jnz .writedir + push ecx + rep movsb + pop ecx +.writedircont: + push ecx + sub ecx, 512 + neg ecx + push eax + xor eax, eax + rep stosb + pop eax + add eax, 31 + pusha + call save_chs_sector + popa + pop ecx + cmp [FDC_Status], 0 + jnz .diskerr + sub [esp+20], ecx + pop edi ecx + jnz .write_loop +.done: + xor eax, eax +.ret: + pop ebx edi edi ecx + mov [esp+28+28], eax + lea eax, [esp+8] + call dword [eax+4] + mov [edi+26], bx + mov ebx, esi + sub ebx, edx + mov [edi+28], ebx + call dword [eax+12] + mov [esp+28+16], ebx + test ebp, ebp + jnz @f + call save_flp_root +@@: + add esp, 28 + cmp [FDC_Status], 0 + jnz .err3 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .err3 + popa + ret +.err3: + popa + mov al, 11 + xor ebx, ebx + ret +.diskerr: + sub esi, ecx + mov eax, 11 + pop edi ecx + jmp .ret +.writedir: + push ecx + mov ecx, 32/4 + push ecx esi + rep movsd + pop esi ecx + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov word [edi-32+26], ax + push esi + rep movsd + pop esi + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov ecx, [esp+28+8] + mov word [edi-32+26], cx + pop ecx + jmp .writedircont + +;---------------------------------------------------------------- +; +; fs_FloppyWrite - LFN variant for writing to floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- + +@@: + push ERROR_ACCESS_DENIED +fs_FloppyWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_FloppyWrite.ret11: + push 11 + jmp fs_FloppyWrite.ret0 + +fs_FloppyWrite: + cmp byte [esi], 0 + jz @b + call read_flp_fat + cmp [FDC_Status], 0 + jnz .ret11 + pushad + call fd_find_lfn + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push eax ; save directory cluster + push 0 ; return value=0 + + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + + push dword [edi+28] ; save current file size + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call floppy_extend_file + jnc .length_ok + mov [esp+4], eax +; floppy_extend_file can return two error codes: FAT table error or disk full. +; First case is fatal error, in second case we may write some data + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + pop eax + mov [esp+4+28], eax + pop eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + pop eax + pop eax + mov [esp+4+28], eax ; eax=return value + pop eax + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: +; save FAT & directory +; note that directory must be saved first because save_flp_fat uses buffer at 0xD000 + mov esi, [edi+28] + movzx edi, word [edi+26] ; starting cluster + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jz @f +.device_err: + mov byte [esp+4], 11 + jmp .ret +@@: + +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret + call SetUserInterrupts +.write_loop: +; skip unmodified sectors + cmp dword [esp], 0x200 + jb .modify + sub ebx, 0x200 + jae .skip + add ebx, 0x200 +.modify: + lea eax, [edi+31] ; current sector +; get length of data in current sector + push ecx + sub ebx, 0x200 + jb .hasdata + neg ebx + xor ecx, ecx + jmp @f +.hasdata: + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: +; load sector if needed + cmp dword [esp+4], 0 ; we don't need to read uninitialized data + jz .noread + cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten + jz .noread + cmp ecx, esi ; (same for the last sector) + jz .noread + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jz @f +.device_err2: + pop ecx + jmp .device_err +@@: +.noread: +; zero uninitialized data if file was extended (because floppy_extend_file does not this) + push eax ecx edi + xor eax, eax + mov ecx, 0x200 + sub ecx, [esp+4+12] + jbe @f + mov edi, FDD_BUFF + add edi, [esp+4+12] + rep stosb +@@: +; zero uninitialized data in the last sector + mov ecx, 0x200 + sub ecx, esi + jbe @f + mov edi, FDD_BUFF + add edi, esi + rep stosb +@@: + pop edi ecx eax +; copy new data + push eax + mov eax, edx + neg ebx + jecxz @f + add ebx, FDD_BUFF+0x200 + call memmove + xor ebx, ebx +@@: + pop eax +; save sector + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + add edx, ecx + sub [esp], ecx + pop ecx + jz .done +.skip: +.next_cluster: + movzx edi, word [edi*2+FLOPPY_FAT] + sub esi, 0x200 + jae @f + xor esi, esi +@@: + sub dword [esp], 0x200 + jae .write_loop + and dword [esp], 0 + jmp .write_loop +.done: + mov [fdc_irq_func], fdc_null + jmp .ret + +floppy_extend_file.zero_size: + xor eax, eax + jmp floppy_extend_file.start_extend + +; extends file on floppy to given size (new data area is undefined) +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) +floppy_extend_file: + push ecx +; find the last cluster of file + movzx eax, word [edi+26] ; first cluster + mov ecx, [edi+28] + jecxz .zero_size +@@: + sub ecx, 0x200 + jbe @f + mov eax, [eax*2+FLOPPY_FAT] + and eax, 0xFFF + jz .fat_err + cmp eax, 0xFF8 + jb @b +.fat_err: + pop ecx + push ERROR_FAT_TABLE + pop eax + stc + ret +@@: + push eax + mov eax, [eax*2+FLOPPY_FAT] + and eax, 0xFFF + cmp eax, 0xFF8 + pop eax + jb .fat_err +; set length to full number of sectors + sub [edi+28], ecx +.start_extend: + pop ecx +; now do extend + push edx esi + mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2 + mov edx, 2847 ; number of clusters to scan +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new sector + push ecx + push edi +.scan: + mov ecx, edx + mov edi, esi + jecxz .disk_full + push eax + xor eax, eax + repnz scasw + pop eax + jnz .disk_full + mov word [edi-2], 0xFFF + mov esi, edi + mov edx, ecx + sub edi, FLOPPY_FAT + shr edi, 1 + dec edi ; now edi=new cluster + test eax, eax + jz .first_cluster + mov [FLOPPY_FAT+eax*2], di + jmp @f +.first_cluster: + pop eax ; eax->direntry + push eax + mov [eax+26], di +@@: + mov eax, edi ; eax=new cluster + pop edi ; edi->direntry + pop ecx ; ecx=required size + add dword [edi+28], 0x200 + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop esi edx + xor eax, eax ; CF=0 + ret +.disk_full: + pop edi ecx + pop esi edx + stc + push ERROR_DISK_FULL + pop eax + ret + +;---------------------------------------------------------------- +; +; fs_FloppySetFileEnd - set end of file on floppy +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppySetFileEnd: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + jmp .doret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + pushad + call save_chs_sector + popad + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: +.doret: + mov [fdc_irq_func], fdc_null + ret +.expand: + push ecx + push dword [edi+28] ; save old size + mov ecx, eax + call floppy_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax ecx ecx edi edi + jmp .doret +.device_err: + pop eax +.device_err2: + pop ecx ecx eax edi + push 11 + jmp .ret +.disk_full: +.expand_ok: +; save directory & FAT + mov eax, [edi+28] + xchg eax, [esp+12] + movzx edi, word [edi+26] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err + call SetUserInterrupts +; now zero new data +; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + cmp dword [esp+4], -0x200 + jz .noread + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, FDD_BUFF+0x200 + add edi, [esp+8] + xor eax, eax + mov [esp+8], eax + rep stosb + pop edi + lea eax, [edi+31] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+12], 0x200 + jbe .expand_done + movzx edi, word [FLOPPY_FAT+edi*2] + jmp .zero_loop +.expand_done: + pop eax ecx ecx edi edi + jmp .doret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [FLOPPY_FAT+ecx*2] + jmp @b +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + lea ecx, [FLOPPY_FAT+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 + push 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [FLOPPY_FAT+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + mov edi, [edi+28] +; save directory & FAT + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err2 +; zero last sector, ignore errors + pop eax + add eax, 31 + and edi, 0x1FF + jz .truncate_done + call SetUserInterrupts + pusha + call read_chs_sector + popa + add edi, FDD_BUFF + mov ecx, FDD_BUFF+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pusha + call save_chs_sector + popa +.truncate_done: + pop ecx eax edi + xor eax, eax + jmp .doret + +fs_FloppyGetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jmp fs_GetFileInfo_finish + +ret11: + mov eax, 11 + ret + +fs_FloppySetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + pusha + call save_chs_sector + popa + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: + ret + +;---------------------------------------------------------------- +; +; fs_FloppyDelete - delete file or empty folder from floppy +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyDelete: + call read_flp_fat + cmp [FDC_Status], 0 + jz @f + push 11 + jmp .pop_ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED +.pop_ret: + pop eax + ret +@@: + and [fd_prev_sector], 0 + and [fd_prev_prev_sector], 0 + push edi + call fd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + push eax + movzx eax, word [edi+26] + push ebx + pusha + add eax, 31 + call read_chs_sector + popa + mov ebx, FDD_BUFF + 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + cmp ebx, FDD_BUFF + 0x200 + jb .checkempty + movzx eax, word [FLOPPY_FAT + eax*2] + pusha + add eax, 31 + call read_chs_sector + popa + mov ebx, FDD_BUFF + jmp .checkempty +.notempty: + pop ebx + pop eax +.access_denied2: + pop edi + jmp .access_denied +.empty: + pop ebx + pop eax + pusha + call read_chs_sector + popa +.dodel: + push eax + movzx eax, word [edi+26] + xchg eax, [esp] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + cmp edi, FDD_BUFF + ja @f + cmp [fd_prev_sector], 0 + jz .lfndone + push [fd_prev_sector] + push [fd_prev_prev_sector] + pop [fd_prev_sector] + and [fd_prev_prev_sector], 0 + pusha + call save_chs_sector + popa + pop eax + pusha + call read_chs_sector + popa + mov edi, FDD_BUFF+0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: + pusha + call save_chs_sector + popa +; delete FAT chain + pop eax + test eax, eax + jz .done +@@: + lea eax, [FLOPPY_FAT + eax*2] + push dword [eax] + and word [eax], 0 + pop eax + and eax, 0xFFF + jnz @b +.done: + call save_flp_fat + pop edi + xor eax, eax + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.7.7.0/fs/fat32.inc b/kernel/tags/kolibri0.7.7.0/fs/fat32.inc new file mode 100644 index 000000000..9477eb007 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/fat32.inc @@ -0,0 +1,2917 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; FAT32.INC ;; +;; ;; +;; FAT16/32 functions for KolibriOS ;; +;; ;; +;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; +;; ;; +;; See file COPYING for details ;; +;; 04.02.2007 LFN create folder - diamond ;; +;; 08.10.2006 LFN delete file/folder - diamond ;; +;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;; +;; 17.08.2006 LFN write/append to file - diamond ;; +;; 23.06.2006 LFN start application - diamond ;; +;; 15.06.2006 LFN get/set file/folder info - diamond ;; +;; 27.05.2006 LFN create/rewrite file - diamond ;; +;; 04.05.2006 LFN read folder - diamond ;; +;; 29.04.2006 Elimination of hangup after the ;; +;; expiration hd_wait_timeout - Mario79 ;; +;; 23.04.2006 LFN read file - diamond ;; +;; 28.01.2006 find all Fat16/32 partition in all input point ;; +;; to MBR, see file part_set.inc - Mario79 ;; +;; 15.01.2005 get file size/attr/date, file_append - ATV ;; +;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; +;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; +;; 23.11.2004 don't allow overwrite dir with file - ATV ;; +;; 18.11.2004 get_disk_info and more error codes - ATV ;; +;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; +;; 10.11.2004 removedir clear whole directory structure - ATV ;; +;; 08.11.2004 rename - ATV ;; +;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; +;; 20.10.2004 Makedir/Removedir - ATV ;; +;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; +;; 06.9.2004 Fix free space by Mario79 added - MH ;; +;; 24.5.2004 Write back buffer for File_write -VT ;; +;; 20.5.2004 File_read function to work with syscall 58 - VT ;; +;; 30.3.2004 Error parameters at function return - VT ;; +;; 01.5.2002 Bugfix in device write - VT ;; +;; 20.5.2002 Hd status check - VT ;; +;; 29.6.2002 Improved fat32 verification - VT ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 + +ERROR_SUCCESS = 0 +ERROR_DISK_BASE = 1 +ERROR_UNSUPPORTED_FS = 2 +ERROR_UNKNOWN_FS = 3 +ERROR_PARTITION = 4 +ERROR_FILE_NOT_FOUND = 5 +ERROR_END_OF_FILE = 6 +ERROR_MEMORY_POINTER = 7 +ERROR_DISK_FULL = 8 +ERROR_FAT_TABLE = 9 +ERROR_ACCESS_DENIED = 10 + +PUSHAD_EAX equ [esp+28] +PUSHAD_ECX equ [esp+24] +PUSHAD_EDX equ [esp+20] +PUSHAD_EBX equ [esp+16] +PUSHAD_EBP equ [esp+8] +PUSHAD_ESI equ [esp+4] +PUSHAD_EDI equ [esp+0] + +uglobal +align 4 +partition_count dd 0 ; partitions found by set_FAT32_variables +longname_sec1 dd 0 ; used by analyze_directory to save 2 previous +longname_sec2 dd 0 ; directory sectors for delete long filename + +hd_error dd 0 ; set by wait_for_sector_buffer +hd_setup dd 0 +hd_wait_timeout dd 0 + +cluster_tmp dd 0 ; used by analyze_directory + ; and analyze_directory_to_write + +file_size dd 0 ; used by file_read + +cache_search_start dd 0 ; used by find_empty_slot +endg + +iglobal +fat_in_cache dd -1 +endg + +uglobal +align 4 +fat_cache: times 512 db 0 + Sector512: ; label for dev_hdcd.inc + buffer: times 512 db 0 + fsinfo_buffer: times 512 db 0 +endg + +uglobal + fat16_root db 0 ; flag for fat16 rootdir + fat_change db 0 ; 1=fat has changed +endg + +reserve_hd1: + + cli + cmp [hd1_status],0 + je reserve_ok1 + + sti + call change_task + jmp reserve_hd1 + + reserve_ok1: + + push eax + mov eax,[CURRENT_TASK] + shl eax,5 + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] + mov [hd1_status],eax + pop eax + sti + ret +;******************************************** + +uglobal +hd_in_cache db ? +endg + +reserve_hd_channel: +; BIOS disk accesses are protected with common mutex hd1_status +; This must be modified when hd1_status will not be valid! + cmp [hdpos], 0x80 + jae .ret + cmp [hdbase], 0x1F0 + jne .IDE_Channel_2 +.IDE_Channel_1: + cli + cmp [IDE_Channel_1],0 + je .reserve_ok_1 + sti + call change_task + jmp .IDE_Channel_1 +.IDE_Channel_2: + cli + cmp [IDE_Channel_2],0 + je .reserve_ok_2 + sti + call change_task + jmp .IDE_Channel_2 +.reserve_ok_1: + mov [IDE_Channel_1], 1 + push eax + mov al, 1 + jmp @f +.reserve_ok_2: + mov [IDE_Channel_2], 1 + push eax + mov al, 3 +@@: + cmp [hdid], 1 + sbb al, -1 + cmp al, [hd_in_cache] + jz @f + mov [hd_in_cache], al + call clear_hd_cache +@@: + pop eax +.ret: + ret + +free_hd_channel: +; see comment at reserve_hd_channel + cmp [hdpos], 0x80 + jae .ret + cmp [hdbase], 0x1F0 + jne .IDE_Channel_2 +.IDE_Channel_1: + mov [IDE_Channel_1],0 +.ret: + ret +.IDE_Channel_2: + mov [IDE_Channel_2],0 + ret +;******************************************** +problem_partition db 0 ; used for partitions search + +include 'part_set.inc' + +set_FAT: +;-------------------------------- +; input : EAX = cluster +; EDX = value to save +; output : EDX = old value +;-------------------------------- + push eax ebx esi + + cmp eax,2 + jb sfc_error + cmp eax,[LAST_CLUSTER] + ja sfc_error + cmp [fs_type],16 + je sfc_1 + add eax,eax + sfc_1: + add eax,eax + mov esi,511 + and esi,eax ; esi = position in fat sector + shr eax,9 ; eax = fat sector + add eax,[FAT_START] + mov ebx,fat_cache + + cmp eax,[fat_in_cache] ; is fat sector already in memory? + je sfc_in_cache ; yes + + cmp [fat_change],0 ; is fat changed? + je sfc_no_change ; no + call write_fat_sector ; yes. write it into disk + cmp [hd_error],0 + jne sfc_error + + sfc_no_change: + mov [fat_in_cache],eax ; save fat sector + call hd_read + cmp [hd_error],0 + jne sfc_error + + + sfc_in_cache: + cmp [fs_type],16 + jne sfc_test32 + + sfc_set16: + xchg [ebx+esi],dx ; save new value and get old value + jmp sfc_write + + sfc_test32: + mov eax,[fatMASK] + + sfc_set32: + and edx,eax + xor eax,-1 ; mask for high bits + and eax,[ebx+esi] ; get high 4 bits + or eax,edx + mov edx,[ebx+esi] ; get old value + mov [ebx+esi],eax ; save new value + + sfc_write: + mov [fat_change],1 ; fat has changed + + sfc_nonzero: + and edx,[fatMASK] + + sfc_error: + pop esi ebx eax + ret + + +get_FAT: +;-------------------------------- +; input : EAX = cluster +; output : EAX = next cluster +;-------------------------------- + push ebx esi + + cmp [fs_type],16 + je gfc_1 + add eax,eax + gfc_1: + add eax,eax + mov esi,511 + and esi,eax ; esi = position in fat sector + shr eax,9 ; eax = fat sector + add eax,[FAT_START] + mov ebx,fat_cache + + cmp eax,[fat_in_cache] ; is fat sector already in memory? + je gfc_in_cache + + cmp [fat_change],0 ; is fat changed? + je gfc_no_change ; no + call write_fat_sector ; yes. write it into disk + cmp [hd_error],0 + jne hd_error_01 + + gfc_no_change: + mov [fat_in_cache],eax + call hd_read + cmp [hd_error],0 + jne hd_error_01 + + gfc_in_cache: + mov eax,[ebx+esi] + and eax,[fatMASK] + hd_error_01: + pop esi ebx + ret + + +get_free_FAT: +;----------------------------------------------------------- +; output : if CARRY=0 EAX = # first cluster found free +; if CARRY=1 disk full +; Note : for more speed need to use fat_cache directly +;----------------------------------------------------------- + push ecx + mov ecx,[LAST_CLUSTER] ; counter for full disk + sub ecx,2 + mov eax,[fatStartScan] + cmp eax,2 + jb gff_reset + + gff_test: + cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2 + jbe gff_in_range + gff_reset: + mov eax,2 + + gff_in_range: + push eax + call get_FAT ; get cluster state + cmp [hd_error],0 + jne gff_not_found_1 + + test eax,eax ; is it free? + pop eax + je gff_found ; yes + inc eax ; next cluster + dec ecx ; is all checked? + jns gff_test ; no + + gff_not_found_1: + add esp,4 + gff_not_found: + pop ecx ; yes. disk is full + stc + ret + + gff_found: + lea ecx,[eax+1] + mov [fatStartScan],ecx + pop ecx + clc + ret + + +write_fat_sector: +;----------------------------------------------------------- +; write changed fat to disk +;----------------------------------------------------------- + push eax ebx ecx + + mov [fat_change],0 + mov eax,[fat_in_cache] + cmp eax,-1 + jz write_fat_not_used + mov ebx,fat_cache + mov ecx,[NUMBER_OF_FATS] + + write_next_fat: + call hd_write + cmp [hd_error],0 + jne write_fat_not_used + + add eax,[SECTORS_PER_FAT] + dec ecx + jnz write_next_fat + + write_fat_not_used: + pop ecx ebx eax + ret + + +analyze_directory: +;----------------------------------------------------------- +; input : EAX = first cluster of the directory +; EBX = pointer to filename +; output : IF CARRY=0 EAX = sector where th file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,ESI,EDI not changed +; IF CARRY=1 filename not found +; Note : if cluster=0 it's changed to read rootdir +; save 2 previous directory sectors in longname_sec +;----------------------------------------------------------- + push ecx edx esi edi ebx ; ebx = [esp+0] + mov [longname_sec1],0 + mov [longname_sec2],0 + + adr_new_cluster: + mov [cluster_tmp],eax + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja adr_not_found ; too big cluster number, something is wrong + cmp eax,2 + jnb adr_data_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fs_type],16 + jne adr_data_cluster + mov eax,[ROOT_START] + mov edx,[ROOT_SECTORS] + mov [fat16_root],1 ; flag for fat16 rootdir + jmp adr_new_sector + + adr_data_cluster: + sub eax,2 + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + adr_new_sector: + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne adr_not_found + + mov ecx,512/32 ; count of dir entrys per sector = 16 + + adr_analyze: + mov edi,[ebx+11] ; file attribute + and edi,0xf + cmp edi,0xf + je adr_long_filename + test edi,0x8 ; skip over volume label + jne adr_long_filename ; Note: label can be same name as file/dir + + mov esi,[esp+0] ; filename need to be uppercase + mov edi,ebx + push ecx + mov ecx,11 + cld + rep cmpsb ; compare 8+3 filename + pop ecx + je adr_found + + adr_long_filename: + add ebx,32 ; position of next dir entry + dec ecx + jnz adr_analyze + + mov ecx,[longname_sec1] ; save 2 previous directory sectors + mov [longname_sec1],eax ; for delete long filename + mov [longname_sec2],ecx + inc eax ; next sector + dec edx + jne adr_new_sector + cmp [fat16_root],1 ; end of fat16 rootdir + je adr_not_found + + adr_next_cluster: + mov eax,[cluster_tmp] + call get_FAT ; get next cluster + cmp [hd_error],0 + jne adr_not_found + + cmp eax,2 ; incorrect fat chain? + jb adr_not_found ; yes + cmp eax,[fatRESERVED] ; is it end of directory? + jb adr_new_cluster ; no. analyse it + + adr_not_found: + pop edi edi esi edx ecx ; first edi will remove ebx + stc ; file not found + ret + + adr_found: + pop edi edi esi edx ecx ; first edi will remove ebx + clc ; file found + ret + + +get_data_cluster: +;----------------------------------------------------------- +; input : EAX = cluster +; EBX = pointer to buffer +; EDX = # blocks to read in buffer +; ESI = # blocks to skip over +; output : if CARRY=0 ok EBX/EDX/ESI updated +; if CARRY=1 cluster out of range +; Note : if cluster=0 it's changed to read rootdir +;----------------------------------------------------------- + push eax ecx + + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja gdc_error ; too big cluster number, something is wrong + cmp eax,2 + jnb gdc_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fs_type],16 + jne gdc_cluster + mov eax,[ROOT_START] + mov ecx,[ROOT_SECTORS] ; Note: not cluster size + mov [fat16_root],1 ; flag for fat16 rootdir + jmp gdc_read + + gdc_cluster: + sub eax,2 + mov ecx,[SECTORS_PER_CLUSTER] + imul eax,ecx + add eax,[DATA_START] + + gdc_read: + test esi,esi ; first wanted block + je gdcl1 ; yes, skip count is 0 + dec esi + jmp gdcl2 + + gdcl1: + call hd_read + cmp [hd_error],0 + jne gdc_error + + add ebx,512 ; update pointer + dec edx + + gdcl2: + test edx,edx ; is all read? + je out_of_read + + inc eax ; next sector + dec ecx + jnz gdc_read + + out_of_read: + pop ecx eax + clc + ret + + gdc_error: + pop ecx eax + stc + ret + + +get_cluster_of_a_path: +;--------------------------------------------------------- +; input : EBX = pointer to a path string +; (example: the path "/files/data/document" become +; "files......data.......document...0" +; '.' = space char +; '0' = char(0) (ASCII=0) !!! ) +; output : if (CARRY=1) -> ERROR in the PATH +; if (CARRY=0) -> EAX=cluster +;--------------------------------------------------------- + push ebx edx + + mov eax,[ROOT_CLUSTER] + mov edx,ebx + +search_end_of_path: + cmp byte [edx],0 + je found_end_of_path + + inc edx ; '/' + mov ebx,edx + call analyze_directory + jc directory_not_found + + mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field + mov ax,[ebx+26] ; read the LOW 16bit cluster field + and eax,[fatMASK] + add edx,11 ; 8+3 (name+extension) + jmp search_end_of_path + +found_end_of_path: + pop edx ebx + clc ; no errors + ret + +directory_not_found: + pop edx ebx + stc ; errors occour + ret + + +bcd2bin: +;---------------------------------- +; input : AL=BCD number (eg. 0x11) +; output : AH=0 +; AL=decimal number (eg. 11) +;---------------------------------- + xor ah,ah + shl ax,4 + shr al,4 + aad + ret + + +get_date_for_file: +;----------------------------------------------------- +; Get date from CMOS and pack day,month,year in AX +; DATE bits 0..4 : day of month 0..31 +; 5..8 : month of year 1..12 +; 9..15 : count of years from 1980 +;----------------------------------------------------- + mov al,0x7 ;day + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,5 + + mov al,0x8 ;month + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,4 + + mov al,0x9 ;year + out 0x70,al + in al,0x71 + call bcd2bin + add ax,20 ;because CMOS return only the two last + ;digit (eg. 2000 -> 00 , 2001 -> 01) and we + rol eax,9 ;need the difference with 1980 (eg. 2001-1980) + ret + + +get_time_for_file: +;----------------------------------------------------- +; Get time from CMOS and pack hour,minute,second in AX +; TIME bits 0..4 : second (the low bit is lost) +; 5..10 : minute 0..59 +; 11..15 : hour 0..23 +;----------------------------------------------------- + mov al,0x0 ;second + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,6 + + mov al,0x2 ;minute + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,6 + + mov al,0x4 ;hour + out 0x70,al + in al,0x71 + call bcd2bin + rol eax,11 + ret + + +set_current_time_for_entry: +;----------------------------------------------------- +; Set current time/date for file entry +; input : ebx = file entry pointer +;----------------------------------------------------- + push eax + call get_time_for_file ; update files date/time + mov [ebx+22],ax + call get_date_for_file + mov [ebx+24],ax + pop eax + ret + + + +add_disk_free_space: +;----------------------------------------------------- +; input : ecx = cluster count +; Note : negative = remove clusters from free space +; positive = add clusters to free space +;----------------------------------------------------- + test ecx,ecx ; no change + je add_dfs_no + cmp [fs_type],32 ; free disk space only used by fat32 + jne add_dfs_no + + push eax ebx + mov eax,[ADR_FSINFO] + mov ebx,fsinfo_buffer + call hd_read + cmp [hd_error],0 + jne add_not_fs + + cmp dword [ebx+0x1fc],0xaa550000 ; check sector id + jne add_not_fs + + add [ebx+0x1e8],ecx + push [fatStartScan] + pop dword [ebx+0x1ec] + call hd_write +; cmp [hd_error],0 +; jne add_not_fs + + add_not_fs: + pop ebx eax + + add_dfs_no: + ret + + +file_read: +;-------------------------------------------------------------------------- +; INPUT : user-register register-in-this meaning symbol-in-this +; +; EAX EDI system call to write / +; EBX EAX (PAR0) pointer to file-name PAR0 +; EDX ECX (PAR1) pointer to buffer PAR1 +; ECX EBX (PAR2) vt file blocks to read PAR2 +; ESI EDX (PAR3) pointer to path PAR3 +; EDI ESI vt first 512 block to read +; EDI if 0 - read root +; +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 6 - end of file +; 9 - fat table corrupted +; 10 - access denied +; ebx = size of file/directory +;-------------------------------------------------------------------------- + cmp [fs_type], 16 + jz fat_ok_for_reading + cmp [fs_type], 32 + jz fat_ok_for_reading + xor ebx,ebx + mov eax,ERROR_UNKNOWN_FS + mov [hd1_status], ebx + ret + + fat_ok_for_reading: +; call reserve_hd1 + + pushad + + mov ebx,edx + call get_cluster_of_a_path + jc file_to_read_not_found + + test edi,edi ; read rootdir + jne no_read_root + + xor eax,eax + call get_dir_size ; return rootdir size + cmp [hd_error],0 + jne file_access_denied + + mov [file_size],eax + mov eax,[ROOT_CLUSTER] + jmp file_read_start + + no_read_root: + mov ebx,PUSHAD_EAX ; file name + call analyze_directory + jc file_to_read_not_found + + mov eax,[ebx+28] ; file size + test byte [ebx+11],0x10 ; is it directory? + jz read_set_size ; no + + mov eax,[ebx+20-2] ; FAT entry + mov ax,[ebx+26] + and eax,[fatMASK] + call get_dir_size + cmp [hd_error],0 + jne file_access_denied + + read_set_size: + mov [file_size],eax + + mov eax,[ebx+20-2] ; FAT entry + mov ax,[ebx+26] + and eax,[fatMASK] + + file_read_start: + mov ebx,PUSHAD_ECX ; pointer to buffer + mov edx,PUSHAD_EBX ; file blocks to read + mov esi,PUSHAD_ESI ; first 512 block to read + + file_read_new_cluster: + call get_data_cluster + jc file_read_eof ; end of file or cluster out of range + + test edx,edx ; is all read? + je file_read_OK ; yes + + call get_FAT ; get next cluster + cmp [hd_error],0 + jne file_access_denied + + cmp eax,[fatRESERVED] ; end of file + jnb file_read_eof + cmp eax,2 ; incorrect fat chain + jnb file_read_new_cluster + + popad + mov [hd1_status],0 + mov ebx,[file_size] + mov eax,ERROR_FAT_TABLE + ret + + file_read_eof: + cmp [hd_error],0 + jne file_access_denied + popad + mov [hd1_status],0 + mov ebx,[file_size] + mov eax,ERROR_END_OF_FILE + ret + + file_read_OK: + popad + mov [hd1_status],0 + mov ebx,[file_size] + xor eax,eax + ret + + file_to_read_not_found: + cmp [hd_error],0 + jne file_access_denied + popad + mov [hd1_status],0 + xor ebx,ebx + mov eax,ERROR_FILE_NOT_FOUND + ret + + file_access_denied: + popad + mov [hd1_status],0 + xor ebx,ebx + mov eax,ERROR_ACCESS_DENIED + ret + +get_dir_size: +;----------------------------------------------------- +; input : eax = first cluster (0=rootdir) +; output : eax = directory size in bytes +;----------------------------------------------------- + push edx + xor edx,edx ; count of directory clusters + test eax,eax + jnz dir_size_next + + mov eax,[ROOT_SECTORS] + shl eax,9 ; fat16 rootdir size in bytes + cmp [fs_type],16 + je dir_size_ret + mov eax,[ROOT_CLUSTER] + + dir_size_next: + cmp eax,2 ; incorrect fat chain + jb dir_size_end + cmp eax,[fatRESERVED] ; end of directory + ja dir_size_end + call get_FAT ; get next cluster + cmp [hd_error],0 + jne dir_size_ret + + inc edx + jmp dir_size_next + + dir_size_end: + imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes + imul eax,edx + + dir_size_ret: + pop edx + ret + + +clear_cluster_chain: +;----------------------------------------------------- +; input : eax = first cluster +;----------------------------------------------------- + push eax ecx edx + xor ecx,ecx ; cluster count + + clean_new_chain: + cmp eax,[LAST_CLUSTER] ; end of file + ja delete_OK + cmp eax,2 ; unfinished fat chain or zero length file + jb delete_OK + cmp eax,[ROOT_CLUSTER] ; don't remove root cluster + jz delete_OK + + xor edx,edx + call set_FAT ; clear fat entry + cmp [hd_error],0 + jne access_denied_01 + + inc ecx ; update cluster count + mov eax,edx ; old cluster + jmp clean_new_chain + + delete_OK: + call add_disk_free_space ; add clusters to free disk space + access_denied_01: + pop edx ecx eax + ret + + +get_hd_info: +;----------------------------------------------------------- +; output : eax = 0 - ok +; 3 - unknown FS +; 10 - access denied +; edx = cluster size in bytes +; ebx = total clusters on disk +; ecx = free clusters on disk +;----------------------------------------------------------- + cmp [fs_type], 16 + jz info_fat_ok + cmp [fs_type], 32 + jz info_fat_ok + xor edx,edx + xor ebx,ebx + xor ecx,ecx + mov eax,ERROR_UNKNOWN_FS + ret + + info_fat_ok: +; call reserve_hd1 + + xor ecx,ecx ; count of free clusters + mov eax,2 + mov ebx,[LAST_CLUSTER] + + info_cluster: + push eax + call get_FAT ; get cluster info + cmp [hd_error],0 + jne info_access_denied + + test eax,eax ; is it free? + jnz info_used ; no + inc ecx + + info_used: + pop eax + inc eax + cmp eax,ebx ; is above last cluster? + jbe info_cluster ; no. test next cluster + + dec ebx ; cluster count + imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes + mov [hd1_status],0 + xor eax,eax + ret + + info_access_denied: + add esp,4 + xor edx,edx + xor ebx,ebx + xor ecx,ecx + mov eax,ERROR_ACCESS_DENIED + ret + +update_disk: +;----------------------------------------------------------- +; write changed fat and cache to disk +;----------------------------------------------------------- + cmp [fat_change],0 ; is fat changed? + je upd_no_change + + call write_fat_sector + cmp [hd_error],0 + jne update_disk_acces_denied + + upd_no_change: + + call write_cache + update_disk_acces_denied: + ret + + +; \begin{diamond} +hd_find_lfn: +; in: esi+ebp -> name +; out: CF=1 - file not found +; else CF=0 and edi->direntry, eax=sector +; destroys eax + push esi edi + push 0 + push 0 + push fat16_root_first + push fat16_root_next + mov eax, [ROOT_CLUSTER] + cmp [fs_type], 32 + jz .fat32 +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found +.continue: + test byte [edi+11], 10h + jz .notfound + and dword [esp+12], 0 + mov eax, [edi+20-2] + mov ax, [edi+26] ; cluster +.fat32: + mov [esp+8], eax + mov dword [esp+4], fat_notroot_first + mov dword [esp], fat_notroot_next + jmp .loop +.notfound: + add esp, 16 + pop edi esi + stc + ret +.found: + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp + jmp .continue +@@: + lea eax, [esp+8] + cmp dword [eax], 0 + jz .root + call fat_get_sector + jmp .cmn +.root: + mov eax, [eax+4] + add eax, [ROOT_START] +.cmn: + add esp, 20 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_HdRead - LFN variant for reading hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_HdRead: + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + cmp [fs_type], 1 + jz ntfs_HdRead + or ebx, -1 + mov eax, ERROR_UNKNOWN_FS + ret +@@: + push edi + cmp byte [esi], 0 + jnz @f +.noaccess: + pop edi +.noaccess_2: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret + +@@: + call hd_find_lfn + jnc .found + pop edi + cmp [hd_error],0 + jne .noaccess_2 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + +.found: + test byte [edi+11], 0x10 ; do not allow read directories + jnz .noaccess + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 +@@: + mov eax, [edi+20-2] + mov ax, [edi+26] +; now eax=cluster, ebx=position, ecx=count, edx=buffer for data +.new_cluster: + jecxz .new_sector + test eax, eax + jz .eof + cmp eax, [fatRESERVED] + jae .eof + mov [cluster_tmp], eax + dec eax + dec eax + mov edi, [SECTORS_PER_CLUSTER] + imul eax, edi + add eax, [DATA_START] +.new_sector: + test ecx, ecx + jz .done + sub ebx, 512 + jae .skip + add ebx, 512 + jnz .force_buf + cmp ecx, 512 + jb .force_buf +; we may read directly to given buffer + push ebx + mov ebx, edx + call hd_read + pop ebx + cmp [hd_error],0 + jne .noaccess_1 + add edx, 512 + sub ecx, 512 + jmp .skip +.force_buf: +; we must read sector to temporary buffer and then copy it to destination + push eax ebx + mov ebx, buffer + call hd_read + mov eax, ebx + pop ebx + cmp [hd_error],0 + jne .noaccess_3 + add eax, ebx + push ecx + add ecx, ebx + cmp ecx, 512 + jbe @f + mov ecx, 512 +@@: + sub ecx, ebx + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + pop eax + xor ebx, ebx +.skip: + inc eax + dec edi + jnz .new_sector + mov eax, [cluster_tmp] + call get_FAT + cmp [hd_error],0 + jne .noaccess_1 + + jmp .new_cluster +.noaccess_3: + pop eax +.noaccess_1: + pop eax + push 11 +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof + +;---------------------------------------------------------------- +; +; fs_HdReadFolder - LFN variant for reading hard disk folder +; +; esi points to filename +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_HdReadFolder: + cmp [fs_type], 1 + jz ntfs_HdReadFolder + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNSUPPORTED_FS + pop eax + or ebx, -1 + ret +@@: + mov eax, [ROOT_CLUSTER] + push edi + cmp byte [esi], 0 + jz .doit + call hd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 ; do not allow read files + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + mov eax, [edi+20-2] + mov ax, [edi+26] ; eax=cluster +.doit: + push esi ecx + push ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + mov byte [edx], 1 ; version + mov esi, edi ; esi points to BDFE +.new_cluster: + mov [cluster_tmp], eax + test eax, eax + jnz @f + cmp [fs_type], 32 + jz .notfound + mov eax, [ROOT_START] + push [ROOT_SECTORS] + push ebx + jmp .new_sector +@@: + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + push [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + push ebx +.new_sector: + mov ebx, buffer + mov edi, ebx + call hd_read + cmp [hd_error], 0 + jnz .notfound2 + add ebx, 512 + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + cmp edi, ebx + jb .do_bdfe + pop eax + inc eax + dec dword [esp+4] + jnz @f + mov eax, [cluster_tmp] + test eax, eax + jz .done + call get_FAT + cmp [hd_error], 0 + jnz .notfound2 + cmp eax, 2 + jb .done + cmp eax, [fatRESERVED] + jae .done + push eax + mov eax, [SECTORS_PER_CLUSTER] + mov [esp+8], eax + pop eax + mov [cluster_tmp], eax + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] +@@: + mov ebx, buffer + mov edi, ebx + call hd_read + cmp [hd_error], 0 + jnz .notfound2 + add ebx, 512 + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec dword [esp+4] + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + cmp edi, ebx + jb .l1 + pop eax + inc eax + dec dword [esp+4] + jnz .new_sector + mov eax, [cluster_tmp] + test eax, eax + jz .done + call get_FAT + cmp [hd_error], 0 + jnz .notfound2 + cmp eax, 2 + jb .done + cmp eax, [fatRESERVED] + jae .done + push eax + mov eax, [SECTORS_PER_CLUSTER] + mov [esp+8], eax + pop eax + pop ebx + add esp, 4 + jmp .new_cluster +.notfound2: + add esp, 8 +.notfound: + add esp, 262*2+4 + pop ebp ecx esi edi + mov eax, ERROR_FILE_NOT_FOUND + or ebx, -1 + ret +.done: + add esp, 262*2+4+8 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx esi edi + ret + +fat16_root_next: + cmp edi, buffer+0x200-0x20 + jae fat16_root_next_sector + add edi, 0x20 + ret ; CF=0 +fat16_root_next_sector: +; read next sector + push [longname_sec2] + pop [longname_sec1] + push ecx + mov ecx, [eax+4] + push ecx + add ecx, [ROOT_START] + mov [longname_sec2], ecx + pop ecx + inc ecx + mov [eax+4], ecx + cmp ecx, [ROOT_SECTORS] + pop ecx + jae fat16_root_first.readerr +fat16_root_first: + mov eax, [eax+4] + add eax, [ROOT_START] + push ebx + mov edi, buffer + mov ebx, edi + call hd_read + pop ebx + cmp [hd_error], 0 + jnz .readerr + ret ; CF=0 +.readerr: + stc + ret +fat16_root_begin_write: + push edi eax + call fat16_root_first + pop eax edi + ret +fat16_root_end_write: + pusha + mov eax, [eax+4] + add eax, [ROOT_START] + mov ebx, buffer + call hd_write + popa + ret +fat16_root_next_write: + cmp edi, buffer+0x200 + jae @f + ret +@@: + call fat16_root_end_write + jmp fat16_root_next_sector +fat16_root_extend_dir: + stc + ret + +fat_notroot_next: + cmp edi, buffer+0x200-0x20 + jae fat_notroot_next_sector + add edi, 0x20 + ret ; CF=0 +fat_notroot_next_sector: + push [longname_sec2] + pop [longname_sec1] + push eax + call fat_get_sector + mov [longname_sec2], eax + pop eax + push ecx + mov ecx, [eax+4] + inc ecx + cmp ecx, [SECTORS_PER_CLUSTER] + jae fat_notroot_next_cluster + mov [eax+4], ecx + jmp @f +fat_notroot_next_cluster: + push eax + mov eax, [eax] + call get_FAT + mov ecx, eax + pop eax + cmp [hd_error], 0 + jnz fat_notroot_next_err + cmp ecx, [fatRESERVED] + jae fat_notroot_next_err + mov [eax], ecx + and dword [eax+4], 0 +@@: + pop ecx +fat_notroot_first: + call fat_get_sector + push ebx + mov edi, buffer + mov ebx, edi + call hd_read + pop ebx + cmp [hd_error], 0 + jnz @f + ret ; CF=0 +fat_notroot_next_err: + pop ecx +@@: + stc + ret +fat_notroot_begin_write: + push eax edi + call fat_notroot_first + pop edi eax + ret +fat_notroot_end_write: + call fat_get_sector + push ebx + mov ebx, buffer + call hd_write + pop ebx + ret +fat_notroot_next_write: + cmp edi, buffer+0x200 + jae @f + ret +@@: + push eax + call fat_notroot_end_write + pop eax + jmp fat_notroot_next_sector +fat_notroot_extend_dir: + push eax + call get_free_FAT + jnc .found + pop eax + ret ; CF=1 +.found: + push edx + mov edx, [fatEND] + call set_FAT + mov edx, eax + mov eax, [esp+4] + mov eax, [eax] + push edx + call set_FAT + pop edx + cmp [hd_error], 0 + jz @f + pop edx + pop eax + stc + ret +@@: + push ecx + or ecx, -1 + call add_disk_free_space +; zero new cluster + mov ecx, 512/4 + mov edi, buffer + push edi + xor eax, eax + rep stosd + pop edi + pop ecx + mov eax, [esp+4] + mov [eax], edx + and dword [eax+4], 0 + pop edx + mov eax, [eax] + dec eax + dec eax + push ebx ecx + mov ecx, [SECTORS_PER_CLUSTER] + imul eax, ecx + add eax, [DATA_START] + mov ebx, edi +@@: + call hd_write + inc eax + loop @b + pop ecx ebx eax + clc + ret + +fat_get_sector: + push ecx + mov ecx, [eax] + dec ecx + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + add ecx, [eax+4] + mov eax, ecx + pop ecx + ret + +;---------------------------------------------------------------- +; +; fs_HdRewrite - LFN variant for writing hard disk +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fshrad: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +fshrfs: + mov eax, ERROR_UNKNOWN_FS + xor ebx, ebx + ret + +fs_HdCreateFolder: + mov al, 1 + jmp fs_HdRewrite.common + +fs_HdRewrite: + xor eax, eax +.common: + cmp [fs_type], 1 + jz ntfs_HdRewrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jnz fshrfs +@@: + cmp byte [esi], 0 + jz fshrad + pushad + xor edi, edi + push esi + test ebp, ebp + jz @f + mov esi, ebp +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea edi, [esi-1] + jmp @b +@@: + pop esi + test edi, edi + jnz .noroot + test ebp, ebp + jnz .hasebp + mov ebp, [ROOT_CLUSTER] + cmp [fs_type], 32 + jz .pushnotroot + push fat16_root_extend_dir + push fat16_root_end_write + push fat16_root_next_write + push fat16_root_begin_write + xor ebp, ebp + push ebp + push ebp + push fat16_root_first + push fat16_root_next + jmp .common1 +.hasebp: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp], 0 + jz .ret1 + push ebp + xor ebp, ebp + call hd_find_lfn + pop esi + jc .notfound0 + jmp .common0 +.noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [edi+1], 0 + jz .ret1 +; check existence + mov byte [edi], 0 + push edi + call hd_find_lfn + pop esi + mov byte [esi], '/' + jnc @f +.notfound0: + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + inc esi +.common0: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + mov ebp, [edi+20-2] + mov bp, [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 +.pushnotroot: + push fat_notroot_extend_dir + push fat_notroot_end_write + push fat_notroot_next_write + push fat_notroot_begin_write + push 0 + push ebp + push fat_notroot_first + push fat_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found + test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 32 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+32+28], 0 + jz @f + add esp, 32 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xor ecx, ecx + mov eax, [edi+20-2] + mov ax, [edi+26] + mov word [edi+20], cx + mov word [edi+26], cx + test eax, eax + jz .done1 +@@: + cmp eax, [fatRESERVED] + jae .done1 + push edx + xor edx, edx + call set_FAT + mov eax, edx + pop edx + inc ecx + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 32 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + and dword [eax+4], 0 + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+32 + popa + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+16+8+12+8] + mov [eax], ebp + and dword [eax+4], 0 + call dword [eax-4] + pop eax + jnc .scan_dir +.fsfrfe3: + add esp, 12+8+12+32 + popad + mov eax, 11 + xor ebx, ebx + ret +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+16+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + cmp [hd_error], 0 + jnz .fsfrfe3 + push eax + lea eax, [esp+16+8+12+8] + call dword [eax+20] ; extend directory + pop eax + jnc .scan_dir + add esp, 12+8+12+32 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+12+8+12+8] + mov [esp+4], ecx + mov ecx, [esp+12+8+12+12] + mov [esp+8], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+12] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+12] + pop dword [esp+8+12+12] +; edi points to first entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + lea eax, [esp+8+8+12+8] + call dword [eax+8] ; begin write + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call fs_RamdiskRewrite.read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call fs_RamdiskRewrite.read_symbols + xor eax, eax + stosw + mov cl, 2 + call fs_RamdiskRewrite.read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+12] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +; lea eax, [esp+8+12+8] +; call dword [eax+16] ; end write +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + xor ecx, ecx + mov word [edi+20], cx ; high word of cluster + mov word [edi+26], cx ; low word of cluster - to be filled + mov dword [edi+28], ecx ; file size - to be filled + cmp byte [esp+32+28], cl + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov edx, edi + lea eax, [esp+8] + call dword [eax+16] ; flush directory + push ecx + mov ecx, [SECTORS_PER_CLUSTER] + shl ecx, 9 + jmp .doit2 +.doit: + lea eax, [esp+8] + call dword [eax+16] ; flush directory + push ecx + mov ecx, [esp+4+32+24] +.doit2: + push ecx + push edi + mov esi, edx + test ecx, ecx + jz .done + call get_free_FAT + jc .diskfull + push eax + mov [edi+26], ax + shr eax, 16 + mov [edi+20], ax + lea eax, [esp+16+8] + call dword [eax+16] ; flush directory + pop eax + push edx + mov edx, [fatEND] + call set_FAT + pop edx +.write_cluster: + push eax + dec eax + dec eax + mov ebp, [SECTORS_PER_CLUSTER] + imul eax, ebp + add eax, [DATA_START] +; write data +.write_sector: + cmp byte [esp+16+32+28], 0 + jnz .writedir + mov ecx, 512 + cmp dword [esp+8], ecx + jb .writeshort +; we can write directly from given buffer + mov ebx, esi + add esi, ecx + jmp .writecommon +.writeshort: + mov ecx, [esp+8] + push ecx + mov edi, buffer + mov ebx, edi + rep movsb +.writedircont: + mov ecx, buffer+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pop ecx +.writecommon: + call hd_write + cmp [hd_error], 0 + jnz .writeerr + inc eax + sub dword [esp+8], ecx + jz .writedone + dec ebp + jnz .write_sector +; allocate new cluster + pop eax + mov ecx, eax + call get_free_FAT + jc .diskfull + push edx + mov edx, [fatEND] + call set_FAT + xchg eax, ecx + mov edx, ecx + call set_FAT + pop edx + xchg eax, ecx + jmp .write_cluster +.diskfull: + mov eax, ERROR_DISK_FULL + jmp .ret +.writeerr: + pop eax + sub esi, ecx + mov eax, 11 + jmp .ret +.writedone: + pop eax +.done: + xor eax, eax +.ret: + pop edi ecx + mov ebx, esi + sub ebx, edx + pop ebp + mov [esp+32+28], eax + lea eax, [esp+8] + call dword [eax+8] + mov [edi+28], ebx + call dword [eax+16] + mov [esp+32+16], ebx + lea eax, [ebx+511] + shr eax, 9 + mov ecx, [SECTORS_PER_CLUSTER] + lea eax, [eax+ecx-1] + xor edx, edx + div ecx + mov ecx, ebp + sub ecx, eax + call add_disk_free_space + add esp, 32 + call update_disk + popad + ret +.writedir: + push 512 + mov edi, buffer + mov ebx, edi + mov ecx, [SECTORS_PER_CLUSTER] + shl ecx, 9 + cmp ecx, [esp+12] + jnz .writedircont + dec dword [esp+16] + push esi + mov ecx, 32/4 + rep movsd + pop esi + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + push esi + mov ecx, 32/4 + rep movsd + pop esi + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov ecx, [esp+20+8] + cmp ecx, [ROOT_CLUSTER] + jnz @f + xor ecx, ecx +@@: + mov word [edi-32+26], cx + shr ecx, 16 + mov [edi-32+20], cx + jmp .writedircont + +;---------------------------------------------------------------- +; +; fs_HdWrite - LFN variant for writing to hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +fs_HdWrite.access_denied: + push ERROR_ACCESS_DENIED +fs_HdWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_HdWrite.ret11: + push 11 + jmp fs_HdWrite.ret0 + +fs_HdWrite: + cmp [fs_type], 1 + jz ntfs_HdWrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNKNOWN_FS + jmp .ret0 +@@: + cmp byte [esi], 0 + jz .access_denied + pushad + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + popad + push 11 + jmp .ret0 +@@: + popfd + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push eax ; save directory sector + push 0 ; return value=0 + + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + + push dword [edi+28] ; save current file size + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call hd_extend_file + jnc .length_ok + mov [esp+4], eax +; hd_extend_file can return three error codes: FAT table error, device error or disk full. +; First two cases are fatal errors, in third case we may write some data + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + pop eax + mov [esp+4+28], eax + pop eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + call update_disk + cmp [hd_error], 0 + jz @f + mov byte [esp+4], 11 +@@: + pop eax + pop eax + mov [esp+4+28], eax ; eax=return value + pop eax + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: + mov esi, [edi+28] + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax ; edi=current cluster + xor ebp, ebp ; ebp=current sector in cluster +; save directory + mov eax, [esp+8] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jz @f +.device_err: + mov byte [esp+4], 11 + jmp .ret +@@: + +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret +.write_loop: +; skip unmodified sectors + cmp dword [esp], 0x200 + jb .modify + sub ebx, 0x200 + jae .skip + add ebx, 0x200 +.modify: +; get length of data in current sector + push ecx + sub ebx, 0x200 + jb .hasdata + neg ebx + xor ecx, ecx + jmp @f +.hasdata: + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: +; get current sector number + mov eax, edi + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp +; load sector if needed + cmp dword [esp+4], 0 ; we don't need to read uninitialized data + jz .noread + cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten + jz .noread + cmp ecx, esi ; (same for the last sector) + jz .noread + push ebx + mov ebx, buffer + call hd_read + pop ebx + cmp [hd_error], 0 + jz @f +.device_err2: + pop ecx + jmp .device_err +@@: +.noread: +; zero uninitialized data if file was extended (because hd_extend_file does not this) + push eax ecx edi + xor eax, eax + mov ecx, 0x200 + sub ecx, [esp+4+12] + jbe @f + mov edi, buffer + add edi, [esp+4+12] + rep stosb +@@: +; zero uninitialized data in the last sector + mov ecx, 0x200 + sub ecx, esi + jbe @f + mov edi, buffer + add edi, esi + rep stosb +@@: + pop edi ecx +; copy new data + mov eax, edx + neg ebx + jecxz @f + add ebx, buffer+0x200 + call memmove + xor ebx, ebx +@@: + pop eax +; save sector + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err2 + add edx, ecx + sub [esp], ecx + pop ecx + jz .ret +.skip: +; next sector + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb @f + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .device_err +@@: + sub esi, 0x200 + jae @f + xor esi, esi +@@: + sub dword [esp], 0x200 + jae @f + and dword [esp], 0 +@@: jmp .write_loop + +hd_extend_file.zero_size: + xor eax, eax + jmp hd_extend_file.start_extend + +; extends file on hd to given size (new data area is undefined) +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) +hd_extend_file: + push ebp + mov ebp, [SECTORS_PER_CLUSTER] + imul ebp, [BYTES_PER_SECTOR] + push ecx +; find the last cluster of file + mov eax, [edi+20-2] + mov ax, [edi+26] + mov ecx, [edi+28] + jecxz .zero_size +.last_loop: + sub ecx, ebp + jbe .last_found + call get_FAT + cmp [hd_error], 0 + jz @f +.device_err: + pop ecx +.device_err2: + pop ebp + push 11 +.ret_err: + pop eax + stc + ret +@@: + cmp eax, 2 + jb .fat_err + cmp eax, [fatRESERVED] + jb .last_loop +.fat_err: + pop ecx ebp + push ERROR_FAT_TABLE + jmp .ret_err +.last_found: + push eax + call get_FAT + cmp [hd_error], 0 + jz @f + pop eax + jmp .device_err +@@: + cmp eax, [fatRESERVED] + pop eax + jb .fat_err +; set length to full number of clusters + sub [edi+28], ecx +.start_extend: + pop ecx +; now do extend + push edx + mov edx, 2 ; start scan from cluster 2 +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new cluster + push eax + call get_free_FAT + jc .disk_full + mov edx, [fatEND] + call set_FAT + mov edx, eax + pop eax + test eax, eax + jz .first_cluster + push edx + call set_FAT + pop edx + jmp @f +.first_cluster: + ror edx, 16 + mov [edi+20], dx + ror edx, 16 + mov [edi+26], dx +@@: + push ecx + mov ecx, -1 + call add_disk_free_space + pop ecx + mov eax, edx + cmp [hd_error], 0 + jnz .device_err3 + add [edi+28], ebp + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop edx ebp + xor eax, eax ; CF=0 + ret +.device_err3: + pop edx + jmp .device_err2 +.disk_full: + pop eax edx ebp + push ERROR_DISK_FULL + pop eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: stc + ret + +;---------------------------------------------------------------- +; +; fs_HdSetFileEnd - set end of file on hard disk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdSetFileEnd: + cmp [fs_type], 1 + jz ntfs_HdSetFileEnd + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNKNOWN_FS +.ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + push 11 + jmp .ret +@@: + popfd + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND + jmp .ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax ; save directory sector +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + mov ebx, buffer + call hd_write + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret +.expand: + push ebx ebp ecx + push dword [edi+28] ; save old size + mov ecx, eax + call hd_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full +.pop_ret: + call update_disk + pop eax ecx ebp ebx ecx edi edi + ret +.expand_ok: +.disk_full: +; save directory + mov eax, [edi+28] + xchg eax, [esp+20] + mov ebx, buffer + call hd_write + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax + cmp [hd_error], 0 + jz @f +.pop_ret11: + mov byte [esp], 11 + jmp .pop_ret +@@: +; now zero new data + xor ebp, ebp +; edi=current cluster, ebp=sector in cluster +; [esp+20]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + lea eax, [edi-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp + cmp dword [esp+4], -0x200 + jz .noread + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, buffer+0x200 + add edi, [esp+8] + push eax + xor eax, eax + mov [esp+12], eax + rep stosb + pop eax + pop edi + call hd_write + cmp [hd_error], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+20], 0x200 + jbe .pop_ret + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb .zero_loop + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .pop_ret11 + jmp .zero_loop +.truncate: + mov [edi+28], eax + push ecx + mov ecx, [edi+20-2] + mov cx, [edi+26] + push eax + test eax, eax + jz .zero_size +; find new last cluster +@@: + mov eax, [SECTORS_PER_CLUSTER] + shl eax, 9 + sub [esp], eax + jbe @f + mov eax, ecx + call get_FAT + mov ecx, eax + cmp [hd_error], 0 + jz @b +.device_err3: + pop eax ecx eax edi + push 11 + pop eax + ret +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + push edx + mov eax, ecx + mov edx, [fatEND] + call set_FAT + mov eax, edx + pop edx + cmp [hd_error], 0 + jz @f +.device_err4: + pop ecx + jmp .device_err3 +.zero_size: + and word [edi+20], 0 + and word [edi+26], 0 + push 0 + mov eax, ecx +@@: +; delete FAT chain + call clear_cluster_chain + cmp [hd_error], 0 + jnz .device_err4 +; save directory + mov eax, [esp+12] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err4 +; zero last sector, ignore errors + pop ecx + pop eax + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + push eax + sar eax, 9 + add ecx, eax + pop eax + and eax, 0x1FF + jz .truncate_done + push ebx eax + mov eax, ecx + mov ebx, buffer + call hd_read + pop eax + lea edi, [buffer+eax] + push ecx + mov ecx, 0x200 + sub ecx, eax + xor eax, eax + rep stosb + pop eax + call hd_write + pop ebx +.truncate_done: + pop ecx eax edi + call update_disk + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret + +fs_HdGetFileInfo: + cmp [fs_type], 1 + jz ntfs_HdGetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jmp fs_GetFileInfo_finish + +fs_HdSetFileInfo: + cmp [fs_type], 1 + jz ntfs_HdSetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + mov ebx, buffer + call hd_write + call update_disk + pop edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_HdDelete - delete file or empty folder from hard disk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdDelete: + cmp [fs_type], 1 + jz ntfs_HdDelete + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNKNOWN_FS +.pop_ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED + jmp .pop_ret +@@: + and [longname_sec1], 0 + and [longname_sec2], 0 + push edi + call hd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + pushad + mov ebp, [edi+20-2] + mov bp, [edi+26] + xor ecx, ecx + lea eax, [ebp-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err1 + add ebx, 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + cmp ebx, buffer+0x200 + jb .checkempty + inc ecx + cmp ecx, [SECTORS_PER_CLUSTER] + jb @f + mov eax, ebp + call get_FAT + cmp [hd_error], 0 + jnz .err1 + mov ebp, eax + xor ecx, ecx +@@: + lea eax, [ebp-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ecx + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jz .checkempty +.err1: + popad +.err2: + pop edi + push 11 + pop eax + ret +.notempty: + popad +.access_denied2: + pop edi + push ERROR_ACCESS_DENIED + pop eax + ret +.empty: + popad + push ebx + mov ebx, buffer + call hd_read + pop ebx + cmp [hd_error], 0 + jnz .err2 +.dodel: + push eax + mov eax, [edi+20-2] + mov ax, [edi+26] + xchg eax, [esp] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + cmp edi, buffer + ja @f + cmp [longname_sec2], 0 + jz .lfndone + push [longname_sec2] + push [longname_sec1] + pop [longname_sec2] + and [longname_sec1], 0 + push ebx + mov ebx, buffer + call hd_write + mov eax, [esp+4] + call hd_read + pop ebx + pop eax + mov edi, buffer+0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: + push ebx + mov ebx, buffer + call hd_write + pop ebx +; delete FAT chain + pop eax + call clear_cluster_chain + call update_disk + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.7.7.0/fs/fs.inc b/kernel/tags/kolibri0.7.7.0/fs/fs.inc new file mode 100644 index 000000000..71faa505c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/fs.inc @@ -0,0 +1,797 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; System service for filesystem call ;; +;; (C) 2004 Ville Turjanmaa, License: GPL ;; +;; 29.04.2006 Elimination of hangup after the ;; +;; expiration hd_wait_timeout (for LBA) - Mario79 ;; +;; 15.01.2005 get file size/attr/date, ;; +;; file_append (only for hd) - ATV ;; +;; 23.11.2004 test if hd/partition is set - ATV ;; +;; 18.11.2004 get_disk_info and more error codes - ATV ;; +;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;; +;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +iglobal +dir0: db 'HARDDISK ' + db 'RAMDISK ' + db 'FLOPPYDISK ' + db 0 + +dir1: db 'FIRST ' + db 'SECOND ' + db 'THIRD ' + db 'FOURTH ' + db 0 + +not_select_IDE db 0 + +hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 + dd 0x170,0x00,0x170,0x10 +endg + +file_system: + +; IN: +; +; eax = 0 ; read file /RamDisk/First 6 +; eax = 8 ; lba read +; eax = 15 ; get_disk_info +; +; OUT: +; +; eax = 0 : read ok +; eax = 1 : no hd base and/or partition defined +; eax = 2 : function is unsupported for this FS +; eax = 3 : unknown FS +; eax = 4 : partition not defined at hd +; eax = 5 : file not found +; eax = 6 : end of file +; eax = 7 : memory pointer not in application area +; eax = 8 : disk full +; eax = 9 : fat table corrupted +; eax = 10 : access denied +; eax = 11 : disk error +; +; ebx = size + +; \begin{diamond}[18.03.2006] +; for subfunction 16 (start application) error codes must be negative +; because positive values are valid PIDs +; so possible return values are: +; eax > 0 : process created, eax=PID + +; -0x10 <= eax < 0 : -eax is filesystem error code: +; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined +; eax = -3 = 0xFFFFFFFD : unknown FS +; eax = -5 = 0xFFFFFFFB : file not found +; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file) +; eax = -9 = 0xFFFFFFF7 : fat table corrupted +; eax = -10 = 0xFFFFFFF6 : access denied + +; -0x20 <= eax < -0x10: eax is process creation error code: +; eax = -0x20 = 0xFFFFFFE0 : too many processes +; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable +; eax = -0x1E = 0xFFFFFFE2 : no memory + +; ebx is not changed + +; \end{diamond}[18.03.2006] + + ; Extract parameters + ; add eax, std_application_base_address ; abs start of info block + + cmp dword [eax+0],15 ; GET_DISK_INFO + je fs_info + + cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests + jz no_checks_for_kernel + mov edx,eax + cmp dword [eax+0],1 + jnz .usual_check + mov ebx,[eax+12] + ; add ebx,std_application_base_address + mov ecx,[eax+8] + call check_region + test eax,eax + jnz area_in_app_mem + +.error_output: + mov esi,buffer_failed + call sys_msg_board_str +; mov eax,7 + mov dword [esp+36],7 + ret +iglobal + buffer_failed db 'K : Buffer check failed',13,10,0 +endg +.usual_check: + cmp dword [eax+0],0 + mov ecx,512 + jnz .small_size + mov ecx,[eax+8] + shl ecx,9 +.small_size: + mov ebx,[eax+12] + ; add ebx,std_application_base_address + call check_region + test eax,eax + jz .error_output + area_in_app_mem: + mov eax,edx + no_checks_for_kernel: + + fs_read: + + mov ebx,[eax+20] ; program wants root directory ? + test bl,bl + je fs_getroot + test bh,bh + jne fs_noroot + fs_getroot: +; \begin{diamond}[18.03.2006] +; root - only read is allowed +; other operations return "access denied", eax=10 +; (execute operation returns eax=-10) + cmp dword [eax], 0 + jz .read_root + mov dword [esp+36], 10 + ret +.read_root: +; \end{diamond}[18.03.2006] + mov esi,dir0 + mov edi,[eax+12] + ; add edi,std_application_base_address + mov ecx,11 + push ecx +; cld ; already is + rep movsb + mov al,0x10 + stosb + add edi,32-11-1 + pop ecx + rep movsb + stosb + and dword [esp+36],0 ; ok read + mov dword [esp+24],32*2 ; size of root + ret + + fs_info: ;start of code - Mihasik + push eax + cmp [eax+21],byte 'h' + je fs_info_h + cmp [eax+21],byte 'H' + je fs_info_h + cmp [eax+21],byte 'r' + je fs_info_r + cmp [eax+21],byte 'R' + je fs_info_r + mov eax,3 ;if unknown disk + xor ebx,ebx + xor ecx,ecx + xor edx,edx + jmp fs_info1 + fs_info_r: + call ramdisk_free_space ;if ramdisk + mov ecx,edi ;free space in ecx + shr ecx,9 ;free clusters + mov ebx,2847 ;total clusters + mov edx,512 ;cluster size + xor eax,eax ;always 0 + jmp fs_info1 + fs_info_h: ;if harddisk + call get_hd_info + fs_info1: + pop edi + mov [esp+36],eax + mov [esp+24],ebx ; total clusters on disk + mov [esp+32],ecx ; free clusters on disk + mov [edi],edx ; cluster size in bytes + ret ;end of code - Mihasik + + fs_noroot: + + push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run + push dword [eax+4] ; 512 block number to read + push dword [eax+8] ; bytes to write/append or 512 blocks to read + mov ebx,[eax+12] + ; add ebx,std_application_base_address + push ebx ; abs start of return/save area + + lea esi,[eax+20] ; abs start of dir + filename + mov edi,[eax+16] + ; add edi,std_application_base_address ; abs start of work area + + call expand_pathz + + push edi ; dir start + push ebx ; name of file start + + mov eax,[edi+1] + cmp eax,'RD ' + je fs_yesramdisk + cmp eax,'RAMD' + jne fs_noramdisk + + fs_yesramdisk: + + cmp byte [edi+1+11],0 + je fs_give_dir1 + + mov eax,[edi+1+12] + cmp eax,'1 ' + je fs_yesramdisk_first + cmp eax,'FIRS' + jne fs_noramdisk + + fs_yesramdisk_first: + + cmp dword [esp+20],8 ; LBA read ramdisk + jne fs_no_LBA_read_ramdisk + + mov eax,[esp+16] ; LBA block to read + mov ecx,[esp+8] ; abs pointer to return area + + call LBA_read_ramdisk + jmp file_system_return + + + fs_no_LBA_read_ramdisk: + + cmp dword [esp+20],0 ; READ + jne fs_noramdisk_read + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+16] ; block start + inc ebx + mov ecx,[esp+12] ; block count + mov edx,[esp+8] ; return + mov esi,[esp+0] + sub esi,eax + add esi,12+1 ; file name length + call fileread + + jmp file_system_return + + + fs_noramdisk_read: + fs_noramdisk: + + ;******************************************************************** + mov eax,[edi+1] + cmp eax,'FD ' + je fs_yesflpdisk + cmp eax,'FLOP' + jne fs_noflpdisk + + fs_yesflpdisk: + call reserve_flp + + cmp byte [edi+1+11],0 + je fs_give_dir1 + + mov eax,[edi+1+12] + cmp eax,'1 ' + je fs_yesflpdisk_first + cmp eax,'FIRS' + je fs_yesflpdisk_first + cmp eax,'2 ' + je fs_yesflpdisk_second + cmp eax,'SECO' + jne fs_noflpdisk + jmp fs_yesflpdisk_second + + fs_yesflpdisk_first: + mov [flp_number],1 + jmp fs_yesflpdisk_start + fs_yesflpdisk_second: + mov [flp_number],2 + fs_yesflpdisk_start: + cmp dword [esp+20],0 ; READ + jne fs_noflpdisk_read + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+16] ; block start + inc ebx + mov ecx,[esp+12] ; block count + mov edx,[esp+8] ; return + mov esi,[esp+0] + sub esi,eax + add esi,12+1 ; file name length + call floppy_fileread + + jmp file_system_return + + + fs_noflpdisk_read: + fs_noflpdisk: + ;***************************************************************** + + mov eax,[edi+1] + cmp eax,'HD0 ' + je fs_yesharddisk_IDE0 + cmp eax,'HD1 ' + je fs_yesharddisk_IDE1 + cmp eax,'HD2 ' + je fs_yesharddisk_IDE2 + cmp eax,'HD3 ' + je fs_yesharddisk_IDE3 + jmp old_path_harddisk +fs_yesharddisk_IDE0: + call reserve_hd1 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE1: + call reserve_hd1 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE2: + call reserve_hd1 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE3: + call reserve_hd1 + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 +fs_yesharddisk_partition: + call reserve_hd_channel +; call choice_necessity_partition +; jmp fs_yesharddisk_all + jmp fs_for_new_semantic + +choice_necessity_partition: + mov eax,[edi+1+12] + call StringToNumber + mov [fat32part],eax +choice_necessity_partition_1: + mov ecx,[hdpos] + xor eax,eax + mov [hd_entries], eax ; entries in hd cache + mov edx,DRIVE_DATA+2 + cmp ecx,0x80 + jb search_partition_array + mov ecx,4 + search_partition_array: + mov bl,[edx] + movzx ebx,bl + add eax,ebx + inc edx + loop search_partition_array + mov ecx,[hdpos] + mov edx,BiosDiskPartitions + sub ecx,0x80 + jb .s + je .f + @@: + mov ebx,[edx] + add edx,4 + add eax,ebx + loop @b + jmp .f + .s: + sub eax,ebx + .f: + add eax,[fat32part] + dec eax + xor edx,edx + imul eax,100 + add eax,DRIVE_DATA+0xa + mov [transfer_adress],eax + call partition_data_transfer_1 + ret + + old_path_harddisk: + mov eax,[edi+1] + cmp eax,'HD ' + je fs_yesharddisk + cmp eax,'HARD' + jne fs_noharddisk + + fs_yesharddisk: + cmp dword [esp+20],8 ; LBA read + jne fs_no_LBA_read + mov eax,[esp+16] ; LBA block to read + lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH + mov ecx,[esp+8] ; abs pointer to return area + call LBA_read + jmp file_system_return + + fs_no_LBA_read: + + cmp byte [edi+1+11],0 ; directory read + je fs_give_dir1 + call reserve_hd1 + fs_for_new_semantic: + call choice_necessity_partition + + fs_yesharddisk_all: + mov eax,1 + mov ebx, [esp+24+24] + cmp [hdpos],0 ; is hd base set? + jz hd_err_return + cmp [fat32part],0 ; is partition set? + jnz @f +hd_err_return: + call free_hd_channel + and [hd1_status], 0 + jmp file_system_return +@@: + + cmp dword [esp+20],0 ; READ + jne fs_noharddisk_read + + mov eax,[esp+0] ; /fname + lea edi,[eax+12] + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + + mov ebx,[esp+12] ; count to read + mov ecx,[esp+8] ; buffer + mov edx,[esp+4] + add edx,12*2 ; dir start + sub edi,edx ; path length + mov esi,[esp+16] ; blocks to read + + call file_read + + mov edi,[esp+0] + mov byte [edi],'/' + + call free_hd_channel + and [hd1_status], 0 + jmp file_system_return + + fs_noharddisk_read: + + call free_hd_channel + and [hd1_status], 0 + + fs_noharddisk: +; \begin{diamond}[18.03.2006] + mov eax, 5 ; file not found +; а может быть, возвращать другой код ошибки? + mov ebx, [esp+24+24] ; do not change ebx in application +; \end{diamond}[18.03.2006] + + file_system_return: + + add esp,24 + + mov [esp+36],eax + mov [esp+24],ebx + ret + + + fs_give_dir1: + +; \begin{diamond}[18.03.2006] +; /RD,/FD,/HD - only read is allowed +; other operations return "access denied", eax=10 +; (execute operation returns eax=-10) + cmp dword [esp+20], 0 + jz .read + add esp, 20 + pop ecx + mov dword [esp+36], 10 + ret +.read: +; \end{diamond}[18.03.2006] + mov al,0x10 + mov ebx,1 + mov edi,[esp+8] + mov esi,dir1 + fs_d1_new: + mov ecx,11 +; cld + rep movsb + stosb + add edi,32-11-1 + dec ebx + jne fs_d1_new + + add esp,24 + + and dword [esp+36],0 ; ok read + mov dword [esp+24],32*1 ; dir/data size + ret + + + +LBA_read_ramdisk: + + cmp [lba_read_enabled],1 + je lbarrl1 + + xor ebx,ebx + mov eax,2 + ret + + lbarrl1: + + cmp eax,18*2*80 + jb lbarrl2 + xor ebx,ebx + mov eax,3 + ret + + lbarrl2: + + pushad + + call restorefatchain + + mov edi,ecx + mov esi,eax + + shl esi,9 + add esi,RAMDISK + mov ecx,512/4 +; cld + rep movsd + + popad + + xor ebx,ebx + xor eax,eax + ret + +LBA_read: + +; IN: +; +; eax = LBA block to read +; ebx = pointer to FIRST/SECOND/THIRD/FOURTH +; ecx = abs pointer to return area + + cmp [lba_read_enabled],1 + je lbarl1 + mov eax,2 + ret + + lbarl1: + + call reserve_hd1 + + push eax + push ecx + + mov edi,hd_address_table + mov esi,dir1 + mov eax,[ebx] + mov edx,'1 ' + mov ecx,4 + blar0: + cmp eax,[esi] + je blar2 + cmp eax,edx + je blar2 + inc edx + add edi,8 + add esi,11 + dec ecx + jnz blar0 + + mov eax,1 + mov ebx,1 + jmp LBA_read_ret + + blar2: + mov eax,[edi+0] + mov ebx,[edi+4] + + mov [hdbase],eax + mov [hdid],ebx + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_lba_error + + ; eax = hd port + ; ebx = set for primary (0x00) or slave (0x10) + + cli + + mov edx,eax + inc edx + xor eax,eax + out dx,al + inc edx + inc eax + out dx,al + inc edx + mov eax,[esp+4] + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + and al,1+2+4+8 + add al,bl + add al,128+64+32 + out dx,al + + inc edx + mov al,20h + out dx,al + + sti + + call wait_for_sector_buffer + cmp [hd_error],0 + jne hd_lba_error + + cli + + mov edi,[esp+0] + mov ecx,256 + sub edx,7 + cld + rep insw + + sti + + xor eax,eax + xor ebx,ebx + + LBA_read_ret: + mov [hd_error],0 + mov [hd1_status],0 + add esp,2*4 + + ret + + +expand_pathz: +; IN: +; esi = asciiz path & file +; edi = buffer for path & file name +; OUT: +; edi = directory & file : / 11 + / 11 + / 11 - zero terminated +; ebx = /file name - zero terminated +; esi = pointer after source + + push eax + push ecx + push edi ;[esp+0] + + pathz_start: + mov byte [edi],'/' + inc edi + mov al,32 + mov ecx,11 + cld + rep stosb ; clear filename area + sub edi,11 + mov ebx,edi ; start of dir/file name + + pathz_new_char: + mov al,[esi] + inc esi + cmp al,0 + je pathz_end + + cmp al,'/' + jne pathz_not_path + cmp edi,ebx ; skip first '/' + jz pathz_new_char + lea edi,[ebx+11] ; start of next directory + jmp pathz_start + + pathz_not_path: + cmp al,'.' + jne pathz_not_ext + lea edi,[ebx+8] ; start of extension + jmp pathz_new_char + + pathz_not_ext: + cmp al,'a' + jb pathz_not_low + cmp al,'z' + ja pathz_not_low + sub al,0x20 ; char to uppercase + + pathz_not_low: + mov [edi],al + inc edi + mov eax,[esp+0] ; start_of_dest_path + add eax,512 ; keep maximum path under 512 bytes + cmp edi,eax + jb pathz_new_char + + pathz_end: + cmp ebx,edi ; if path end with '/' + jnz pathz_put_zero ; go back 1 level + sub ebx,12 + + pathz_put_zero: + mov byte [ebx+11],0 + dec ebx ; include '/' char into file name + pop edi + pop ecx + pop eax + ret + +;******************************************* +;* string to number +;* input eax - 4 byte string +;* output eax - number +;******************************************* +StringToNumber: +; ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД +; Вход: +; EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh +; Выход: +; CF - индикатор ошибок: +; 0 - ошибок нет; +; 1 - ошибка +; Если CF=0, то AX - число. + + push bx + push cx + push dx + push edi + mov [partition_string],eax + mov edi,partition_string + xor cx,cx +i1: + mov al,[edi] + cmp al,32 ;13 + je i_exit +; cmp al,'0' +; jb err +; cmp al,'9' +; ja err + sub al,48 + shl cx,1 + jc error + mov bx,cx + shl cx,1 + jc error + shl cx,1 + jc error + add cx,bx + jc error + cbw + add cx,ax + jc error +i3: + inc edi + jmp i1 +i_exit: + mov ax,cx + clc +i4: + movzx eax,ax + pop edi + pop dx + pop cx + pop bx + ret + +error: + stc + jmp i4 + +partition_string: dd 0 + db 32 diff --git a/kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc b/kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc new file mode 100644 index 000000000..5aa794027 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/fs_lfn.inc @@ -0,0 +1,1145 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +image_of_eax EQU esp+36 +image_of_ebx EQU esp+24 + +; System function 70 - files with long names (LFN) +; diamond, 2006 + +iglobal +; in this table names must be in lowercase +rootdirs: + db 2,'rd' + dd fs_OnRamdisk + dd fs_NextRamdisk + db 7,'ramdisk' + dd fs_OnRamdisk + dd fs_NextRamdisk + db 2,'fd' + dd fs_OnFloppy + dd fs_NextFloppy + db 10,'floppydisk' + dd fs_OnFloppy + dd fs_NextFloppy + db 3,'hd0' + dd fs_OnHd0 + dd fs_NextHd0 + db 3,'hd1' + dd fs_OnHd1 + dd fs_NextHd1 + db 3,'hd2' + dd fs_OnHd2 + dd fs_NextHd2 + db 3,'hd3' + dd fs_OnHd3 + dd fs_NextHd3 +;********************************************** + db 3,'cd0' + dd fs_OnCd0 + dd fs_NextCd + db 3,'cd1' + dd fs_OnCd1 + dd fs_NextCd + db 3,'cd2' + dd fs_OnCd2 + dd fs_NextCd + db 3,'cd3' + dd fs_OnCd3 + dd fs_NextCd +;*********************************************** + db 0 + + +virtual_root_query: + dd fs_HasRamdisk + db 'rd',0 + dd fs_HasFloppy + db 'fd',0 + dd fs_HasHd0 + db 'hd0',0 + dd fs_HasHd1 + db 'hd1',0 + dd fs_HasHd2 + db 'hd2',0 + dd fs_HasHd3 + db 'hd3',0 +;********************************************** + dd fs_HasCd0 + db 'cd0',0 + dd fs_HasCd1 + db 'cd1',0 + dd fs_HasCd2 + db 'cd2',0 + dd fs_HasCd3 + db 'cd3',0 +;********************************************** + dd 0 + +fs_additional_handlers: + dd biosdisk_handler, biosdisk_enum_root +; add new handlers here + dd 0 + +endg + +file_system_lfn: +; in: eax->fileinfo block +; operation codes: +; 0 : read file +; 1 : read folder +; 2 : create/rewrite file +; 3 : write/append to file +; 4 : set end of file +; 5 : get file/directory attributes structure +; 6 : set file/directory attributes structure +; 7 : start application +; 8 : delete file +; 9 : create directory + +; parse file name + xchg ebx, eax + lea esi, [ebx+20] + lodsb + test al, al + jnz @f + mov esi, [esi] + lodsb +@@: + cmp al, '/' + jz .notcurdir + dec esi + mov ebp, esi + test al, al + jnz @f + xor ebp, ebp +@@: + mov esi, [current_slot] + mov esi, [esi+APPDATA.cur_dir] + jmp .parse_normal +.notcurdir: + cmp byte [esi], 0 + jz .rootdir + call process_replace_file_name +.parse_normal: + cmp dword [ebx], 7 + jne @F + mov edx, [ebx+4] + mov ebx, [ebx+8] + call fs_execute ; esi+ebp, ebx, edx + mov [image_of_eax], eax + ret +@@: + mov edi, rootdirs-8 + xor ecx, ecx + push esi +.scan1: + pop esi + add edi, ecx + scasd + scasd + mov cl, byte [edi] + test cl, cl + jz .notfound_try + inc edi + push esi +@@: + lodsb + or al, 20h + scasb + loopz @b + jnz .scan1 + lodsb + cmp al, '/' + jz .found1 + test al, al + jnz .scan1 + pop eax +; directory /xxx +.maindir: + mov esi, [edi+4] +.maindir_noesi: + cmp dword [ebx], 1 + jnz .access_denied + xor eax, eax + mov ebp, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + push dword [ebx+4] ; first block + mov ebx, [ebx+8] ; flags +; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler + mov edi, edx + push ecx + mov ecx, 32/4 + rep stosd + pop ecx + mov byte [edx], 1 ; version +.maindir_loop: + call esi + jc .maindir_done + inc dword [edx+8] + dec dword [esp] + jns .maindir_loop + dec ebp + js .maindir_loop + inc dword [edx+4] + mov dword [edi], 0x10 ; attributes: folder + mov dword [edi+4], 1 ; name type: UNICODE + push eax + xor eax, eax + add edi, 8 + push ecx + mov ecx, 40/4-2 + rep stosd + pop ecx + pop eax + push eax edx +; convert number in eax to decimal UNICODE string + push edi + push ecx + push -'0' + mov ecx, 10 +@@: + xor edx, edx + div ecx + push edx + test eax, eax + jnz @b +@@: + pop eax + add al, '0' + stosb + test bl, 1 ; UNICODE name? + jz .ansi2 + mov byte [edi], 0 + inc edi +.ansi2: + test al, al + jnz @b + mov byte [edi-1], 0 + pop ecx + pop edi +; UNICODE name length is 520 bytes, ANSI - 264 + add edi, 520 + test bl, 1 + jnz @f + sub edi, 520-264 +@@: + pop edx eax + jmp .maindir_loop +.maindir_done: + pop eax + mov ebx, [edx+4] + xor eax, eax + dec ebp + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret +; directory / +.rootdir: + cmp dword [ebx], 1 ; read folder? + jz .readroot +.access_denied: + mov dword [image_of_eax], 10 ; access denied + ret + +.readroot: +; virtual root folder - special handler + mov esi, virtual_root_query + mov ebp, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + push dword [ebx+4] ; first block + mov ebx, [ebx+8] ; flags + xor eax, eax +; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area + mov edi, edx + mov ecx, 32/4 + rep stosd + mov byte [edx], 1 ; version +.readroot_loop: + cmp dword [esi], eax + jz .readroot_done_static + call dword [esi] + add esi, 4 + test eax, eax + jnz @f +.readroot_next: + or ecx, -1 + xchg esi, edi + repnz scasb + xchg esi, edi + jmp .readroot_loop +@@: + xor eax, eax + inc dword [edx+8] + dec dword [esp] + jns .readroot_next + dec ebp + js .readroot_next + inc dword [edx+4] + mov dword [edi], 0x10 ; attributes: folder + mov dword [edi+4], ebx ; name type: UNICODE + add edi, 8 + mov ecx, 40/4-2 + rep stosd + push edi +@@: + lodsb + stosb + test bl, 1 + jz .ansi + mov byte [edi], 0 + inc edi +.ansi: + test eax, eax + jnz @b + pop edi + add edi, 520 + test bl, 1 + jnz .readroot_loop + sub edi, 520-264 + jmp .readroot_loop +.readroot_done_static: + mov esi, fs_additional_handlers-8 + sub esp, 16 +.readroot_ah_loop: + add esi, 8 + cmp dword [esi], 0 + jz .readroot_done + xor eax, eax +.readroot_ah_loop2: + push edi + lea edi, [esp+4] + call dword [esi+4] + pop edi + test eax, eax + jz .readroot_ah_loop + inc dword [edx+8] + dec dword [esp+16] + jns .readroot_ah_loop2 + dec ebp + js .readroot_ah_loop2 + push eax + xor eax, eax + inc dword [edx+4] + mov dword [edi], 0x10 ; attributes: folder + mov dword [edi+4], ebx + add edi, 8 + mov ecx, 40/4-2 + rep stosd + push esi edi + lea esi, [esp+12] +@@: + lodsb + stosb + test bl, 1 + jz .ansi3 + mov byte [edi], 0 + inc edi +.ansi3: + test al, al + jnz @b + pop edi esi eax + add edi, 520 + test bl, 1 + jnz .readroot_ah_loop2 + sub edi, 520-264 + jmp .readroot_ah_loop2 +.readroot_done: + add esp, 16 + pop eax + mov ebx, [edx+4] + xor eax, eax + dec ebp + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret +.notfound_try: + mov edi, fs_additional_handlers +@@: + cmp dword [edi], 0 + jz .notfound + call dword [edi] + scasd + scasd + jmp @b +.notfound: + mov dword [image_of_eax], ERROR_FILE_NOT_FOUND + and dword [image_of_ebx], 0 + ret + +.notfounda: + cmp edi, esp + jnz .notfound + add esp, 8 + jmp .notfound + +.found1: + pop eax + cmp byte [esi], 0 + jz .maindir +.found2: +; read partition number + xor ecx, ecx + xor eax, eax +@@: + lodsb + cmp al, '/' + jz .done1 + test al, al + jz .done1 + sub al, '0' + cmp al, 9 + ja .notfounda + lea ecx, [ecx*5] + lea ecx, [ecx*2+eax] + jmp @b +.done1: + jecxz .notfounda + test al, al + jnz @f + dec esi +@@: + cmp byte [esi], 0 + jnz @f + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp +@@: +; now [edi] contains handler address, ecx - partition number, +; esi points to ASCIIZ string - rest of name + jmp dword [edi] + +; handlers for devices +; in: ecx = 0 => query virtual directory /xxx +; in: ecx = partition number +; esi -> relative (for device) name +; ebx -> fileinfo +; ebp = 0 or pointer to rest of name from folder addressed by esi +; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx + +fs_OnRamdisk: + cmp ecx, 1 + jnz file_system_lfn.notfound + mov eax, [ebx] + cmp eax, fs_NumRamdiskServices + jae .not_impl + mov ecx, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + add ebx, 4 + call dword [fs_RamdiskServices + eax*4] + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret +.not_impl: + mov dword [image_of_eax], 2 ; not implemented + ret + +fs_NotImplemented: + mov eax, 2 + ret + +fs_RamdiskServices: + dd fs_RamdiskRead + dd fs_RamdiskReadFolder + dd fs_RamdiskRewrite + dd fs_RamdiskWrite + dd fs_RamdiskSetFileEnd + dd fs_RamdiskGetFileInfo + dd fs_RamdiskSetFileInfo + dd 0 + dd fs_RamdiskDelete + dd fs_RamdiskCreateFolder +fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 + +fs_OnFloppy: + cmp ecx, 2 + ja file_system_lfn.notfound + mov eax, [ebx] + cmp eax, fs_NumFloppyServices + jae fs_OnRamdisk.not_impl + call reserve_flp + mov [flp_number], cl + mov ecx, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + add ebx, 4 + call dword [fs_FloppyServices + eax*4] + and [flp_status], 0 + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret + +fs_FloppyServices: + dd fs_FloppyRead + dd fs_FloppyReadFolder + dd fs_FloppyRewrite + dd fs_FloppyWrite + dd fs_FloppySetFileEnd + dd fs_FloppyGetFileInfo + dd fs_FloppySetFileInfo + dd 0 + dd fs_FloppyDelete + dd fs_FloppyCreateFolder +fs_NumFloppyServices = ($ - fs_FloppyServices)/4 + +fs_OnHd0: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0 + push 1 + jmp fs_OnHd +fs_OnHd1: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0x10 + push 2 + jmp fs_OnHd +fs_OnHd2: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0 + push 3 + jmp fs_OnHd +fs_OnHd3: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0x10 + push 4 +fs_OnHd: + call reserve_hd_channel + pop eax + mov [hdpos], eax + cmp ecx, 0x100 + jae fs_OnHdAndBd.nf + cmp cl, [DRIVE_DATA+1+eax] +fs_OnHdAndBd: + jbe @f +.nf: + call free_hd_channel + and [hd1_status], 0 + mov dword [image_of_eax], 5 ; not found + ret +@@: + mov [fat32part], ecx + push ebx esi + call choice_necessity_partition_1 + pop esi ebx + mov ecx, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + mov eax, [ebx] + cmp eax, fs_NumHdServices + jae .not_impl + add ebx, 4 + call dword [fs_HdServices + eax*4] + call free_hd_channel + and [hd1_status], 0 + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret +.not_impl: + call free_hd_channel + and [hd1_status], 0 + mov dword [image_of_eax], 2 ; not implemented + ret + +fs_HdServices: + dd fs_HdRead + dd fs_HdReadFolder + dd fs_HdRewrite + dd fs_HdWrite + dd fs_HdSetFileEnd + dd fs_HdGetFileInfo + dd fs_HdSetFileInfo + dd 0 + dd fs_HdDelete + dd fs_HdCreateFolder +fs_NumHdServices = ($ - fs_HdServices)/4 + +;******************************************************* +fs_OnCd0: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],0 + push 6 + push 1 + jmp fs_OnCd +fs_OnCd1: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],1 + push 4 + push 2 + jmp fs_OnCd +fs_OnCd2: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],0 + push 2 + push 3 + jmp fs_OnCd +fs_OnCd3: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],1 + push 0 + push 4 +fs_OnCd: + call reserve_cd_channel + pop eax + mov [cdpos], eax + pop eax + cmp ecx, 0x100 + jae .nf + push ecx ebx + mov cl,al + mov bl,[DRIVE_DATA+1] + shr bl,cl + test bl,2 + pop ebx ecx + + jnz @f +.nf: + call free_cd_channel + and [cd_status], 0 + mov dword [image_of_eax], 5 ; not found + ret +@@: + mov ecx, [ebx+12] + mov edx, [ebx+16] + ; add edx, std_application_base_address + mov eax, [ebx] + cmp eax,fs_NumCdServices + jae .not_impl + add ebx, 4 + call dword [fs_CdServices + eax*4] + call free_cd_channel + and [cd_status], 0 + mov [image_of_eax], eax + mov [image_of_ebx], ebx + ret +.not_impl: + call free_cd_channel + and [cd_status], 0 + mov dword [image_of_eax], 2 ; not implemented + ret + +fs_CdServices: + dd fs_CdRead + dd fs_CdReadFolder + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_CdGetFileInfo + dd fs_NotImplemented + dd 0 + dd fs_NotImplemented + dd fs_NotImplemented +fs_NumCdServices = ($ - fs_CdServices)/4 + +;******************************************************* + +fs_HasRamdisk: + mov al, 1 ; we always have ramdisk + ret + +fs_HasFloppy: + cmp byte [DRIVE_DATA], 0 + setnz al + ret + +fs_HasHd0: + mov al, [DRIVE_DATA+1] + and al, 11000000b + cmp al, 01000000b + setz al + ret +fs_HasHd1: + mov al, [DRIVE_DATA+1] + and al, 00110000b + cmp al, 00010000b + setz al + ret +fs_HasHd2: + mov al, [DRIVE_DATA+1] + and al, 00001100b + cmp al, 00000100b + setz al + ret +fs_HasHd3: + mov al, [DRIVE_DATA+1] + and al, 00000011b + cmp al, 00000001b + setz al + ret + +;******************************************************* +fs_HasCd0: + mov al, [DRIVE_DATA+1] + and al, 11000000b + cmp al, 10000000b + setz al + ret +fs_HasCd1: + mov al, [DRIVE_DATA+1] + and al, 00110000b + cmp al, 00100000b + setz al + ret +fs_HasCd2: + mov al, [DRIVE_DATA+1] + and al, 00001100b + cmp al, 00001000b + setz al + ret +fs_HasCd3: + mov al, [DRIVE_DATA+1] + and al, 00000011b + cmp al, 00000010b + setz al + ret +;******************************************************* + +; fs_NextXXX functions: +; in: eax = partition number, from which start to scan +; out: CF=1 => no more partitions +; CF=0 => eax=next partition number + +fs_NextRamdisk: +; we always have /rd/1 + test eax, eax + stc + jnz @f + mov al, 1 + clc +@@: + ret + +fs_NextFloppy: +; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0) + test byte [DRIVE_DATA], 0xF0 + jz .no1 + test eax, eax + jnz .no1 + inc eax + ret ; CF cleared +.no1: + test byte [DRIVE_DATA], 0x0F + jz .no2 + cmp al, 2 + jae .no2 + mov al, 2 + clc + ret +.no2: + stc + ret + +; on hdx, we have partitions from 1 to [0x40002+x] +fs_NextHd0: + push 0 + jmp fs_NextHd +fs_NextHd1: + push 1 + jmp fs_NextHd +fs_NextHd2: + push 2 + jmp fs_NextHd +fs_NextHd3: + push 3 +fs_NextHd: + pop ecx + movzx ecx, byte [DRIVE_DATA+2+ecx] + cmp eax, ecx + jae fs_NextFloppy.no2 + inc eax + clc + ret + +;******************************************************* +fs_NextCd: +; we always have /cdX/1 + test eax, eax + stc + jnz @f + mov al, 1 + clc +@@: + ret +;******************************************************* + +; Additional FS handlers. +; This handler gets the control each time when fn 70 is called +; with unknown item of root subdirectory. +; in: esi -> name +; ebp = 0 or rest of name relative to esi +; out: if the handler processes path, he must not return in file_system_lfn, +; but instead pop return address and return directly to the caller +; otherwise simply return + +; here we test for /bd/... - BIOS disks +biosdisk_handler: + cmp [NumBiosDisks], 0 + jz .ret + mov al, [esi] + or al, 20h + cmp al, 'b' + jnz .ret + mov al, [esi+1] + or al, 20h + cmp al, 'd' + jnz .ret + push esi + inc esi + inc esi + cmp byte [esi], '0' + jb .ret2 + cmp byte [esi], '9' + ja .ret2 + xor edx, edx +@@: + lodsb + test al, al + jz .ok + cmp al, '/' + jz .ok + sub al, '0' + cmp al, 9 + ja .ret2 + lea edx, [edx*5] + lea edx, [edx*2+eax] + jmp @b +.ret2: + pop esi +.ret: + ret +.ok: + cmp al, '/' + jz @f + dec esi +@@: + add dl, 80h + xor ecx, ecx +@@: + cmp dl, [BiosDisksData+ecx*4] + jz .ok2 + inc ecx + cmp ecx, [NumBiosDisks] + jb @b + jmp .ret2 +.ok2: + add esp, 8 + test al, al + jnz @f + mov esi, fs_BdNext + jmp file_system_lfn.maindir_noesi +@@: + push ecx + push fs_OnBd + mov edi, esp + jmp file_system_lfn.found2 + +fs_BdNext: + cmp eax, [BiosDiskPartitions+ecx*4] + inc eax + cmc + ret + +fs_OnBd: + pop edx edx +; edx = disk number, ecx = partition number +; esi+ebp = name + call reserve_hd1 + add edx, 0x80 + mov [hdpos], edx + cmp ecx, [BiosDiskPartitions+(edx-0x80)*4] + jmp fs_OnHdAndBd + +; This handler is called when virtual root is enumerated +; and must return all items which can be handled by this. +; It is called several times, first time with eax=0 +; in: eax = 0 for first call, previously returned value for subsequent calls +; out: eax = 0 => no more items +; eax != 0 => buffer pointed to by edi contains name of item + +; here we enumerate existing BIOS disks /bd +biosdisk_enum_root: + cmp eax, [NumBiosDisks] + jae .end + push eax + movzx eax, byte [BiosDisksData+eax*4] + sub al, 80h + push eax + mov al, 'b' + stosb + mov al, 'd' + stosb + pop eax + cmp al, 10 + jae .big + add al, '0' + stosb + mov byte [edi], 0 + pop eax + inc eax + ret +.end: + xor eax, eax + ret +.big: + push ecx + push -'0' + mov ecx, 10 +@@: + xor edx, edx + div ecx + push edx + test eax, eax + jnz @b + xchg eax, edx +@@: + pop eax + add al, '0' + stosb + jnz @b + pop ecx + pop eax + inc eax + ret + +process_replace_file_name: + mov ebp, [full_file_name_table] + mov edi, [full_file_name_table.size] + dec edi + shl edi, 7 + add edi, ebp +.loop: + cmp edi, ebp + jb .notfound + push esi edi +@@: + cmp byte [edi], 0 + jz .dest_done + lodsb + test al, al + jz .cont + or al, 20h + scasb + jz @b + jmp .cont +.dest_done: + cmp byte [esi], 0 + jz .found + cmp byte [esi], '/' + jnz .cont + inc esi + jmp .found +.cont: + pop edi esi + sub edi, 128 + jmp .loop +.found: + pop edi eax + mov ebp, esi + cmp byte [esi], 0 + lea esi, [edi+64] + jnz .ret +.notfound: + xor ebp, ebp +.ret: + ret + +sys_current_directory: +; mov esi, [current_slot] +; mov esi, [esi+APPDATA.cur_dir] +; mov edx, esi + +;get length string of appdata.cur_dir + mov eax, [current_slot] + mov edi, [eax+APPDATA.cur_dir] + + dec ebx + jz .set + dec ebx + jz .get + ret +.get: +; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len +; for our code: ebx->buffer,ecx=len +max_cur_dir equ 0x1000 + + mov ebx,edi + + push ecx + push edi + + xor eax,eax + mov ecx,max_cur_dir + + repne scasb ;find zerro at and string + jnz .error ; no zero in cur_dir: internal error, should not happen + + sub edi,ebx ;lenght for copy + inc edi + mov [esp+32+8],edi ;return in eax + + cmp edx, edi + jbe @f + mov edx, edi +@@: +;source string + pop esi +;destination string + pop edi + cmp edx, 1 + jbe .ret + + mov al,'/' ;start string with '/' + stosb + mov ecx,edx + rep movsb ;copy string +.ret: ret + +.error: add esp,8 + or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir] + ret +.set: +; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string +; for our code: ebx->string to set +; use generic resolver with APPDATA.cur_dir as destination + push max_cur_dir ;0x1000 + push edi ;destination + mov ebx,ecx + call get_full_file_name + ret + +; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination +; destroys all registers except ebp,esp +get_full_file_name: + push ebp + mov esi, [current_slot] + mov esi, [esi+APPDATA.cur_dir] + mov edx, esi +@@: + inc esi + cmp byte [esi-1], 0 + jnz @b + dec esi + cmp byte [ebx], '/' + jz .set_absolute +; string gives relative path + mov edi, [esp+8] ; destination +.relative: + cmp byte [ebx], 0 + jz .set_ok + cmp word [ebx], '.' + jz .set_ok + cmp word [ebx], './' + jnz @f + add ebx, 2 + jmp .relative +@@: + cmp word [ebx], '..' + jnz .doset_relative + cmp byte [ebx+2], 0 + jz @f + cmp byte [ebx+2], '/' + jnz .doset_relative +@@: + dec esi + cmp byte [esi], '/' + jnz @b + add ebx, 3 + jmp .relative +.set_ok: + cmp edx, edi ; is destination equal to APPDATA.cur_dir? + jz .set_ok.cur_dir + sub esi, edx + cmp esi, [esp+12] + jb .set_ok.copy +.fail: + mov byte [edi], 0 + xor eax, eax ; fail + pop ebp + ret 8 +.set_ok.copy: + mov ecx, esi + mov esi, edx + rep movsb + mov byte [edi], 0 +.ret.ok: + mov al, 1 ; ok + pop ebp + ret 8 +.set_ok.cur_dir: + mov byte [esi], 0 + jmp .ret.ok +.doset_relative: + cmp edx, edi + jz .doset_relative.cur_dir + sub esi, edx + cmp esi, [esp+12] + jae .fail + mov ecx, esi + mov esi, edx + mov edx, edi + rep movsb + jmp .doset_relative.copy +.doset_relative.cur_dir: + mov edi, esi +.doset_relative.copy: + add edx, [esp+12] + mov byte [edi], '/' + inc edi + cmp edi, edx + jae .overflow +@@: + mov al, [ebx] + inc ebx + stosb + test al, al + jz .ret.ok + cmp edi, edx + jb @b +.overflow: + dec edi + jmp .fail +.set_absolute: + lea esi, [ebx+1] + call process_replace_file_name + mov edi, [esp+8] + mov edx, [esp+12] + add edx, edi +.set_copy: + lodsb + stosb + test al, al + jz .set_part2 +.set_copy_cont: + cmp edi, edx + jb .set_copy + jmp .overflow +.set_part2: + mov esi, ebp + xor ebp, ebp + test esi, esi + jz .ret.ok + mov byte [edi-1], '/' + jmp .set_copy_cont diff --git a/kernel/tags/kolibri0.7.7.0/fs/iso9660.inc b/kernel/tags/kolibri0.7.7.0/fs/iso9660.inc new file mode 100644 index 000000000..8f0555e29 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/iso9660.inc @@ -0,0 +1,757 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +uglobal +cd_current_pointer_of_input dd 0 +cd_current_pointer_of_input_2 dd 0 +cd_mem_location dd 0 +cd_counter_block dd 0 +IDE_Channel_1 db 0 +IDE_Channel_2 db 0 +endg + +reserve_cd: + + cli + cmp [cd_status],0 + je reserve_ok2 + + sti + call change_task + jmp reserve_cd + + reserve_ok2: + + push eax + mov eax,[CURRENT_TASK] + shl eax,5 + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] + mov [cd_status],eax + pop eax + sti + ret + +reserve_cd_channel: + cmp [ChannelNumber],1 + jne .IDE_Channel_2 +.IDE_Channel_1: + cli + cmp [IDE_Channel_1],0 + je .reserve_ok_1 + sti + call change_task + jmp .IDE_Channel_1 +.IDE_Channel_2: + cli + cmp [IDE_Channel_2],0 + je .reserve_ok_2 + sti + call change_task + jmp .IDE_Channel_1 +.reserve_ok_1: + mov [IDE_Channel_1],1 + ret +.reserve_ok_2: + mov [IDE_Channel_2],1 + ret + +free_cd_channel: + cmp [ChannelNumber],1 + jne .IDE_Channel_2 +.IDE_Channel_1: + mov [IDE_Channel_1],0 + ret +.IDE_Channel_2: + mov [IDE_Channel_2],0 + ret + +uglobal +cd_status dd 0 +endg + +;---------------------------------------------------------------- +; +; fs_CdRead - LFN variant for reading CD disk +; +; esi points to filename /dir1/dir2/.../dirn/file,0 +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_CdRead: + push edi + cmp byte [esi], 0 + jnz @f +.noaccess: + pop edi +.noaccess_2: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret + +.noaccess_3: + pop eax edx ecx edi + jmp .noaccess_2 + +@@: + call cd_find_lfn + jnc .found + pop edi + cmp [DevErrorCode],0 + jne .noaccess_2 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + +.found: + mov edi,[cd_current_pointer_of_input] + test byte [edi+25],10b ; do not allow read directories + jnz .noaccess + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; end of file + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+10] ; реальный размер файловой секции + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 +@@: + mov eax,[edi+2] + mov [CDSectorAddress],eax +; now eax=cluster, ebx=position, ecx=count, edx=buffer for data +.new_sector: + test ecx, ecx + jz .done + sub ebx, 2048 + jae .next + add ebx, 2048 + jnz .incomplete_sector + cmp ecx, 2048 + jb .incomplete_sector +; we may read and memmove complete sector + mov [CDDataBuf_pointer],edx + call ReadCDWRetr ; читаем сектор файла + cmp [DevErrorCode],0 + jne .noaccess_3 + add edx, 2048 + sub ecx, 2048 +.next: + inc dword [CDSectorAddress] + jmp .new_sector +.incomplete_sector: +; we must read and memmove incomplete sector + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr ; читаем сектор файла + cmp [DevErrorCode],0 + jne .noaccess_3 + push ecx + add ecx, ebx + cmp ecx, 2048 + jbe @f + mov ecx, 2048 +@@: + sub ecx, ebx + push edi esi ecx + mov edi,edx + lea esi, [CDDataBuf + ebx] + cld + rep movsb + pop ecx esi edi + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx + jmp .next + +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof + +;---------------------------------------------------------------- +; +; fs_CdReadFolder - LFN variant for reading CD disk folder +; +; esi points to filename /dir1/dir2/.../dirn/file,0 +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_CdReadFolder: + push edi + call cd_find_lfn + jnc .found + pop edi + cmp [DevErrorCode], 0 + jne .noaccess_1 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + mov edi, [cd_current_pointer_of_input] + test byte [edi+25], 10b ; do not allow read directories + jnz .found_dir + pop edi +.noaccess_1: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + mov eax, [edi+2] ; eax=cluster + mov [CDSectorAddress], eax + mov eax, [edi+10] ; размер директрории +.doit: +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + mov byte [edx], 1 ; version + mov [cd_mem_location], edx + add [cd_mem_location], 32 +; начинаем переброску БДВК в УСВК +;.mainloop: + mov [cd_counter_block], dword 0 + dec dword [CDSectorAddress] + push ecx +.read_to_buffer: + inc dword [CDSectorAddress] + mov [CDDataBuf_pointer], CDDataBuf + call ReadCDWRetr ; читаем сектор директории + cmp [DevErrorCode], 0 + jne .noaccess_1 + call .get_names_from_buffer + sub eax,2048 +; директория закончилась? + ja .read_to_buffer + mov edi, [cd_counter_block] + mov [edx+8], edi + mov edi, [ebx] + sub [edx+4], edi + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx edi + mov ebx, [edx+4] + ret + +.get_names_from_buffer: + mov [cd_current_pointer_of_input_2],CDDataBuf + push eax esi edi edx +.get_names_from_buffer_1: + call cd_get_name + jc .end_buffer + inc dword [cd_counter_block] + mov eax,[cd_counter_block] + cmp [ebx],eax + jae .get_names_from_buffer_1 + test ecx, ecx + jz .get_names_from_buffer_1 + mov edi,[cd_counter_block] + mov [edx+4],edi + dec ecx + mov esi,ebp + mov edi,[cd_mem_location] + add edi,40 + test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE + jnz .unicode +; jmp .unicode +.ansi: + cmp [cd_counter_block],2 + jbe .ansi_parent_directory + cld + lodsw + xchg ah,al + call uni2ansi_char + cld + stosb +; проверка конца файла + mov ax,[esi] + cmp ax,word 3B00h ; сепаратор конца файла ';' + je .cd_get_parameters_of_file_1 +; проверка для файлов не заканчивающихся сепаратором + movzx eax,byte [ebp-33] + add eax,ebp + sub eax,34 + cmp esi,eax + je .cd_get_parameters_of_file_1 +; проверка конца папки + movzx eax,byte [ebp-1] + add eax,ebp + cmp esi,eax + jb .ansi +.cd_get_parameters_of_file_1: + mov [edi],byte 0 + call cd_get_parameters_of_file + add [cd_mem_location],304 + jmp .get_names_from_buffer_1 + +.ansi_parent_directory: + cmp [cd_counter_block],2 + je @f + mov [edi],byte '.' + inc edi + jmp .cd_get_parameters_of_file_1 +@@: + mov [edi],word '..' + add edi,2 + jmp .cd_get_parameters_of_file_1 + +.unicode: + cmp [cd_counter_block],2 + jbe .unicode_parent_directory + cld + movsw +; проверка конца файла + mov ax,[esi] + cmp ax,word 3B00h ; сепаратор конца файла ';' + je .cd_get_parameters_of_file_2 +; проверка для файлов не заканчивающихся сепаратором + movzx eax,byte [ebp-33] + add eax,ebp + sub eax,34 + cmp esi,eax + je .cd_get_parameters_of_file_2 +; проверка конца папки + movzx eax,byte [ebp-1] + add eax,ebp + cmp esi,eax + jb .unicode +.cd_get_parameters_of_file_2: + mov [edi],word 0 + call cd_get_parameters_of_file + add [cd_mem_location],560 + jmp .get_names_from_buffer_1 + +.unicode_parent_directory: + cmp [cd_counter_block],2 + je @f + mov [edi],word 2E00h ; '.' + add edi,2 + jmp .cd_get_parameters_of_file_2 +@@: + mov [edi],dword 2E002E00h ; '..' + add edi,4 + jmp .cd_get_parameters_of_file_2 + +.end_buffer: + pop edx edi esi eax + ret + +cd_get_parameters_of_file: + mov edi,[cd_mem_location] +cd_get_parameters_of_file_1: +; получаем атрибуты файла + xor eax,eax +; файл не архивировался + inc eax + shl eax,1 +; это каталог? + test [ebp-8],byte 2 + jz .file + inc eax +.file: +; метка тома не как в FAT, в этом виде отсутсвует +; файл не является системным + shl eax,3 +; файл является скрытым? (атрибут существование) + test [ebp-8],byte 1 + jz .hidden + inc eax +.hidden: + shl eax,1 +; файл всегда только для чтения, так как это CD + inc eax + mov [edi],eax +; получаем время для файла +;час + movzx eax,byte [ebp-12] + shl eax,8 +;минута + mov al,[ebp-11] + shl eax,8 +;секунда + mov al,[ebp-10] +;время создания файла + mov [edi+8],eax +;время последнего доступа + mov [edi+16],eax +;время последней записи + mov [edi+24],eax +; получаем дату для файла +;год + movzx eax,byte [ebp-15] + add eax,1900 + shl eax,8 +;месяц + mov al,[ebp-14] + shl eax,8 +;день + mov al,[ebp-13] +;дата создания файла + mov [edi+12],eax +;время последнего доступа + mov [edi+20],eax +;время последней записи + mov [edi+28],eax +; получаем тип данных имени + xor eax,eax + test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE + jnz .unicode_1 + mov [edi+4],eax + jmp @f +.unicode_1: + inc eax + mov [edi+4],eax +@@: +; получаем размер файла в байтах + xor eax,eax + mov [edi+32+4],eax + mov eax,[ebp-23] + mov [edi+32],eax + ret + +;---------------------------------------------------------------- +; +; fs_CdGetFileInfo - LFN variant for CD +; get file/directory attributes structure +; +;---------------------------------------------------------------- +fs_CdGetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call cd_find_lfn + pushfd + cmp [DevErrorCode], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + + mov edi, edx + push ebp + mov ebp, [cd_current_pointer_of_input] + add ebp, 33 + call cd_get_parameters_of_file_1 + pop ebp + and dword [edi+4], 0 + pop edi + xor eax, eax + ret + +;---------------------------------------------------------------- +cd_find_lfn: + mov [cd_appl_data],0 +; in: esi+ebp -> name +; out: CF=1 - file not found +; else CF=0 and [cd_current_pointer_of_input] direntry + push eax esi +; 16 сектор начало набора дескрипторов томов + + call WaitUnitReady + cmp [DevErrorCode],0 + jne .access_denied + + call prevent_medium_removal +; тестовое чтение + mov [CDSectorAddress],dword 16 + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr ;_1 + cmp [DevErrorCode],0 + jne .access_denied + +; вычисление последней сессии + call WaitUnitReady + cmp [DevErrorCode],0 + jne .access_denied + call Read_TOC + mov ah,[CDDataBuf+4+4] + mov al,[CDDataBuf+4+5] + shl eax,16 + mov ah,[CDDataBuf+4+6] + mov al,[CDDataBuf+4+7] + add eax,15 + mov [CDSectorAddress],eax +; mov [CDSectorAddress],dword 15 + mov [CDDataBuf_pointer],CDDataBuf + +.start: + inc dword [CDSectorAddress] + call ReadCDWRetr ;_1 + cmp [DevErrorCode],0 + jne .access_denied + +.start_check: +; проверка на вшивость + cmp [CDDataBuf+1],dword 'CD00' + jne .access_denied + cmp [CDDataBuf+5],byte '1' + jne .access_denied +; сектор является терминатором набор дескрипторов томов? + cmp [CDDataBuf],byte 0xff + je .access_denied +; сектор является дополнительным и улучшенным дескриптором тома? + cmp [CDDataBuf],byte 0x2 + jne .start +; сектор является дополнительным дескриптором тома? + cmp [CDDataBuf+6],byte 0x1 + jne .start + +; параметры root директрории + mov eax,[CDDataBuf+0x9c+2] ; начало root директрории + mov [CDSectorAddress],eax + mov eax,[CDDataBuf+0x9c+10] ; размер root директрории + cmp byte [esi], 0 + jnz @f + mov [cd_current_pointer_of_input],CDDataBuf+0x9c + jmp .done +@@: +; начинаем поиск +.mainloop: + dec dword [CDSectorAddress] +.read_to_buffer: + inc dword [CDSectorAddress] + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr ; читаем сектор директории + cmp [DevErrorCode],0 + jne .access_denied + push ebp + call cd_find_name_in_buffer + pop ebp + jnc .found + sub eax,2048 +; директория закончилась? + cmp eax,0 + ja .read_to_buffer +; нет искомого элемента цепочки +.access_denied: + pop esi eax + mov [cd_appl_data],1 + stc + ret +; искомый элемент цепочки найден + .found: +; конец пути файла + cmp byte [esi-1], 0 + jz .done + .nested: + mov eax,[cd_current_pointer_of_input] + push dword [eax+2] + pop dword [CDSectorAddress] ; начало директории + mov eax,[eax+2+8] ; размер директории + jmp .mainloop +; указатель файла найден + .done: + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp + jmp .nested +@@: + pop esi eax + mov [cd_appl_data],1 + clc + ret + +cd_find_name_in_buffer: + mov [cd_current_pointer_of_input_2],CDDataBuf +.start: + call cd_get_name + jc .not_found + call cd_compare_name + jc .start +.found: + clc + ret +.not_found: + stc + ret + +cd_get_name: + push eax + mov ebp,[cd_current_pointer_of_input_2] + mov [cd_current_pointer_of_input],ebp + mov eax,[ebp] + cmp eax,0 ; входы закончились? + je .next_sector + cmp ebp,CDDataBuf+2048 ; буфер закончился? + jae .next_sector + movzx eax, byte [ebp] + add [cd_current_pointer_of_input_2],eax ; следующий вход каталога + add ebp,33 ; указатель установлен на начало имени + pop eax + clc + ret +.next_sector: + pop eax + stc + ret + +cd_compare_name: +; compares ASCIIZ-names, case-insensitive (cp866 encoding) +; in: esi->name, ebp->name +; out: if names match: ZF=1 and esi->next component of name +; else: ZF=0, esi is not changed +; destroys eax + push esi eax edi + mov edi,ebp +.loop: + cld + lodsb + push eax + call char_todown + call ansi2uni_char + xchg ah,al + scasw + pop eax + je .coincides + call char_toupper + call ansi2uni_char + xchg ah,al + sub edi,2 + scasw + jne .name_not_coincide +.coincides: + cmp [esi],byte '/' ; разделитель пути, конец имени текущего элемента + je .done + cmp [esi],byte 0 ; разделитель пути, конец имени текущего элемента + je .done + jmp .loop +.name_not_coincide: + pop edi eax esi + stc + ret +.done: +; проверка конца файла + cmp [edi],word 3B00h ; сепаратор конца файла ';' + je .done_1 +; проверка для файлов не заканчивающихся сепаратором + movzx eax,byte [ebp-33] + add eax,ebp + sub eax,34 + cmp edi,eax + je .done_1 +; проверка конца папки + movzx eax,byte [ebp-1] + add eax,ebp + cmp edi,eax + jne .name_not_coincide +.done_1: + pop edi eax + add esp,4 + inc esi + clc + ret + +char_todown: +; convert character to uppercase, using cp866 encoding +; in: al=symbol +; out: al=converted symbol + cmp al, 'A' + jb .ret + cmp al, 'Z' + jbe .az + cmp al, 'Ђ' + jb .ret + cmp al, 'ђ' + jb .rus1 + cmp al, 'џ' + ja .ret +; 0x90-0x9F -> 0xE0-0xEF + add al, 'а'-'ђ' +.ret: + ret +.rus1: +; 0x80-0x8F -> 0xA0-0xAF +.az: + add al, 0x20 + ret + +uni2ansi_char: +; convert UNICODE character in al to ANSI character in ax, using cp866 encoding +; in: ax=UNICODE character +; out: al=converted ANSI character + cmp ax, 0x80 + jb .ascii + cmp ax, 0x401 + jz .yo1 + cmp ax, 0x451 + jz .yo2 + cmp ax, 0x410 + jb .unk + cmp ax, 0x440 + jb .rus1 + cmp ax, 0x450 + jb .rus2 +.unk: + mov al, '_' + jmp .doit +.yo1: + mov al, 'р' + jmp .doit +.yo2: + mov al, 'с' + jmp .doit +.rus1: +; 0x410-0x43F -> 0x80-0xAF + add al, 0x70 + jmp .doit +.rus2: +; 0x440-0x44F -> 0xE0-0xEF + add al, 0xA0 +.ascii: +.doit: + ret diff --git a/kernel/tags/kolibri0.7.7.0/fs/ntfs.inc b/kernel/tags/kolibri0.7.7.0/fs/ntfs.inc new file mode 100644 index 000000000..a28c48c93 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/ntfs.inc @@ -0,0 +1,1815 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +ntfs_test_bootsec: +; in: ebx->buffer, edx=size of partition +; out: CF set <=> invalid +; 1. Name=='NTFS ' + cmp dword [ebx+3], 'NTFS' + jnz .no + cmp dword [ebx+7], ' ' + jnz .no +; 2. Number of bytes per sector is the same as for physical device +; (that is, 0x200 for hard disk) + cmp word [ebx+11], 0x200 + jnz .no +; 3. Number of sectors per cluster must be power of 2 + movzx eax, byte [ebx+13] + dec eax + js .no + test al, [ebx+13] + jnz .no +; 4. FAT parameters must be zero + cmp word [ebx+14], 0 + jnz .no + cmp dword [ebx+16], 0 + jnz .no + cmp byte [ebx+20], 0 + jnz .no + cmp word [ebx+22], 0 + jnz .no + cmp dword [ebx+32], 0 + jnz .no +; 5. Number of sectors <= partition size + cmp dword [ebx+0x2C], 0 + ja .no + cmp [ebx+0x28], edx + ja .no +; 6. $MFT and $MFTMirr clusters must be within partition + cmp dword [ebx+0x34], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x30] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no + cmp dword [ebx+0x3C], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x38] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no +; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 + movsx eax, byte [ebx+0x40] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x40], al + jnz .no +@@: +; 8. Same for clusters per IndexAllocationBuffer + movsx eax, byte [ebx+0x44] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x44], al + jnz .no +@@: +; OK, this is correct NTFS bootsector + clc + ret +.no: +; No, this bootsector isn't NTFS + stc + ret + +ntfs_setup: ; CODE XREF: part_set.inc +; By given bootsector, initialize some NTFS variables + call ntfs_test_bootsec + jc problem_fat_dec_count + movzx eax, byte [ebx+13] + mov [ntfs_data.sectors_per_cluster], eax + mov eax, [ebx+0x28] + add eax, [PARTITION_START] + dec eax + mov [PARTITION_END], eax + mov [fs_type], 1 + mov eax, [ebx+0x30] + mov [ntfs_data.mft_cluster], eax + mov eax, [ebx+0x38] + mov [ntfs_data.mftmirr_cluster], eax + movsx eax, byte [ebx+0x40] + test eax, eax + js .1 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .2 +.1: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.2: + mov [ntfs_data.frs_size], eax + movsx eax, byte [ebx+0x44] + test eax, eax + js .3 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .4 +.3: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.4: + mov [ntfs_data.iab_size], eax +; allocate space for buffers + add eax, [ntfs_data.frs_size] + push eax + call kernel_alloc + test eax, eax + jz problem_fat_dec_count + mov [ntfs_data.frs_buffer], eax + add eax, [ntfs_data.frs_size] + mov [ntfs_data.iab_buffer], eax +; read $MFT disposition + mov eax, [ntfs_data.mft_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz .usemirr + cmp dword [ebx], 'FILE' + jnz .usemirr + call ntfs_restore_usa_frs + jnc .mftok +.usemirr: + and [hd_error], 0 + mov eax, [ntfs_data.mftmirr_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz @f + cmp dword [ebx], 'FILE' + jnz @f + call ntfs_restore_usa_frs + jnc .mftok +@@: +; $MFT and $MFTMirr invalid! +.fail_free_frs: + push [ntfs_data.frs_buffer] + call kernel_free + jmp problem_fat_dec_count +.fail_free_mft: + push [ntfs_data.mft_retrieval] + call kernel_free + jmp .fail_free_frs +.mftok: +; read $MFT table retrieval information +; start with one page, increase if not enough (when MFT too fragmented) + push ebx + push 0x1000 + call kernel_alloc + pop ebx + test eax, eax + jz .fail_free_frs + mov [ntfs_data.mft_retrieval], eax + and [ntfs_data.mft_retrieval_size], 0 + mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 +; $MFT base record must contain unnamed non-resident $DATA attribute + movzx eax, word [ebx+14h] + add eax, ebx +.scandata: + cmp dword [eax], -1 + jz .fail_free_mft + cmp dword [eax], 0x80 + jnz @f + cmp byte [eax+9], 0 + jz .founddata +@@: + add eax, [eax+4] + jmp .scandata +.founddata: + cmp byte [eax+8], 0 + jz .fail_free_mft +; load first portion of $DATA attribute retrieval information + mov edx, [eax+0x18] + mov [ntfs_data.mft_retrieval_end], edx + mov esi, eax + movzx eax, word [eax+0x20] + add esi, eax + sub esp, 10h +.scanmcb: + call ntfs_decode_mcb_entry + jnc .scanmcbend + call .get_mft_retrieval_ptr + mov edx, [esp] ; block length + mov [eax], edx + mov edx, [esp+8] ; block addr (relative) + mov [eax+4], edx + inc [ntfs_data.mft_retrieval_size] + jmp .scanmcb +.scanmcbend: + add esp, 10h +; there may be other portions of $DATA attribute in auxiliary records; +; if they will be needed, they will be loaded later + + mov [ntfs_data.cur_index_size], 0x1000/0x200 + push 0x1000 + call kernel_alloc + test eax, eax + jz .fail_free_mft + mov [ntfs_data.cur_index_buf], eax + + popad + call free_hd_channel + and [hd1_status], 0 + ret + +.get_mft_retrieval_ptr: + pushad + mov eax, [ntfs_data.mft_retrieval_size] + cmp eax, [ntfs_data.mft_retrieval_alloc] + jnz .ok + add eax, 0x1000/8 + mov [ntfs_data.mft_retrieval_alloc], eax + shl eax, 3 + push eax + call kernel_alloc + test eax, eax + jnz @f + popad + add esp, 14h + jmp .fail_free_mft +@@: + mov esi, [ntfs_data.mft_retrieval] + mov edi, eax + mov ecx, [ntfs_data.mft_retrieval_size] + add ecx, ecx + rep movsd + push [ntfs_data.mft_retrieval] + mov [ntfs_data.mft_retrieval], eax + call kernel_free + mov eax, [ntfs_data.mft_retrieval_size] +.ok: + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + mov [esp+28], eax + popad + ret + +ntfs_read_frs_sector: + push eax ecx + add eax, [PARTITION_START] + mov ecx, [ntfs_data.frs_size] + shr ecx, 9 + mov ebx, [ntfs_data.frs_buffer] + push ebx +@@: + call hd_read + cmp [hd_error], 0 + jnz .fail + add ebx, 0x200 + inc eax + loop @b +.fail: + pop ebx + pop ecx eax + ret + +uglobal +align 4 +ntfs_cur_attr dd ? +ntfs_cur_iRecord dd ? +ntfs_cur_offs dd ? ; in sectors +ntfs_cur_size dd ? ; in sectors +ntfs_cur_buf dd ? +ntfs_cur_read dd ? ; [output] +ntfs_bCanContinue db ? + rb 3 + +ntfs_attrlist_buf rb 0x400 +ntfs_attrlist_mft_buf rb 0x400 +ntfs_bitmap_buf rb 0x400 + +ntfs_attr_iRecord dd ? +ntfs_attr_iBaseRecord dd ? +ntfs_attr_offs dd ? +ntfs_attr_list dd ? +ntfs_attr_size dq ? +ntfs_cur_tail dd ? +endg + +ntfs_read_attr: +; in: global variables +; out: [ntfs_cur_read] + pushad + and [ntfs_cur_read], 0 + cmp [ntfs_cur_iRecord], 0 + jnz .nomft + cmp [ntfs_cur_attr], 0x80 + jnz .nomft + mov eax, [ntfs_data.mft_retrieval_end] + inc eax + mul [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + jbe .nomft +; precalculated part of $Mft $DATA + mov esi, [ntfs_data.mft_retrieval] + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] +; eax = VCN, edx = offset in sectors from beginning of cluster + xor ecx, ecx ; ecx will contain LCN +.mftscan: + add ecx, [esi+4] + sub eax, [esi] + jb @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jnz .mftscan + jmp .nomft +@@: + push ecx + add ecx, eax + add ecx, [esi] + push eax + push edx + mov eax, [ntfs_data.sectors_per_cluster] + mul ecx +; eax = sector on partition + add eax, [PARTITION_START] + pop edx + add eax, edx + mov ebx, [ntfs_cur_buf] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: +; ecx = number of sequential sectors to read + call hd_read + cmp [hd_error], 0 + jnz .errread + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + loop @b + pop ecx + xor eax, eax + xor edx, edx + cmp [ntfs_cur_size], eax + jz @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jz .nomft + jmp .mftscan +@@: + popad + ret +.errread: + pop ecx +.errret: + stc + popad + ret +.nomft: +; 1. Read file record. +; N.B. This will do recursive call of read_attr for $MFT::$Data. + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iRecord], eax + and [ntfs_attr_list], 0 + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + or [ntfs_attr_iBaseRecord], -1 + call ntfs_read_file_record + test eax, eax + jz .errret +; 2. Find required attribute. + mov eax, [ntfs_data.frs_buffer] +; a) For auxiliary records, read base record +; N.B. If base record is present, +; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero + cmp dword [eax+24h], 0 + jz @f + mov eax, [eax+20h] +; test eax, eax +; jz @f +.beginfindattr: + mov [ntfs_attr_iRecord], eax + call ntfs_read_file_record + test eax, eax + jz .errret +@@: +; b) Scan for required attribute and for $ATTR_LIST + mov eax, [ntfs_data.frs_buffer] + movzx ecx, word [eax+14h] + add eax, ecx + mov ecx, [ntfs_cur_attr] + and [ntfs_attr_offs], 0 +.scanattr: + cmp dword [eax], -1 + jz .scandone + cmp dword [eax], ecx + jz .okattr + cmp [ntfs_attr_iBaseRecord], -1 + jnz .scancont + cmp dword [eax], 0x20 ; $ATTR_LIST + jnz .scancont + mov [ntfs_attr_list], eax + jmp .scancont +.okattr: +; ignore named $DATA attributes (aka NTFS streams) + cmp ecx, 0x80 + jnz @f + cmp byte [eax+9], 0 + jnz .scancont +@@: + mov [ntfs_attr_offs], eax +.scancont: + add eax, [eax+4] + jmp .scanattr +.continue: + pushad + and [ntfs_cur_read], 0 +.scandone: +; c) Check for required offset and length + mov ecx, [ntfs_attr_offs] + jecxz .noattr + push [ntfs_cur_size] + push [ntfs_cur_read] + call .doreadattr + pop edx + pop eax + jc @f + cmp [ntfs_bCanContinue], 0 + jz @f + sub edx, [ntfs_cur_read] + neg edx + shr edx, 9 + sub eax, edx + mov [ntfs_cur_size], eax + jnz .not_in_cur +@@: + popad + ret +.noattr: +.not_in_cur: + cmp [ntfs_cur_attr], 0x20 + jz @f + mov ecx, [ntfs_attr_list] + test ecx, ecx + jnz .lookattr +.ret_is_attr: + cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 + popad + ret +.lookattr: +; required attribute or required offset was not found in base record; +; it may be present in auxiliary records; +; scan $ATTR_LIST + mov eax, [ntfs_attr_iBaseRecord] + cmp eax, -1 + jz @f + call ntfs_read_file_record + test eax, eax + jz .errret + or [ntfs_attr_iBaseRecord], -1 +@@: + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + push dword [ntfs_attr_size] + push dword [ntfs_attr_size+4] + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 2 + and [ntfs_cur_read], 0 + mov eax, ntfs_attrlist_buf + cmp [ntfs_cur_iRecord], 0 + jnz @f + mov eax, ntfs_attrlist_mft_buf +@@: + mov [ntfs_cur_buf], eax + push eax + call .doreadattr + pop esi + mov edx, 1 + pop dword [ntfs_attr_size+4] + pop dword [ntfs_attr_size] + mov ebp, [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + or edi, -1 + lea ebp, [ebp+esi-1Ah] +.scanliststart: + mov eax, [ntfs_cur_attr] +.scanlist: + cmp esi, ebp + jae .scanlistdone + cmp eax, [esi] + jz @f +.scanlistcont: + movzx ecx, word [esi+4] + add esi, ecx + jmp .scanlist +@@: +; ignore named $DATA attributes (aka NTFS streams) + cmp eax, 0x80 + jnz @f + cmp byte [esi+6], 0 + jnz .scanlistcont +@@: + push eax + mov eax, [esi+8] + test eax, eax + jnz .testf + mov eax, dword [ntfs_attr_size] + and eax, dword [ntfs_attr_size+4] + cmp eax, -1 + jnz .testfz +; if attribute is in auxiliary records, its size is defined only in first + mov eax, [esi+10h] + call ntfs_read_file_record + test eax, eax + jnz @f +.errret_pop: + pop eax + jmp .errret +@@: + mov eax, [ntfs_data.frs_buffer] + movzx ecx, word [eax+14h] + add eax, ecx + mov ecx, [ntfs_cur_attr] +@@: + cmp dword [eax], -1 + jz .errret_pop + cmp dword [eax], ecx + jz @f +.l1: + add eax, [eax+4] + jmp @b +@@: + cmp eax, 0x80 + jnz @f + cmp byte [eax+9], 0 + jnz .l1 +@@: + cmp byte [eax+8], 0 + jnz .sdnores + mov eax, [eax+10h] + mov dword [ntfs_attr_size], eax + and dword [ntfs_attr_size+4], 0 + jmp .testfz +.sdnores: + mov ecx, [eax+30h] + mov dword [ntfs_attr_size], ecx + mov ecx, [eax+34h] + mov dword [ntfs_attr_size+4], ecx +.testfz: + xor eax, eax +.testf: + imul eax, [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + pop eax + ja @f + mov edi, [esi+10h] ; keep previous iRecord + jmp .scanlistcont +@@: +.scanlistfound: + cmp edi, -1 + jnz @f + popad + ret +@@: + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iBaseRecord], eax + mov eax, edi + jmp .beginfindattr +.sde: + popad + stc + ret +.scanlistdone: + sub ebp, ntfs_attrlist_buf-1Ah + cmp [ntfs_cur_iRecord], 0 + jnz @f + sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf +@@: + cmp ebp, 0x400 + jnz .scanlistfound + inc edx + push esi edi + mov esi, ntfs_attrlist_buf+0x200 + mov edi, ntfs_attrlist_buf + cmp [ntfs_cur_iRecord], 0 + jnz @f + mov esi, ntfs_attrlist_mft_buf+0x200 + mov edi, ntfs_attrlist_mft_buf +@@: + mov ecx, 0x200/4 + rep movsd + mov eax, edi + pop edi esi + sub esi, 0x200 + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + push dword [ntfs_attr_size] + push dword [ntfs_attr_size+4] + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + mov [ntfs_cur_offs], edx + mov [ntfs_cur_size], 1 + and [ntfs_cur_read], 0 + mov [ntfs_cur_buf], eax + mov ecx, [ntfs_attr_list] + push esi edx + call .doreadattr + pop edx esi + mov ebp, [ntfs_cur_read] + pop dword [ntfs_attr_size+4] + pop dword [ntfs_attr_size] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + add ebp, ntfs_attrlist_buf+0x200-0x1A + cmp [ntfs_cur_iRecord], 0 + jnz .scanliststart + add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf + jmp .scanliststart + +.doreadattr: + mov [ntfs_bCanContinue], 0 + cmp byte [ecx+8], 0 + jnz .nonresident + mov eax, [ecx+10h] ; length + mov esi, eax + mov edx, [ntfs_cur_offs] + shr eax, 9 + cmp eax, edx + jb .okret + shl edx, 9 + sub esi, edx + movzx eax, word [ecx+14h] + add edx, eax + add edx, ecx ; edx -> data + mov eax, [ntfs_cur_size] + cmp eax, (0xFFFFFFFF shr 9)+1 + jbe @f + mov eax, (0xFFFFFFFF shr 9)+1 +@@: + shl eax, 9 + cmp eax, esi + jbe @f + mov eax, esi +@@: +; eax = length, edx -> data + mov [ntfs_cur_read], eax + mov ecx, eax + mov eax, edx + mov ebx, [ntfs_cur_buf] + call memmove + and [ntfs_cur_size], 0 ; CF=0 + ret +.nonresident: +; Not all auxiliary records contain correct FileSize info + mov eax, dword [ntfs_attr_size] + mov edx, dword [ntfs_attr_size+4] + push eax + and eax, edx + cmp eax, -1 + pop eax + jnz @f + mov eax, [ecx+30h] ; FileSize + mov edx, [ecx+34h] + mov dword [ntfs_attr_size], eax + mov dword [ntfs_attr_size+4], edx +@@: + add eax, 0x1FF + adc edx, 0 + shrd eax, edx, 9 + sub eax, [ntfs_cur_offs] + ja @f +; return with nothing read + and [ntfs_cur_size], 0 +.okret: + clc + ret +@@: +; reduce read length + and [ntfs_cur_tail], 0 + cmp [ntfs_cur_size], eax + jb @f + mov [ntfs_cur_size], eax + mov eax, dword [ntfs_attr_size] + and eax, 0x1FF + mov [ntfs_cur_tail], eax +@@: + cmp [ntfs_cur_size], 0 + jz .okret + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] + sub eax, [ecx+10h] ; first_vbo + jb .okret +; eax = cluster, edx = starting sector + sub esp, 10h + movzx esi, word [ecx+20h] ; mcb_info_ofs + add esi, ecx + xor ebp, ebp +.readloop: + call ntfs_decode_mcb_entry + jnc .break + add ebp, [esp+8] + sub eax, [esp] + jae .readloop + push ecx + push eax + add eax, [esp+8] + add eax, ebp + imul eax, [ntfs_data.sectors_per_cluster] + add eax, edx + add eax, [PARTITION_START] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: + mov ebx, [ntfs_cur_buf] +@@: + call hd_read + cmp [hd_error], 0 + jnz .errread2 + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + loop @b + pop ecx + xor eax, eax + xor edx, edx + cmp [ntfs_cur_size], 0 + jnz .readloop + add esp, 10h + mov eax, [ntfs_cur_tail] + test eax, eax + jz @f + sub eax, 0x200 + add [ntfs_cur_read], eax +@@: + clc + ret +.errread2: + pop ecx + add esp, 10h + stc + ret +.break: + add esp, 10h ; CF=0 + mov [ntfs_bCanContinue], 1 + ret + +ntfs_read_file_record: +; in: eax=iRecord +; out: [ntfs_data.frs_buffer] contains information +; eax=0 - failed, eax=1 - success +; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] + push ecx edx + mov ecx, [ntfs_data.frs_size] + mul ecx + shrd eax, edx, 9 + shr edx, 9 + jnz .err + push [ntfs_attr_iRecord] + push [ntfs_attr_iBaseRecord] + push [ntfs_attr_offs] + push [ntfs_attr_list] + push dword [ntfs_attr_size+4] + push dword [ntfs_attr_size] + push [ntfs_cur_iRecord] + push [ntfs_cur_attr] + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_buf] + push [ntfs_cur_read] + mov [ntfs_cur_attr], 0x80 ; $DATA + and [ntfs_cur_iRecord], 0 ; $Mft + mov [ntfs_cur_offs], eax + shr ecx, 9 + mov [ntfs_cur_size], ecx + mov eax, [ntfs_data.frs_buffer] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + mov eax, [ntfs_cur_read] + pop [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + pop [ntfs_cur_attr] + pop [ntfs_cur_iRecord] + pop dword [ntfs_attr_size] + pop dword [ntfs_attr_size+4] + pop [ntfs_attr_list] + pop [ntfs_attr_offs] + pop [ntfs_attr_iBaseRecord] + pop [ntfs_attr_iRecord] + pop edx ecx + jc .errret + cmp eax, [ntfs_data.frs_size] + jnz .errret + mov eax, [ntfs_data.frs_buffer] + cmp dword [eax], 'FILE' + jnz .errret + push ebx + mov ebx, eax + call ntfs_restore_usa_frs + pop ebx + setnc al + movzx eax, al +.ret: + ret +.err: + pop edx ecx +.errret: + xor eax, eax + ret + +ntfs_restore_usa_frs: + mov eax, [ntfs_data.frs_size] +ntfs_restore_usa: + pushad + shr eax, 9 + mov ecx, eax + inc eax + cmp [ebx+6], ax + jnz .err + movzx eax, word [ebx+4] + lea esi, [eax+ebx] + lodsw + mov edx, eax + lea edi, [ebx+0x1FE] +@@: + cmp [edi], dx + jnz .err + lodsw + stosw + add edi, 0x1FE + loop @b + popad + clc + ret +.err: + popad + stc + ret + +ntfs_decode_mcb_entry: + push eax ecx edi + lea edi, [esp+16] + xor eax, eax + lodsb + test al, al + jz .end + mov ecx, eax + and ecx, 0xF + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + jae .end + push eax + xor eax, eax + rep stosb + pop ecx + shr ecx, 4 + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + cmc + sbb eax, eax + rep stosb + stc +.end: + pop edi ecx eax + ret + +ntfs_find_lfn: +; in: esi+ebp -> name +; out: CF=1 - file not found +; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory + mov [ntfs_cur_iRecord], 5 ; start parse from root cluster +.doit2: + mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ntfs_cur_offs], 0 + mov eax, [ntfs_data.cur_index_size] + mov [ntfs_cur_size], eax + mov eax, [ntfs_data.cur_index_buf] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + jnc @f +.ret: + ret +@@: + cmp [ntfs_cur_read], 0x20 + jc .ret + pushad + mov esi, [ntfs_data.cur_index_buf] + mov eax, [esi+14h] + add eax, 10h + cmp [ntfs_cur_read], eax + jae .readok1 + add eax, 1FFh + shr eax, 9 + cmp eax, [ntfs_data.cur_index_size] + ja @f +.stc_ret: + popad + stc + ret +@@: +; reallocate + push eax + push [ntfs_data.cur_index_buf] + call kernel_free + pop eax + mov [ntfs_data.cur_index_size], eax + push eax + call kernel_alloc + test eax, eax + jnz @f + and [ntfs_data.cur_index_size], 0 + and [ntfs_data.cur_index_buf], 0 + jmp .stc_ret +@@: + mov [ntfs_data.cur_index_buf], eax + popad + jmp .doit2 +.readok1: + mov ebp, [esi+8] ; subnode_size + shr ebp, 9 + cmp ebp, [ntfs_data.cur_index_size] + jbe .ok2 + push esi ebp + push ebp + call kernel_alloc + pop ebp esi + test eax, eax + jz .stc_ret + mov edi, eax + mov ecx, [ntfs_data.cur_index_size] + shl ecx, 9-2 + rep movsd + mov esi, eax + mov [ntfs_data.cur_index_size], ebp + push esi ebp + push [ntfs_data.cur_index_buf] + call kernel_free + pop ebp esi + mov [ntfs_data.cur_index_buf], esi +.ok2: + add esi, 10h + mov edi, [esp+4] +; edi -> name, esi -> current index data, ebp = subnode size +.scanloop: + add esi, [esi] +.scanloopint: + test byte [esi+0Ch], 2 + jnz .subnode + push esi + add esi, 0x52 + movzx ecx, byte [esi-2] + push edi +@@: + lodsw + call uni2ansi_char + call char_toupper + push eax + mov al, [edi] + inc edi + cmp al, '/' + jz .slash + call char_toupper + cmp al, [esp] + pop eax + loopz @b + jz .found + pop edi + pop esi + jb .subnode +.scanloopcont: + movzx eax, word [esi+8] + add esi, eax + jmp .scanloopint +.slash: + pop eax + pop edi + pop esi +.subnode: + test byte [esi+0Ch], 1 + jz .notfound + movzx eax, word [esi+8] + mov eax, [esi+eax-8] + mul [ntfs_data.sectors_per_cluster] + mov [ntfs_cur_offs], eax + mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION + mov [ntfs_cur_size], ebp + mov eax, [ntfs_data.cur_index_buf] + mov esi, eax + mov [ntfs_cur_buf], eax + call ntfs_read_attr + mov eax, ebp + shl eax, 9 + cmp [ntfs_cur_read], eax + jnz .notfound + cmp dword [esi], 'INDX' + jnz .notfound + mov ebx, esi + call ntfs_restore_usa + jc .notfound + add esi, 0x18 + jmp .scanloop +.notfound: + popad + stc + ret +.found: + cmp byte [edi], 0 + jz .done + cmp byte [edi], '/' + jz .next + pop edi + pop esi + jmp .scanloopcont +.done: +.next: + pop esi + pop esi + mov eax, [esi] + mov [ntfs_cur_iRecord], eax + mov [esp+1Ch], esi + mov [esp+4], edi + popad + inc esi + cmp byte [esi-1], 0 + jnz .doit2 + test ebp, ebp + jz @f + mov esi, ebp + xor ebp, ebp + jmp .doit2 +@@: + ret + +;---------------------------------------------------------------- +; +; ntfs_HdRead - read NTFS hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdRead: + cmp byte [esi], 0 + jnz @f + or ebx, -1 + push ERROR_ACCESS_DENIED + pop eax + ret +@@: + call ntfs_find_lfn + jnc .found + or ebx, -1 + push ERROR_FILE_NOT_FOUND + pop eax + ret +.found: + mov [ntfs_cur_attr], 0x80 ; $DATA + and [ntfs_cur_offs], 0 + and [ntfs_cur_size], 0 + call ntfs_read_attr + jnc @f + or ebx, -1 + push ERROR_ACCESS_DENIED + pop eax + ret +@@: + pushad + and dword [esp+10h], 0 + xor eax, eax + test ebx, ebx + jz .zero1 + cmp dword [ebx+4], 0x200 + jb @f +.eof0: + popad + xor ebx, ebx +.eof: + push ERROR_END_OF_FILE + pop eax + ret +@@: + mov eax, [ebx] + test eax, 0x1FF + jz .alignedstart + push edx + mov edx, [ebx+4] + shrd eax, edx, 9 + pop edx + mov [ntfs_cur_offs], eax + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr.continue + mov eax, [ebx] + and eax, 0x1FF + lea esi, [ntfs_bitmap_buf+eax] + sub eax, [ntfs_cur_read] + jae .eof0 + neg eax + push ecx + cmp ecx, eax + jb @f + mov ecx, eax +@@: + mov [esp+10h+4], ecx + mov edi, edx + rep movsb + mov edx, edi + pop ecx + sub ecx, [esp+10h] + jnz @f +.retok: + popad + xor eax, eax + ret +@@: + cmp [ntfs_cur_read], 0x200 + jz .alignedstart +.eof_ebx: + popad + jmp .eof +.alignedstart: + mov eax, [ebx] + push edx + mov edx, [ebx+4] + add eax, 511 + adc edx, 0 + shrd eax, edx, 9 + pop edx +.zero1: + mov [ntfs_cur_offs], eax + mov [ntfs_cur_buf], edx + mov eax, ecx + shr eax, 9 + mov [ntfs_cur_size], eax + add eax, [ntfs_cur_offs] + push eax + call ntfs_read_attr.continue + pop [ntfs_cur_offs] + mov eax, [ntfs_cur_read] + add [esp+10h], eax + mov eax, ecx + and eax, not 0x1FF + cmp [ntfs_cur_read], eax + jnz .eof_ebx + and ecx, 0x1FF + jz .retok + add edx, [ntfs_cur_read] + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr.continue + cmp [ntfs_cur_read], ecx + jb @f + mov [ntfs_cur_read], ecx +@@: + xchg ecx, [ntfs_cur_read] + push ecx + mov edi, edx + mov esi, ntfs_bitmap_buf + add [esp+10h+4], ecx + rep movsb + pop ecx + xor eax, eax + cmp ecx, [ntfs_cur_read] + jz @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+1Ch], eax + popad + ret + +;---------------------------------------------------------------- +; +; ntfs_HdReadFolder - read NTFS hard disk folder +; +; esi points to filename +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdReadFolder: + mov eax, 5 ; root cluster + cmp byte [esi], 0 + jz .doit + call ntfs_find_lfn + jnc .doit2 +.notfound: + or ebx, -1 + push ERROR_FILE_NOT_FOUND +.pop_ret: + pop eax + ret +.doit: + mov [ntfs_cur_iRecord], eax +.doit2: + mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr + jc .notfound + mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ntfs_cur_offs], 0 + mov eax, [ntfs_data.cur_index_size] + mov [ntfs_cur_size], eax + mov eax, [ntfs_data.cur_index_buf] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + jnc .ok + cmp [hd_error], 0 + jz .notfound + or ebx, -1 + push 11 + jmp .pop_ret +.ok: + cmp [ntfs_cur_read], 0x20 + jae @f + or ebx, -1 +.fserr: + push ERROR_FAT_TABLE + jmp .pop_ret +@@: + pushad + mov esi, [ntfs_data.cur_index_buf] + mov eax, [esi+14h] + add eax, 10h + cmp [ntfs_cur_read], eax + jae .readok1 + add eax, 1FFh + shr eax, 9 + cmp eax, [ntfs_data.cur_index_size] + ja @f + popad + jmp .fserr +@@: +; reallocate + push eax + push [ntfs_data.cur_index_buf] + call kernel_free + pop eax + mov [ntfs_data.cur_index_size], eax + push eax + call kernel_alloc + test eax, eax + jnz @f + and [ntfs_data.cur_index_size], 0 + and [ntfs_data.cur_index_buf], 0 +.nomem: + popad + or ebx, -1 + push 12 + pop eax + ret +@@: + mov [ntfs_data.cur_index_buf], eax + popad + jmp .doit2 +.readok1: + mov ebp, [esi+8] ; subnode_size + shr ebp, 9 + cmp ebp, [ntfs_data.cur_index_size] + jbe .ok2 + push esi ebp + push ebp + call kernel_alloc + pop ebp esi + test eax, eax + jz .nomem + mov edi, eax + mov ecx, [ntfs_data.cur_index_size] + shl ecx, 9-2 + rep movsd + mov esi, eax + mov [ntfs_data.cur_index_size], ebp + push esi ebp + push [ntfs_data.cur_index_buf] + call kernel_free + pop ebp esi + mov [ntfs_data.cur_index_buf], esi +.ok2: + add esi, 10h + mov ebx, [esp+10h] + mov edx, [esp+14h] + push dword [ebx+4] ; read ANSI/UNICODE name + mov ebx, [ebx] +; init header + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + mov byte [edx], 1 ; version + mov ecx, [esp+4+18h] + push edx + mov edx, esp +; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, +; ecx = number of blocks to read +; edx -> parameters block: dd , 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/tags/kolibri0.7.7.0/fs/parse_fn.inc b/kernel/tags/kolibri0.7.7.0/fs/parse_fn.inc new file mode 100644 index 000000000..a1061ca93 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/parse_fn.inc @@ -0,0 +1,236 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;------------------------------------------------------------------------- +; +; File path partial substitution (according to configuration) +; +; +; SPraid +; +;------------------------------------------------------------------------- + +$Revision$ + + +iglobal +; pointer to memory for path replace table, +; size of one record is 128 bytes: 64 bytes for search pattern + 64 bytes for replace string + +; start with one entry: sys -> +full_file_name_table dd sysdir_name +.size dd 1 + +tmp_file_name_size dd 1 +endg + +uglobal +; Parser_params will initialize: sysdir_name = "sys", sysdir_path = +sysdir_name rb 64 +sysdir_path rb 64 +tmp_file_name_table dd ? +endg + +; use bx_from_load and init system directory /sys +proc Parser_params +locals + buff db 4 dup(?) ; for test cd +endl + mov eax,[OS_BASE+0x10000+bx_from_load] + mov ecx,sysdir_path + mov [ecx-64],dword 'sys' + cmp al,'r' ; if ram disk + jnz @f + mov [ecx],dword 'RD/?' + mov [ecx+3],byte ah + mov [ecx+4],byte 0 + ret +@@: + cmp al,'m' ; if ram disk + jnz @f + mov [ecx],dword 'CD?/' ; if cd disk {m} + mov [ecx+4],byte '1' + mov [ecx+5],dword '/KOL' + mov [ecx+9],dword 'IBRI' + mov [ecx+13],byte 0 +.next_cd: + mov [ecx+2],byte ah + inc ah + cmp ah,'5' + je .not_found_cd + lea edx,[buff] + pushad + stdcall read_file,read_firstapp,edx,0,4 + popad + cmp [edx],dword 'MENU' + jne .next_cd + jmp .ok + +@@: + sub al,49 + mov [ecx],dword 'HD?/' ; if hard disk + mov [ecx+2],byte al + mov [ecx+4],byte ah + mov [ecx+5],dword '/KOL' + mov [ecx+9],dword 'IBRI' + mov [ecx+13],byte 0 +.ok: +.not_found_cd: + ret +endp + +proc load_file_parse_table + stdcall kernel_alloc,0x1000 + mov [tmp_file_name_table],eax + mov edi,eax + mov esi,sysdir_name + mov ecx,128/4 + rep movsd + + invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key + + mov eax,[tmp_file_name_table] + mov [full_file_name_table],eax + mov eax,[tmp_file_name_size] + mov [full_file_name_table.size],eax + ret +endp + +uglobal +def_val_1 db 0 +endg + +proc get_every_key stdcall, f_name, sec_name, key_name + mov esi, [key_name] + mov ecx, esi + cmp byte [esi], '/' + jnz @f + inc esi +@@: + mov edi, [tmp_file_name_size] + shl edi, 7 + cmp edi, 0x1000 + jae .stop_parse + add edi, [tmp_file_name_table] + lea ebx, [edi+64] +@@: + cmp edi, ebx + jae .skip_this_key + lodsb + test al, al + jz @f + or al, 20h + stosb + jmp @b +@@: + stosb + + invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1 + + cmp byte [ebx], '/' + jnz @f + lea esi, [ebx+1] + mov edi, ebx + mov ecx, 63 + rep movsb +@@: + push ebp + mov ebp, [tmp_file_name_table] + mov ecx, [tmp_file_name_size] + jecxz .noreplace + mov eax, ecx + dec eax + shl eax, 7 + add ebp, eax +.replace_loop: + mov edi, ebx + mov esi, ebp +@@: + lodsb + test al, al + jz .doreplace + mov dl, [edi] + inc edi + test dl, dl + jz .replace_loop_cont + or dl, 20h + cmp al, dl + jz @b + jmp .replace_loop_cont +.doreplace: + cmp byte [edi], 0 + jz @f + cmp byte [edi], '/' + jnz .replace_loop_cont +@@: + lea esi, [ebp+64] + call .replace + jc .skip_this_key2 +.replace_loop_cont: + sub ebp, 128 + loop .replace_loop +.noreplace: + pop ebp + + inc [tmp_file_name_size] +.skip_this_key: + xor eax, eax + inc eax + ret +.skip_this_key2: + pop ebp + jmp .skip_this_key +.stop_parse: + xor eax, eax + ret +endp + +proc get_every_key.replace +; in: ebx->destination, esi->first part of name, edi->second part of name +; maximum length is 64 bytes +; out: CF=1 <=> overflow +; 1) allocate temporary buffer in stack + sub esp, 64 +; 2) save second part of name to temporary buffer + push esi + lea esi, [esp+4] ; esi->tmp buffer + xchg esi, edi ; edi->tmp buffer, esi->source +@@: + lodsb + stosb + test al, al + jnz @b +; 3) copy first part of name to destination + pop esi + mov edi, ebx +@@: + lodsb + test al, al + jz @f + stosb + jmp @b +@@: +; 4) restore second part of name from temporary buffer to destination +; (may cause overflow) + lea edx, [ebx+64] ; limit of destination + mov esi, esp +@@: + cmp edi, edx + jae .overflow + lodsb + stosb + test al, al + jnz @b +; all is OK + add esp, 64 ; CF is cleared + ret +.overflow: +; name is too long + add esp, 64 + stc + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/fs/part_set.inc b/kernel/tags/kolibri0.7.7.0/fs/part_set.inc new file mode 100644 index 000000000..4d9ed4120 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/fs/part_set.inc @@ -0,0 +1,481 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;************************************************************* +;* 12.07.2007 Check all 4 entry of MBR and EMBR +;* 29.04.2006 Elimination of hangup after the +;* expiration hd_wait_timeout - Mario79 +;* 28.01.2006 find all Fat16/32 partition in all input point +;* to MBR - Mario79 +;************************************************************* + +uglobal +align 4 + +;****************************************************** +; Please do not change this place - variables in text +; Mario79 +; START place +;****************************************************** +PARTITION_START dd 0x3f +PARTITION_END dd 0 +fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 +align 4 + +fs_dependent_data_start: +; FATxx data + +SECTORS_PER_FAT dd 0x1f3a +NUMBER_OF_FATS dd 0x2 +SECTORS_PER_CLUSTER dd 0x8 +BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes +ROOT_CLUSTER dd 2 ; first rootdir cluster +FAT_START dd 0 ; start of fat table +ROOT_START dd 0 ; start of rootdir (only fat16) +ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) +DATA_START dd 0 ; start of data area (=first cluster 2) +LAST_CLUSTER dd 0 ; last availabe cluster +ADR_FSINFO dd 0 ; used only by fat32 + +fatRESERVED dd 0x0FFFFFF6 +fatBAD dd 0x0FFFFFF7 +fatEND dd 0x0FFFFFF8 +fatMASK dd 0x0FFFFFFF + +fatStartScan dd 2 + +fs_dependent_data_end: +file_system_data_size = $ - PARTITION_START +if file_system_data_size > 96 +ERROR: sizeof(file system data) too big! +end if + +virtual at fs_dependent_data_start +; NTFS data +ntfs_data: +.sectors_per_cluster dd ? +.mft_cluster dd ? +.mftmirr_cluster dd ? +.frs_size dd ? ; FRS size in bytes +.iab_size dd ? ; IndexAllocationBuffer size in bytes +.frs_buffer dd ? +.iab_buffer dd ? +.mft_retrieval dd ? +.mft_retrieval_size dd ? +.mft_retrieval_alloc dd ? +.mft_retrieval_end dd ? +.cur_index_size dd ? +.cur_index_buf dd ? +if $ > fs_dependent_data_end +ERROR: increase sizeof(fs_dependent_data)! +end if +end virtual + +;*************************************************************************** +; End place +; Mario79 +;*************************************************************************** +endg +iglobal + + partition_types: ; list of fat16/32 partitions + db 0x04 ; DOS: fat16 <32M + db 0x06 ; DOS: fat16 >32M + db 0x0b ; WIN95: fat32 + db 0x0c ; WIN95: fat32, LBA-mapped + db 0x0e ; WIN95: fat16, LBA-mapped + db 0x14 ; Hidden DOS: fat16 <32M + db 0x16 ; Hidden DOS: fat16 >32M + db 0x1b ; Hidden WIN95: fat32 + db 0x1c ; Hidden WIN95: fat32, LBA-mapped + db 0x1e ; Hidden WIN95: fat16, LBA-mapped + db 0xc4 ; DRDOS/secured: fat16 <32M + db 0xc6 ; DRDOS/secured: fat16 >32M + db 0xcb ; DRDOS/secured: fat32 + db 0xcc ; DRDOS/secured: fat32, LBA-mapped + db 0xce ; DRDOS/secured: fat16, LBA-mapped + db 0xd4 ; Old Multiuser DOS secured: fat16 <32M + db 0xd6 ; Old Multiuser DOS secured: fat16 >32M + db 0x07 ; NTFS + db 0x27 ; NTFS, hidden + partition_types_end: + + + extended_types: ; list of extended partitions + db 0x05 ; DOS: extended partition + db 0x0f ; WIN95: extended partition, LBA-mapped + db 0xc5 ; DRDOS/secured: extended partition + db 0xd5 ; Old Multiuser DOS secured: extended partition + extended_types_end: + +endg + +; Partition chain used: +; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 +;========================================================== +; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- +; extended --+ extended --+ extended --+ extended --+ +; 0 0 0 0 +; 0 0 0 0 +; Notes: +; - extended partition need to be in second entry on table +; - it will skip over removed partitions + +set_FAT32_variables: + mov [problem_partition],0 + call reserve_hd1 + call reserve_hd_channel + + pushad + + cmp dword [hdpos],0 + je problem_hd + + xor ecx,ecx ; partition count + mov edx,-1 ; flag for partition + xor eax,eax ; read MBR + xor ebp,ebp ; extended partition start + +new_partition: + test ebp,ebp ; is there extended partition? + jnz extended_already_set ; yes + xchg ebp,eax ; no. set it now + +extended_already_set: + add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne problem_hd + + cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? + jnz end_partition_chain + cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition +; jz next_partition + jnz .next_primary_partition + cmp dword [ebx+0x1be+0xc+16],0 + jnz next_primary_partition + cmp dword [ebx+0x1be+0xc+16+16],0 + jnz next_primary_partition_1 + cmp dword [ebx+0x1be+0xc+16+16+16],0 + jnz next_primary_partition_2 + jmp next_partition + +.next_primary_partition: + push eax + mov al,[ebx+0x1be+4] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition ; no + + mov edx, eax ; start sector + add edx, [ebx+0x1be+8] ; add relative start + push edx + add edx, [ebx+0x1be+12] ; add length + dec edx ; PARTITION_END is inclusive + mov [PARTITION_END], edx ; note that this can be changed + ; when file system data will be available + mov dl, [ebx+0x1be+4] + mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) + pop edx + +next_primary_partition: + push eax + mov al,[ebx+0x1be+4+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition_1 ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition_1 ; no + + mov edx, eax + add edx, [ebx+0x1be+8+16] + push edx + add edx, [ebx+0x1be+12+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16] + mov [fs_type], dl + pop edx + +next_primary_partition_1: + push eax + mov al,[ebx+0x1be+4+16+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition_2 ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition_2 ; no + + mov edx, eax + add edx, [ebx+0x1be+8+16+16] + push edx + add edx, [ebx+0x1be+12+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16] + mov [fs_type], dl + pop edx + +next_primary_partition_2: + push eax + mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_partition ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_partition ; no + + mov edx, eax + add edx, [ebx+0x1be+8+16+16+16] + push edx + add edx, [ebx+0x1be+12+16+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16+16] + mov [fs_type], dl + pop edx + +next_partition: + push eax + mov al,[ebx+0x1be+4] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_1 + + mov eax,[ebx+0x1be+8] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_1: + push eax + mov al,[ebx+0x1be+4+16] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_2 + + mov eax,[ebx+0x1be+8+16] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_2: + push eax + mov al,[ebx+0x1be+4+16+16] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_3 + + mov eax,[ebx+0x1be+8+16+16] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_3: + push eax + mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type + call scan_extended_types + pop eax + jnz end_partition_chain ; no. end chain + + mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +end_partition_chain: + mov [partition_count],ecx + + cmp edx,-1 ; found wanted partition? + jnz hd_and_partition_ok ; yes. install it + jmp problem_partition_or_fat + +scan_partition_types: + push ecx + mov edi,partition_types + mov ecx,partition_types_end-partition_types + cld + repne scasb ; is partition type ok? + pop ecx + ret + +scan_extended_types: + push ecx + mov edi,extended_types + mov ecx,extended_types_end-extended_types + cld + repne scasb ; is it extended partition? + pop ecx + ret + +problem_fat_dec_count: ; bootsector is missing or another problem + dec [partition_count] ; remove it from partition_count + +problem_partition_or_fat: +problem_hd: + popad + + mov [fs_type],0 + call free_hd_channel + mov [hd1_status],0 ; free + mov [problem_partition],1 + ret + +hd_and_partition_ok: + mov eax,edx + mov [PARTITION_START],eax + mov edx, [PARTITION_END] + sub edx, eax + inc edx ; edx = length of partition + +; mov [hd_setup],1 + mov ebx,buffer + call hd_read ; read boot sector of partition + cmp [hd_error], 0 + jz boot_read_ok + cmp [fs_type], 7 + jnz problem_fat_dec_count +; NTFS duplicates bootsector: +; NT4/2k/XP+ saves bootsector copy in the end of disk +; NT 3.51 saves bootsector copy in the middle of disk + and [hd_error], 0 + mov eax, [PARTITION_END] + call hd_read + cmp [hd_error], 0 + jnz @f + call ntfs_test_bootsec + jnc boot_read_ok +@@: + and [hd_error], 0 + mov eax, edx + shr eax, 1 + add eax, [PARTITION_START] + call hd_read + cmp [hd_error], 0 + jnz problem_fat_dec_count ; ­Ґ бг¤мЎ ... +boot_read_ok: +; mov [hd_setup], 0 +; if we are running on NTFS, check bootsector +; cmp [fs_type], 7 +; jz ntfs_setup + call ntfs_test_bootsec + jnc ntfs_setup + + cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? + jnz problem_fat_dec_count + + movzx eax,word [ebx+0xe] ; sectors reserved + add eax,[PARTITION_START] + mov [FAT_START],eax ; fat_start = partition_start + reserved + + movzx eax,byte [ebx+0xd] ; sectors per cluster + test eax,eax + jz problem_fat_dec_count + mov [SECTORS_PER_CLUSTER],eax + + movzx ecx,word [ebx+0xb] ; bytes per sector + cmp ecx,0x200 + jnz problem_fat_dec_count + mov [BYTES_PER_SECTOR],ecx + + movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32) + mov edx,32 + mul edx + dec ecx + add eax,ecx ; round up if not equal count + inc ecx ; bytes per sector + div ecx + mov [ROOT_SECTORS],eax ; count of rootdir sectors + + movzx eax,word [ebx+0x16] ; sectors per fat <65536 + test eax,eax + jnz fat16_fatsize + mov eax,[ebx+0x24] ; sectors per fat + fat16_fatsize: + mov [SECTORS_PER_FAT],eax + + movzx eax,byte [ebx+0x10] ; number of fats + test eax,eax ; if 0 it's not fat partition + jz problem_fat_dec_count + mov [NUMBER_OF_FATS],eax + imul eax,[SECTORS_PER_FAT] + add eax,[FAT_START] + mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count + add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32 + mov [DATA_START],eax ; data area = rootdir + rootdir_size + + movzx eax,word [ebx+0x13] ; total sector count <65536 + test eax,eax + jnz fat16_total + mov eax,[ebx+0x20] ; total sector count + fat16_total: + add eax,[PARTITION_START] + dec eax + mov [PARTITION_END],eax + inc eax + sub eax,[DATA_START] ; eax = count of data sectors + xor edx,edx + div dword [SECTORS_PER_CLUSTER] + inc eax + mov [LAST_CLUSTER],eax + dec eax ; cluster count + mov [fatStartScan],2 + + ; limits by Microsoft Hardware White Paper v1.03 + cmp eax,4085 ; 0xff5 + jb problem_fat_dec_count ; fat12 not supported + cmp eax,65525 ; 0xfff5 + jb fat16_partition + +fat32_partition: + mov eax,[ebx+0x2c] ; rootdir cluster + mov [ROOT_CLUSTER],eax + movzx eax,word [ebx+0x30] ; fs info sector + add eax,[PARTITION_START] + mov [ADR_FSINFO],eax + call hd_read + mov eax,[ebx+0x1ec] + cmp eax,-1 + jz @f + mov [fatStartScan],eax +@@: + + popad + + mov [fatRESERVED],0x0FFFFFF6 + mov [fatBAD],0x0FFFFFF7 + mov [fatEND],0x0FFFFFF8 + mov [fatMASK],0x0FFFFFFF + mov [fs_type],32 ; Fat32 + call free_hd_channel + mov [hd1_status],0 ; free + ret + +fat16_partition: + xor eax,eax + mov [ROOT_CLUSTER],eax + + popad + + mov [fatRESERVED],0x0000FFF6 + mov [fatBAD],0x0000FFF7 + mov [fatEND],0x0000FFF8 + mov [fatMASK],0x0000FFFF + mov [fs_type],16 ; Fat16 + call free_hd_channel + mov [hd1_status],0 ; free + ret diff --git a/kernel/tags/kolibri0.7.7.0/gui/button.inc b/kernel/tags/kolibri0.7.7.0/gui/button.inc new file mode 100644 index 000000000..ad5e13f68 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/button.inc @@ -0,0 +1,643 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +max_buttons=4095 +dececx: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0x20 + jae @f + mov [esp+edx],byte 0x20 + @@: + sub [esp+edx],byte 0x20 + + dec edx + jns .loop + + pop ecx + pop edx + ret + +incecx: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0xdf + jbe @f + mov [esp+edx],byte 0xdf + @@: + add [esp+edx],byte 0x20 + + dec edx + jns .loop + pop ecx + pop edx + ret + +incecx2: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0xeb + jbe @f + mov [esp+edx],byte 0xeb + @@: + add [esp+edx],byte 0x14 + + dec edx + jns .loop + pop ecx + pop edx + ret + +drawbuttonframes: + + push esi + push edi + push eax + push ebx + push ecx + push edx + + shr ebx,16 + shr ecx,16 + mov eax,[TASK_BASE] + + add ebx,[eax-twdw + WDATA.box.left] + add ecx,[eax-twdw + WDATA.box.top] + mov eax, ebx + shl eax, 16 + mov ax, bx + add ax, word [esp+8] + mov ebx, ecx + shl ebx, 16 + mov bx, cx + push ebx + xor edi, edi + mov ecx, esi + call incecx + call [draw_line] + + movzx edx,word [esp+4+4] + add ebx,edx + shl edx,16 + add ebx,edx + mov ecx,esi + call dececx + call [draw_line] + + pop ebx + push edx + mov edx,eax + shr edx,16 + mov ax,dx + mov edx,ebx + shr edx,16 + mov bx,dx + mov dx,[esp+4+4] + add bx,dx + pop edx + mov ecx,esi + call incecx + call [draw_line] + + mov dx,[esp+8] + add ax,dx + shl edx,16 + add eax,edx + add ebx,1*65536 + mov ecx,esi + call dececx + call [draw_line] + + pop edx + pop ecx + pop ebx + pop eax + pop edi + pop esi + + ret + +button_dececx: + + cmp [buttontype],dword 1 + jne .finish +; je bdece +; ret +; bdece: + push eax + mov eax,0x01 + cmp edi,20 + jg @f + mov eax,0x02 + @@: + test ecx,0xff + jz @f + sub ecx,eax + @@: + shl eax,8 + test ecx,0xff00 + jz @f + sub ecx,eax + @@: + shl eax,8 + test ecx,0xff0000 + jz @f + sub ecx,eax + @@: + pop eax + .finish: + ret + + +sys_button: + + mov eax, [current_slot] + rol ebx, 16 + add bx, word [eax+APPDATA.wnd_clientbox.left] + rol ebx, 16 + rol ecx, 16 + add cx, word [eax+APPDATA.wnd_clientbox.top] + rol ecx, 16 +.forced: + + test edx, 0x80000000 + jnz remove_button + + or bx, bx + jle noaddbutt + or cx, cx + jle noaddbutt + + test edx, 0x40000000 + jnz button_no_draw + + pushad ; button body + movzx edi, cx + shr ebx, 16 + shr ecx, 16 + mov eax, [TASK_BASE] + add ebx, [eax-twdw + WDATA.box.left] + add ecx, [eax-twdw + WDATA.box.top] + mov eax, ebx + shl eax, 16 + mov ax, bx + add ax, word [esp+16] + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov ecx, esi + cmp [buttontype], 0 + je @f + call incecx2 +@@: + mov edx, edi + +.newline: + call button_dececx + push edi + xor edi, edi + call [draw_line] + pop edi + add ebx, 1*65536+1 ; [ y start | y end ] + dec edx + jnz .newline + popad + + call drawbuttonframes + +button_no_draw: + + mov edi, [BTN_ADDR] + movzx eax, word [edi] + cmp eax, max_buttons + jge noaddbutt + inc eax + mov [edi], ax + + shl eax, 4 + add edi, eax + + mov ax, [CURRENT_TASK] + stosw + mov ax, dx + stosw ; button id number: bits 0-15 + mov eax, ebx + rol eax, 16 + stosd ; x start | x size + mov eax, ecx + rol eax, 16 + stosd ; y start | y size + mov eax, edx + shr eax, 16 + stosw ; button id number: bits 16-31 + +noaddbutt: + + ret + + +remove_button: + + and edx, 0x7fffffff + +rnewba2: + + mov edi, [BTN_ADDR] + mov eax, edi + movzx ebx, word [edi] + inc ebx + +rnewba: + + dec ebx + jz rnmba + + add eax, 0x10 + + mov cx, [CURRENT_TASK] + cmp cx, [eax] + jnz rnewba + cmp dx, [eax+2] + jnz rnewba + + lea ecx, [ebx+1] + shl ecx, 4 + mov ebx, eax + add eax, 0x10 + call memmove + dec dword [edi] + jmp rnewba2 + +rnmba: + + ret + +find_pressed_button_frames: + + pushad + + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+ WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add ecx,edx + push ecx + + mov dx,[eax+6] ; button x size + add cx,dx + mov esi,ecx + inc esi + mov ecx, [ebx+WDATA.box.top] ; window y start + mov dx,[eax+8] ; button y start + add ecx,edx + mov ebx,ecx + mov dx,[eax+10] ; button y size + add dx,cx + inc dx + + pop eax + + ; eax x beginning + ; ebx y beginning + ; esi x end + ; edx y end + ; ecx color + + mov [pressed_button_eax],eax + mov [pressed_button_ebx],ebx + mov [pressed_button_ecx],ecx + mov [pressed_button_edx],edx + mov [pressed_button_esi],esi + + popad + ret + +uglobal + pressed_button_eax dd 0 + pressed_button_ebx dd 0 + pressed_button_ecx dd 0 + pressed_button_edx dd 0 + pressed_button_esi dd 0 +endg + +; negative button image + +negativebutton: + ; If requested, do not display button + ; boarder on press. + test ebx,0x20000000 + jz draw_negative_button + ret + draw_negative_button: + + pushad + + mov eax,[pressed_button_eax] + mov ebx,[pressed_button_ebx] + mov ecx,[pressed_button_ecx] + mov edx,[pressed_button_edx] + mov esi,[pressed_button_esi] + mov ecx,0x01000000 + + dec edx + push edx + inc edx + dec esi + push esi + inc esi + + push eax + push ebx + push ecx + push edx + push edi + + call [_display.disable_mouse] + + bdbnewline: + mov edi,1 ; force + cmp eax,[esp+16] + jz bneg + cmp eax,[esp+20] + jz bneg + cmp ebx,[esp+12] + jz bneg + cmp ebx,[esp+24] + jnz nbneg +; jz bneg +; jmp nbneg + + bneg: + + call [putpixel] + + nbneg: + + inc eax + cmp eax,esi + jnz bdbnewline + mov eax,[esp+16] + inc ebx + cmp ebx,edx + jnz bdbnewline + + add esp,28 + + popad + + ret + +; check buttons + + +; 0000 word process number +; 0002 word button id number : bits 0-15 +; 0004 word x start +; 0006 word x size +; 0008 word y start +; 000A word y size +; 000C word button id number : bits 16-31 +; +; button table in 0x10 increments +; +; first at 0x10 + +align 4 +checkbuttons: + + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed + jnz @f +;..................................... start 1/5 : modified by vhanla ............................. + mov [bPressedMouseXY_B],0 +;..................................... end 1/5 : modified by vhanla ............................. + ret + @@: + pushad + + xor esi, esi + mov edi, [BTN_ADDR] + movzx edx, word [edi] + test edx, edx + jne @f + popad + ret + + @@: +;..................................... start 2/5 : modified by vhanla ............................. + ;here i catch the coordinates when the mouse's button is clicked + push ax + cmp [bPressedMouseXY_B],0;FALSE + jnz @f + mov [bPressedMouseXY_B],1;TRUE - it was already clicked + mov ax,[MOUSE_X] + mov [mx],ax + mov ax,[MOUSE_Y] + mov [my],ax + @@: + pop ax + ;and it is only refreshed after the mouse's button release +;..................................... end 2/5 : modified by vhanla ............................. + + push esi + inc edx + push edx + + buttonnewcheck: + + pop edx + pop esi + inc esi + cmp edx,esi + jge bch + + popad ; no button pressed + ret + + bch: + + push esi + push edx + mov eax,esi + shl eax,4 + add eax,edi + + ; check that button is at top of windowing stack + + movzx ebx,word [eax] + movzx ecx,word [WIN_STACK + ebx * 2] + cmp ecx,[TASK_COUNT] + jne buttonnewcheck + + ; check that button start is inside window x/y end + + movzx ebx,word [eax+0] + shl ebx,5 + + test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED + jnz buttonnewcheck + +; add ebx,window_data +; mov ecx,[window_data+ebx+8] ; window end X + movzx edx,word [eax+4] ; button start X + cmp edx, [window_data+ebx+WDATA.box.width] ;ecx + jge buttonnewcheck + +; mov ecx,[window_data+ebx+12] ; window end Y + movzx edx, word [eax+8] ; button start Y + cmp edx, [window_data+ebx+WDATA.box.height] ;ecx + jge buttonnewcheck + + ; check coordinates + ; mouse x >= button x ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add edx,ecx +;..................................... start 3/5 : modified by vhanla ............................. + mov cx,[mx] ;mov cx,[MOUSE_X] +;..................................... end 3/5 : modified by vhanla ............................. + cmp edx,ecx + jg buttonnewcheck + + movzx ebx,word [eax+6] ; button x size + add edx,ebx + cmp ecx,edx + jg buttonnewcheck + + ; mouse y >= button y ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.top] ; window y start + movzx edx,word [eax+8] ; button y start + add edx,ecx +;..................................... start 4/5 : modified by vhanla ............................. + mov cx,[my] ;mov cx,[MOUSE_Y] +;..................................... start 4/5 : modified by vhanla ............................. + cmp edx,ecx + jg buttonnewcheck + + movzx ebx,word [eax+10] ; button y size + add edx,ebx + cmp ecx,edx + jg buttonnewcheck + + ; mouse on button + + pop edx + pop esi + + mov bx,[eax+0xc] ; button id : bits 16-31 + shl ebx,16 + mov bx,[eax+2] ; button id : bits 00-16 + push ebx + + mov [MOUSE_DOWN],byte 1 ; no mouse down checks + call find_pressed_button_frames + call negativebutton + + pushad +; // Alver 22.06.2008 // { + push eax + mov al, byte [BTN_DOWN] + mov byte [btn_down_determ], al + pop eax +; } \\ Alver \\ + + cbwaitmouseup: + + call checkidle + + call [draw_pointer] + + pushad + call stack_handler + popad + + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? + jnz cbwaitmouseup + popad + + call negativebutton + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse +;..................................... start 5/5 : modified by vhanla ............................. + ; check coordinates +iglobal + mx dw 0x0 ; keeps the x mouse's position when it was clicked + my dw 0x0 ; keeps the y mouse's position when it was clicked + bPressedMouseXY_B db 0x0 + btn_down_determ db 0x0 ; << // Alver 22.06.2008// << +endg + + pusha + ; mouse x >= button x ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add edx,ecx + mov cx,[MOUSE_X] + cmp edx,ecx + jg no_on_button ;if we release the pointer out of the button area + + movzx ebx,word [eax+6] ; button x size + add edx,ebx + cmp ecx,edx + jg no_on_button + + ; mouse y >= button y ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.top] ; window y start + movzx edx,word [eax+8] ; button y start + add edx,ecx + mov cx,[MOUSE_Y] + cmp edx,ecx + jg no_on_button + + movzx ebx,word [eax+10] ; button y size + add edx,ebx + cmp ecx,edx + jg no_on_button + popa + mov [BTN_COUNT],byte 1 ; no of buttons in buffer + pop ebx + mov [BTN_BUFF],ebx ; lets put the button id in buffer + push ebx + pusha + jmp yes_on_button +no_on_button: + mov [BTN_COUNT],byte 0 ; no of buttons in buffer +yes_on_button: + mov [MOUSE_DOWN],byte 0 ; mouse down -> do not draw + popa + pop ebx + popa + ret + +;..................................... end 5/5 : modified by vhanla ................................ diff --git a/kernel/tags/kolibri0.7.7.0/gui/event.inc b/kernel/tags/kolibri0.7.7.0/gui/event.inc new file mode 100644 index 000000000..2046feac4 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/event.inc @@ -0,0 +1,487 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +uglobal +align 4 + event_start dd ? + event_end dd ? + event_uid dd 0 +endg +EV_SPACE = 512 +FreeEvents = event_start-EVENT.fd ; "виртуальный" event, используются только поля: + ; FreeEvents.fd=event_start и FreeEvents.bk=event_end +align 4 +init_events: ;; used from kernel.asm + stdcall kernel_alloc,EV_SPACE*EVENT.size + or eax,eax + jz .fail + ; eax - current event, ebx - previos event below + mov ecx,EV_SPACE ; current - in allocated space + mov ebx,FreeEvents ; previos - начало списка + push ebx ; оно же и конец потом будет + @@: mov [ebx+EVENT.fd],eax + mov [eax+EVENT.bk],ebx + mov ebx,eax ; previos <- current + add eax,EVENT.size ; new current + loop @b + pop eax ; вот оно концом и стало + mov [ebx+EVENT.fd],eax + mov [eax+EVENT.bk],ebx +.fail: ret + +EVENT_WATCHED equ 0x10000000 ;бит 28 +EVENT_SIGNALED equ 0x20000000 ;бит 29 +MANUAL_RESET equ 0x40000000 ;бит 30 +MANUAL_DESTROY equ 0x80000000 ;бит 31 + +align 4 +create_event: ;; EXPORT use +;info: +; Переносим EVENT из списка FreeEvents в список ObjList текущего слота +; EVENT.state устанавливаем из ecx, EVENT.code косвенно из esi (если esi<>0) +;param: +; esi - event data +; ecx - flags +;retval: +; eax - event (=0 => fail) +; edx - uid +;scratched: ebx,ecx,esi,edi + mov ebx,[current_slot] + add ebx,APP_OBJ_OFFSET + mov edx,[TASK_BASE] + mov edx,[edx+TASKDATA.pid] + pushfd + cli + +set_event: ;; INTERNAL use !!! don't use for Call +;info: +; Берем новый event из FreeEvents, заполняем его поля, как указано в ecx,edx,esi +; и устанавливаем в список, указанный в ebx. +; Возвращаем сам event (в eax), и его uid (в edx) +;param: +; ebx - start-chain "virtual" event for entry new event Right of him +; ecx - flags (copied to EVENT.state) +; edx - pid (copied to EVENT.pid) +; esi - event data (copied to EVENT.code indirect, =0 => skip) +;retval: +; eax - event (=0 => fail) +; edx - uid +;scratched: ebx,ecx,esi,edi + mov eax,FreeEvents + cmp eax,[eax+EVENT.fd] + jne @f ; not empty ??? + pushad + call init_events + popad + jz RemoveEventTo.break ; POPF+RET + @@: mov eax,[eax+EVENT.fd] + mov [eax+EVENT.magic],'EVNT' + mov [eax+EVENT.destroy],destroy_event.internal + mov [eax+EVENT.state],ecx + mov [eax+EVENT.pid],edx + inc [event_uid] + Mov [eax+EVENT.id],edx,[event_uid] + or esi,esi + jz RemoveEventTo + lea edi,[eax+EVENT.code] + mov ecx,EVENT.codesize/4 + cld + rep movsd + +RemoveEventTo: ;; INTERNAL use !!! don't use for Call +;param: +; eax - указатель на event, КОТОРЫЙ вставляем +; ebx - указатель на event, ПОСЛЕ которого вставляем +;scratched: ebx,ecx + mov ecx,eax ; ecx=eax=Self, ebx=NewLeft + xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight + cmp eax,ecx ; стоп, себе думаю... + je .break ; - а не дурак ли я? + mov [ecx+EVENT.bk],eax ; NewRight.bk=Self + xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft + xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight + mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight + mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft +.break: popfd + ret + +align 4 +NotDummyTest: ;; INTERNAL use (not returned for fail !!!) + pop edi + call DummyTest ; not returned for fail !!! + mov ebx,eax + mov eax,[ebx+EVENT.pid] + push edi +.small: ; криво как-то... + pop edi + pushfd + cli + call pid_to_slot ; saved all registers (eax - retval) + shl eax,8 + jz RemoveEventTo.break ; POPF+RET + jmp edi ; штатный возврат + +align 4 +raise_event: ;; EXPORT use +;info: +; Устанавливаем данные EVENT.code +; Если там флаг EVENT_SIGNALED уже активен - больше ничего +; Иначе: этот флаг взводится, за исключением случая наличия флага EVENT_WATCHED в edx +; В этом случае EVENT_SIGNALED взводится лишь при наличие EVENT_WATCHED в самом событии +;param: +; eax - event +; ebx - uid (for Dummy testing) +; edx - flags +; esi - event data (=0 => skip) +;scratched: ebx,ecx,esi,edi + call NotDummyTest ; not returned for fail !!! + or esi,esi + jz @f + lea edi,[ebx+EVENT.code] + mov ecx,EVENT.codesize/4 + cld + rep movsd + @@: + test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 + jnz RemoveEventTo.break ; POPF+RET + bt edx, 28 ;EVENT_WATCHED + jnc @f + test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24 + jz RemoveEventTo.break ; POPF+RET + @@: + or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 + add eax,SLOT_BASE+APP_EV_OFFSET + xchg eax,ebx + jmp RemoveEventTo + +align 4 +clear_event: ;; EXPORT use +;info: +; +;param: +; eax - event +; ebx - uid (for Dummy testing) +;scratched: ebx,ecx + call NotDummyTest ; not returned for fail !!! + add eax,SLOT_BASE+APP_OBJ_OFFSET + and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) + xchg eax,ebx + jmp RemoveEventTo + +align 4 +send_event: ;; EXPORT use +;info: +; Создает новый EVENT (вытаскивает из списка FreeEvents) в списке EventList +; целевого слота (eax=pid), с данными из esi косвенно, и state=EVENT_SIGNALED +;param: +; eax - slots pid, to sending new event +; esi - pointer to sending data (in code field of new event) +;retval: +; eax - event (=0 => fail) +; edx - uid +;warning: +; may be used as CDECL with such prefix... +; mov esi,[esp+8] +; mov eax,[esp+4] +; but not as STDCALL :( +;scratched: ebx,ecx,esi,edi + mov edx,eax + call NotDummyTest.small ; not returned for fail !!! + lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET] + mov ecx,EVENT_SIGNALED + jmp set_event + +align 4 +DummyTest: ;; INTERNAL use (not returned for fail !!!) +;param: +; eax - event +; ebx - uid (for Dummy testing) + cmp [eax+EVENT.magic],'EVNT' + jne @f + cmp [eax+EVENT.id],ebx + je .ret + @@: pop eax + xor eax,eax +.ret: ret + + +align 4 +Wait_events: + or ebx,-1 ; infinite timeout +Wait_events_ex: +;info: +; Ожидание "абстрактного" события через перевод слота в 5-ю позицию. +; Абстрактность заключена в том, что факт события определяется функцией APPDATA.wait_test, +; которая задается клиентом и может быть фактически любой. +; Это позволяет shed-у надежно определить факт события, и не совершать "холостых" переключений, +; предназначенных для разборок типа "свой/чужой" внутри задачи. +;param: +; edx - wait_test, клиентская ф-я тестирования (адрес кода) +; ecx - wait_param, дополнительный параметр, возможно необходимый для [wait_test] +; ebx - wait_timeout +;retval: +; eax - результат вызова [wait_test] (=0 => timeout) +;scratched: esi + mov esi,[current_slot] + mov [esi+APPDATA.wait_param],ecx + pushad + mov ebx,esi;пока это вопрос, чего куды сувать.......... + pushfd ; это следствие общей концепции: пусть ф-я тестирования имеет + cli ; право рассчитывать на закрытые прерывания, как при вызове из shed + call edx + popfd + mov [esp+28],eax + popad + or eax,eax + jnz @f ;RET + mov [esi+APPDATA.wait_test],edx + mov [esi+APPDATA.wait_timeout],ebx + Mov [esi+APPDATA.wait_begin],eax,[timer_ticks] + mov eax,[TASK_BASE] + mov [eax+TASKDATA.state], 5 + call change_task + mov eax,[esi+APPDATA.wait_param] + @@: ret + +align 4 +wait_event: ;; EXPORT use +;info: +; Ожидание флага EVENT_SIGNALED в совершенно конкретном Event +; (устанавливаемого, надо полагать, через raise_event) +; При активном флаге MANUAL_RESET - больше ничего +; Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются, +; и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота, +; а при не активном - уничтожается штатно (destroy_event.internal) +;param: +; eax - event +; ebx - uid (for Dummy testing) +;scratched: ecx,edx,esi + call DummyTest + mov ecx,eax ; wait_param + mov edx, get_event_alone ; wait_test + call Wait_events ; timeout ignored + jmp wait_finish + +align 4 +get_event_ex: ;; f68:14 +;info: +; Ожидание любого события в очереди EventList текущего слота +; Данные события code - копируются в память приложения (косвенно по edi) +; При активном флаге MANUAL_RESET - больше ничего +; Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются, +; и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота, +; а при не активном - уничтожается штатно (destroy_event.internal) +;param: +; edi - адрес в коде приложения для копирования данных из EVENT.code +;retval: +; eax - собственно EVENT (будем называть это его хэндлом) +;scratched: ebx,ecx,edx,esi,edi + mov edx, get_event_queue ; wait_test + call Wait_events ; timeout ignored + lea esi,[eax+EVENT.code] + mov ecx,EVENT.codesize/4 + cld + rep movsd + mov [edi-EVENT.codesize+2],cl ;clear priority field +wait_finish: + test byte[eax+EVENT.state+3], MANUAL_RESET shr 24 + jnz get_event_queue.ret ; RET + and byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) + test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24 + jz destroy_event.internal + mov ebx,[current_slot] + add ebx,APP_OBJ_OFFSET + pushfd + cli + jmp RemoveEventTo + +align 4 +destroy_event: ;; EXPORT use +;info: +; Переносим EVENT в список FreeEvents, чистим поля magic,destroy,pid,id +;param: +; eax - event +; ebx - uid (for Dummy testing) +;retval: +; eax - адрес объекта EVENT (=0 => fail) +;scratched: ebx,ecx + call DummyTest ; not returned for fail !!! +.internal: + xor ecx,ecx ; clear common header + pushfd + cli + mov [eax+EVENT.magic],ecx + mov [eax+EVENT.destroy],ecx + mov [eax+EVENT.pid],ecx + mov [eax+EVENT.id],ecx + mov ebx,FreeEvents + jmp RemoveEventTo + +align 4 +get_event_queue: +;info: +; клиентская ф-я тестирования для get_event_ex +;warning: +; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot +; -may be assumed, that interrupt are disabled +; -it is not restriction for scratched registers +;param: +; ebx - адрес APPDATA слота тестирования +;retval: +; eax - адрес объекта EVENT (=0 => fail) + add ebx,APP_EV_OFFSET + mov eax,[ebx+APPOBJ.bk] ; выбираем с конца, по принципу FIFO + cmp eax,ebx ; empty ??? + je get_event_alone.ret0 +.ret: ret + +align 4 +get_event_alone: +;info: +; клиентская ф-я тестирования для wait_event +;warning: +; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot +; -may be assumed, that interrupt are disabled +; -it is not restriction for scratched registers +;param: +; ebx - адрес APPDATA слота тестирования +;retval: +; eax - адрес объекта EVENT (=0 => fail) + mov eax,[ebx+APPDATA.wait_param] + test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24 + jnz .ret + or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24 +.ret0: xor eax,eax ; NO event!!! +.ret: ret + +align 4 +sys_sendwindowmsg: ;; f72 + dec ebx + jnz .ret ;subfunction==1 ? + ;pushfd ;а нафига? + cli + sub ecx,2 + je .sendkey + loop .retf +.sendbtn: + cmp byte[BTN_COUNT],1 + jae .result ;overflow + inc byte[BTN_COUNT] + mov [BTN_BUFF],edx + jmp .result +.sendkey: + movzx eax,byte[KEY_COUNT] + cmp al,120 + jae .result ;overflow + inc byte[KEY_COUNT] + mov [KEY_COUNT+1+eax],dl +.result: + setae byte[esp+32] ;считаем, что исходно: dword[esp+32]==72 +.retf: ;popfd +.ret: ret + +align 4 +sys_getevent: ;; f11 + mov ebx,[current_slot] ;пока это вопрос, чего куды сувать.......... + pushfd ; это следствие общей концепции: пусть ф-я тестирования имеет + cli ; право рассчитывать на закрытые прерывания, как при вызове из shed + call get_event_for_app + popfd + mov [esp+32],eax + ret + +align 4 +sys_waitforevent: ;; f10 + or ebx,-1 ; infinite timeout +sys_wait_event_timeout: ;; f23 + mov edx,get_event_for_app ; wait_test + call Wait_events_ex ; ebx - timeout + mov [esp+32],eax + ret + +align 4 +get_event_for_app: ;; used from f10,f11,f23 +;info: +; клиентская ф-я тестирования для приложений (f10,f23) +;warning: +; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot +; -may be assumed, that interrupt are disabled +; -it is not restriction for scratched registers +;param: +; ebx - адрес APPDATA слота тестирования +;retval: +; eax - номер события (=0 => no events) + movzx edi,bh ; bh is assumed as [CURRENT_TASK] + shl edi,5 + add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE] + mov ecx,[edi+TASKDATA.event_mask] +.loop: ; пока не исчерпаем все биты маски + bsr eax,ecx ; находим ненулевой бит маски (31 -> 0) + jz .no_events ; исчерпали все биты маски, но ничего не нашли ??? + btr ecx,eax ; сбрасываем проверяемый бит маски + ; переходим на обработчик этого (eax) бита + cmp eax,16 + jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15 + cmp eax,9 + jae .loop ; eax=[9..15], ignored + cmp eax,3 + je .loop ; eax=3, ignored + ja .FlagAutoReset ; eax=[4..8], retvals=eax+1 + cmp eax,1 + jae .BtKy ; eax=[1,2], retvals=eax+1 +.WndRedraw: ; eax=0, retval WndRedraw=1 + cmp [edi-twdw+WDATA.fl_redraw],al ;al==0 + jne .result + jmp .loop + .no_events: + xor eax,eax + ret +.IRQ: +;TODO: сделать так же, как и для FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) + mov edx,[irq_owner+eax*4-64] ; eax==16+irq + cmp edx,[edi+TASKDATA.pid] + jne .loop + mov edx,eax + shl edx,12 + cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000 + je .loop ; empty ??? + ret ; retval = eax +.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9 + btr [ebx+APPDATA.event_mask],eax + jnc .loop + .result: ; retval = eax+1 + inc eax + ret + .BtKy: + movzx edx,bh + movzx edx, word[WIN_STACK+edx*2] + je .Keys ; eax=1, retval Keys=2 +.Buttons: ; eax=2, retval Buttons=3 + cmp byte[BTN_COUNT],0 + je .loop ; empty ??? + cmp edx,[TASK_COUNT] + jne .loop ; not Top ??? + cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form + jne .result + mov [window_minimize],1 + dec byte[BTN_COUNT] + jmp .loop +.Keys: ; eax==1 + cmp edx,[TASK_COUNT] + jne @f ; not Top ??? + cmp [KEY_COUNT],al ; al==1 + jae .result ; not empty ??? + @@: mov edx, hotkey_buffer + @@: cmp [edx],bh ; bh - slot for testing + je .result + add edx,8 + cmp edx, hotkey_buffer+120*8 + jb @b + jmp .loop +;end. diff --git a/kernel/tags/kolibri0.7.7.0/gui/font.inc b/kernel/tags/kolibri0.7.7.0/gui/font.inc new file mode 100644 index 000000000..b5fbbab45 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/font.inc @@ -0,0 +1,132 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +; // Alver 22.06.2008 // { +align 4 +dtext_asciiz_esi: ; for skins title out + push eax + xor eax, eax + inc eax + jmp dtext.1 +; } \\ Alver \\ + +align 4 +dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) + ; ebx x & y + ; ecx style ( 0xX0000000 ) & color ( 0x00RRGGBB ) + ; X = ABnnb: + ; nn = font + ; A = 0 <=> output esi characters; otherwise output ASCIIZ string + ; B = 1 <=> fill background with color eax + ; edx start of text + ; edi 1 force + +; // Alver 22.06.2008 // { + push eax + xor eax, eax +.1: +; } \\ Alver \\ + pushad + call [_display.disable_mouse] + + movsx eax, bx ; eax=y + sar ebx, 16 ; ebx=x + xchg eax, ebx ; eax=x, ebx=y + cmp esi, 255 + jb .loop + mov esi, 255 +.loop: + test ecx, ecx + js .test_asciiz + dec esi + js .end + jmp @f +.test_asciiz: + cmp byte [edx], 0 + jz .end +; // Alver 22.06.2008 // { + cmp byte [esp+28], 1 + jne @f + dec esi + js .end +; } \\ Alver \\ +@@: + inc edx + pushad + movzx edx, byte [edx-1] + test ecx, 0x10000000 + jnz .font2 + mov esi, 9 + lea ebp, [FONT_I+8*edx+edx] +.symloop1: + mov dl, byte [ebp] + or dl, 1 shl 6 +.pixloop1: + shr dl, 1 + jz .pixloop1end + jnc .nopix + call [putpixel] + jmp .pixloop1cont +.nopix: + test ecx, 0x40000000 + jz .pixloop1cont + push ecx + mov ecx, [esp+4+20h+20h] + call [putpixel] + pop ecx +.pixloop1cont: + inc eax + jmp .pixloop1 +.pixloop1end: + sub eax, 6 + inc ebx + inc ebp + dec esi + jnz .symloop1 + popad + add eax, 6 + jmp .loop +.font2: + add edx, edx + lea ebp, [FONT_II+4*edx+edx+1] + push 9 + movzx esi, byte [ebp-1] +.symloop2: + mov dl, byte [ebp] + push esi +.pixloop2: + shr dl, 1 + jnc .nopix2 + call [putpixel] + jmp .pixloop2cont +.nopix2: + test ecx, 0x40000000 + jz .pixloop2cont + push ecx + mov ecx, [esp+12+20h+20h] + call [putpixel] + pop ecx +.pixloop2cont: + inc eax + dec esi + jnz .pixloop2 + pop esi + sub eax, esi + inc ebx + inc ebp + dec dword [esp] + jnz .symloop2 + pop eax + add dword [esp+28], esi + popad + jmp .loop +.end: + popad + pop eax ; << // Alver 22.06.2008 // << + ret diff --git a/kernel/tags/kolibri0.7.7.0/gui/mouse.inc b/kernel/tags/kolibri0.7.7.0/gui/mouse.inc new file mode 100644 index 000000000..98b38f88c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/mouse.inc @@ -0,0 +1,250 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +iglobal + +align 4 +mousepointer: +db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f +db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 +db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 +db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 +db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 +db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 +db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 +db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 +db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f +db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 +db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e +db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a +db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 +db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e +db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 +db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 +db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c +db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff +db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 +db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d +db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 +db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e +db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e +db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 +db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 +db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d +db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d +db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 +db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a +db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c +db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 +db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 +db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 +db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff +db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 +db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 +db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d +db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 +db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 +db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 +db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 +db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d +db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a +db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff +db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 +db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 +db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 +db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 +db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff +db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 +db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f +db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 +db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e +db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 +db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 +db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c +db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f +db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 +db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d +db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e +db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 +db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 +db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b +db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f +db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 +db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 +db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 +db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 +db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 +db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b +db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c +db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a +db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f +db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e +db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e +db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 +db 0x80,0x80 + +mousepointer1: +db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a +db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 +db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e +db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f +db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 +db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 +db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c +db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c +db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c +db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 +db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 +db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 +db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 +db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 +db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 +db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 +db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e +db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e +db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 +db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff +db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 +db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 +db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a +db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 +db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 +db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d +db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 +db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 +db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00 + +endg diff --git a/kernel/tags/kolibri0.7.7.0/gui/skincode.inc b/kernel/tags/kolibri0.7.7.0/gui/skincode.inc new file mode 100644 index 000000000..9e6ffbce9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/skincode.inc @@ -0,0 +1,467 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +include "skindata.inc" + +;skin_data = 0x00778000 + +read_skin_file: + stdcall load_file, ebx + test eax, eax + jz .notfound + cmp dword [eax], 'SKIN' + jnz .noskin + cmp ebx, 32*1024 + jb @f + mov ebx, 32*1024 +@@: + lea ecx, [ebx+3] + shr ecx, 2 + mov esi, eax + mov edi, skin_data + rep movsd + stdcall kernel_free, eax + + call parse_skin_data + xor eax, eax + ret +.notfound: + xor eax, eax + inc eax + ret +.noskin: + stdcall kernel_free, eax + push 2 + pop eax + ret + +struct SKIN_HEADER + .ident dd ? + .version dd ? + .params dd ? + .buttons dd ? + .bitmaps dd ? +ends + +struct SKIN_PARAMS + .skin_height dd ? + .margin.right dw ? + .margin.left dw ? + .margin.bottom dw ? + .margin.top dw ? + .colors.inner dd ? + .colors.outer dd ? + .colors.frame dd ? + .colors_1.inner dd ? + .colors_1.outer dd ? + .colors_1.frame dd ? + .dtp.size dd ? + .dtp.data db 40 dup (?) +ends + +struct SKIN_BUTTONS + .type dd ? + .pos: + .left dw ? + .top dw ? + .size: + .width dw ? + .height dw ? +ends + +struct SKIN_BITMAPS + .kind dw ? + .type dw ? + .data dd ? +ends + +load_default_skin: + mov [_skinh],22 + mov ebx,_skin_file_default + call read_skin_file + ret + +parse_skin_data: + mov ebp,skin_data + cmp [ebp+SKIN_HEADER.ident],'SKIN' + jne .exit + + mov edi,skin_udata + mov ecx,(skin_udata.end-skin_udata)/4 + xor eax,eax + cld + rep stosd + + mov ebx,[ebp+SKIN_HEADER.params] + add ebx,skin_data + mov eax,[ebx+SKIN_PARAMS.skin_height] + mov [_skinh],eax + mov eax,[ebx+SKIN_PARAMS.colors.inner] + mov [skin_active.colors.inner],eax + mov eax,[ebx+SKIN_PARAMS.colors.outer] + mov [skin_active.colors.outer],eax + mov eax,[ebx+SKIN_PARAMS.colors.frame] + mov [skin_active.colors.frame],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.inner] + mov [skin_inactive.colors.inner],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.outer] + mov [skin_inactive.colors.outer],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.frame] + mov [skin_inactive.colors.frame],eax + lea esi,[ebx+SKIN_PARAMS.dtp.data] + mov edi,common_colours + mov ecx,[ebx+SKIN_PARAMS.dtp.size] + and ecx,127 + rep movsb + mov eax,dword[ebx+SKIN_PARAMS.margin.right] + mov dword[_skinmargins+0],eax + mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] + mov dword[_skinmargins+4],eax + + mov ebx,[ebp+SKIN_HEADER.bitmaps] + add ebx,skin_data + .lp1: cmp dword[ebx],0 + je .end_bitmaps + movzx eax,[ebx+SKIN_BITMAPS.kind] + movzx ecx,[ebx+SKIN_BITMAPS.type] + dec eax + jnz .not_left + xor eax,eax + mov edx,skin_active.left.data + or ecx,ecx + jnz @f + mov edx,skin_inactive.left.data + @@: jmp .next_bitmap + .not_left: + dec eax + jnz .not_oper + mov esi,[ebx+SKIN_BITMAPS.data] + add esi,skin_data + mov eax,[esi+0] + neg eax + mov edx,skin_active.oper.data + or ecx,ecx + jnz @f + mov edx,skin_inactive.oper.data + @@: jmp .next_bitmap + .not_oper: + dec eax + jnz .not_base + mov eax,[skin_active.left.width] + mov edx,skin_active.base.data + or ecx,ecx + jnz @f + mov eax,[skin_inactive.left.width] + mov edx,skin_inactive.base.data + @@: jmp .next_bitmap + .not_base: + add ebx,8 + jmp .lp1 + .next_bitmap: + mov ecx,[ebx+SKIN_BITMAPS.data] + add ecx,skin_data + mov [edx+4],eax + mov eax,[ecx+0] + mov [edx+8],eax + add ecx,8 + mov [edx+0],ecx + add ebx,8 + jmp .lp1 + .end_bitmaps: + + mov ebx,[ebp+SKIN_HEADER.buttons] + add ebx,skin_data + .lp2: cmp dword[ebx],0 + je .end_buttons + mov eax,[ebx+SKIN_BUTTONS.type] + dec eax + jnz .not_close + mov edx,skin_btn_close + jmp .next_button + .not_close: + dec eax + jnz .not_minimize + mov edx,skin_btn_minimize + jmp .next_button + .not_minimize: + add ebx,12 + jmp .lp2 + .next_button: + movsx eax,[ebx+SKIN_BUTTONS.left] + mov [edx+SKIN_BUTTON.left],eax + movsx eax,[ebx+SKIN_BUTTONS.top] + mov [edx+SKIN_BUTTON.top],eax + movsx eax,[ebx+SKIN_BUTTONS.width] + mov [edx+SKIN_BUTTON.width],eax + movsx eax,[ebx+SKIN_BUTTONS.height] + mov [edx+SKIN_BUTTON.height],eax + add ebx,12 + jmp .lp2 + .end_buttons: + + .exit: + ret + +sys_putimage_with_check: + or ebx,ebx + jz @f + call sys_putimage.forced + @@: ret + +drawwindow_IV_caption: + + mov ebp,skin_active + or al,al + jnz @f + mov ebp,skin_inactive + @@: + + mov esi,[esp+4] + mov eax,[esi+WDATA.box.width] ; window width + mov edx,[ebp+SKIN_DATA.left.left] + shl edx,16 + mov ecx,[ebp+SKIN_DATA.left.width] + shl ecx,16 + add ecx,[_skinh] + + mov ebx, [ebp+SKIN_DATA.left.data] + call sys_putimage_with_check + + mov esi,[esp+4] + mov eax,[esi+WDATA.box.width] + sub eax,[ebp+SKIN_DATA.left.width] + sub eax,[ebp+SKIN_DATA.oper.width] + cmp eax,[ebp+SKIN_DATA.base.left] + jng .non_base + xor edx,edx + mov ecx,[ebp+SKIN_DATA.base.width] + jecxz .non_base + div ecx + + inc eax + + mov ebx,[ebp+SKIN_DATA.base.data] + mov ecx,[ebp+SKIN_DATA.base.width] + shl ecx,16 + add ecx,[_skinh] + mov edx,[ebp+SKIN_DATA.base.left] + sub edx,[ebp+SKIN_DATA.base.width] + shl edx,16 + .baseskinloop: + shr edx,16 + add edx,[ebp+SKIN_DATA.base.width] + shl edx,16 + + push eax ebx ecx edx + call sys_putimage_with_check + pop edx ecx ebx eax + + dec eax + jnz .baseskinloop + .non_base: + + mov esi,[esp+4] + mov edx,[esi+WDATA.box.width] + sub edx,[ebp+SKIN_DATA.oper.width] + inc edx + shl edx,16 + mov ebx,[ebp+SKIN_DATA.oper.data] + + mov ecx,[ebp+SKIN_DATA.oper.width] + shl ecx,16 + add ecx,[_skinh] + call sys_putimage_with_check + + ret + +;//mike.dld, 2006-08-02 ] + + +drawwindow_IV: +;param1 - aw_yes + + pusha + + push edx + + mov edi,edx + + mov ebp,skin_active + cmp byte [esp+32+4+4],0 + jne @f + mov ebp,skin_inactive + @@: + + mov eax,[edi+WDATA.box.left] + shl eax,16 + mov ax,word [edi+WDATA.box.left] + add ax,word [edi+WDATA.box.width] + mov ebx,[edi+WDATA.box.top] + shl ebx,16 + mov bx,word [edi+WDATA.box.top] + add bx,word [edi+WDATA.box.height] +; mov esi,[edi+24] +; shr esi,1 +; and esi,0x007f7f7f + mov esi,[ebp+SKIN_DATA.colors.outer] + or [edi+WDATA.fl_wdrawn], 4 + call draw_rectangle + mov ecx,3 + _dw3l: + add eax,1*65536-1 + add ebx,1*65536-1 + test ax,ax + js no_skin_add_button + test bx,bx + js no_skin_add_button + mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24] + call draw_rectangle + dec ecx + jnz _dw3l + mov esi,[ebp+SKIN_DATA.colors.inner] + add eax,1*65536-1 + add ebx,1*65536-1 + test ax,ax + js no_skin_add_button + test bx,bx + js no_skin_add_button + call draw_rectangle + + cmp dword[skin_data],'SKIN' + je @f + xor eax,eax + xor ebx,ebx + mov esi,[esp] + mov ecx,[esi+WDATA.box.width] + inc ecx + mov edx,[_skinh] + mov edi,[common_colours+4] ; standard grab color + call [drawbar] + jmp draw_clientbar + @@: + + mov al,[esp+32+4+4] + call drawwindow_IV_caption + + draw_clientbar: + + mov esi,[esp] + + mov edx,[esi+WDATA.box.top] ; WORK AREA + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg _noinside2 + mov eax,5 + mov ebx,[_skinh] + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + sub ecx,4 + sub edx,4 + mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz _noinside2 + call [drawbar] + _noinside2: + + cmp dword[skin_data],'SKIN' + jne no_skin_add_button + +;* close button + mov edi,[BTN_ADDR] + movzx eax,word [edi] + cmp eax,1000 + jge no_skin_add_button + inc eax + mov [edi],ax + + shl eax,4 + add eax,edi + + mov bx,[CURRENT_TASK] + mov [eax],bx + + add eax,2 ; save button id number + mov bx,1 + mov [eax],bx + add eax,2 ; x start + xor ebx,ebx + cmp [skin_btn_close.left],0 + jge _bCx_at_right + mov ebx,[esp] + mov ebx,[ebx+WDATA.box.width] + inc ebx + _bCx_at_right: + add ebx,[skin_btn_close.left] + mov [eax],bx + add eax,2 ; x size + mov ebx,[skin_btn_close.width] + dec ebx + mov [eax],bx + add eax,2 ; y start + mov ebx,[skin_btn_close.top] + mov [eax],bx + add eax,2 ; y size + mov ebx,[skin_btn_close.height] + dec ebx + mov [eax],bx + +;* minimize button + mov edi,[BTN_ADDR] + movzx eax,word [edi] + cmp eax,1000 + jge no_skin_add_button + inc eax + mov [edi],ax + + shl eax,4 + add eax,edi + + mov bx,[CURRENT_TASK] + mov [eax],bx + + add eax,2 ; save button id number + mov bx,65535 ;999 + mov [eax],bx + add eax,2 ; x start + xor ebx,ebx + cmp [skin_btn_minimize.left],0 + jge _bMx_at_right + mov ebx,[esp] + mov ebx,[ebx+WDATA.box.width] + inc ebx + _bMx_at_right: + add ebx,[skin_btn_minimize.left] + mov [eax],bx + add eax,2 ; x size + mov ebx,[skin_btn_minimize.width] + dec ebx + mov [eax],bx + add eax,2 ; y start + mov ebx,[skin_btn_minimize.top] + mov [eax],bx + add eax,2 ; y size + mov ebx,[skin_btn_minimize.height] + dec ebx + mov [eax],bx + + no_skin_add_button: + pop edi + and [edi+WDATA.fl_wdrawn], not 4 + test [edi+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes2 +@@: + + popa + + ret 4 + diff --git a/kernel/tags/kolibri0.7.7.0/gui/skindata.inc b/kernel/tags/kolibri0.7.7.0/gui/skindata.inc new file mode 100644 index 000000000..b2e3c1244 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/skindata.inc @@ -0,0 +1,64 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; +; WINDOW SKIN DATA +; + +iglobal + _skin_file_default db '/sys/DEFAULT.SKN',0 +endg + +struct SKIN_DATA + .colors.inner dd ? + .colors.outer dd ? + .colors.frame dd ? + .left.data dd ? + .left.left dd ? + .left.width dd ? + .oper.data dd ? + .oper.left dd ? + .oper.width dd ? + .base.data dd ? + .base.left dd ? + .base.width dd ? +ends + +struct SKIN_BUTTON + .left dd ? + .top dd ? + .width dd ? + .height dd ? +ends + +uglobal + +align 4 + +skin_udata: + _skinh dd ? + + _skinmargins: ; rw 4 + .right dw ? + .left dw ? + .bottom dw ? + .top dw ? + + skin_btn_close SKIN_BUTTON + skin_btn_minimize SKIN_BUTTON + + skin_active SKIN_DATA + skin_inactive SKIN_DATA + +align 4 + +skin_udata.end: + +endg diff --git a/kernel/tags/kolibri0.7.7.0/gui/window.inc b/kernel/tags/kolibri0.7.7.0/gui/window.inc new file mode 100644 index 000000000..bff2aa004 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/gui/window.inc @@ -0,0 +1,1823 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +get_titlebar_height: ; edi = window draw_data pointer + mov al,[edi+WDATA.fl_wstyle] + and al,0x0F + cmp al,0x03 + jne @f + mov eax,[_skinh] + ret + @@: mov eax,21 + ret + +get_rolledup_height: ; edi = window draw_data pointer + mov al,[edi+WDATA.fl_wstyle] + and al,0x0F + cmp al,0x03 + jb @f + mov eax,[_skinh] + add eax,3 + ret + @@: or al,al + jnz @f + mov eax,21 + ret + @@: mov eax,21+2 + ret + + +setwindowdefaults: + pushad + + xor eax,eax + mov ecx,WIN_STACK + @@: + inc eax + add ecx,2 + mov [ecx+0x000],ax ; process no + mov [ecx+0x400],ax ; positions in stack + cmp ecx,WIN_POS-2 ; the more high, the more surface + jnz @b + + popad + ret + + + +; eax = cx +; ebx = cy +; ecx = ex +; edx = ey +; идея: перебрать все окна, начиная с самого нижнего, +; и для попавших в заданную область +; частей окон вызвать setscreen +align 4 +calculatescreen: + pushad + pushfd + cli + + push edx ecx ebx eax + + mov esi, 1 + call setscreen + + mov ebp, [TASK_COUNT] ; number of processes + cmp ebp, 1 + jbe .finish + align 4 + .new_wnd: + movzx edi, word [WIN_POS + esi * 2] + shl edi, 5 + + cmp [CURRENT_TASK+edi+TASKDATA.state], byte 9 + je .not_wnd + + add edi, window_data + test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .not_wnd + + mov eax,[edi+WDATA.box.left] + cmp eax, [esp+RECT.right] + ja .out_of_bounds + mov ebx,[edi+WDATA.box.top] + cmp ebx, [esp+RECT.bottom] + ja .out_of_bounds + mov ecx,[edi+WDATA.box.width] + add ecx, eax + cmp ecx, [esp+RECT.left] + jb .out_of_bounds + mov edx,[edi+WDATA.box.height] + add edx, ebx + cmp edx, [esp+RECT.top] + jb .out_of_bounds + + cmp eax, [esp+RECT.left] + jae @f + mov eax, [esp+RECT.left] + @@: + cmp ebx, [esp+RECT.top] + jae @f + mov ebx, [esp+RECT.top] + @@: + cmp ecx, [esp+RECT.right] + jbe @f + mov ecx, [esp+RECT.right] + @@: + cmp edx, [esp+RECT.bottom] + jbe @f + mov edx, [esp+RECT.bottom] + @@: + + push esi + movzx esi, word [WIN_POS + esi * 2] + call setscreen + pop esi + + .not_wnd: + .out_of_bounds: + inc esi + dec ebp + jnz .new_wnd + .finish: + + pop eax ebx ecx edx + + popfd + popad +ret + + + +virtual at esp + ff_x dd ? + ff_y dd ? + ff_width dd ? + ff_xsz dd ? + ff_ysz dd ? + ff_scale dd ? +end virtual + +align 4 +; резервирует место под окно заданного процесса +setscreen: +; eax x start +; ebx y start +; ecx x end +; edx y end +; esi process number +pushad +; \begin{diamond}[29.08.2006] + cmp esi, 1 + jz @f + mov edi, esi + shl edi, 5 + cmp [edi+window_data+WDATA.box.width], 0 + jnz @f + cmp [edi+window_data+WDATA.box.height], 0 + jz .ret +@@: +; \end{diamond}[29.08.2006] + mov edi, esi ;;;word [esi*2+WIN_POS] + shl edi, 8 + add edi, SLOT_BASE ; address of random shaped window area + cmp [edi+APPDATA.wnd_shape], dword 0 + jne .free_form + + ; get x&y size + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + ; get WinMap start + mov edi, [Screen_Max_X] ; screen_sx + inc edi + imul edi, ebx + add edi, eax + add edi, [_WinMapAddress] + + .new_y: + push ecx ; sx + push edx + + mov edx, esi + align 4 + .new_x: + mov byte [edi], dl + inc edi + dec ecx + jnz .new_x + + pop edx + pop ecx + add edi, [Screen_Max_X] + inc edi + sub edi, ecx + dec edx + jnz .new_y +.ret: + popad + ret + .read_byte: + ;eax - address + ;esi - slot + push eax + push ebx + push ecx + push edx + mov edx,eax + mov eax,esi + lea ebx,[esp+12] + mov ecx,1 + call read_process_memory + pop edx + pop ecx + pop ebx + pop eax + ret + .free_form: + + ; for (y=0; y <= x_size; y++) + ; for (x=0; x <= x_size; x++) + ; if (shape[coord(x,y,scale)]==1) + ; set_pixel(x, y, process_number); + + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + push dword [edi+APPDATA.wnd_shape_scale] ; push scale first -> for loop + + ; get WinMap start -> ebp + push eax + mov eax, [Screen_Max_X] ; screen_sx + inc eax + imul eax, ebx + add eax, [esp] + add eax, [_WinMapAddress] + mov ebp, eax + + mov edi, [edi+APPDATA.wnd_shape] + pop eax + + ; eax = x_start + ; ebx = y_start + ; ecx = x_size + ; edx = y_size + ; esi = process_number + ; edi = &shape + ; [scale] + push edx ecx ; for loop - x,y size + + mov ecx, esi + shl ecx, 5 + mov edx, [window_data+ecx+WDATA.box.top] + push [window_data+ecx+WDATA.box.width] ; for loop - width + mov ecx, [window_data+ecx+WDATA.box.left] + sub ebx, edx + sub eax, ecx + push ebx eax ; for loop - x,y + + add [ff_xsz], eax + add [ff_ysz], ebx + + mov ebx, [ff_y] + + .ff_new_y: + mov edx, [ff_x] + + .ff_new_x: + ; -- body -- + mov ecx, [ff_scale] + mov eax, [ff_width] + inc eax + shr eax, cl + push ebx edx + shr ebx, cl + shr edx, cl + imul eax, ebx + add eax, edx + pop edx ebx + add eax, edi + call .read_byte + test al,al + jz @f + mov eax, esi + mov [ebp], al + @@: + ; -- end body -- + inc ebp + inc edx + cmp edx, [ff_xsz] + jb .ff_new_x + sub ebp, [ff_xsz] + add ebp, [ff_x] + add ebp, [Screen_Max_X] ; screen.x + inc ebp + inc ebx + cmp ebx, [ff_ysz] + jb .ff_new_y + + add esp, 24 +popad +ret + + +display_settings: + +; eax = 0 ; DISPLAY redraw +; ebx = 0 ; all +; +; eax = 1 ; BUTTON type +; ebx = 0 ; flat +; ebx = 1 ; 3D +; eax = 2 ; set WINDOW colours +; ebx = pointer to table +; ecx = number of bytes define +; eax = 3 ; get WINDOW colours +; ebx = pointer to table +; ecx = number of bytes wanted +; eax = 4 ; get skin height +; input : nothing +; output : eax = skin height in pixel +; eax = 5 ; get screen workarea +; input : nothing +; output : eax = [left]*65536+[right] +; ebx = [top]*65536+[bottom] +; eax = 6 ; set screen workarea +; input : ecx = [left]*65536+[right] +; edx = [top]*65536+[bottom] +; output : nothing +; eax = 7 ; get skin margins +; input : nothing +; output : eax = [left]*65536+[right] +; ebx = [top]*65536+[bottom] +; eax = 8 ; set window skin +; input : ecx = pointer to file info block +; output : eax = FS error code + + + pushad + + test eax, eax ; redraw display + jnz dspl0 + test ebx, ebx + jnz dspl0 + cmp [windowtypechanged],dword 1 + jne dspl00 + mov [windowtypechanged],dword 0 + redraw_screen_direct: + mov [dlx],dword 0 + mov [dly],dword 0 + mov eax,[Screen_Max_X] + mov [dlxe],eax + mov eax,[Screen_Max_Y] + mov [dlye],eax + mov eax,window_data + call redrawscreen + dspl00: + popad + ret + dspl0: + + cmp eax,1 ; button type + jne dspl1 + and ebx,1 + cmp ebx,[buttontype] + je dspl9 + mov [buttontype],ebx + mov [windowtypechanged],dword 1 + dspl9: + popad + ret + dspl1: + + cmp eax,2 ; set common window colours + jne no_com_colours + mov [windowtypechanged],dword 1 + mov esi,[TASK_BASE] + add esi,TASKDATA.mem_start + add ebx,[esi] + mov esi,ebx + mov edi,common_colours + and ecx,127 + cld + rep movsb + popad + ret + no_com_colours: + + cmp eax,3 ; get common window colours + jne no_get_com + mov esi,[TASK_BASE] + add esi,TASKDATA.mem_start + add ebx,[esi] + mov edi,ebx + mov esi,common_colours + and ecx,127 + cld + rep movsb + popad + ret + no_get_com: + + cmp eax,4 ; get skin height + jne no_skin_height + popad + mov eax,[_skinh] + mov [esp+36],eax + ret + no_skin_height: + + cmp eax,5 ; get screen workarea + jne no_get_workarea + popad + mov eax,[screen_workarea.left-2] + mov ax,word[screen_workarea.right] + mov [esp+36],eax + mov eax,[screen_workarea.top-2] + mov ax,word[screen_workarea.bottom] + mov [esp+24],eax + ret + no_get_workarea: + + cmp eax,6 ; set screen workarea + jne no_set_workarea + movsx eax,word[esp+16+2] + movsx ebx,word[esp+16] + cmp eax,ebx + jge .lp1 + or eax,eax;[Screen_Max_X] + jl @f + mov [screen_workarea.left],eax + @@: cmp ebx,[Screen_Max_X] + jg .lp1 + mov [screen_workarea.right],ebx + .lp1: movsx eax,word[esp+24+2] + movsx ebx,word[esp+24] + cmp eax,ebx + jge .lp2 + or eax,eax;[0xFE04] + jl @f + mov [screen_workarea.top],eax + @@: cmp ebx,[Screen_Max_Y] + jg .lp2 + mov [screen_workarea.bottom],ebx + .lp2: call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen +; jmp redraw_screen_direct + .exit: + popad + ret + no_set_workarea: + + cmp eax,7 ; get skin margins + jne no_get_skinmargins + popad + mov eax,dword[_skinmargins+0] + mov [esp+36],eax + mov eax,dword[_skinmargins+4] + mov [esp+24],eax + ret + no_get_skinmargins: + + cmp eax,8 ; set window skin + jne no_set_skin + call read_skin_file + mov [esp+32+36], eax + test eax, eax + jnz .ret + xor eax, eax + xor ebx, ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + jmp redraw_screen_direct +.ret: + popad + ret + no_set_skin: + + popad + ret + + +repos_windows: + mov ecx,[TASK_COUNT] + mov edi, window_data+0x20*2 + call force_redraw_background + dec ecx + jge @f + ret + @@: mov [edi+WDATA.fl_redraw],1 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jz .lp2 + mov eax,[screen_workarea.left] + mov [edi+WDATA.box.left],eax + sub eax,[screen_workarea.right] + neg eax + mov [edi+WDATA.box.width],eax + mov eax,[screen_workarea.top] + mov [edi+WDATA.box.top],eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .lp1 + sub eax,[screen_workarea.bottom] + neg eax + mov [edi+WDATA.box.height],eax + .lp1: + + call set_window_clientbox + add edi,0x20 + loop @b + ret + .lp2: mov eax,[edi+WDATA.box.left] + add eax,[edi+WDATA.box.width] + mov ebx,[Screen_Max_X] +; inc ebx + cmp eax,ebx + jle .lp4 + mov eax,[edi+WDATA.box.width] + sub eax,ebx + jle .lp3 + mov [edi+WDATA.box.width],ebx + .lp3: sub ebx,[edi+WDATA.box.width] + mov [edi+WDATA.box.left],ebx + .lp4: mov eax,[edi+WDATA.box.top] + add eax,[edi+WDATA.box.height] + mov ebx,[Screen_Max_Y] +; inc ebx + cmp eax,ebx + jle .lp6 + mov eax,[edi+WDATA.box.height] + sub eax,ebx + jle .lp5 + mov [edi+WDATA.box.height],ebx + .lp5: sub ebx,[edi+WDATA.box.height] + mov [edi+WDATA.box.top],ebx + .lp6: jmp .lp1 + +uglobal + common_colours: + times 128 db 0x0 +endg + + + + +check_window_position: + + pushad ; window inside screen ? + + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, [edi+WDATA.box.width] + mov edx, [edi+WDATA.box.height] + + cmp ecx,[Screen_Max_X] ; check x size + jbe x_size_ok + mov ecx,[Screen_Max_X] + mov [edi+WDATA.box.width],ecx + + x_size_ok: + + cmp edx,[Screen_Max_Y] ; check y size + jbe y_size_ok + mov edx,[Screen_Max_Y] + mov [edi+WDATA.box.height],edx + + y_size_ok: + + cmp eax,0 ; check x pos + jnle @f + xor eax,eax + mov [edi+WDATA.box.left],eax + jmp x_pos_ok + @@: + add eax,ecx + cmp eax,[Screen_Max_X] + jbe x_pos_ok + mov eax,[Screen_Max_X] + sub eax,ecx + mov [edi+WDATA.box.left],eax + + x_pos_ok: + + cmp ebx,0 ; check x pos + jnle @f + xor ebx,ebx + mov [edi+WDATA.box.top],ebx + jmp y_pos_ok + @@: + add ebx,edx + cmp ebx,[Screen_Max_Y] + jbe y_pos_ok + mov ebx,[Screen_Max_Y] + sub ebx,edx + mov [edi+WDATA.box.top],ebx + + y_pos_ok: + + popad + + ret + + +uglobal + new_window_starting dd 0 +endg + + +sys_window_mouse: + + push eax + + mov eax,[timer_ticks] + cmp [new_window_starting],eax + jb swml1 + + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse + + mov [new_window_starting],eax + + swml1: + + pop eax + + ret + + + + +drawwindow_I_caption: + + mov ecx,[edx+WDATA.cl_titlebar] ; grab bar + push ecx + mov esi,edx + mov edx,[esi+WDATA.box.top] + add edx,1 + mov ebx,[esi+WDATA.box.top] + add ebx,21 + mov eax,[esi+WDATA.box.top] + add eax,[esi+WDATA.box.height] + cmp ebx,eax + jb .wdsizeok + mov ebx,eax + .wdsizeok: + push ebx + .drwi: + mov ebx,edx + shl ebx,16 + add ebx,edx + mov eax,[esi+WDATA.box.left] + inc eax + shl eax,16 + add eax,[esi+WDATA.box.left] + add eax,[esi+WDATA.box.width] + sub eax,1 + push edx + mov edx,0x80000000 + mov ecx,[esi+WDATA.cl_titlebar] + and ecx,edx + cmp ecx,edx + jnz .nofa + mov ecx,[esi+WDATA.cl_titlebar] + sub ecx,0x00040404 + mov [esi+WDATA.cl_titlebar],ecx + and ecx,0x00ffffff + jmp .faj + .nofa: + mov ecx,[esi+WDATA.cl_titlebar] + and ecx,0x00ffffff + .faj: + pop edx + mov edi,0 + call [draw_line] + inc edx + cmp edx,[esp] + jb .drwi + add esp,4 + pop ecx + mov [esi+WDATA.cl_titlebar],ecx + + ret + + +drawwindow_I: + + pushad + or [edx+WDATA.fl_wdrawn], 4 + + mov esi,[edx+WDATA.cl_frames] ; rectangle + mov eax,[edx+WDATA.box.left] + shl eax,16 + add eax,[edx+WDATA.box.left] + add eax,[edx+WDATA.box.width] + mov ebx,[edx+WDATA.box.top] + shl ebx,16 + add ebx,[edx+WDATA.box.top] + add ebx,[edx+WDATA.box.height] + call draw_rectangle + + and [edx+WDATA.fl_wdrawn], not 4 + test [edx+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes2 +@@: + + call drawwindow_I_caption + + mov edx,[esi+WDATA.box.top] ; inside work area + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg noinside + mov eax,1 + mov ebx,21 + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz noinside + call [drawbar] + noinside: + + popad + + ret + + +draw_rectangle: + +r_eax equ [esp+28] ; x start +r_ax equ [esp+30] ; x end +r_ebx equ [esp+16] ; y start +r_bx equ [esp+18] ; y end +;esi ; color + + pushad + + mov ecx,esi ; yb,xb -> yb,xe + mov eax, r_eax + rol eax, 16 + mov ebx,r_ebx + shl ebx,16 + mov bx,r_ebx + xor edi, edi + call [draw_line] + + mov ebx,r_bx ; ye,xb -> ye,xe + shl ebx,16 + mov bx,r_bx + call [draw_line] + + mov ecx,esi ; ya,xa -> ye,xa + mov eax,r_eax + shl eax,16 + mov ax,r_eax + mov ebx,r_ebx + shl ebx,16 + mov bx,r_bx + mov edi,0 + call [draw_line] + + mov eax,r_ax ; ya,xe -> ye,xe + shl eax,16 + mov ax,r_ax + call [draw_line] + + popad + ret + + +drawwindow_III_caption: + + mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR + push ecx + mov esi,edx + mov edx,[esi+WDATA.box.top] + add edx,4 + mov ebx,[esi+WDATA.box.top] + add ebx,20 + mov eax,[esi+WDATA.box.top] + add eax,[esi+WDATA.box.height] + cmp ebx,eax + jb .wdsizeok + mov ebx,eax + .wdsizeok: + push ebx + .drwi: + mov ebx,edx + shl ebx,16 + add ebx,edx + mov eax,[esi+WDATA.box.left] + shl eax,16 + add eax,[esi+WDATA.box.left] + add eax,[esi+WDATA.box.width] + add eax,4*65536-4 + mov ecx,[esi+WDATA.cl_titlebar] + test ecx,0x40000000 + jz .nofa + add ecx,0x040404 + .nofa: + test ecx,0x80000000 + jz .nofa2 + sub ecx,0x040404 + .nofa2: + mov [esi+WDATA.cl_titlebar],ecx + and ecx,0xffffff + xor edi, edi + call [draw_line] + inc edx + cmp edx,[esp] + jb .drwi + add esp,4 + pop ecx + mov [esi+WDATA.cl_titlebar],ecx + + ret + + +drawwindow_III: + + pushad + + mov edi,edx ; RECTANGLE + mov eax,[edi+WDATA.box.left] + shl eax,16 + mov ax, word [edi+WDATA.box.left] + add ax, word [edi+WDATA.box.width] + mov ebx,[edi+WDATA.box.top] + shl ebx,16 + mov bx, word [edi+WDATA.box.top] + add bx, word [edi+WDATA.box.height] + mov esi,[edi+WDATA.cl_frames] + shr esi,1 + and esi,0x007f7f7f + push esi + or [edi+WDATA.fl_wdrawn], 4 + call draw_rectangle + and [edi+WDATA.fl_wdrawn], not 4 + test [edi+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes2 +@@: + mov ecx,3 + dw3l: + add eax,1*65536-1 + add ebx,1*65536-1 + mov esi,[edi+WDATA.cl_frames] + call draw_rectangle + dec ecx + jnz dw3l + pop esi + add eax,1*65536-1 + add ebx,1*65536-1 + call draw_rectangle + + call drawwindow_III_caption + + mov edx,[esi+WDATA.box.top] ; WORK AREA + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg noinside2 + mov eax,5 + mov ebx,20 + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + sub ecx,4 + sub edx,4 + mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz noinside2 + call [drawbar] + noinside2: + + popad + + ret + + + +; activate window +align 4 +windowactivate: + + ; esi = abs mem position in stack 0xC400+ + + pushad + + ; if type of current active window is 3, + ; it must be redrawn + mov eax, [TASK_COUNT] + movzx eax, word [WIN_POS + eax*2] + shl eax, 5 + add eax, window_data + mov ebx, [eax + WDATA.cl_workarea] + and ebx, 0x0f000000 + cmp ebx, 0x03000000 + je .set_WDATA_fl_redraw ; for 3 and 4 style + cmp ebx, 0x04000000 + je .set_WDATA_fl_redraw + jmp @f + .set_WDATA_fl_redraw: + mov [eax + WDATA.fl_redraw], byte 1 + @@: + + push esi + movzx eax, word [esi] ; ax <- process no + movzx eax, word [WIN_STACK+eax*2] ; ax <- position in window stack + + xor esi, esi ; drop others + waloop: + cmp esi, dword [TASK_COUNT] + jae wacont + inc esi + lea edi, [WIN_STACK + esi*2] + mov bx, [edi] ; position of the current process + cmp bx, ax + jbe @f + dec bx ; upper? => drop! + mov [edi], bx + @@: + jmp waloop + wacont: + ; set to no 1 + pop esi ; esi = pointer at 0xC400 + + movzx eax, word [esi] + mov bx, [TASK_COUNT] ; number of processes + mov [WIN_STACK+eax*2], bx ; this is the last (and the upper) + + ; update on screen -window stack + xor esi, esi + waloop2: + mov edi, [TASK_COUNT] + cmp esi, edi + jae wacont2 + inc esi + movzx ebx, word [esi*2 + WIN_STACK] + mov [ebx*2 + WIN_POS], si + jmp waloop2 + wacont2: + mov [KEY_COUNT], byte 0 ; empty keyboard buffer + mov [BTN_COUNT], byte 0 ; empty button buffer + mov [MOUSE_SCROLL_H], word 0 ; zero mouse z-index + mov [MOUSE_SCROLL_V], word 0 ; zero mouse z-index + popad + ret + + +; check if window is necessary to draw + +checkwindowdraw: + + ; edi = position in window_data+ + + mov eax, [edi + WDATA.cl_workarea] + and eax, 0x0f000000 + cmp eax, 0x03000000 + je .return_yes ; window type 3 + cmp eax, 0x04000000 + je .return_yes ; window type 4 + + mov esi, edi + sub esi, window_data + shr esi, 5 + + ; esi = process number + + movzx eax, word [WIN_STACK + esi * 2] ; get value of the curr process + lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 + + push esi + + .new_check: + + pop esi + add esi, 2 + push esi + + mov eax, [TASK_COUNT] + lea eax, word [WIN_POS + eax * 2] ; number of the upper window + + cmp esi, eax + ja .all_wnds_to_top + + movzx eax, word [esi] + shl eax, 5 + cmp [CURRENT_TASK + eax + TASKDATA.state], byte 9 + je .new_check ; skip dead windows + + lea esi, [eax+window_data] + + mov ebx, [edi+WDATA.box.top] ; y0 + mov edx, [edi+WDATA.box.height] + add edx, ebx ; y0e + + mov ecx, [esi+WDATA.box.top] ; y ; y check + cmp ecx, edx + jae .new_check ; y < y0e + mov eax, [esi+WDATA.box.height] + add ecx, eax ; ye + cmp ebx, ecx ; y0 >= ye + ja .new_check + + mov eax, [edi+WDATA.box.left] ; x0 + mov ecx, [edi+WDATA.box.width] + add ecx, eax ; x0e + + mov edx, [esi+WDATA.box.left] ; x ; x check + cmp edx, ecx + jae .new_check ; x < x0e + mov ecx, [esi+WDATA.box.width] + add edx, ecx + cmp eax, edx + ja .new_check + + pop esi + .return_yes: + mov ecx,1 ; overlap some window + ret + + .all_wnds_to_top: + + pop esi + + xor ecx, ecx ; passed all windows to top + ret + + + + +waredraw: ; if redraw necessary at activate + + pushad + + call checkwindowdraw ; draw window on activation ? + test ecx, ecx + jz .do_not_draw + + popad + mov [MOUSE_DOWN], byte 1 ; do draw mouse + call windowactivate + + ; update screen info + pushad + mov edi, [TASK_COUNT] ; the last process (number) + movzx esi, word [WIN_POS + edi * 2] + shl esi, 5 + add esi, window_data + + ; coordinates of the upper window + mov eax, [esi + WDATA.box.left] ; cx + mov ebx, [esi + WDATA.box.top] ; cy + mov ecx, [esi + WDATA.box.width] ; sx + mov edx, [esi + WDATA.box.height] ; sy + + add ecx, eax ; ecx = x_end + add edx, ebx ; edx = y_end + + mov edi, [TASK_COUNT] + movzx esi, word [WIN_POS + edi * 2] + call setscreen + popad + + mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app + mov [MOUSE_DOWN],byte 0 ; mouse down checks + + ret + + .do_not_draw: + + popad + + call windowactivate + mov [MOUSE_DOWN],byte 0 ; mouse down checks + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse + ret + + +; eax = window number on screen +; corrupts registers and [dl*] +minimize_window: + movzx eax, word [WIN_POS+eax*2] + shl eax, 5 + add eax, window_data + test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .skip_redrawings + pushfd + cli + or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED + mov edi, eax + ;call calculatescreen + mov eax, [edi+WDATA.box.left] + mov [dlx], eax + mov ecx, eax + add ecx, [edi+WDATA.box.width] + mov [dlxe], ecx + mov ebx, [edi+WDATA.box.top] + mov [dly], ebx + mov edx, ebx + add edx, [edi+WDATA.box.height] + mov [dlye], edx + call calculatescreen + xor esi, esi + xor eax, eax + call redrawscreen + popfd +.skip_redrawings: + ret + +; eax = window number on screen +; corrupts registers and [dl*] +restore_minimized_window: + pushfd + cli + movzx esi, word [WIN_POS+eax*2] + mov edi, esi + shl edi, 5 + add edi, window_data + test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED + jz .skip_redrawings + mov [edi+WDATA.fl_redraw], 1 + and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED + cmp eax, [TASK_COUNT] ; the uppermost window + jnz .no_uppermost + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, eax + mov edx, ebx + add ecx, [edi+WDATA.box.width] + add edx, [edi+WDATA.box.height] + call setscreen + jmp .done +.no_uppermost: + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, eax + mov edx, ebx + add ecx, [edi+WDATA.box.width] + add edx, [edi+WDATA.box.height] + call calculatescreen +.done: + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under +.skip_redrawings: + popfd + ret + + +;iglobal +; window_moving db 'K : Window - move/resize',13,10,0 +; window_moved db 'K : Window - done',13,10,0 +;endg + +; check window touch +align 4 +checkwindows: + pushad + + cmp [window_minimize], 0 + je .no_minimizing + mov eax, [TASK_COUNT] ; the uppermost window + mov bl, 0 + xchg [window_minimize], bl + cmp bl, 1 + jne .restore + call minimize_window + jmp .continue + .restore: + call restore_minimized_window + .continue: + .no_minimizing: + + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? + jne .mouse_buttons_pressed +;..................................... start 1/4 : modified by vhanla ................. + mov [bPressedMouseXY_W],0 +;..................................... end 1/4 : modified by vhanla ................... + popad + ret + .mouse_buttons_pressed: +;..................................... start 2/4 : modified by vhanla ................. +uglobal + bPressedMouseXY_W db 0x0 +endg +;..................................... end 2/4 : modified by vhanla ................... + mov esi,[TASK_COUNT] + inc esi + +;..................................... start 3/4 : modified by vhanla ................. + cmp [bPressedMouseXY_W],1 + ja @f + inc [bPressedMouseXY_W] + jnc @f + ;mov ax,[MOUSE_X] + ;mov [mx],ax + ;mov ax,[MOUSE_Y] + ;mov [my],ax + mov eax,dword[MOUSE_X] + mov dword[mx],eax + @@: +;..................................... end 3/4 : modified by vhanla ................... + + cwloop: + cmp esi,2 + jb .exit + + dec esi + movzx edi, word [WIN_POS + esi * 2] ; ebx + shl edi, 5 + add edi, window_data +; mov edi, ebx + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + + mov eax,ecx + mov ebx,edx + test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED + jnz cwloop + +;..................................... start 4/4 : modified by vhanla ................. + movzx eax, word [mx]; movzx eax,word[MOUSE_X] + movzx ebx, word [my]; movzx ebx,word[MOUSE_Y] +;..................................... endt 4/4 : modified by vhanla .................. + cmp ecx, eax + jae cwloop + cmp edx, ebx + jae cwloop + add ecx, [edi + WDATA.box.width] + add edx, [edi + WDATA.box.height] + cmp eax, ecx + jae cwloop + cmp ebx, edx + jae cwloop + + pushad + mov eax, esi + mov ebx, [TASK_COUNT] + cmp eax, ebx ; is this window active? + jz .move_resize_window + + cmp [bPressedMouseXY_W], 1 + ja .exit_popa + + ; eax = position in windowing stack + ; redraw must ? + lea esi, [WIN_POS + esi * 2] + call waredraw + .exit_popa: + add esp, 32 + + .exit: + popad + ret + + .move_resize_window: ; MOVE OR RESIZE WINDOW + popad + + ; Check for user enabled fixed window + mov edx, [edi + WDATA.cl_titlebar] + and edx, 0x0f000000 + cmp edx, 0x01000000 + jne .window_move_enabled_for_user + popad + ret + .window_move_enabled_for_user: + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .no_resize_2 + + mov [do_resize_from_corner],byte 0 ; resize for skinned window + mov edx, [edi + WDATA.cl_workarea] + and edx, 0x0f000000 + cmp edx, 0x00000000 ;{test for resized} + je .no_resize_2 + cmp edx, 0x01000000 ;{test for resized} + je .no_resize_2 + cmp edx, 0x04000000 ;{test for resized} + je .no_resize_2 +; jb .no_resize_2 ; not type 2 wnd + + mov edx, [edi + WDATA.box.top] + add edx, [edi + WDATA.box.height] + sub edx, 6 ; edx = y_end - 6 + cmp ebx, edx ; ebx = mouse_y + jb .no_resize_2 + mov [do_resize_from_corner],byte 1 + jmp .continue + .no_resize_2: + + push eax + call get_titlebar_height + add eax,[edi + WDATA.box.top] + cmp ebx,eax + pop eax + jae .exit + + .continue: + +; push esi +; mov esi, window_moving +; call sys_msg_board_str +; pop esi + + mov ecx, [timer_ticks] ; double-click ? + mov edx, ecx + sub edx, [latest_window_touch] + mov [latest_window_touch], ecx + mov [latest_window_touch_delta], edx + + mov cl, [BTN_DOWN] ; save for shade check + mov [do_resize], cl + no_emulation_righ_button: + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + + push eax ecx edx + mov [dlx], ecx ; save for drawlimits + mov [dly], edx + mov eax, [edi + WDATA.box.width] + add ecx, eax + mov eax, [edi + WDATA.box.height] + add edx, eax + mov [dlxe], ecx + mov [dlye], edx + pop edx ecx eax + + sub eax, ecx + sub ebx, edx + + mov esi, [MOUSE_X] + mov [WIN_TEMP_XY], esi + + pushad ; wait for putimages to finish +; mov ebx,5 +; call delay_hs + mov eax,[edi + WDATA.box.left] + mov [npx],eax + mov eax,[edi + WDATA.box.top] + mov [npy],eax + popad + + push eax ; save old coordinates + mov ax, word [edi + WDATA.box.left] + mov word [oldc+BOX.left],ax + mov ax, word [edi + WDATA.box.top] + mov word [oldc+BOX.top],ax + mov ax, word [edi + WDATA.box.width] + mov word [oldc+BOX.width],ax + mov word [npxe],ax + mov ax, word [edi + WDATA.box.height] + mov word [oldc+BOX.height],ax + mov word [npye],ax + pop eax + + call drawwindowframes + + mov [reposition],0 + mov [MOUSE_DOWN],byte 1 ; no reaction to mouse up/down + + ; move window + + newchm: + + mov [DONT_DRAW_MOUSE],byte 1 + + call checkidle + + call checkVga_N13 + + mov [MOUSE_BACKGROUND],byte 0 + + call [draw_pointer] + + pushad + call stack_handler + popad + + mov esi,[WIN_TEMP_XY] + cmp esi,[MOUSE_X] + je cwb + + mov cx,[MOUSE_X] + mov dx,[MOUSE_Y] + sub cx,ax + sub dx,bx + + push ax + push bx + + call drawwindowframes + + mov ax,[Screen_Max_X] + mov bx,[Screen_Max_Y] + + cmp [do_resize_from_corner],1 + je no_new_position + + mov word [npx],word 0 ; x repos ? + cmp ax,cx + jb noreposx + mov [reposition],1 + sub ax,word [npxe] + mov word [npx],ax + cmp ax,cx + jb noreposx + mov word [npx],cx + noreposx: + + mov word [npy],word 0 ; y repos ? + cmp bx,dx + jb noreposy + mov [reposition],1 + sub bx,word [npye] + mov word [npy],bx + cmp bx,dx + jb noreposy + mov word [npy],dx + noreposy: + + no_new_position: + + cmp [do_resize_from_corner],0 ; resize from right corner + je norepos_size + pushad + + mov edx,edi + sub edx,window_data + ;shr edx,5 + ;shl edx,8 + ;add edx,0x80000 ; process base at 0x80000+ + lea edx, [SLOT_BASE + edx*8] + + movzx eax,word [MOUSE_X] + cmp eax,[edi + WDATA.box.left] + jb nnepx + sub eax,[edi + WDATA.box.left] + cmp eax,32 ; [edx+0x90+8] + jge nnepx2 + mov eax,32 ; [edx+0x90+8] + nnepx2: + mov [npxe],eax + nnepx: + + call get_rolledup_height + mov ebx,eax + movzx eax,word [MOUSE_Y] + cmp eax,[edi + WDATA.box.top] + jb nnepy + sub eax,[edi + WDATA.box.top] + cmp eax,ebx ; [edx+0x90+12] + jge nnepy2 + mov eax,ebx ; [edx+0x90+12] + nnepy2: + mov [npye],eax + nnepy: + + mov [reposition],1 + + popad + norepos_size: + + pop bx + pop ax + call drawwindowframes + + mov esi,[MOUSE_X] + mov [WIN_TEMP_XY],esi + + cwb: + cmp [BTN_DOWN],byte 0 + jne newchm + ; new position done + mov [DONT_DRAW_MOUSE],byte 1 + mov cl,0 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz @f + mov cl,[reposition] + call drawwindowframes + + mov eax,[npx] + mov [edi + WDATA.box.left],eax + mov eax,[npy] + mov [edi + WDATA.box.top],eax + mov eax,[npxe] + mov [edi + WDATA.box.width],eax + mov eax,[npye] + mov [edi + WDATA.box.height],eax + call set_window_clientbox + + @@: mov [reposition],cl + + cmp [reposition],1 ; save new position and size + jne no_bounds_save + push esi edi ecx + mov esi,edi + mov ecx,2 + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED + jnz @f + add ecx,2 + @@: sub edi,window_data + shr edi,5 + shl edi,8 + add edi,SLOT_BASE+APPDATA.saved_box + cld + rep movsd + pop ecx edi esi + no_bounds_save: + + pushad ; WINDOW SHADE/FULLSCREEN + + ;{doule click not worked for 4 type window} + mov edx, [edi + WDATA.cl_workarea] + and edx, 0x0f000000 + cmp edx, 0x00000000 + je no_fullscreen_restore + cmp edx, 0x01000000 + je no_fullscreen_restore + + cmp [reposition],1 + je no_window_sizing + mov edx,edi + sub edx,window_data + shr edx,5 + shl edx,8 + add edx,SLOT_BASE ; process base at 0x80000+ + + cmp [do_resize],2 ; window shade ? + jne no_window_shade + mov [reposition],1 + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz wnd_rolldown + wnd_rollup: + or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + call get_rolledup_height + jmp @f + wnd_rolldown: + and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP + mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jz @f + mov eax,[screen_workarea.bottom] + sub eax,[screen_workarea.top] + @@: mov [edi+WDATA.box.height],eax + add eax, [edi+WDATA.box.top] + cmp eax, [Screen_Max_Y] + jbe @f + mov eax, [Screen_Max_Y] + sub eax, [edi+WDATA.box.height] + mov [edi+WDATA.box.top], eax + @@: call check_window_position + call set_window_clientbox + + no_window_shade: + + push edx + mov edx, [edi + WDATA.cl_workarea] + and edx, 0x0f000000 + cmp edx, 0x04000000 + pop edx + je no_fullscreen_restore + + cmp [do_resize],1 ; fullscreen/restore ? + jne no_fullscreen_restore + cmp [latest_window_touch_delta],dword 50 + jg no_fullscreen_restore + mov [reposition],1 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz restore_from_fullscreen + or [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + mov eax,[screen_workarea.left] + mov [edi+WDATA.box.left],eax + sub eax,[screen_workarea.right] + neg eax + mov [edi+WDATA.box.width],eax + mov eax,[screen_workarea.top] + mov [edi+WDATA.box.top],eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz @f + sub eax,[screen_workarea.bottom] + neg eax + mov [edi+WDATA.box.height],eax + @@: + jmp restore_from_fullscreen.clientbox + restore_from_fullscreen: + and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED + push [edi+WDATA.box.height] + push edi ; restore + lea esi, [edx + APPDATA.saved_box] + mov ecx,4 + cld + rep movsd + pop edi + pop eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jz @f + mov [edi+WDATA.box.height],eax + @@: + .clientbox: + call set_window_clientbox + + no_fullscreen_restore: + + mov eax,[edi+WDATA.box.top] ; check Y inside screen + add eax,[edi+WDATA.box.height] + cmp eax,[Screen_Max_Y] + jbe no_window_sizing + mov eax,[edi+WDATA.box.left] ; check X inside screen + add eax,[edi+WDATA.box.width] + cmp eax,[Screen_Max_X] + jbe no_window_sizing + mov eax,[Screen_Max_X] + sub eax,[edi+WDATA.box.width] + mov [edi+WDATA.box.left],eax + mov eax,[Screen_Max_Y] + sub eax,[edi+WDATA.box.height] + mov [edi+WDATA.box.top],eax + call set_window_clientbox + no_window_sizing: + + popad + + cmp [reposition],0 + je retwm + + mov [DONT_DRAW_MOUSE],byte 1 ; no mouse + + + push eax ebx ecx edx + mov eax,[edi+WDATA.box.left] + mov ebx,[edi+WDATA.box.top] + mov ecx,[edi+WDATA.box.width] + mov edx,[edi+WDATA.box.height] + add ecx,eax + add edx,ebx + call calculatescreen + + mov eax,[oldc+BOX.left] + mov ebx,[oldc+BOX.top] + mov ecx,[oldc+BOX.width] + mov edx,[oldc+BOX.height] + add ecx,eax + add edx,ebx + call calculatescreen + pop edx ecx ebx eax + + mov eax,edi + call redrawscreen + + + mov [edi+WDATA.fl_redraw],1 + + mov ecx,100 ; wait to avoid mouse residuals + waitre2: + mov [DONT_DRAW_MOUSE],byte 1 + call checkidle + cmp [edi+WDATA.fl_redraw],0 + jz retwm + loop waitre2 + + retwm: + + mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under + mov [MOUSE_DOWN],byte 0 ; react to mouse up/down + +; mov esi,window_moved +; call sys_msg_board_str + + popad + + ret + + +uglobal + add_window_data dd 0 + do_resize_from_corner db 0x0 + reposition db 0x0 + latest_window_touch dd 0x0 + latest_window_touch_delta dd 0x0 + + do_resize db 0x0 + + oldc dd 0x0,0x0,0x0,0x0 + + dlx dd 0x0 + dly dd 0x0 + dlxe dd 0x0 + dlye dd 0x0 + + npx dd 0x0 + npy dd 0x0 + npxe dd 0x0 + npye dd 0x0 + + mpx dd 0x0 + mpy dd 0x0 +endg + + +; draw negative window frames +drawwindowframes2: + pushad + cli + jmp drawwindowframes.do +drawwindowframes: + pushad + cli + + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz .ret + mov eax, [npx] + cmp eax, [edi+WDATA.box.left] + jnz .nowndframe + mov eax, [npxe] + cmp eax, [edi+WDATA.box.width] + jnz .nowndframe + mov eax, [npy] + cmp eax, [edi+WDATA.box.top] + jnz .nowndframe + mov eax, [npye] + cmp eax, [edi+WDATA.box.height] + jnz .nowndframe + xor [edi+WDATA.fl_wdrawn], 2 + test [edi+WDATA.fl_wdrawn], 4 + jnz .ret + +.nowndframe: +.do: + mov edi, 1 + mov ecx, 0x01000000 + mov eax,[npx] + shl eax,16 + add eax,[npx] + add eax,[npxe] + add eax,65536*1-1 + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + call [draw_line] + + mov eax,[npx] + shl eax,16 + add eax,[npx] + add eax,[npxe] + add eax,65536*1-1 + mov ebx,[npy] + add ebx,[npye] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + call [draw_line] + + mov eax,[npx] + shl eax,16 + add eax,[npx] + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + call [draw_line] + + mov eax,[npx] + add eax,[npxe] + shl eax,16 + add eax,[npx] + add eax,[npxe] + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + call [draw_line] + +.ret: + sti + popad + ret + + + +random_shaped_window: + +; +; eax = 0 giving address of data area +; ebx address +; eax = 1 shape area scale +; ebx 2^ebx scale + + test eax, eax + jne rsw_no_address + mov eax,[current_slot] + mov [eax+APPDATA.wnd_shape],ebx +rsw_no_address: + + cmp eax,1 + jne rsw_no_scale + mov eax,[current_slot] + mov byte [eax+APPDATA.wnd_shape_scale], bl +rsw_no_scale: + + ret + + diff --git a/kernel/tags/kolibri0.7.7.0/hid/keyboard.inc b/kernel/tags/kolibri0.7.7.0/hid/keyboard.inc new file mode 100644 index 000000000..9d6d0b836 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/hid/keyboard.inc @@ -0,0 +1,343 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;// mike.dld [ + +VKEY_LSHIFT = 0000000000000001b +VKEY_RSHIFT = 0000000000000010b +VKEY_LCONTROL = 0000000000000100b +VKEY_RCONTROL = 0000000000001000b +VKEY_LALT = 0000000000010000b +VKEY_RALT = 0000000000100000b +VKEY_CAPSLOCK = 0000000001000000b +VKEY_NUMLOCK = 0000000010000000b +VKEY_SCRLOCK = 0000000100000000b + +VKEY_SHIFT = 0000000000000011b +VKEY_CONTROL = 0000000000001100b +VKEY_ALT = 0000000000110000b + +uglobal + align 4 + kb_state dd 0 + ext_code db 0 + + keyboard_mode db 0 + keyboard_data db 0 + + altmouseb db 0 + ctrl_alt_del db 0 + + kb_lights db 0 + +align 4 + hotkey_scancodes rd 256 ; we have 256 scancodes + hotkey_list rd 256*4 ; max 256 defined hotkeys + hotkey_buffer rd 120*2 ; buffer for 120 hotkeys +endg + +iglobal +hotkey_tests dd hotkey_test0 + dd hotkey_test1 + dd hotkey_test2 + dd hotkey_test3 + dd hotkey_test4 +hotkey_tests_num = 5 +endg + +hotkey_test0: + test al, al + setz al + ret +hotkey_test1: + test al, al + setnp al + ret +hotkey_test2: + cmp al, 3 + setz al + ret +hotkey_test3: + cmp al, 1 + setz al + ret +hotkey_test4: + cmp al, 2 + setz al + ret + +hotkey_do_test: + push eax + mov edx, [kb_state] + shr edx, cl + add cl, cl + mov eax, [eax+4] + shr eax, cl + and eax, 15 + cmp al, hotkey_tests_num + jae .fail + xchg eax, edx + and al, 3 + call [hotkey_tests + edx*4] + cmp al, 1 + pop eax + ret +.fail: + stc + pop eax + ret + +align 4 +irq1: +; save_ring3_context +; mov ax, os_data +; mov ds, ax +; mov es, ax + + movzx eax,word[TASK_COUNT] ; top window process + movzx eax,word[WIN_POS+eax*2] + shl eax,8 + mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode] + mov [keyboard_mode],al + + in al,0x60 + mov [keyboard_data],al + +; ch = scancode +; cl = ext_code +; bh = 0 - normal key +; bh = 1 - modifier (Shift/Ctrl/Alt) +; bh = 2 - extended code + + mov ch,al + cmp al,0xE0 + je @f + cmp al,0xE1 + jne .normal_code + @@: + mov bh, 2 + mov [ext_code], al + jmp .writekey + .normal_code: + mov cl, 0 + xchg cl, [ext_code] + and al,0x7F + mov bh, 1 + @@: cmp al,0x2A + jne @f + cmp cl,0xE0 + je .writekey + mov eax,VKEY_LSHIFT + jmp .modifier + @@: cmp al,0x36 + jne @f + cmp cl,0xE0 + je .writekey + mov eax,VKEY_RSHIFT + jmp .modifier + @@: cmp al,0x38 + jne @f + mov eax, VKEY_LALT + test cl, cl + jz .modifier + mov al, VKEY_RALT + jmp .modifier + @@: cmp al,0x1D + jne @f + mov eax, VKEY_LCONTROL + test cl, cl + jz .modifier + mov al, VKEY_RCONTROL + cmp cl, 0xE0 + jz .modifier + mov [ext_code], cl + jmp .writekey + @@: cmp al,0x3A + jne @f + mov bl,4 + mov eax,VKEY_CAPSLOCK + jmp .no_key.xor + @@: cmp al,0x45 + jne @f + test cl, cl + jnz .writekey + mov bl,2 + mov eax,VKEY_NUMLOCK + jmp .no_key.xor + @@: cmp al,0x46 + jne @f + mov bl,1 + mov eax,VKEY_SCRLOCK + jmp .no_key.xor + @@: + test ch,ch + js .writekey + movzx eax,ch ; plain key + mov bl,[keymap+eax] + mov edx,[kb_state] + test dl,VKEY_CONTROL ; ctrl alt del + jz .noctrlaltdel + test dl,VKEY_ALT + jz .noctrlaltdel + cmp ch,53h + jne .noctrlaltdel + mov [ctrl_alt_del],1 + .noctrlaltdel: + test dl,VKEY_CONTROL ; ctrl on ? + jz @f + sub bl,0x60 + @@: test dl,VKEY_SHIFT ; shift on ? + jz @f + mov bl,[keymap_shift+eax] + @@: test dl,VKEY_ALT ; alt on ? + jz @f + mov bl,[keymap_alt+eax] + @@: + mov bh, 0 + jmp .writekey +.modifier: + test ch, ch + js .modifier.up + or [kb_state], eax + jmp .writekey +.modifier.up: + not eax + and [kb_state], eax + jmp .writekey +.no_key.xor: + mov bh, 0 + test ch, ch + js .writekey + xor [kb_state], eax + xor [kb_lights], bl + call set_lights + +.writekey: +; test for system hotkeys + movzx eax, ch + cmp bh, 1 + ja .nohotkey + jb @f + xor eax, eax +@@: + mov eax, [hotkey_scancodes + eax*4] +.hotkey_loop: + test eax, eax + jz .nohotkey + mov cl, 0 + call hotkey_do_test + jc .hotkey_cont + mov cl, 2 + call hotkey_do_test + jc .hotkey_cont + mov cl, 4 + call hotkey_do_test + jnc .hotkey_found +.hotkey_cont: + mov eax, [eax] + jmp .hotkey_loop +.hotkey_found: + mov eax, [eax+8] +; put key in buffer for process in slot eax + mov edi, hotkey_buffer +@@: + cmp dword [edi], 0 + jz .found_free + add edi, 8 + cmp edi, hotkey_buffer+120*8 + jb @b +; no free space - replace first entry + mov edi, hotkey_buffer +.found_free: + mov [edi], eax + movzx eax, ch + cmp bh, 1 + jnz @f + xor eax, eax +@@: + mov [edi+4], ax + mov eax, [kb_state] + mov [edi+6], ax + jmp .exit.irq1 +.nohotkey: + cmp [keyboard_mode],0 ; return from keymap + jne .scancode + test bh, bh + jnz .exit.irq1 + test bl, bl + jz .exit.irq1 + +;.........................Part1 Start.......Code by Rus, optimize by Ghost................................... + test [kb_state], VKEY_NUMLOCK + jz .dowrite + cmp cl, 0xE0 + jz .dowrite + + cmp ch, 55 + jnz @f + mov bl, 0x2A ;* + jmp .dowrite + @@: + cmp ch, 71 + jb .dowrite + cmp ch, 83 + ja .dowrite + ;push eax + movzx eax, ch + mov bl, [numlock_map + eax - 71] + ;pop eax + +;.........................Part1 End................................................. + + jmp .dowrite +.scancode: + mov bl, ch +.dowrite: + movzx eax,byte[KEY_COUNT] + cmp al,120 + jae .exit.irq1 + inc eax + mov [KEY_COUNT],al + mov [KEY_COUNT+eax],bl + + .exit.irq1: + mov [check_idle_semaphore],5 + +; mov al,0x20 ; ready for next irq +; out 0x20,al + +; restore_ring3_context +; iret + ret + +set_lights: + mov al,0xED + call kb_write + mov al,[kb_lights] + call kb_write + ret + +;// mike.dld ] +;..........................Part2 Start.......Code by Rus....................................... +numlock_map: + db 0x37 ;Num 7 + db 0x38 ;Num 8 + db 0x39 ;Num 9 + db 0x2D ;Num - + db 0x34 ;Num 4 + db 0x35 ;Num 5 + db 0x36 ;Num 6 + db 0x2B ;Num + + db 0x31 ;Num 1 + db 0x32 ;Num 2 + db 0x33 ;Num 3 + db 0x30 ;Num 0 + db 0x2E ;Num . +;..........................Part2 End................................................ \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc b/kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc new file mode 100644 index 000000000..e6de7c5af --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/hid/mousedrv.inc @@ -0,0 +1,456 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; check mouse +; +; +; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y +; FB10 -> FB17 mouse color mem +; FB21 x move +; FB22 y move +; FB30 color temp +; FB28 high bits temp +; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under +; FC00 -> FCFE com1/ps2 buffer +; FCFF com1/ps2 buffer count starting from FC00 + +uglobal + mousecount dd 0x0 + mousedata dd 0x0 +endg + +iglobal +mouse_delay dd 10 +mouse_speed_factor: dd 3 +mouse_timer_ticks dd 0 +endg + +;include 'm_com.inc' + + +;test_mario79: +; push esi +; push eax +; mov [write_error_to],process_test_m79+43 +; movzx eax,al ;[DevErrorCode] +; call writehex +; mov esi,process_test_m79 +; call sys_msg_board_str +; pop eax +; pop esi +; ret +;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0 + +draw_mouse_under: + ; return old picture + + cmp [_display.restore_cursor], 0 + je @F + + pushad + movzx eax,word [X_UNDER] + movzx ebx,word [Y_UNDER] + stdcall [_display.restore_cursor], eax, ebx + popad + ret +@@: + pushad + xor ecx,ecx + xor edx,edx + align 4 +mres: + movzx eax,word [X_UNDER] + movzx ebx,word [Y_UNDER] + add eax,ecx + add ebx,edx + push ecx + push edx + push eax + push ebx + mov eax,edx + shl eax,6 + shl ecx,2 + add eax,ecx + add eax,mouseunder + mov ecx,[eax] + pop ebx + pop eax + mov edi, 1 ;force + call [putpixel] + pop edx + pop ecx + inc ecx + cmp ecx, 16 + jnz mres + xor ecx, ecx + inc edx + cmp edx, 24 + jnz mres + popad + ret + +save_draw_mouse: + + cmp [_display.move_cursor], 0 + je .no_hw_cursor + pushad + + mov [X_UNDER],ax + mov [Y_UNDER],bx + movzx eax,word [MOUSE_Y] + movzx ebx,word [MOUSE_X] + push eax + push ebx + + mov ecx, [Screen_Max_X] + inc ecx + mul ecx + add eax, [_WinMapAddress] + movzx edx, byte [ebx+eax] + shl edx, 8 + mov esi, [edx+SLOT_BASE+APPDATA.cursor] + + cmp esi, [current_cursor] + je .draw + + push esi + call [_display.select_cursor] + mov [current_cursor], esi +.draw: + stdcall [_display.move_cursor], esi + popad + ret +.fail: + mov ecx, [def_cursor] + mov [edx+SLOT_BASE+APPDATA.cursor], ecx + stdcall [_display.move_cursor], ecx ; stdcall: [esp]=ebx,eax + popad + ret + +.no_hw_cursor: + pushad + ; save & draw + mov [X_UNDER],ax + mov [Y_UNDER],bx + push eax + push ebx + mov ecx,0 + mov edx,0 + align 4 +drm: + push eax + push ebx + push ecx + push edx + ; helloworld + push ecx + add eax,ecx ; save picture under mouse + add ebx,edx + push ecx + call getpixel + mov [COLOR_TEMP],ecx + pop ecx + mov eax,edx + shl eax,6 + shl ecx,2 + add eax,ecx + add eax,mouseunder + mov ebx,[COLOR_TEMP] + mov [eax],ebx + pop ecx + mov edi,edx ; y cycle + shl edi,4 ; *16 bytes per row + add edi,ecx ; x cycle + mov esi, edi + add edi, esi + add edi, esi ; *3 + add edi,[MOUSE_PICTURE] ; we have our str address + mov esi, edi + add esi, 16*24*3 + push ecx + mov ecx, [COLOR_TEMP] + call combine_colors + mov [MOUSE_COLOR_MEM], ecx + pop ecx + pop edx + pop ecx + pop ebx + pop eax + add eax,ecx ; we have x coord+cycle + add ebx,edx ; and y coord+cycle + push ecx + mov ecx, [MOUSE_COLOR_MEM] + mov edi, 1 + call [putpixel] + pop ecx + mov ebx,[esp+0] ; pure y coord again + mov eax,[esp+4] ; and x + inc ecx ; +1 cycle + cmp ecx,16 ; if more than 16 + jnz drm + xor ecx, ecx + inc edx + cmp edx,24 + jnz drm + add esp,8 + popad + ret + + +combine_colors: + ; in + ; ecx - color ( 00 RR GG BB ) + ; edi - ref to new color byte + ; esi - ref to alpha byte + ; + ; out + ; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) + push eax + push ebx + push edx + push ecx + xor ecx, ecx + ; byte 2 + mov eax, 0xff + sub al, [esi+0] + mov ebx, [esp] + shr ebx, 16 + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+0] + mov bl, [esi+0] + mul ebx + shr eax, 8 + add ecx, eax + shl ecx, 8 + ; byte 1 + mov eax, 0xff + sub al, [esi+1] + mov ebx, [esp] + shr ebx, 8 + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+1] + mov bl, [esi+1] + mul ebx + shr eax, 8 + add ecx, eax + shl ecx, 8 + ; byte 2 + mov eax, 0xff + sub al, [esi+2] + mov ebx, [esp] + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+2] + mov bl, [esi+2] + mul ebx + shr eax, 8 + add ecx, eax + pop eax + pop edx + pop ebx + pop eax + ret + + +__sys_disable_mouse: + cmp dword [MOUSE_VISIBLE],dword 0 + je @f + ret +@@: + pushad + cmp [CURRENT_TASK],dword 1 + je disable_m + mov edx,[CURRENT_TASK] + shl edx,5 + add edx,window_data + movzx eax, word [MOUSE_X] + movzx ebx, word [MOUSE_Y] + mov ecx,[Screen_Max_X] + inc ecx + imul ecx,ebx + add ecx,eax + add ecx, [_WinMapAddress] + mov eax, [CURRENT_TASK] + movzx ebx, byte [ecx] + cmp eax,ebx + je yes_mouse_disable + movzx ebx, byte [ecx+16] + cmp eax,ebx + je yes_mouse_disable + mov ebx,[Screen_Max_X] + inc ebx + imul ebx,10 + add ecx,ebx + movzx ebx, byte [ecx] + cmp eax,ebx + je yes_mouse_disable + movzx ebx, byte [ecx+16] + cmp eax,ebx + je yes_mouse_disable + jmp no_mouse_disable +yes_mouse_disable: + mov edx,[CURRENT_TASK] + shl edx,5 + add edx,window_data + movzx eax, word [MOUSE_X] + movzx ebx, word [MOUSE_Y] + mov ecx,[edx+0] ; mouse inside the area ? + add eax,10 + cmp eax,ecx + jb no_mouse_disable + sub eax,10 + add ecx,[edx+8] + cmp eax,ecx + jg no_mouse_disable + mov ecx,[edx+4] + add ebx,14 + cmp ebx,ecx + jb no_mouse_disable + sub ebx,14 + add ecx,[edx+12] + cmp ebx,ecx + jg no_mouse_disable +disable_m: + cmp dword [MOUSE_VISIBLE],dword 0 + jne no_mouse_disable + pushf + cli + call draw_mouse_under + popf + mov [MOUSE_VISIBLE],dword 1 +no_mouse_disable: + popad + ret + +__sys_draw_pointer: + cmp [mouse_pause],0 + je @f + ret +@@: + push eax + mov eax,[timer_ticks] + sub eax,[MouseTickCounter] + cmp eax,1 + ja @f + pop eax + ret +@@: + mov eax,[timer_ticks] + mov [MouseTickCounter],eax + pop eax + pushad + cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ? + je chms00 + mov [MOUSE_VISIBLE], dword 0 + movzx ebx,word [MOUSE_Y] + movzx eax,word [MOUSE_X] + pushfd + cli + call save_draw_mouse + popfd +nodmu2: + popad + ret +chms00: + movzx ecx,word [X_UNDER] + movzx edx,word [Y_UNDER] + movzx ebx,word [MOUSE_Y] + movzx eax,word [MOUSE_X] + cmp eax,ecx + jne redrawmouse + cmp ebx,edx + jne redrawmouse + jmp nodmp +redrawmouse: + pushfd + cli + call draw_mouse_under + call save_draw_mouse + popfd +nodmp: + popad + ret + +proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword + + mov eax,[BtnState] + mov [BTN_DOWN],eax + + mov eax,[XMoving] + call mouse_acceleration + add ax,[MOUSE_X] ;[XCoordinate] + cmp ax,0 + jge @@M1 + mov eax,0 + jmp @@M2 +@@M1: + cmp ax,[Screen_Max_X] ;ScreenLength + jl @@M2 + mov ax,[Screen_Max_X] ;ScreenLength-1 + +@@M2: + mov [MOUSE_X],ax ;[XCoordinate] + + mov eax,[YMoving] + neg eax + call mouse_acceleration + + add ax,[MOUSE_Y] ;[YCoordinate] + cmp ax,0 + jge @@M3 + mov ax,0 + jmp @@M4 +@@M3: + cmp ax,[Screen_Max_Y] ;ScreenHeigth + jl @@M4 + mov ax,[Screen_Max_Y] ;ScreenHeigth-1 + +@@M4: + mov [MOUSE_Y],ax ;[YCoordinate] + + mov eax,[VScroll] + add [MOUSE_SCROLL_V],ax + + mov eax,[HScroll] + add [MOUSE_SCROLL_H],ax + + mov [mouse_active],1 + mov eax,[timer_ticks] + mov [mouse_timer_ticks],eax + ret +endp + +mouse_acceleration: + push eax + mov eax,[timer_ticks] + sub eax,[mouse_timer_ticks] + cmp eax,[mouse_delay] + pop eax + ja @f + ;push edx + imul eax,[mouse_speed_factor] + ;pop edx +@@: + ret + diff --git a/kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc b/kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc new file mode 100644 index 000000000..abaa3eddf --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/hid/set_dtc.inc @@ -0,0 +1,203 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;setting date,time,clock and alarm-clock +;add sys_settime at servetable as for ex. 22 fcn: +; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK +; ebx =0 - set time ecx - 00SSMMHH +; ebx =1 - set date ecx=00DDMMYY +; ebx =2 - set day of week ecx- 1-7 +; ebx =3 - set alarm-clock ecx - 00SSMMHH +; out: 0 -Ok 1 -wrong format 2 -battery low +sys_settime: + + cli + mov al,0x0d + out 0x70,al + in al,0x71 + bt ax,7 + jnc bat_low + cmp ebx,2 ;day of week + jne nosetweek + test ecx,ecx ;test day of week + je wrongtime + cmp ecx,7 + ja wrongtime + mov edx,0x70 + call startstopclk + dec edx + mov al,6 + out dx,al + inc edx + mov al,cl + out dx,al + jmp endsettime + nosetweek: ;set date + cmp ebx,1 + jne nosetdate + cmp cl,0x99 ;test year + ja wrongtime + shl ecx,4 + cmp cl,0x90 + ja wrongtime + cmp ch,0x99 ;test month + ja wrongtime + shr ecx,4 + test ch,ch + je wrongtime + cmp ch,0x12 + ja wrongtime + shl ecx,8 + bswap ecx ;ebx=00YYMMDD + test cl,cl ;test day + je wrongtime + shl ecx,4 + cmp cl,0x90 + ja wrongtime + shr ecx,4 + cmp ch,2 ;February + jne testday + cmp cl,0x29 + ja wrongtime + jmp setdate + testday: + cmp ch,8 + jb testday1 ;Aug-Dec + bt cx,8 + jnc days31 + jmp days30 + testday1: + bt cx,8 ;Jan-Jul ex.Feb + jnc days30 + days31: + cmp cl,0x31 + ja wrongtime + jmp setdate + days30: + cmp cl,0x30 + ja wrongtime + setdate: + mov edx,0x70 + call startstopclk + dec edx + mov al,7 ;set days + out dx,al + inc edx + mov al,cl + out dx,al + dec edx + mov al,8 ;set months + out dx,al + inc edx + mov al,ch + out dx,al + dec edx + mov al,9 ;set years + out dx,al + inc edx + shr ecx,8 + mov al,ch + out dx,al + jmp endsettime + nosetdate: ;set time or alarm-clock + cmp ebx,3 + ja wrongtime + cmp cl,0x23 + ja wrongtime + cmp ch,0x59 + ja wrongtime + shl ecx,4 + cmp cl,0x90 + ja wrongtime + cmp ch,0x92 + ja wrongtime + shl ecx,4 + bswap ecx ;00HHMMSS + cmp cl,0x59 + ja wrongtime + shl ecx,4 + cmp cl,0x90 + ja wrongtime + shr ecx,4 + + mov edx,0x70 + call startstopclk + dec edx + cmp ebx,3 + + je setalarm + xor eax,eax ;al=0-set seconds + out dx,al + inc edx + mov al,cl + out dx,al + dec edx + mov al,2 ;set minutes + out dx,al + inc edx + mov al,ch + out dx,al + dec edx + mov al,4 ;set hours + out dx,al + inc edx + shr ecx,8 + mov al,ch + out dx,al + jmp endsettime + setalarm: + mov al,1 ;set seconds for al. + out dx,al + inc edx + mov al,cl + out dx,al + dec edx + mov al,3 ;set minutes for al. + out dx,al + inc edx + mov al,ch + out dx,al + dec edx + mov al,5 ;set hours for al. + out dx,al + inc edx + shr ecx,8 + mov al,ch + out dx,al + dec edx + mov al,0x0b ;enable irq's + out dx,al + inc dx + in al,dx + bts ax,5 ;set bit 5 + out dx,al + endsettime: + dec edx + call startstopclk + sti + and [esp+36-4],dword 0 + ret + bat_low: + sti + mov [esp+36-4],dword 2 + ret + wrongtime: + sti + mov [esp+36-4],dword 1 + ret + +startstopclk: + mov al,0x0b + out dx,al + inc dx + in al,dx + btc ax,7 + out dx,al + ret diff --git a/kernel/tags/kolibri0.7.7.0/imports.inc b/kernel/tags/kolibri0.7.7.0/imports.inc new file mode 100644 index 000000000..3d94b67a1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/imports.inc @@ -0,0 +1,27 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;============================================================================ +; +; External kernel dependencies +; +;============================================================================ + +$Revision$ + + +align 4 +@IMPORT: + +library \ + libini,'libini.obj' + +import libini, \ + ini.lib_init,'lib_init',\ + ini.get_str,'ini.get_str',\ + ini.enum_keys,'ini.enum_keys',\ + ini.get_int,'ini.get_int' diff --git a/kernel/tags/kolibri0.7.7.0/init.inc b/kernel/tags/kolibri0.7.7.0/init.inc new file mode 100644 index 000000000..54aa7b597 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/init.inc @@ -0,0 +1,437 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +MEM_WB equ 6 ;write-back memory +MEM_WC equ 1 ;write combined memory +MEM_UC equ 0 ;uncached memory + +align 4 +proc mem_test +; if we have BIOS with fn E820, skip the test + cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0 + jnz .ret + + mov eax, cr0 + and eax, not (CR0_CD+CR0_NW) + or eax, CR0_CD ;disable caching + mov cr0, eax + wbinvd ;invalidate cache + + xor edi, edi + mov ebx, 'TEST' +@@: + add edi, 0x100000 + xchg ebx, dword [edi] + cmp dword [edi], 'TEST' + xchg ebx, dword [edi] + je @b + + and eax, not (CR0_CD+CR0_NW) ;enable caching + mov cr0, eax + inc dword [BOOT_VAR-OS_BASE + 0x9100] + xor eax, eax + mov [BOOT_VAR-OS_BASE + 0x9104], eax + mov [BOOT_VAR-OS_BASE + 0x9108], eax + mov [BOOT_VAR-OS_BASE + 0x910C], edi + mov [BOOT_VAR-OS_BASE + 0x9110], eax +.ret: + ret +endp + +align 4 +proc init_mem +; calculate maximum allocatable address and number of allocatable pages + mov edi, BOOT_VAR-OS_BASE + 0x9104 + mov ecx, [edi-4] + xor esi, esi ; esi will hold total amount of memory + xor edx, edx ; edx will hold maximum allocatable address +.calcmax: +; round all to pages + mov eax, [edi] + test eax, 0xFFF + jz @f + neg eax + and eax, 0xFFF + add [edi], eax + adc dword [edi+4], 0 + sub [edi+8], eax + sbb dword [edi+12], 0 + jc .unusable +@@: + and dword [edi+8], not 0xFFF + jz .unusable +; ignore memory after 4 Gb + cmp dword [edi+4], 0 + jnz .unusable + mov eax, [edi] + cmp dword [edi+12], 0 + jnz .overflow + add eax, [edi+8] + jnc @f +.overflow: + mov eax, 0xFFFFF000 +@@: + cmp edx, eax + jae @f + mov edx, eax +@@: + sub eax, [edi] + mov [edi+8], eax + add esi, eax + jmp .usable +.unusable: + and dword [edi+8], 0 +.usable: + add edi, 20 + loop .calcmax +.calculated: + mov [MEM_AMOUNT-OS_BASE], esi + mov [pg_data.mem_amount-OS_BASE], esi + shr esi, 12 + mov [pg_data.pages_count-OS_BASE], esi + + shr edx, 12 + add edx, 31 + and edx, not 31 + shr edx, 3 + mov [pg_data.pagemap_size-OS_BASE], edx + + add edx, (sys_pgmap-OS_BASE)+4095 + and edx, not 4095 + mov [tmp_page_tabs], edx + + mov edx, esi + and edx, -1024 + cmp edx, (OS_BASE/4096) + jbe @F + mov edx, (OS_BASE/4096) + jmp .set +@@: + cmp edx, (HEAP_BASE+HEAP_MIN_SIZE)/4096 + jae .set + mov edx, (HEAP_BASE+HEAP_MIN_SIZE)/4096 +.set: + mov [pg_data.kernel_pages-OS_BASE], edx + shr edx, 10 + mov [pg_data.kernel_tables-OS_BASE], edx + + xor eax, eax + mov edi, sys_pgdir-OS_BASE + mov ecx, 4096/4 + cld + rep stosd + + mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20) + bt [cpu_caps-OS_BASE], CAPS_PSE + jnc .no_PSE + + mov ebx, cr4 + or ebx, CR4_PSE + mov eax, PG_LARGE+PG_SW + mov cr4, ebx + dec [pg_data.kernel_tables-OS_BASE] + + mov [edx], eax + add eax, 0x00400000 + add edx, 4 + + mov eax, 0x400000+PG_SW + mov ecx, [tmp_page_tabs] + sub ecx, 0x400000 + shr ecx, 12 ;ecx/=4096 + jmp .map_low +.no_PSE: + mov eax, PG_SW + mov ecx, [tmp_page_tabs] + shr ecx, 12 +.map_low: + mov edi, [tmp_page_tabs] +@@: ; + stosd + add eax, 0x1000 + dec ecx + jnz @B + + mov ecx, [pg_data.kernel_tables-OS_BASE] + shl ecx, 10 + xor eax, eax + rep stosd + + mov ecx, [pg_data.kernel_tables-OS_BASE] + mov eax, [tmp_page_tabs] + or eax, PG_SW + mov edi, edx + +.map_kernel_tabs: + + stosd + add eax, 0x1000 + dec ecx + jnz .map_kernel_tabs + + mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE + + mov edi, (sys_pgdir-OS_BASE) + lea esi, [edi+(OS_BASE shr 20)] + movsd + movsd + ret +endp + +align 4 +proc init_page_map +; mark all memory as unavailable + mov edi, sys_pgmap-OS_BASE + mov ecx, [pg_data.pagemap_size-OS_BASE] + shr ecx, 2 + xor eax, eax + cld + rep stosd + +; scan through memory map and mark free areas as available + mov ebx, BOOT_VAR-OS_BASE + 0x9104 + mov edx, [ebx-4] +.scanmap: + mov ecx, [ebx+8] + shr ecx, 12 ; ecx = number of pages + jz .next + mov edi, [ebx] + shr edi, 12 ; edi = first page + mov eax, edi + neg eax + shr edi, 5 + add edi, sys_pgmap-OS_BASE + and eax, 31 + jz .startok + sub ecx, eax + jbe .onedword + push ecx + mov ecx, eax + xor eax, eax + inc eax + shl eax, cl + dec eax + or [edi], eax + add edi, 4 + pop ecx +.startok: + push ecx + shr ecx, 5 + or eax, -1 + rep stosd + pop ecx + and ecx, 31 + not eax + shl eax, cl + or [edi], eax + jmp .next +.onedword: + add ecx, eax +@@: + dec eax + bts [edi], eax + loop @b +.next: + add ebx, 20 + dec edx + jnz .scanmap + +; mark kernel memory as allocated (unavailable) + mov ecx, [tmp_page_tabs] + mov edx, [pg_data.pages_count-OS_BASE] + shr ecx, 12 + add ecx, [pg_data.kernel_tables-OS_BASE] + sub edx, ecx + mov [pg_data.pages_free-OS_BASE], edx + + mov edi, sys_pgmap-OS_BASE + mov ebx, ecx + shr ecx, 5 + xor eax, eax + rep stosd + + not eax + mov ecx, ebx + and ecx, 31 + shl eax, cl + and [edi], eax + add edi, OS_BASE + mov [page_start-OS_BASE], edi; + + mov ebx, sys_pgmap + add ebx, [pg_data.pagemap_size-OS_BASE] + mov [page_end-OS_BASE], ebx + + mov [pg_data.pg_mutex-OS_BASE], 0 + ret +endp + +align 4 + +init_BIOS32: + mov edi, 0xE0000 +.pcibios_nxt: + cmp dword[edi], '_32_' ; "magic" word + je .BIOS32_found +.pcibios_nxt2: + add edi, 0x10 + cmp edi, 0xFFFF0 + je .BIOS32_not_found + jmp .pcibios_nxt +.BIOS32_found: ; magic word found, check control summ + + movzx ecx, byte[edi + 9] + shl ecx, 4 + mov esi, edi + xor eax, eax + cld ; paranoia +@@: lodsb + add ah, al + loop @b + jnz .pcibios_nxt2 ; control summ must be zero + ; BIOS32 service found ! + mov ebp, [edi + 4] + mov [bios32_entry], ebp + ; check PCI BIOS present + mov eax, '$PCI' + xor ebx, ebx + push cs ; special for 'ret far' from BIOS + call ebp + test al, al + jnz .PCI_BIOS32_not_found + + ; здесь создаются дискрипторы для PCI BIOS + + add ebx, OS_BASE + dec ecx + mov [(pci_code_32-OS_BASE)], cx ;limit 0-15 + mov [(pci_data_32-OS_BASE)], cx ;limit 0-15 + + mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15 + mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15 + + shr ebx, 16 + mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23 + mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23 + + shr ecx, 16 + and cl, 0x0F + mov ch, bh + add cx, D32 + mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 & + mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31 + + mov [(pci_bios_entry-OS_BASE)], edx + ; jmp .end +.PCI_BIOS32_not_found: + ; здесь должна заполнятся pci_emu_dat +.BIOS32_not_found: +.end: + ret + +align 4 +proc test_cpu + locals + cpu_type dd ? + cpu_id dd ? + cpu_Intel dd ? + cpu_AMD dd ? + endl + + xor eax, eax + mov [cpu_type], eax + mov [cpu_caps-OS_BASE], eax + mov [cpu_caps+4-OS_BASE], eax + + pushfd + pop eax + mov ecx, eax + xor eax, 0x40000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov [cpu_type], CPU_386 + jz .end_cpuid + push ecx + popfd + + mov [cpu_type], CPU_486 + mov eax, ecx + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + je .end_cpuid + mov [cpu_id], 1 + + xor eax, eax + cpuid + + mov [cpu_vendor-OS_BASE], ebx + mov [cpu_vendor+4-OS_BASE], edx + mov [cpu_vendor+8-OS_BASE], ecx + cmp ebx, dword [intel_str-OS_BASE] + jne .check_AMD + cmp edx, dword [intel_str+4-OS_BASE] + jne .check_AMD + cmp ecx, dword [intel_str+8-OS_BASE] + jne .check_AMD + mov [cpu_Intel], 1 + cmp eax, 1 + jl .end_cpuid + mov eax, 1 + cpuid + mov [cpu_sign-OS_BASE], eax + mov [cpu_info-OS_BASE], ebx + mov [cpu_caps-OS_BASE], edx + mov [cpu_caps+4-OS_BASE],ecx + + shr eax, 8 + and eax, 0x0f + ret +.end_cpuid: + mov eax, [cpu_type] + ret + +.check_AMD: + cmp ebx, dword [AMD_str-OS_BASE] + jne .unknown + cmp edx, dword [AMD_str+4-OS_BASE] + jne .unknown + cmp ecx, dword [AMD_str+8-OS_BASE] + jne .unknown + mov [cpu_AMD], 1 + cmp eax, 1 + jl .unknown + mov eax, 1 + cpuid + mov [cpu_sign-OS_BASE], eax + mov [cpu_info-OS_BASE], ebx + mov [cpu_caps-OS_BASE], edx + mov [cpu_caps+4-OS_BASE],ecx + shr eax, 8 + and eax, 0x0f + ret +.unknown: + mov eax, 1 + cpuid + mov [cpu_sign-OS_BASE], eax + mov [cpu_info-OS_BASE], ebx + mov [cpu_caps-OS_BASE], edx + mov [cpu_caps+4-OS_BASE],ecx + shr eax, 8 + and eax, 0x0f + ret +endp + diff --git a/kernel/tags/kolibri0.7.7.0/kernel.asm b/kernel/tags/kolibri0.7.7.0/kernel.asm new file mode 100644 index 000000000..f218bc8e6 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/kernel.asm @@ -0,0 +1,5785 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. +;; PROGRAMMING: +;; Ivan Poddubny +;; Marat Zakiyanov (Mario79) +;; VaStaNi +;; Trans +;; Mihail Semenyako (mike.dld) +;; Sergey Kuzmin (Wildwest) +;; Andrey Halyavin (halyavin) +;; Mihail Lisovin (Mihasik) +;; Andrey Ignatiev (andrew_programmer) +;; NoName +;; Evgeny Grechnikov (Diamond) +;; Iliya Mihailov (Ghost) +;; Sergey Semyonov (Serge) +;; Johnny_B +;; SPraid (simba) +;; Hidnplayr +;; Alexey Teplov () +;; +;; Data in this file was originally part of MenuetOS project which is +;; distributed under the terms of GNU GPL. It is modified and redistributed as +;; part of KolibriOS project under the terms of GNU GPL. +;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa +;; PROGRAMMING: +;; +;; Ville Mikael Turjanmaa, villemt@itu.jyu.fi +;; - main os coding/design +;; Jan-Michael Brummer, BUZZ2@gmx.de +;; Felix Kaiser, info@felix-kaiser.de +;; Paolo Minazzi, paolo.minazzi@inwind.it +;; quickcode@mail.ru +;; Alexey, kgaz@crosswinds.net +;; Juan M. Caravaca, bitrider@wanadoo.es +;; kristol@nic.fi +;; Mike Hibbett, mikeh@oceanfree.net +;; Lasse Kuusijarvi, kuusijar@lut.fi +;; Jarek Pelczar, jarekp3@wp.pl +;; +;; KolibriOS is distributed in the hope that it will be useful, but WITHOUT ANY +;; WARRANTY. No author or distributor accepts responsibility to anyone for the +;; consequences of using it or for whether it serves any particular purpose or +;; works at all, unless he says so in writing. Refer to the GNU General Public +;; License (the "GPL") for full details. +; +;; Everyone is granted permission to copy, modify and redistribute KolibriOS, +;; but only under the conditions described in the GPL. A copy of this license +;; is supposed to have been given to you along with KolibriOS so you can know +;; your rights and responsibilities. It should be in a file named COPYING. +;; Among other things, the copyright notice and this notice must be preserved +;; on all copies. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +include 'macros.inc' + +$Revision$ + + +USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices + +; Enabling the next line will enable serial output console +;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used + +include "proc32.inc" +include "kglobals.inc" +include "lang.inc" + +include "const.inc" +max_processes equ 255 +tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 + + +os_stack equ (os_data_l-gdts) ; GDTs +os_code equ (os_code_l-gdts) +graph_data equ (3+graph_data_l-gdts) +tss0 equ (tss0_l-gdts) +app_code equ (3+app_code_l-gdts) +app_data equ (3+app_data_l-gdts) +app_tls equ (3+tls_data_l-gdts) +pci_code_sel equ (pci_code_32-gdts) +pci_data_sel equ (pci_data_32-gdts) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Included files: +;; +;; Kernel16.inc +;; - Booteng.inc English text for bootup +;; - Bootcode.inc Hardware setup +;; - Pci16.inc PCI functions +;; +;; Kernel32.inc +;; - Sys32.inc Process management +;; - Shutdown.inc Shutdown and restart +;; - Fat32.inc Read / write hd +;; - Vesa12.inc Vesa 1.2 driver +;; - Vesa20.inc Vesa 2.0 driver +;; - Vga.inc VGA driver +;; - Stack.inc Network interface +;; - Mouse.inc Mouse pointer +;; - Scincode.inc Window skinning +;; - Pci32.inc PCI functions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 16 BIT ENTRY FROM BOOTSECTOR ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +use16 + org 0x0 + jmp start_of_code + +version db 'Kolibri OS version 0.7.7.0 ',13,10,13,10,0 + +include "boot/bootstr.inc" ; language-independent boot messages +include "boot/preboot.inc" + +if lang eq en +include "boot/booteng.inc" ; english system boot messages +else if lang eq ru +include "boot/bootru.inc" ; russian system boot messages +include "boot/ru.inc" ; Russian font +else if lang eq et +include "boot/bootet.inc" ; estonian system boot messages +include "boot/et.inc" ; Estonian font +else +include "boot/bootge.inc" ; german system boot messages +end if + +include "boot/bootcode.inc" ; 16 bit system boot code +include "bus/pci/pci16.inc" +include "detect/biosdisk.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SWITCH TO 32 BIT PROTECTED MODE ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; CR0 Flags - Protected mode and Paging + + mov ecx, CR0_PE + +; Enabling 32 bit protected mode + + sidt [cs:old_ints_h] + + cli ; disable all irqs + cld + mov al,255 ; mask all irqs + out 0xa1,al + out 0x21,al + l.5: in al, 0x64 ; Enable A20 + test al, 2 + jnz l.5 + mov al, 0xD1 + out 0x64, al + l.6: in al, 0x64 + test al, 2 + jnz l.6 + mov al, 0xDF + out 0x60, al + l.7: in al, 0x64 + test al, 2 + jnz l.7 + mov al, 0xFF + out 0x64, al + + lgdt [cs:tmp_gdt] ; Load GDT + mov eax, cr0 ; protected mode + or eax, ecx + and eax, 10011111b *65536*256 + 0xffffff ; caching enabled + mov cr0, eax + jmp pword os_code:B32 ; jmp to enable 32 bit mode + +align 8 +tmp_gdt: + + dw 23 + dd tmp_gdt+0x10000 + dw 0 + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 + +include "data16.inc" + +use32 +org $+0x10000 + +align 4 +B32: + mov ax,os_stack ; Selector for os + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + mov esp,0x3ec00 ; Set stack + +; CLEAR 0x280000 - HEAP_BASE + + xor eax,eax + mov edi,0x280000 + mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 + cld + rep stosd + + mov edi,0x40000 + mov ecx,(0x90000-0x40000)/4 + rep stosd + +; CLEAR KERNEL UNDEFINED GLOBALS + mov edi, endofcode-OS_BASE + mov ecx, (uglobals_size/4)+4 + rep stosd + +; SAVE & CLEAR 0-0xffff + + xor esi, esi + mov edi,0x2F0000 + mov ecx,0x10000 / 4 + rep movsd + mov edi,0x1000 + mov ecx,0xf000 / 4 + rep stosd + + call test_cpu + bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc + + call init_BIOS32 +; MEMORY MODEL + call mem_test + call init_mem + call init_page_map + +; ENABLE PAGING + + mov eax, sys_pgdir-OS_BASE + mov cr3, eax + + mov eax,cr0 + or eax,CR0_PG+CR0_WP + mov cr0,eax + + lgdt [gdts] + jmp pword os_code:high_code + +align 4 +bios32_entry dd ? +tmp_page_tabs dd ? + +use16 +org $-0x10000 +include "boot/shutdown.inc" ; shutdown or restart +org $+0x10000 +use32 + +__DEBUG__ fix 1 +__DEBUG_LEVEL__ fix 1 +include 'init.inc' + +org OS_BASE+$ + +align 4 +high_code: + mov ax, os_stack + mov bx, app_data + mov cx, app_tls + mov ss, ax + add esp, OS_BASE + + mov ds, bx + mov es, bx + mov fs, cx + mov gs, bx + + bt [cpu_caps], CAPS_PGE + jnc @F + + or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL + + mov ebx, cr4 + or ebx, CR4_PGE + mov cr4, ebx +@@: + xor eax, eax + mov dword [sys_pgdir], eax + mov dword [sys_pgdir+4], eax + + mov eax, cr3 + mov cr3, eax ; flush TLB + +; SAVE REAL MODE VARIABLES + mov ax, [BOOT_VAR + 0x9031] + mov [IDEContrRegsBaseAddr], ax +; --------------- APM --------------------- + +; init selectors + mov ebx,[BOOT_VAR+0x9040] ; offset of APM entry point + movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of + ; protected-mode 32-bit code segment + movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of + ; protected-mode 16-bit code segment + movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of + ; protected-mode 16-bit data segment + + shl eax, 4 + mov [dword apm_code_32 + 2], ax + shr eax, 16 + mov [dword apm_code_32 + 4], al + + shl ecx, 4 + mov [dword apm_code_16 + 2], cx + shr ecx, 16 + mov [dword apm_code_16 + 4], cl + + shl edx, 4 + mov [dword apm_data_16 + 2], dx + shr edx, 16 + mov [dword apm_data_16 + 4], dl + + mov dword[apm_entry], ebx + mov word [apm_entry + 4], apm_code_32 - gdts + + mov eax, [BOOT_VAR + 0x9044] ; version & flags + mov [apm_vf], eax +; ----------------------------------------- +; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port +; mov [0xF604],byte 1 ;al + mov al, [BOOT_VAR+0x901F] ; DMA access + mov [allow_dma_access], al + movzx eax, byte [BOOT_VAR+0x9000] ; bpp + mov [ScreenBPP],al + + mov [_display.bpp], eax + mov [_display.vrefresh], 60 + mov [_display.disable_mouse], __sys_disable_mouse + + movzx eax,word [BOOT_VAR+0x900A] ; X max + mov [_display.width], eax + dec eax + mov [Screen_Max_X],eax + mov [screen_workarea.right],eax + movzx eax,word [BOOT_VAR+0x900C] ; Y max + mov [_display.height], eax + dec eax + mov [Screen_Max_Y],eax + mov [screen_workarea.bottom],eax + movzx eax,word [BOOT_VAR+0x9008] ; screen mode + mov [SCR_MODE],eax + mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add + mov [BANK_SWITCH],eax + mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine + cmp [SCR_MODE],word 0x13 ; 320x200 + je @f + cmp [SCR_MODE],word 0x12 ; VGA 640x480 + je @f + movzx eax, word[BOOT_VAR+0x9001] ; for other modes + mov [BytesPerScanLine],ax + mov [_display.pitch], eax +@@: + mov eax, [_display.width] + mul [_display.height] + mov [_WinMapSize], eax + + mov esi, BOOT_VAR+0x9080 + movzx ecx, byte [esi-1] + mov [NumBiosDisks], ecx + mov edi, BiosDisksData + rep movsd + +; GRAPHICS ADDRESSES + + and byte [BOOT_VAR+0x901e],0x0 + mov eax,[BOOT_VAR+0x9018] + mov [LFBAddress],eax + + cmp [SCR_MODE],word 0100000000000000b + jge setvesa20 + cmp [SCR_MODE],word 0x13 + je v20ga32 + mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 + mov [GETPIXEL],dword Vesa12_getpixel24 + cmp [ScreenBPP],byte 24 + jz ga24 + mov [PUTPIXEL],dword Vesa12_putpixel32 + mov [GETPIXEL],dword Vesa12_getpixel32 + ga24: + jmp v20ga24 + setvesa20: + mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 + mov [GETPIXEL],dword Vesa20_getpixel24 + cmp [ScreenBPP],byte 24 + jz v20ga24 + v20ga32: + mov [PUTPIXEL],dword Vesa20_putpixel32 + mov [GETPIXEL],dword Vesa20_getpixel32 + v20ga24: + cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 + jne no_mode_0x12 + mov [PUTPIXEL],dword VGA_putpixel + mov [GETPIXEL],dword Vesa20_getpixel32 + no_mode_0x12: + +; -------- Fast System Call init ---------- +; Intel SYSENTER/SYSEXIT (AMD CPU support it too) + bt [cpu_caps], CAPS_SEP + jnc .SEnP ; SysEnter not Present + xor edx, edx + mov ecx, MSR_SYSENTER_CS + mov eax, os_code + wrmsr + mov ecx, MSR_SYSENTER_ESP +; mov eax, sysenter_stack ; Check it + xor eax, eax + wrmsr + mov ecx, MSR_SYSENTER_EIP + mov eax, sysenter_entry + wrmsr +.SEnP: +; AMD SYSCALL/SYSRET + cmp byte[cpu_vendor], 'A' + jne .noSYSCALL + mov eax, 0x80000001 + cpuid + test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support + jz .noSYSCALL + mov ecx, MSR_AMD_EFER + rdmsr + or eax, 1 ; bit_0 - System Call Extension (SCE) + wrmsr + + ; !!!! It`s dirty hack, fix it !!! + ; Bits of EDX : + ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + + ; mov edx, (os_code + 16) * 65536 + os_code + mov edx, 0x1B0008 + + mov eax, syscall_entry + mov ecx, MSR_AMD_STAR + wrmsr +.noSYSCALL: +; ----------------------------------------- + stdcall alloc_page + stdcall map_page, tss-0xF80, eax, PG_SW + stdcall alloc_page + inc eax + mov [SLOT_BASE+256+APPDATA.io_map], eax + stdcall map_page, tss+0x80, eax, PG_SW + stdcall alloc_page + inc eax + mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax + stdcall map_page, tss+0x1080, eax, PG_SW + +; LOAD IDT + + call build_interrupt_table ;lidt is executed + ;lidt [idtreg] + + call init_kernel_heap + stdcall kernel_alloc, RING0_STACK_SIZE+512 + mov [os_stack_seg], eax + + lea esp, [eax+RING0_STACK_SIZE] + + mov [tss._ss0], os_stack + mov [tss._esp0], esp + mov [tss._esp], esp + mov [tss._cs],os_code + mov [tss._ss],os_stack + mov [tss._ds],app_data + mov [tss._es],app_data + mov [tss._fs],app_data + mov [tss._gs],app_data + mov [tss._io],128 +;Add IO access table - bit array of permitted ports + mov edi, tss._io_map_0 + xor eax, eax + not eax + mov ecx, 8192/4 + rep stosd ; access to 4096*8=65536 ports + + mov ax,tss0 + ltr ax + + mov [LFBSize], 0x800000 + call init_LFB + call init_fpu + call init_malloc + + stdcall alloc_kernel_space, 0x51000 + mov [default_io_map], eax + + add eax, 0x2000 + mov [ipc_tmp], eax + mov ebx, 0x1000 + + add eax, 0x40000 + mov [proc_mem_map], eax + + add eax, 0x8000 + mov [proc_mem_pdir], eax + + add eax, ebx + mov [proc_mem_tab], eax + + add eax, ebx + mov [tmp_task_pdir], eax + + add eax, ebx + mov [tmp_task_ptab], eax + + add eax, ebx + mov [ipc_pdir], eax + + add eax, ebx + mov [ipc_ptab], eax + + stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \ + (unpack.lc+unpack.lp)))*4 + + mov [unpack.p], eax + + call init_events + mov eax, srv.fd-SRV_FD_OFFSET + mov [srv.fd], eax + mov [srv.bk], eax + + mov edi, irq_tab + xor eax, eax + mov ecx, 16 + rep stosd + +;Set base of graphic segment to linear address of LFB + mov eax,[LFBAddress] ; set for gs + mov [graph_data_l+2],ax + shr eax,16 + mov [graph_data_l+4],al + mov [graph_data_l+7],ah + + stdcall kernel_alloc, [_WinMapSize] + mov [_WinMapAddress], eax + + xor eax,eax + inc eax + mov [CURRENT_TASK],eax ;dword 1 + mov [TASK_COUNT],eax ;dword 1 + mov [TASK_BASE],dword TASK_DATA + mov [current_slot], SLOT_BASE+256 + +; set background + + mov [BgrDrawMode],eax + mov [BgrDataWidth],eax + mov [BgrDataHeight],eax + mov [mem_BACKGROUND], 4 + mov [img_background], static_background_data + + mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE + + stdcall kernel_alloc, 0x10000/8 + mov edi, eax + mov [network_free_ports], eax + or eax, -1 + mov ecx, 0x10000/32 + rep stosd + +; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f + + call rerouteirqs + +; Initialize system V86 machine + call init_sys_v86 + +; TIMER SET TO 1/100 S + + mov al,0x34 ; set to 100Hz + out 0x43,al + mov al,0x9b ; lsb 1193180 / 1193 + out 0x40,al + mov al,0x2e ; msb + out 0x40,al + +; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) +; they are used: when partitions are scanned, hd_read relies on timer +; Also enable IRQ2, because in some configurations +; IRQs from slave controller are not delivered until IRQ2 on master is enabled + mov al, 0xFA + out 0x21, al + mov al, 0x3F + out 0xA1, al + +;!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'detect/disks.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!! + + call Parser_params + +; READ RAMDISK IMAGE FROM HD + +;!!!!!!!!!!!!!!!!!!!!!!! +include 'boot/rdload.inc' +;!!!!!!!!!!!!!!!!!!!!!!! +; mov [dma_hdd],1 +; CALCULATE FAT CHAIN FOR RAMDISK + + call calculatefatchain + +; LOAD VMODE DRIVER + +;!!!!!!!!!!!!!!!!!!!!!!! +include 'vmodeld.inc' +;!!!!!!!!!!!!!!!!!!!!!!! + +if 0 + mov ax,[OS_BASE+0x10000+bx_from_load] + cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} + je no_lib_load +; LOADING LIBRARES + stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files) + call load_file_parse_table ; prepare file parse table + call set_kernel_conf ; configure devices and gui +no_lib_load: +end if + +; LOAD FONTS I and II + + stdcall read_file, char, FONT_I, 0, 2304 + stdcall read_file, char2, FONT_II, 0, 2560 + + mov esi,boot_fonts + call boot_log + +; PRINT AMOUNT OF MEMORY + mov esi, boot_memdetect + call boot_log + + movzx ecx, word [boot_y] + or ecx, (10+29*6) shl 16 ; "Determining amount of memory" + sub ecx, 10 + mov edx, 0xFFFFFF + mov ebx, [MEM_AMOUNT] + shr ebx, 20 + xor edi,edi + mov eax, 0x00040000 + inc edi + call display_number_force + +; BUILD SCHEDULER + + call build_scheduler ; sys32.inc + + mov esi,boot_devices + call boot_log + + mov [pci_access_enabled],1 + + +; SET PRELIMINARY WINDOW STACK AND POSITIONS + + mov esi,boot_windefs + call boot_log + call setwindowdefaults + +; SET BACKGROUND DEFAULTS + + mov esi,boot_bgr + call boot_log + call init_background + call calculatebackground + +; RESERVE SYSTEM IRQ'S JA PORT'S + + mov esi,boot_resirqports + call boot_log + call reserve_irqs_ports + +; SET PORTS FOR IRQ HANDLERS + + mov esi,boot_setrports + call boot_log + ;call setirqreadports + +; SET UP OS TASK + + mov esi,boot_setostask + call boot_log + + xor eax, eax + mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data + mov dword [SLOT_BASE+APPDATA.exc_handler], eax + mov dword [SLOT_BASE+APPDATA.except_mask], eax + + ; name for OS/IDLE process + + mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' + mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' + mov edi, [os_stack_seg] + mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi + add edi, 0x2000-512 + mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi + mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case + ; [SLOT_BASE+256+APPDATA.io_map] was set earlier + + mov esi, fpu_data + mov ecx, 512/4 + cld + rep movsd + + mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax + mov dword [SLOT_BASE+256+APPDATA.except_mask], eax + + mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET + mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx + mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx + + mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path + mov dword [SLOT_BASE+256+APPDATA.tls_base], eax + + ; task list + mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address + inc eax + mov dword [CURRENT_TASK],eax + mov dword [TASK_COUNT],eax + mov [current_slot], SLOT_BASE+256 + mov [TASK_BASE],dword TASK_DATA + mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number + mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number + + call init_display + mov eax, [def_cursor] + mov [SLOT_BASE+APPDATA.cursor],eax + mov [SLOT_BASE+APPDATA.cursor+256],eax + + ; READ TSC / SECOND + + mov esi,boot_tsc + call boot_log + cli + rdtsc ;call _rdtsc + mov ecx,eax + mov esi,250 ; wait 1/4 a second + call delay_ms + rdtsc ;call _rdtsc + sti + sub eax,ecx + shl eax,2 + mov [CPU_FREQ],eax ; save tsc / sec +; mov ebx, 1000000 +; div ebx +; ў®®ЎйҐ-в® Їа®Ё§ў®¤ЁвҐ«м­®бвм ў ¤ ­­®¬ Є®­ЄаҐв­®¬ ¬Ґб⥠+; б®ўҐа襭­® ­ҐЄаЁвЁз­ , ­® зв®Ўл § вЄ­гвм «оЎЁвҐ«Ґ© +; ®ЇвЁ¬Ё§ЁагойЁе Є®¬ЇЁ«пв®а®ў џ‚“... + mov edx, 2251799814 + mul edx + shr edx, 19 + mov [stall_mcs], edx +; PRINT CPU FREQUENCY + mov esi, boot_cpufreq + call boot_log + + mov ebx, edx + movzx ecx, word [boot_y] + add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is ' + mov edx, 0xFFFFFF + xor edi,edi + mov eax, 0x00040000 + inc edi + call display_number_force + +; SET VARIABLES + + call set_variables + +; SET MOUSE + + ;call detect_devices + stdcall load_driver, szPS2MDriver +; stdcall load_driver, szCOM_MDriver + + mov esi,boot_setmouse + call boot_log + call setmouse + + +; STACK AND FDC + + call stack_init + call fdc_init + +; PALETTE FOR 320x200 and 640x480 16 col + + cmp [SCR_MODE],word 0x12 + jne no_pal_vga + mov esi,boot_pal_vga + call boot_log + call paletteVGA + no_pal_vga: + + cmp [SCR_MODE],word 0x13 + jne no_pal_ega + mov esi,boot_pal_ega + call boot_log + call palette320x200 + no_pal_ega: + +; LOAD DEFAULT SKIN + + call load_default_skin + +;protect io permission map + + mov esi, [default_io_map] + stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP + add esi, 0x1000 + stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP + + stdcall map_page,tss._io_map_0,\ + [SLOT_BASE+256+APPDATA.io_map], PG_MAP + stdcall map_page,tss._io_map_1,\ + [SLOT_BASE+256+APPDATA.io_map+4], PG_MAP + + mov ax,[OS_BASE+0x10000+bx_from_load] + cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba} + je no_st_network + call set_network_conf + no_st_network: + +; LOAD FIRST APPLICATION + cli + + cmp byte [BOOT_VAR+0x9030],1 + jne no_load_vrr_m + + mov ebp, vrr_m + call fs_execute_from_sysdir + +; cmp eax,2 ; if vrr_m app found (PID=2) + sub eax,2 + jz first_app_found + +no_load_vrr_m: + + mov ebp, firstapp + call fs_execute_from_sysdir + +; cmp eax,2 ; continue if a process has been loaded + sub eax,2 + jz first_app_found + + mov esi, boot_failed + call boot_log + + mov eax, 0xDEADBEEF ; otherwise halt + hlt + +first_app_found: + + cli + + ;mov [TASK_COUNT],dword 2 + push 1 + pop dword [CURRENT_TASK] ; set OS task fisrt + +; SET KEYBOARD PARAMETERS + mov al, 0xf6 ; reset keyboard, scan enabled + call kb_write + + ; wait until 8042 is ready + xor ecx,ecx + @@: + in al,64h + and al,00000010b + loopnz @b + + ; mov al, 0xED ; svetodiody - only for testing! + ; call kb_write + ; call kb_read + ; mov al, 111b + ; call kb_write + ; call kb_read + + mov al, 0xF3 ; set repeat rate & delay + call kb_write +; call kb_read + mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 + call kb_write +; call kb_read + ;// mike.dld [ + call set_lights + ;// mike.dld ] + + +; Setup serial output console (if enabled) + +if defined debug_com_base + + ; enable Divisor latch + + mov dx, debug_com_base+3 + mov al, 1 shl 7 + out dx, al + + ; Set speed to 115200 baud (max speed) + + mov dx, debug_com_base + mov al, 0x01 + out dx, al + + mov dx, debug_com_base+1 + mov al, 0x00 + out dx, al + + ; No parity, 8bits words, one stop bit, dlab bit back to 0 + + mov dx, debug_com_base+3 + mov al, 3 + out dx, al + + ; disable interrupts + + mov dx, debug_com_base+1 + mov al, 0 + out dx, al + + ; clear + enable fifo (64 bits) + + mov dx, debug_com_base+2 + mov al, 0x7 + 1 shl 5 + out dx, al + + +end if + +; START MULTITASKING + +if preboot_blogesc + mov esi, boot_tasking + call boot_log +.bll1: in al, 0x60 ; wait for ESC key press + cmp al, 129 + jne .bll1 +end if + +; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled + +; UNMASK ALL IRQ'S + + mov esi,boot_allirqs + call boot_log + + cli ;guarantee forbidance of interrupts. + mov al,0 ; unmask all irq's + out 0xA1,al + out 0x21,al + + mov ecx,32 + + ready_for_irqs: + + mov al,0x20 ; ready for irqs + out 0x20,al + out 0xa0,al + + loop ready_for_irqs ; flush the queue + + stdcall attach_int_handler, dword 1, irq1, dword 0 + +; mov [dma_hdd],1 + cmp [IDEContrRegsBaseAddr], 0 + setnz [dma_hdd] + mov [timer_ticks_enable],1 ; for cd driver + + sti + call change_task + + jmp osloop + +; jmp $ ; wait here for timer to take control + + ; Fly :) + +include 'unpacker.inc' +include 'fdo.inc' + +align 4 +boot_log: + pushad + + mov ebx,10*65536 + mov bx,word [boot_y] + add [boot_y],dword 10 + mov ecx,0x80ffffff ; ASCIIZ string with white color + xor edi,edi + mov edx,esi + inc edi + call dtext + + mov [novesachecksum],1000 + call checkVga_N13 + + popad + + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MAIN OS LOOP START ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +osloop: + call [draw_pointer] + call checkbuttons + call checkwindows +; call check_window_move_request + call checkmisc + call checkVga_N13 + call stack_handler + call checkidle + call check_fdd_motor_status + call check_ATAPI_device_event + jmp osloop +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MAIN OS LOOP END ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 4 +checkidle: + pushad + call change_task + jmp idle_loop_entry + idle_loop: + cmp eax,[idlemem] ; eax == [timer_ticks] + jne idle_exit + rdtsc ;call _rdtsc + mov ecx,eax + hlt + rdtsc ;call _rdtsc + sub eax,ecx + add [idleuse],eax + idle_loop_entry: + mov eax,[timer_ticks] ; eax = [timer_ticks] + cmp [check_idle_semaphore],0 + je idle_loop + dec [check_idle_semaphore] + idle_exit: + mov [idlemem],eax ; eax == [timer_ticks] + popad + ret + +uglobal + idlemem dd 0x0 + idleuse dd 0x0 + idleusesec dd 0x0 + check_idle_semaphore dd 0x0 +endg + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; INCLUDED SYSTEM FILES ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +include "kernel32.inc" + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; KERNEL FUNCTIONS ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +reserve_irqs_ports: + + push eax + xor eax,eax + inc eax + mov byte [irq_owner+4*0],al ;1 ; timer + ;mov [irq_owner+4*1], 1 ; keyboard + mov byte [irq_owner+4*6],al ;1 ; floppy diskette + mov byte [irq_owner+4*13],al ;1 ; math co-pros + mov byte [irq_owner+4*14],al ;1 ; ide I + mov byte [irq_owner+4*15],al ;1 ; ide II + pop eax + +; RESERVE PORTS + push 4 + pop dword [RESERVED_PORTS] ;,edi + + push 1 + pop dword [RESERVED_PORTS+16+0] ;,dword 1 + and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0 + mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d + + push 1 + pop dword [RESERVED_PORTS+32+0] ;,dword 1 + push 0x30 + pop dword [RESERVED_PORTS+32+4] ;,dword 0x30 + push 0x4d + pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d + + push 1 + pop dword [RESERVED_PORTS+48+0] ;,dword 1 + push 0x50 + pop dword [RESERVED_PORTS+48+4] ;,dword 0x50 + mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf + + push 1 + pop dword [RESERVED_PORTS+64+0] ;,dword 1 + + mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5 + mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff + + ret + +setirqreadports: + + mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte + and dword [irq12read+4],0 ; end of port list +; mov [irq12read+4],dword 0 ; end of port list + ;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte + ;mov [irq04read+4],dword 0 ; end of port list + ;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte + ;mov [irq03read+4],dword 0 ; end of port list + + ret + +iglobal + process_number dd 0x1 +endg + +set_variables: + + mov ecx,0x100 ; flush port 0x60 +.fl60: in al,0x60 + loop .fl60 + push eax + + mov ax,[BOOT_VAR+0x900c] + shr ax,1 + shl eax,16 + mov ax,[BOOT_VAR+0x900A] + shr ax,1 + mov [MOUSE_X],eax + + xor eax,eax + mov [BTN_ADDR],dword BUTTON_INFO ; address of button list + + mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer + mov byte [KEY_COUNT],al ; keyboard buffer + mov byte [BTN_COUNT],al ; button buffer +; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y + + ;!! IP 04.02.2005: + mov byte [DONT_SWITCH],al ; change task if possible + pop eax + ret + +align 4 +;input eax=43,bl-byte of output, ecx - number of port +sys_outport: + + mov edi,ecx ; separate flag for read / write + and ecx,65535 + + mov eax,[RESERVED_PORTS] + test eax,eax + jnz .sopl8 + inc eax + mov [esp+32],eax + ret + + .sopl8: + mov edx,[TASK_BASE] + mov edx,[edx+0x4] + ;and ecx,65535 + ;cld - set on interrupt 0x40 + .sopl1: + + mov esi,eax + shl esi,4 + add esi,RESERVED_PORTS + cmp edx,[esi+0] + jne .sopl2 + cmp ecx,[esi+4] + jb .sopl2 + cmp ecx,[esi+8] + jg .sopl2 +.sopl3: + + test edi,0x80000000 ; read ? + jnz .sopl4 + + mov eax,ebx + mov dx,cx ; write + out dx,al + and [esp+32],dword 0 + ret + + .sopl2: + + dec eax + jnz .sopl1 + inc eax + mov [esp+32],eax + ret + + + .sopl4: + + mov dx,cx ; read + in al,dx + and eax,0xff + and [esp+32],dword 0 + mov [esp+20],eax + ret + +display_number: + +; eax = print type, al=0 -> ebx is number +; al=1 -> ebx is pointer +; ah=0 -> display decimal +; ah=1 -> display hexadecimal +; ah=2 -> display binary +; eax bits 16-21 = number of digits to display (0-32) +; eax bits 22-31 = reserved +; +; ebx = number or pointer +; ecx = x shl 16 + y +; edx = color + xor edi, edi +display_number_force: + push eax + and eax,0x3fffffff + cmp eax,0xffff ; length > 0 ? + pop eax + jge cont_displ + ret + cont_displ: + push eax + and eax,0x3fffffff + cmp eax,61*0x10000 ; length <= 60 ? + pop eax + jb cont_displ2 + ret + cont_displ2: + + pushad + + cmp al,1 ; ecx is a pointer ? + jne displnl1 + mov ebp,ebx + add ebp,4 + mov ebp,[ebp+std_application_base_address] + mov ebx,[ebx+std_application_base_address] + displnl1: + sub esp,64 + + test ah,ah ; DECIMAL + jnz no_display_desnum + shr eax,16 + and eax,0xC03f +; and eax,0x3f + push eax + and eax,0x3f + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,10 + d_desnum: + xor edx,edx + call division_64_bits + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_desnum + pop eax + call normalize_number + call draw_num_text + add esp,64 + popad + ret + no_display_desnum: + + cmp ah,0x01 ; HEXADECIMAL + jne no_display_hexnum + shr eax,16 + and eax,0xC03f +; and eax,0x3f + push eax + and eax,0x3f + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,16 + d_hexnum: + xor edx,edx + call division_64_bits + div ebx + hexletters = __fdo_hexdigits + add edx,hexletters + mov dl,[edx] + mov [edi],dl + dec edi + loop d_hexnum + pop eax + call normalize_number + call draw_num_text + add esp,64 + popad + ret + no_display_hexnum: + + cmp ah,0x02 ; BINARY + jne no_display_binnum + shr eax,16 + and eax,0xC03f +; and eax,0x3f + push eax + and eax,0x3f + mov edi,esp + add edi,4+64-1 + mov ecx,eax + mov eax,ebx + mov ebx,2 + d_binnum: + xor edx,edx + call division_64_bits + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_binnum + pop eax + call normalize_number + call draw_num_text + add esp,64 + popad + ret + no_display_binnum: + + add esp,64 + popad + ret + +normalize_number: + test ah,0x80 + jz .continue + mov ecx,48 + and eax,0x3f +@@: + inc edi + cmp [edi],cl + jne .continue + dec eax + cmp eax,1 + ja @r + mov al,1 +.continue: + and eax,0x3f + ret + +division_64_bits: + test [esp+1+4],byte 0x40 + jz .continue + push eax + mov eax,ebp + div ebx + mov ebp,eax + pop eax +.continue: + ret + +draw_num_text: + mov esi,eax + mov edx,64+4 + sub edx,eax + add edx,esp + mov ebx,[esp+64+32-8+4] +; add window start x & y + mov ecx,[TASK_BASE] + + mov edi,[CURRENT_TASK] + shl edi,8 + + mov eax,[ecx-twdw+WDATA.box.left] + add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + shl eax,16 + add eax,[ecx-twdw+WDATA.box.top] + add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + add ebx,eax + mov ecx,[esp+64+32-12+4] + and ecx, not 0x80000000 ; force counted string + mov eax, [esp+64+8] ; background color (if given) + mov edi, [esp+64+4] + jmp dtext + +align 4 + +sys_setup: + +; 1=roland mpu midi base , base io address +; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 5=system language, 1eng 2fi 3ger 4rus +; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 8=fat32 partition in hd +; 9 +; 10 = sound dma channel +; 11 = enable lba read +; 12 = enable pci access + + + and [esp+32],dword 0 + dec ebx ; MIDI + jnz nsyse1 + cmp ecx,0x100 + + jb nsyse1 + mov esi,65535 + cmp esi,ecx + + jb nsyse1 + mov [midi_base],cx ;bx + mov word [mididp],cx ;bx + inc cx ;bx + mov word [midisp],cx ;bx + ret + +iglobal +midi_base dw 0 +endg + + nsyse1: + dec ebx ; KEYBOARD + jnz nsyse2 + mov edi,[TASK_BASE] + mov eax,[edi+TASKDATA.mem_start] + add eax,edx + + dec ecx + jnz kbnobase + mov ebx,keymap + mov ecx,128 + call memmove + ret + kbnobase: + dec ecx + jnz kbnoshift + + mov ebx,keymap_shift + mov ecx,128 + call memmove + ret + kbnoshift: + dec ecx + jnz kbnoalt + mov ebx,keymap_alt + mov ecx,128 + call memmove + ret + kbnoalt: + sub ecx,6 + jnz kbnocountry + mov word [keyboard],dx + ret + kbnocountry: + mov [esp+32],dword 1 + ret + nsyse2: + dec ebx ; CD + jnz nsyse4 + + test ecx,ecx + jz nosesl + + cmp ecx, 4 + ja nosesl + mov [cd_base],cl + + dec ecx + jnz noprma + mov [cdbase],0x1f0 + mov [cdid],0xa0 + noprma: + + dec ecx + jnz noprsl + mov [cdbase],0x1f0 + mov [cdid],0xb0 + noprsl: + dec ecx + jnz nosema + mov [cdbase],0x170 + mov [cdid],0xa0 + nosema: + dec ecx + jnz nosesl + mov [cdbase],0x170 + mov [cdid],0xb0 + nosesl: + ret + +iglobal +cd_base db 0 + +endg + nsyse4: + + sub ebx,2 ; SYSTEM LANGUAGE + jnz nsyse5 + mov [syslang],ecx + ret + nsyse5: + + sub ebx,2 ; HD BASE + jnz nsyse7 + + test ecx,ecx + jz nosethd + + cmp ecx,4 + ja nosethd + mov [hd_base],cl + + cmp ecx,1 + jnz noprmahd + mov [hdbase],0x1f0 + and dword [hdid],0x0 + mov dword [hdpos],ecx +; call set_FAT32_variables + noprmahd: + + cmp ecx,2 + jnz noprslhd + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov dword [hdpos],ecx +; call set_FAT32_variables + noprslhd: + + cmp ecx,3 + jnz nosemahd + mov [hdbase],0x170 + and dword [hdid],0x0 + mov dword [hdpos],ecx +; call set_FAT32_variables + nosemahd: + + cmp ecx,4 + jnz noseslhd + mov [hdbase],0x170 + mov [hdid],0x10 + mov dword [hdpos],ecx +; call set_FAT32_variables + noseslhd: + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel + and dword [hd1_status],0 ; free + nosethd: + ret + +iglobal +hd_base db 0 +endg + +nsyse7: + +; cmp eax,8 ; HD PARTITION + dec ebx + jnz nsyse8 + mov [fat32part],ecx +; call set_FAT32_variables + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel +; pusha + call choice_necessity_partition_1 +; popa + and dword [hd1_status],0 ; free + ret + +nsyse8: +; cmp eax,11 ; ENABLE LBA READ + and ecx,1 + sub ebx,3 + jnz no_set_lba_read + mov [lba_read_enabled],ecx + ret + +no_set_lba_read: +; cmp eax,12 ; ENABLE PCI ACCESS + dec ebx + jnz no_set_pci_access + mov [pci_access_enabled],ecx + ret +no_set_pci_access: + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'vmodeint.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +sys_setup_err: + or [esp+32],dword -1 + ret + +align 4 + +sys_getsetup: + +; 1=roland mpu midi base , base io address +; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 5=system language, 1eng 2fi 3ger 4rus +; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 8=fat32 partition in hd +; 9=get hs timer tic + +; cmp eax,1 + dec ebx + jnz ngsyse1 + movzx eax,[midi_base] + mov [esp+32],eax + ret +ngsyse1: +; cmp eax,2 + dec ebx + jnz ngsyse2 + + mov edi,[TASK_BASE] + mov ebx,[edi+TASKDATA.mem_start] + add ebx,edx + +; cmp ebx,1 + dec ecx + jnz kbnobaseret + mov eax,keymap + mov ecx,128 + call memmove + ret +kbnobaseret: +; cmp ebx,2 + dec ecx + jnz kbnoshiftret + + mov eax,keymap_shift + mov ecx,128 + call memmove + ret +kbnoshiftret: +; cmp ebx,3 + dec ecx + jne kbnoaltret + + mov eax,keymap_alt + mov ecx,128 + call memmove + ret +kbnoaltret: +; cmp ebx,9 + sub ecx,6 + jnz ngsyse2 + movzx eax,word [keyboard] + mov [esp+32],eax + ret + + +ngsyse2: +; cmp eax,3 + dec ebx + jnz ngsyse3 + movzx eax,[cd_base] + mov [esp+32],eax + ret +ngsyse3: +; cmp eax,5 + sub ebx,2 + jnz ngsyse5 + mov eax,[syslang] + mov [esp+32],eax + ret +ngsyse5: +; cmp eax,7 + sub ebx,2 + jnz ngsyse7 + movzx eax,[hd_base] + mov [esp+32],eax + ret +ngsyse7: +; cmp eax,8 + dec ebx + jnz ngsyse8 + mov eax,[fat32part] + mov [esp+32],eax + ret +ngsyse8: +; cmp eax,9 + dec ebx + jnz ngsyse9 + mov eax,[timer_ticks] ;[0xfdf0] + mov [esp+32],eax + ret +ngsyse9: +; cmp eax,11 + sub ebx,2 + jnz ngsyse11 + mov eax,[lba_read_enabled] + mov [esp+32],eax + ret +ngsyse11: +; cmp eax,12 + dec ebx + jnz ngsyse12 + mov eax,[pci_access_enabled] + mov [esp+32],eax + ret +ngsyse12: + mov [esp+32],dword 1 + ret + + +get_timer_ticks: + mov eax,[timer_ticks] + ret + +iglobal +align 4 +mousefn dd msscreen, mswin, msbutton, msset + dd app_load_cursor + dd app_set_cursor + dd app_delete_cursor + dd msz +endg + +readmousepos: + +; eax=0 screen relative +; eax=1 window relative +; eax=2 buttons pressed +; eax=3 set mouse pos ; reserved +; eax=4 load cursor +; eax=5 set cursor +; eax=6 delete cursor ; reserved +; eax=7 get mouse_z + + cmp ebx, 7 + ja msset + jmp [mousefn+ebx*4] +msscreen: + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov [esp+36-4],eax + ret +mswin: + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov esi,[TASK_BASE] + mov bx, word [esi-twdw+WDATA.box.left] + shl ebx,16 + mov bx, word [esi-twdw+WDATA.box.top] + sub eax,ebx + + mov edi,[CURRENT_TASK] + shl edi,8 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol eax,16 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol eax,16 + mov [esp+36-4],eax + ret +msbutton: + movzx eax,byte [BTN_DOWN] + mov [esp+36-4],eax + ret +msz: + mov edi, [TASK_COUNT] + movzx edi, word [WIN_POS + edi*2] + cmp edi, [CURRENT_TASK] + jne @f + mov ax,[MOUSE_SCROLL_H] + shl eax,16 + mov ax,[MOUSE_SCROLL_V] + mov [esp+36-4],eax + and [MOUSE_SCROLL_H],word 0 + and [MOUSE_SCROLL_V],word 0 + ret + @@: + and [esp+36-4],dword 0 +; ret +msset: + ret + +app_load_cursor: + cmp ecx, OS_BASE + jae msset + stdcall load_cursor, ecx, edx + mov [esp+36-4], eax + ret + +app_set_cursor: + stdcall set_cursor, ecx + mov [esp+36-4], eax + ret + +app_delete_cursor: + stdcall delete_cursor, ecx + mov [esp+36-4], eax + ret + +is_input: + + push edx + mov dx,word [midisp] + in al,dx + and al,0x80 + pop edx + ret + +is_output: + + push edx + mov dx,word [midisp] + in al,dx + and al,0x40 + pop edx + ret + + +get_mpu_in: + + push edx + mov dx,word [mididp] + in al,dx + pop edx + ret + + +put_mpu_out: + + push edx + mov dx,word [mididp] + out dx,al + pop edx + ret + + + +align 4 + +sys_midi: + cmp [mididp],0 + jnz sm0 + mov [esp+36],dword 1 + ret +sm0: + and [esp+36],dword 0 + dec ebx + jnz smn1 + ; call setuart +su1: + call is_output + test al,al + jnz su1 + mov dx,word [midisp] + mov al,0xff + out dx,al +su2: + mov dx,word [midisp] + mov al,0xff + out dx,al + call is_input + test al,al + jnz su2 + call get_mpu_in + cmp al,0xfe + jnz su2 +su3: + call is_output + test al,al + jnz su3 + mov dx,word [midisp] + mov al,0x3f + out dx,al + ret +smn1: + dec ebx + jnz smn2 +sm10: + call get_mpu_in + call is_output + test al,al + jnz sm10 + mov al,bl + call put_mpu_out + smn2: + ret + +detect_devices: +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +;include 'detect/commouse.inc' +;include 'detect/ps2mouse.inc' +;include 'detect/dev_fd.inc' +;include 'detect/dev_hdcd.inc' +;include 'detect/sear_par.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ret + +sys_end: + + mov ecx, [current_slot] + mov eax, [ecx+APPDATA.tls_base] + test eax, eax + jz @F + + stdcall user_free, eax +@@: + + mov eax,[TASK_BASE] + mov [eax+TASKDATA.state], 3 ; terminate this program + + waitterm: ; wait here for termination + mov ebx,100 + call delay_hs + jmp waitterm + +iglobal +align 4 +sys_system_table: + dd exit_for_anyone ; 1 = obsolete + dd sysfn_terminate ; 2 = terminate thread + dd sysfn_activate ; 3 = activate window + dd sysfn_getidletime ; 4 = get idle time + dd sysfn_getcpuclock ; 5 = get cpu clock + dd sysfn_saveramdisk ; 6 = save ramdisk + dd sysfn_getactive ; 7 = get active window + dd sysfn_sound_flag ; 8 = get/set sound_flag + dd sysfn_shutdown ; 9 = shutdown with parameter + dd sysfn_minimize ; 10 = minimize window + dd sysfn_getdiskinfo ; 11 = get disk subsystem info + dd sysfn_lastkey ; 12 = get last pressed key + dd sysfn_getversion ; 13 = get kernel version + dd sysfn_waitretrace ; 14 = wait retrace + dd sysfn_centermouse ; 15 = center mouse cursor + dd sysfn_getfreemem ; 16 = get free memory size + dd sysfn_getallmem ; 17 = get total memory size + dd sysfn_terminate2 ; 18 = terminate thread using PID + ; instead of slot + dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration + dd sysfn_meminfo ; 20 = get extended memory info + dd sysfn_pid_to_slot ; 21 = get slot number for pid + dd sysfn_min_rest_window ; 22 = minimize and restore any window +sysfn_num = ($ - sys_system_table)/4 +endg + +sys_system: + dec ebx + cmp ebx, sysfn_num + jae @f + jmp dword [sys_system_table + ebx*4] +@@: + ret + + +sysfn_shutdown: ; 18.9 = system shutdown + cmp ecx,1 + jl exit_for_anyone + cmp ecx,4 + jg exit_for_anyone + mov [BOOT_VAR+0x9030],cl + + mov eax,[TASK_COUNT] + mov [SYS_SHUTDOWN],al + mov [shutdown_processes],eax + and dword [esp+32], 0 + exit_for_anyone: + ret + uglobal + shutdown_processes: dd 0x0 + endg + +sysfn_terminate: ; 18.2 = TERMINATE + cmp ecx,2 + jb noprocessterminate + mov edx,[TASK_COUNT] + cmp ecx,edx + ja noprocessterminate + mov eax,[TASK_COUNT] + shl ecx,5 + mov edx,[ecx+CURRENT_TASK+TASKDATA.pid] + add ecx,CURRENT_TASK+TASKDATA.state + cmp byte [ecx], 9 + jz noprocessterminate + + ;call MEM_Heap_Lock ;guarantee that process isn't working with heap + mov [ecx],byte 3 ; clear possible i40's + ;call MEM_Heap_UnLock + + cmp edx,[application_table_status] ; clear app table stat + jne noatsc + mov [application_table_status],0 + noatsc: + noprocessterminate: + ret + +sysfn_terminate2: +;lock application_table_status mutex +.table_status: + cli + cmp [application_table_status],0 + je .stf + sti + call change_task + jmp .table_status +.stf: + call set_application_table_status + mov eax,ecx + call pid_to_slot + test eax,eax + jz .not_found + mov ecx,eax + cli + call sysfn_terminate + mov [application_table_status],0 + sti + and dword [esp+32],0 + ret +.not_found: + mov [application_table_status],0 + or dword [esp+32],-1 + ret + +sysfn_activate: ; 18.3 = ACTIVATE WINDOW + cmp ecx,2 + jb .nowindowactivate + cmp ecx,[TASK_COUNT] + ja .nowindowactivate + + mov [window_minimize], 2 ; restore window if minimized + + movzx esi, word [WIN_STACK + ecx*2] + cmp esi, [TASK_COUNT] + je .nowindowactivate ; already active + + mov edi, ecx + shl edi, 5 + add edi, window_data + movzx esi, word [WIN_STACK + ecx * 2] + lea esi, [WIN_POS + esi * 2] + call waredraw +.nowindowactivate: + ret + +sysfn_getidletime: ; 18.4 = GET IDLETIME + mov eax,[idleusesec] + mov [esp+32], eax + ret + +sysfn_getcpuclock: ; 18.5 = GET TSC/SEC + mov eax,[CPU_FREQ] + mov [esp+32], eax + ret + +; SAVE ramdisk to /hd/1/menuet.img +;!!!!!!!!!!!!!!!!!!!!!!!! + include 'blkdev/rdsave.inc' +;!!!!!!!!!!!!!!!!!!!!!!!! +align 4 +sysfn_getactive: ; 18.7 = get active window + mov eax, [TASK_COUNT] + movzx eax, word [WIN_POS + eax*2] + mov [esp+32],eax + ret + +sysfn_sound_flag: ; 18.8 = get/set sound_flag +; cmp ecx,1 + dec ecx + jnz nogetsoundflag + movzx eax,byte [sound_flag] ; get sound_flag + mov [esp+32],eax + ret + nogetsoundflag: +; cmp ecx,2 + dec ecx + jnz nosoundflag + xor byte [sound_flag], 1 + nosoundflag: + ret + +sysfn_minimize: ; 18.10 = minimize window + mov [window_minimize],1 + ret +align 4 +sysfn_getdiskinfo: ; 18.11 = get disk info table +; cmp ecx,1 + dec ecx + jnz full_table + small_table: + call for_all_tables + mov ecx,10 + cld + rep movsb + ret + for_all_tables: + mov edi,edx + mov esi,DRIVE_DATA + ret + full_table: +; cmp ecx,2 + dec ecx + jnz exit_for_anyone + call for_all_tables + mov ecx,16384 + cld + rep movsd + ret + +sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) + and dword [esp+32], 0 + ret + +sysfn_getversion: ; 18.13 = get kernel ID and version + mov edi,ebx + mov esi,version_inf + mov ecx,version_end-version_inf + rep movsb + ret + +sysfn_waitretrace: ; 18.14 = sys wait retrace + ;wait retrace functions + sys_wait_retrace: + mov edx,0x3da + WaitRetrace_loop: + in al,dx + test al,1000b + jz WaitRetrace_loop + and [esp+32],dword 0 + ret + +align 4 +sysfn_centermouse: ; 18.15 = mouse centered +; removed here by +; call mouse_centered +;* mouse centered - start code- Mario79 +;mouse_centered: +; push eax + mov eax,[Screen_Max_X] + shr eax,1 + mov [MOUSE_X],ax + mov eax,[Screen_Max_Y] + shr eax,1 + mov [MOUSE_Y],ax +; ret +;* mouse centered - end code- Mario79 + xor eax,eax + and [esp+32],eax +; pop eax + + ret +align 4 +sysfn_mouse_acceleration: ; 18.19 = set/get mouse features + test ecx,ecx ; get mouse speed factor + jnz .set_mouse_acceleration + xor eax,eax + mov ax,[mouse_speed_factor] + mov [esp+32],eax + ret + .set_mouse_acceleration: +; cmp ecx,1 ; set mouse speed factor + dec ecx + jnz .get_mouse_delay + mov [mouse_speed_factor],dx + ret + .get_mouse_delay: +; cmp ecx,2 ; get mouse delay + dec ecx + jnz .set_mouse_delay + mov eax,[mouse_delay] + mov [esp+32],eax + ret + .set_mouse_delay: +; cmp ecx,3 ; set mouse delay + dec ecx + jnz .set_pointer_position + mov [mouse_delay],edx + ret + .set_pointer_position: +; cmp ecx,4 ; set mouse pointer position + dec ecx + jnz .set_mouse_button + mov [MOUSE_Y],dx ;y + ror edx,16 + mov [MOUSE_X],dx ;x + rol edx,16 + ret + .set_mouse_button: +; cmp ecx,5 ; set mouse button features + dec ecx + jnz .end + mov [BTN_DOWN],dl + mov [mouse_active],1 + .end: + ret + +sysfn_getfreemem: + mov eax, [pg_data.pages_free] + shl eax, 2 + mov [esp+32],eax + ret + +sysfn_getallmem: + mov eax,[MEM_AMOUNT] + shr eax, 10 + mov [esp+32],eax + ret + +; // Alver, 2007-22-08 // { +sysfn_pid_to_slot: + mov eax, ecx + call pid_to_slot + mov [esp+32], eax + ret + +sysfn_min_rest_window: + pushad + mov eax, edx ; ebx - operating + shr ecx, 1 + jnc @f + call pid_to_slot +@@: + or eax, eax ; eax - number of slot + jz .error + cmp eax, 255 ; varify maximal slot number + ja .error + movzx eax, word [WIN_STACK + eax*2] + shr ecx, 1 + jc .restore + ; .minimize: + call minimize_window + jmp .exit +.restore: + call restore_minimized_window +.exit: + popad + xor eax, eax + mov [esp+32], eax + ret +.error: + popad + xor eax, eax + dec eax + mov [esp+32], eax + ret +; } \\ Alver, 2007-22-08 \\ + +uglobal +;// mike.dld, 2006-29-01 [ +screen_workarea RECT +;// mike.dld, 2006-29-01 ] +window_minimize db 0 +sound_flag db 0 +endg + +iglobal +version_inf: + db 0,7,7,0 ; version 0.7.7.0 + db UID_KOLIBRI + dd __REV__ +version_end: +endg + +UID_NONE=0 +UID_MENUETOS=1 ;official +UID_KOLIBRI=2 ;russian + +sys_cachetodiskette: + cmp ebx, 1 + jne .no_floppy_a_save + mov [flp_number], 1 + jmp .save_image_on_floppy +.no_floppy_a_save: + cmp ebx, 2 + jne .no_floppy_b_save + mov [flp_number], 2 +.save_image_on_floppy: + call save_image + mov [esp + 32], dword 0 + cmp [FDC_Status], 0 + je .yes_floppy_save +.no_floppy_b_save: + mov [esp + 32], dword 1 +.yes_floppy_save: + ret + +uglobal +; bgrchanged dd 0x0 +align 4 +bgrlockpid dd 0 +bgrlock db 0 +endg + +sys_background: + + cmp ebx,1 ; BACKGROUND SIZE + jnz nosb1 + test ecx,ecx +; cmp ecx,0 + jz sbgrr + test edx,edx +; cmp edx,0 + jz sbgrr +@@: +;;Maxis use atomic bts for mutexes 4.4.2009 + bts dword [bgrlock], 0 + jnc @f + call change_task + jmp @b +@@: + mov [BgrDataWidth],ecx + mov [BgrDataHeight],edx +; mov [bgrchanged],1 + + pushad +; return memory for old background + mov eax, [img_background] + cmp eax, static_background_data + jz @f + stdcall kernel_free, eax +@@: +; calculate RAW size + xor eax,eax + inc eax + cmp [BgrDataWidth],eax + jae @f + mov [BgrDataWidth],eax +@@: + cmp [BgrDataHeight],eax + jae @f + mov [BgrDataHeight],eax +@@: + mov eax,[BgrDataWidth] + imul eax,[BgrDataHeight] + lea eax,[eax*3] + mov [mem_BACKGROUND],eax +; get memory for new background + stdcall kernel_alloc, eax + test eax, eax + jz .memfailed + mov [img_background], eax + jmp .exit +.memfailed: +; revert to static monotone data + mov [img_background], static_background_data + xor eax, eax + inc eax + mov [BgrDataWidth], eax + mov [BgrDataHeight], eax + mov [mem_BACKGROUND], 4 +.exit: + popad + mov [bgrlock], 0 + + sbgrr: + ret + +nosb1: + + cmp ebx,2 ; SET PIXEL + jnz nosb2 + + mov eax, [img_background] + test ecx, ecx + jz @f + cmp eax, static_background_data + jz .ret +@@: + mov ebx, [mem_BACKGROUND] + add ebx, 4095 + and ebx, -4096 + sub ebx, 4 + cmp ecx, ebx + ja .ret + + mov ebx,[eax+ecx] + and ebx,0xFF000000 ;255*256*256*256 + and edx,0x00FFFFFF ;255*256*256+255*256+255 + add edx,ebx + mov [eax+ecx],edx +.ret: + ret +nosb2: + + cmp ebx,3 ; DRAW BACKGROUND + jnz nosb3 +draw_background_temp: +; cmp [bgrchanged],1 ;0 +; je nosb31 +;draw_background_temp: +; mov [bgrchanged],1 ;0 + mov [background_defined], 1 + call force_redraw_background + mov [REDRAW_BACKGROUND], byte 2 + nosb31: + ret + nosb3: + + cmp ebx,4 ; TILED / STRETCHED + jnz nosb4 + cmp ecx,[BgrDrawMode] + je nosb41 + mov [BgrDrawMode],ecx +; mov [bgrchanged],1 + nosb41: + ret + nosb4: + + cmp ebx,5 ; BLOCK MOVE TO BGR + jnz nosb5 + cmp [img_background], static_background_data + jnz @f + test edx, edx + jnz .fin + cmp esi, 4 + ja .fin + @@: + ; bughere + mov eax, ecx + mov ebx, edx + add ebx, [img_background] ;IMG_BACKGROUND + mov ecx, esi + call memmove + .fin: + ret + nosb5: + + cmp ebx, 6 + jnz nosb6 +;;Maxis use atomic bts for mutex 4.4.2009 +@@: + bts dword [bgrlock], 0 + jnc @f + call change_task + jmp @b +@@: + mov eax, [CURRENT_TASK] + mov [bgrlockpid], eax + cmp [img_background], static_background_data + jz .nomem + stdcall user_alloc, [mem_BACKGROUND] + mov [esp+32], eax + test eax, eax + jz .nomem + mov ebx, eax + shr ebx, 12 + or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK + mov esi, [img_background] + shr esi, 12 + mov ecx, [mem_BACKGROUND] + add ecx, 0xFFF + shr ecx, 12 +.z: + mov eax, [page_tabs+ebx*4] + test al, 1 + jz @f + call free_page +@@: + mov eax, [page_tabs+esi*4] + or al, PG_UW + mov [page_tabs+ebx*4], eax + mov eax, ebx + shl eax, 12 + invlpg [eax] + inc ebx + inc esi + loop .z + ret +.nomem: + and [bgrlockpid], 0 + mov [bgrlock], 0 +nosb6: + cmp ebx, 7 + jnz nosb7 + cmp [bgrlock], 0 + jz .err + mov eax, [CURRENT_TASK] + cmp [bgrlockpid], eax + jnz .err + mov eax, ecx + mov ebx, ecx + shr eax, 12 + mov ecx, [page_tabs+(eax-1)*4] + test cl, USED_BLOCK+DONT_FREE_BLOCK + jz .err + jnp .err + push eax + shr ecx, 12 + dec ecx +@@: + and dword [page_tabs+eax*4], 0 + mov edx, eax + shl edx, 12 + push eax + invlpg [edx] + pop eax + inc eax + loop @b + pop eax + and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK + stdcall user_free, ebx + mov [esp+32], eax + and [bgrlockpid], 0 + mov [bgrlock], 0 + ret +.err: + and dword [esp+32], 0 + ret + +nosb7: + ret + +force_redraw_background: + and [draw_data+32 + RECT.left],dword 0 + and [draw_data+32 + RECT.top],dword 0 + push eax ebx + mov eax,[Screen_Max_X] + mov ebx,[Screen_Max_Y] + mov [draw_data+32 + RECT.right],eax + mov [draw_data+32 + RECT.bottom],ebx + pop ebx eax + mov byte [REDRAW_BACKGROUND], 1 + ret + +align 4 + +sys_getbackground: +; cmp eax,1 ; SIZE + dec ebx + jnz nogb1 + mov eax,[BgrDataWidth] + shl eax,16 + mov ax,[BgrDataHeight] + mov [esp+32],eax + ret + +nogb1: +; cmp eax,2 ; PIXEL + dec ebx + jnz nogb2 + + mov eax, [img_background] + test ecx, ecx + jz @f + cmp eax, static_background_data + jz .ret +@@: + mov ebx, [mem_BACKGROUND] + add ebx, 4095 + and ebx, -4096 + sub ebx, 4 + cmp ecx, ebx + ja .ret + + mov eax,[ecx+eax] + + and eax, 0xFFFFFF + mov [esp+32],eax +.ret: + ret + nogb2: + +; cmp eax,4 ; TILED / STRETCHED + dec ebx + dec ebx + jnz nogb4 + mov eax,[BgrDrawMode] + nogb4: + mov [esp+32],eax + ret + +align 4 + +sys_getkey: + mov [esp + 32],dword 1 + ; test main buffer + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK + movzx ecx, word [WIN_STACK + ebx * 2] + mov edx, [TASK_COUNT] + cmp ecx, edx + jne .finish + cmp [KEY_COUNT], byte 0 + je .finish + movzx eax, byte [KEY_BUFF] + shl eax, 8 + push eax + dec byte [KEY_COUNT] + and byte [KEY_COUNT], 127 + movzx ecx, byte [KEY_COUNT] + add ecx, 2 + mov eax, KEY_BUFF + 1 + mov ebx, KEY_BUFF + call memmove + pop eax +.ret_eax: + mov [esp + 32], eax + ret +.finish: +; test hotkeys buffer + mov ecx, hotkey_buffer +@@: + cmp [ecx], ebx + jz .found + add ecx, 8 + cmp ecx, hotkey_buffer + 120 * 8 + jb @b + ret +.found: + mov ax, [ecx + 6] + shl eax, 16 + mov ah, [ecx + 4] + mov al, 2 + and dword [ecx + 4], 0 + and dword [ecx], 0 + jmp .ret_eax + +align 4 + +sys_getbutton: + + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK + mov [esp + 32], dword 1 + movzx ecx, word [WIN_STACK + ebx * 2] + mov edx, [TASK_COUNT] ; less than 256 processes + cmp ecx, edx + jne .exit + movzx eax, byte [BTN_COUNT] + test eax, eax + jz .exit + mov eax, [BTN_BUFF] + shl eax, 8 +; // Alver 22.06.2008 // { + mov al, byte [btn_down_determ] + and al,0xFE ; delete left button bit +; } \\ Alver \\ + mov [BTN_COUNT], byte 0 + mov [esp + 32], eax +.exit: + ret + + +align 4 + +sys_cpuusage: + +; RETURN: +; +; +00 dword process cpu usage +; +04 word position in windowing stack +; +06 word windowing stack value at current position (cpu nro) +; +10 12 bytes name +; +22 dword start in mem +; +26 dword used mem +; +30 dword PID , process idenfification number +; + + cmp ecx,-1 ; who am I ? + jne .no_who_am_i + mov ecx,[CURRENT_TASK] + .no_who_am_i: + cmp ecx, max_processes + ja .nofillbuf + +; +4: word: position of the window of thread in the window stack + mov ax, [WIN_STACK + ecx * 2] + mov [ebx+4], ax +; +6: word: number of the thread slot, which window has in the window stack +; position ecx (has no relation to the specific thread) + mov ax, [WIN_POS + ecx * 2] + mov [ebx+6], ax + + shl ecx, 5 + +; +0: dword: memory usage + mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage] + mov [ebx], eax +; +10: 11 bytes: name of the process + push ecx + lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name] + add ebx, 10 + mov ecx, 11 + call memmove + pop ecx + +; +22: address of the process in memory +; +26: size of used memory - 1 + push edi + lea edi, [ebx+12] + xor eax, eax + mov edx, 0x100000*16 + cmp ecx, 1 shl 5 + je .os_mem + mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size] + mov eax, std_application_base_address +.os_mem: + stosd + lea eax, [edx-1] + stosd + +; +30: PID/TID + mov eax, [ecx+CURRENT_TASK+TASKDATA.pid] + stosd + + ; window position and size + push esi + lea esi, [ecx + window_data + WDATA.box] + movsd + movsd + movsd + movsd + + ; Process state (+50) + mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state] + stosd + + ; Window client area box + lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox] + movsd + movsd + movsd + movsd + + ; Window state + mov al, [ecx+window_data+WDATA.fl_wstate] + stosb + + pop esi + pop edi + +.nofillbuf: + ; return number of processes + + mov eax,[TASK_COUNT] + mov [esp+32],eax + ret + +align 4 +sys_clock: + cli + ; Mikhail Lisovin xx Jan 2005 + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b + @@: + ; end Lisovin's fix + + xor al,al ; seconds + out 0x70,al + in al,0x71 + movzx ecx,al + mov al,02 ; minutes + shl ecx,16 + out 0x70,al + in al,0x71 + movzx edx,al + mov al,04 ; hours + shl edx,8 + out 0x70,al + in al,0x71 + add ecx,edx + movzx edx,al + add ecx,edx + sti + mov [esp + 32], ecx + ret + + +align 4 + +sys_date: + + cli + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b + @@: + + mov ch,0 + mov al,7 ; date + out 0x70,al + in al,0x71 + mov cl,al + mov al,8 ; month + shl ecx,16 + out 0x70,al + in al,0x71 + mov ch,al + mov al,9 ; year + out 0x70,al + in al,0x71 + mov cl,al + sti + mov [esp+32], ecx + ret + + +; redraw status + +sys_redrawstat: + cmp ebx, 1 + jne no_widgets_away + ; buttons away + mov ecx,[CURRENT_TASK] + sys_newba2: + mov edi,[BTN_ADDR] + cmp [edi], dword 0 ; empty button list ? + je end_of_buttons_away + movzx ebx, word [edi] + inc ebx + mov eax,edi + sys_newba: + dec ebx + jz end_of_buttons_away + + add eax, 0x10 + cmp cx, [eax] + jnz sys_newba + + push eax ebx ecx + mov ecx,ebx + inc ecx + shl ecx, 4 + mov ebx, eax + add eax, 0x10 + call memmove + dec dword [edi] + pop ecx ebx eax + + jmp sys_newba2 + + end_of_buttons_away: + + ret + + no_widgets_away: + + cmp ebx, 2 + jnz srl1 + + mov edx, [TASK_BASE] ; return whole screen draw area for this app + add edx, draw_data - CURRENT_TASK + mov [edx + RECT.left], 0 + mov [edx + RECT.top], 0 + mov eax, [Screen_Max_X] + mov [edx + RECT.right], eax + mov eax, [Screen_Max_Y] + mov [edx + RECT.bottom], eax + + mov edi, [TASK_BASE] + or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app + call sys_window_mouse + ret + + srl1: + ret + + +sys_drawwindow: + + mov eax,edx + shr eax,16+8 + and eax,15 + +; cmp eax,0 ; type I - original style + jne nosyswI + inc [mouse_pause] + call [_display.disable_mouse] + call sys_set_window + call [_display.disable_mouse] + call drawwindow_I + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswI: + + cmp al,1 ; type II - only reserve area, no draw + jne nosyswII + inc [mouse_pause] + call [_display.disable_mouse] + call sys_set_window + call [_display.disable_mouse] + call sys_window_mouse + dec [mouse_pause] + call [draw_pointer] + ret + nosyswII: + + cmp al,2 ; type III - new style + jne nosyswIII + inc [mouse_pause] + call [_display.disable_mouse] + call sys_set_window + call [_display.disable_mouse] + call drawwindow_III + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswIII: + + cmp al,3 ; type IV - skinned window + je draw_skin_window + cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window} + jne nosyswV + draw_skin_window: + + inc [mouse_pause] + call [_display.disable_mouse] + call sys_set_window + call [_display.disable_mouse] + mov eax, [TASK_COUNT] + movzx eax, word [WIN_POS + eax*2] + cmp eax, [CURRENT_TASK] + setz al + movzx eax, al + push eax + call drawwindow_IV + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswV: + + ret + + +draw_window_caption: + inc [mouse_pause] + call [_display.disable_mouse] + + xor eax,eax + mov edx,[TASK_COUNT] + movzx edx,word[WIN_POS+edx*2] + cmp edx,[CURRENT_TASK] + jne @f + inc eax + @@: mov edx,[CURRENT_TASK] + shl edx,5 + add edx,window_data + movzx ebx,[edx+WDATA.fl_wstyle] + and bl,0x0F + cmp bl,3 + je .draw_caption_style_3 ;{for 3 and 4 style write caption} + cmp bl,4 + je .draw_caption_style_3 + + jmp .not_style_3 + .draw_caption_style_3: + + push edx + call drawwindow_IV_caption + add esp,4 + jmp .2 + + .not_style_3: + cmp bl,2 + jne .not_style_2 + + call drawwindow_III_caption + jmp .2 + + .not_style_2: + cmp bl,0 + jne .2 + + call drawwindow_I_caption + +;-------------------------------------------------------------- + .2: ;jmp @f + mov edi,[CURRENT_TASK] + shl edi,5 + test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + jz @f + mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] + or edx,edx + jz @f + + movzx eax,[edi+window_data+WDATA.fl_wstyle] + and al,0x0F + cmp al,3 + je .skinned + cmp al,4 + je .skinned + + jmp .not_skinned + .skinned: + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub ax,[_skinmargins.left] + sub ax,[_skinmargins.right] + push edx + cwde + cdq + mov ebx,6 + idiv ebx + pop edx + or eax,eax + js @f + mov esi,eax + mov ebx,dword[_skinmargins.left-2] + mov bx,word[_skinh] + sub bx,[_skinmargins.bottom] + sub bx,[_skinmargins.top] + sar bx,1 + adc bx,0 + add bx,[_skinmargins.top] + add bx,-3 + add ebx,ebp + jmp .dodraw + + .not_skinned: + cmp al,1 + je @f + + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub eax,16 + push edx + cwde + cdq + mov ebx,6 + idiv ebx + pop edx + or eax,eax + js @f + mov esi,eax + mov ebx,0x00080007 + add ebx,ebp +.dodraw: + mov ecx,[common_colours+16];0x00FFFFFF + or ecx, 0x80000000 + xor edi,edi +; // Alver 22.06.2008 // { +; call dtext + call dtext_asciiz_esi +; } \\ Alver \\ + + @@: +;-------------------------------------------------------------- + dec [mouse_pause] + call [draw_pointer] + ret + +iglobal +align 4 +window_topleft dd \ + 1, 21,\ ;type 0 + 0, 0,\ ;type 1 + 5, 20,\ ;type 2 + 5, ?,\ ;type 3 {set by skin} + 5, ? ;type 4 {set by skin} +endg + +set_window_clientbox: + push eax ecx edi + + mov eax,[_skinh] + mov [window_topleft+4*7],eax + mov [window_topleft+4*9],eax + + mov ecx,edi + sub edi,window_data + shl edi,3 + test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE + jz @f + + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + mov eax,[eax*8+window_topleft+0] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax + shl eax,1 + neg eax + add eax,[ecx+WDATA.box.width] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax + + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + push [eax*8+window_topleft+0] + mov eax,[eax*8+window_topleft+4] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax + neg eax + sub eax,[esp] + add eax,[ecx+WDATA.box.height] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax + add esp,4 + + pop edi ecx eax + ret + @@: + xor eax,eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax + mov eax,[ecx+WDATA.box.width] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax + mov eax,[ecx+WDATA.box.height] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax + + pop edi ecx eax + ret + +sys_set_window: + + mov eax,[CURRENT_TASK] + shl eax,5 + add eax,window_data + + ; colors + mov [eax+WDATA.cl_workarea],edx + mov [eax+WDATA.cl_titlebar],esi + mov [eax+WDATA.cl_frames],edi + + mov edi, eax + + ; check flag (?) + test [edi+WDATA.fl_wdrawn],1 + jnz newd + + mov eax,[timer_ticks] ;[0xfdf0] + add eax,100 + mov [new_window_starting],eax + + movsx eax,bx + mov [edi+WDATA.box.width],eax + movsx eax,cx + mov [edi+WDATA.box.height],eax + sar ebx,16 + sar ecx,16 + mov [edi+WDATA.box.left],ebx + mov [edi+WDATA.box.top],ecx + + call check_window_position + + push ecx esi edi ; save for window fullscreen/resize + ;mov esi,edi + + mov cl, [edi+WDATA.fl_wstyle] + mov eax, [edi+WDATA.cl_frames] + + sub edi,window_data + shl edi,3 + add edi,SLOT_BASE + + and cl,0x0F + mov [edi+APPDATA.wnd_caption],0 + cmp cl,3 + je set_APPDATA_wnd_caption + cmp cl,4 ; {SPraid.simba} + je set_APPDATA_wnd_caption + + jmp @f + set_APPDATA_wnd_caption: + mov [edi+APPDATA.wnd_caption],eax + @@: mov esi,[esp+0] + + add edi, APPDATA.saved_box + movsd + movsd + movsd + movsd + pop edi esi ecx + + mov esi, [CURRENT_TASK] + movzx esi, word [WIN_STACK+esi*2] + lea esi, [WIN_POS+esi*2] + call waredraw + +;;; mov ebx, 1 +;;; call delay_hs + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, [edi+WDATA.box.width] + mov edx, [edi+WDATA.box.height] + add ecx, eax + add edx, ebx + call calculatescreen + + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer + + newd: + call set_window_clientbox + + mov [edi+WDATA.fl_redraw],byte 0 ; no redraw + mov edx,edi + + ret + +syscall_windowsettings: + + .set_window_caption: + dec eax ; subfunction #1 - set window caption + jnz .get_window_caption + + ; NOTE: only window owner thread can set its caption, + ; so there's no parameter for PID/TID + + mov edi,[CURRENT_TASK] + shl edi,5 + + ; have to check if caption is within application memory limit + ; check is trivial, and if application resizes its memory, + ; caption still can become over bounds +; diamond, 31.10.2006: check removed because with new memory manager +; there can be valid data after APPDATA.mem_size bound +; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size] +; add ecx,255 ; max caption length +; cmp ebx,ecx +; ja .exit_fail + + mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ebx + or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + + call draw_window_caption + + xor eax,eax ; eax = 0 (success) + ret + + .get_window_caption: + dec eax ; subfunction #2 - get window caption + jnz .exit_fail + + ; not implemented yet + + .exit_fail: + xor eax,eax + inc eax ; eax = 1 (fail) + ret + + +sys_window_move: + + mov edi,[CURRENT_TASK] + shl edi,5 + add edi,window_data + + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz .window_move_return + + push dword [edi + WDATA.box.left] ; save old coordinates + push dword [edi + WDATA.box.top] + push dword [edi + WDATA.box.width] + push dword [edi + WDATA.box.height] + + cmp eax,-1 ; set new position and size + je .no_x_reposition + mov [edi + WDATA.box.left], eax + .no_x_reposition: + cmp ebx,-1 + je .no_y_reposition + mov [edi + WDATA.box.top], ebx + .no_y_reposition: + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .no_y_resizing + + cmp ecx,-1 + je .no_x_resizing + mov [edi + WDATA.box.width], ecx + .no_x_resizing: + cmp edx,-1 + je .no_y_resizing + mov [edi + WDATA.box.height], edx + .no_y_resizing: + + call check_window_position + call set_window_clientbox + + pushad ; save for window fullscreen/resize + mov esi,edi + sub edi,window_data + shr edi,5 + shl edi,8 + add edi, SLOT_BASE + APPDATA.saved_box + mov ecx,4 + cld + rep movsd + popad + + pushad ; calculcate screen at new position + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx,eax + add edx,ebx + + call calculatescreen + popad + + pop edx ; calculcate screen at old position + pop ecx + pop ebx + pop eax + add ecx,eax + add edx,ebx + mov [dlx],eax ; save for drawlimits + mov [dly],ebx + mov [dlxe],ecx + mov [dlye],edx + call calculatescreen + + mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw + + mov eax,edi ; redraw screen at old position + xor esi,esi + call redrawscreen + + mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under + mov [MOUSE_DOWN],byte 0 ; react to mouse up/down + + call [draw_pointer] + + mov [window_move_pr],0 + + .window_move_return: + + ret + +uglobal + window_move_pr dd 0x0 + window_move_eax dd 0x0 + window_move_ebx dd 0x0 + window_move_ecx dd 0x0 + window_move_edx dd 0x0 +endg + +;ok - 100% work +;nt - not tested +;--------------------------------------------------------------------------------------------- +;eax +;0 - task switch counter. Ret switch counter in eax. Block. ok. +;1 - change task. Ret nothing. Block. ok. +;2 - performance control +; ebx +; 0 - enable or disable (inversion) PCE flag on CR4 for rdmpc in user mode. +; returned new cr4 in eax. Ret cr4 in eax. Block. ok. +; 1 - is cache enabled. Ret cr0 in eax if enabled else zero in eax. Block. ok. +; 2 - enable cache. Ret 1 in eax. Ret nothing. Block. ok. +; 3 - disable cache. Ret 0 in eax. Ret nothing. Block. ok. +;eax +;3 - rdmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. +;4 - wrmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. +;--------------------------------------------------------------------------------------------- +sys_sheduler: +; old sys_sheduler ;noname & halyavin +; cmp eax,0 +; je shed_counter +; cmp eax,2 +; je perf_control +; cmp eax,3 +; je rdmsr_instr +; cmp eax,4 +; je wrmsr_instr +; cmp eax,1 +; jne not_supported +; call change_task ;delay,0 + +;rewritten by 15.11.2009 + test eax,eax + jz .shed_counter ;eax=0 + dec eax + jz change_task ;eax=1 + dec eax + jz .perf_control ;eax=2 + dec eax + jz .rdmsr_instr ;eax=3 + dec eax + jnz @f +;wrmsr_instr ;eax=4 +;.wrmsr_instr: +;now counter in ecx +;(edx:eax) esi:edi => edx:esi + ; Fast Call MSR can't be destroy + ; Ќ® MSR_AMD_EFER ¬®¦­® Ё§¬Ґ­пвм, в.Є. ў н⮬ ॣЁбвॠ«Ёи + ; ўЄ«оз овбп/ўлЄ«оз овбп а биЁаҐ­­лҐ ў®§¬®¦­®бвЁ + cmp ecx, MSR_SYSENTER_CS + je @f + cmp ecx, MSR_SYSENTER_ESP + je @f + cmp ecx, MSR_SYSENTER_EIP + je @f + cmp ecx, MSR_AMD_STAR + je @f + + mov eax, esi + wrmsr + ; mov [esp + 36], eax + ; mov [esp + 24], edx ;ret in ebx? +@@: +ret + +.shed_counter: + mov eax,[context_counter] + mov [esp+36],eax +ret +.perf_control: +; inc eax ;now eax=3 + add eax,3 ;restore eax=3 + cmp ebx,eax + je cache_disable + dec eax + cmp ebx,eax + je cache_enable + dec eax + cmp ebx,eax + je is_cache_enabled + dec eax + cmp ebx,eax + je modify_pce +ret + +.rdmsr_instr: +;now counter in ecx +;(edx:eax) esi:edi => edx:esi +mov eax,esi +rdmsr +mov [esp+36],eax +mov [esp+24],edx ;ret in ebx? +ret + +cache_disable: + mov eax,cr0 + or eax,01100000000000000000000000000000b + mov cr0,eax + wbinvd ;set MESI +ret + +cache_enable: + mov eax,cr0 + and eax,10011111111111111111111111111111b + mov cr0,eax +ret + +is_cache_enabled: + mov eax,cr0 + mov ebx,eax + and eax,01100000000000000000000000000000b + jz cache_disabled + mov [esp+36],ebx +cache_disabled: + mov dword [esp+36],eax ;0 +ret + +modify_pce: + mov eax,cr4 +; mov ebx,0 +; or bx,100000000b ;pce +; xor eax,ebx ;invert pce + bts eax,8 ;pce=cr4[8] + mov cr4,eax + mov [esp+36],eax +ret +;--------------------------------------------------------------------------------------------- + + +; check if pixel is allowed to be drawn + +checkpixel: + push eax edx + + mov edx,[Screen_Max_X] ; screen x size + inc edx + imul edx, ebx + add eax, [_WinMapAddress] + mov dl, [eax+edx] ; lea eax, [...] + + xor ecx, ecx + mov eax, [CURRENT_TASK] + cmp al, dl + setne cl + + pop edx eax + ret + +iglobal + cpustring db 'CPU',0 +endg + +uglobal +background_defined db 0 ; diamond, 11.04.2006 +endg + +align 4 +; check misc + +checkmisc: + + cmp [ctrl_alt_del], 1 + jne nocpustart + + mov ebp, cpustring + call fs_execute_from_sysdir + + mov [ctrl_alt_del], 0 + +nocpustart: + cmp [mouse_active], 1 + jne mouse_not_active + mov [mouse_active], 0 + xor edi, edi + mov ecx, [TASK_COUNT] +set_mouse_event: + add edi, 256 + or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b + loop set_mouse_event + +mouse_not_active: + cmp [REDRAW_BACKGROUND],byte 0 ; background update ? + jz nobackgr + cmp [background_defined], 0 + jz nobackgr + cmp [REDRAW_BACKGROUND], byte 2 + jnz no_set_bgr_event + xor edi, edi + mov ecx, [TASK_COUNT] +set_bgr_event: + add edi, 256 + or [edi+SLOT_BASE+APPDATA.event_mask], 16 + loop set_bgr_event +no_set_bgr_event: +; mov [draw_data+32 + RECT.left],dword 0 +; mov [draw_data+32 + RECT.top],dword 0 +; mov eax,[Screen_Max_X] +; mov ebx,[Screen_Max_Y] +; mov [draw_data+32 + RECT.right],eax +; mov [draw_data+32 + RECT.bottom],ebx + call drawbackground + mov [REDRAW_BACKGROUND],byte 0 + mov [MOUSE_BACKGROUND],byte 0 + +nobackgr: + + ; system shutdown request + + cmp [SYS_SHUTDOWN],byte 0 + je noshutdown + + mov edx,[shutdown_processes] + + cmp [SYS_SHUTDOWN],dl + jne no_mark_system_shutdown + + lea ecx,[edx-1] + mov edx,OS_BASE+0x3040 + jecxz @f +markz: + mov [edx+TASKDATA.state],byte 3 + add edx,0x20 + loop markz +@@: + + no_mark_system_shutdown: + + call [_display.disable_mouse] + + dec byte [SYS_SHUTDOWN] + je system_shutdown + +noshutdown: + + + mov eax,[TASK_COUNT] ; termination + mov ebx,TASK_DATA+TASKDATA.state + mov esi,1 + +newct: + mov cl,[ebx] + cmp cl,byte 3 + jz terminate + cmp cl,byte 4 + jz terminate + + add ebx,0x20 + inc esi + dec eax + jnz newct + ret + +; redraw screen + +redrawscreen: + +; eax , if process window_data base is eax, do not set flag/limits + + pushad + push eax + +;;; mov ebx,2 +;;; call delay_hs + + ;mov ecx,0 ; redraw flags for apps + xor ecx,ecx + newdw2: + + inc ecx + push ecx + + mov eax,ecx + shl eax,5 + add eax,window_data + + cmp eax,[esp+4] + je not_this_task + ; check if window in redraw area + mov edi,eax + + cmp ecx,1 ; limit for background + jz bgli + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx,eax + add edx,ebx + + mov ecx,[dlye] ; ecx = area y end ebx = window y start + cmp ecx,ebx + jb ricino + + mov ecx,[dlxe] ; ecx = area x end eax = window x start + cmp ecx,eax + jb ricino + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + + mov eax,[dly] ; eax = area y start edx = window y end + cmp edx,eax + jb ricino + + mov eax,[dlx] ; eax = area x start ecx = window x end + cmp ecx,eax + jb ricino + + bgli: + + cmp ecx,1 + jnz .az + mov al,[REDRAW_BACKGROUND] + cmp al,2 + jz newdw8 + test al,al + jz .az + lea eax,[edi+draw_data-window_data] + mov ebx,[dlx] + cmp ebx,[eax+RECT.left] + jae @f + mov [eax+RECT.left],ebx + @@: + mov ebx,[dly] + cmp ebx,[eax+RECT.top] + jae @f + mov [eax+RECT.top],ebx + @@: + mov ebx,[dlxe] + cmp ebx,[eax+RECT.right] + jbe @f + mov [eax+RECT.right],ebx + @@: + mov ebx,[dlye] + cmp ebx,[eax+RECT.bottom] + jbe @f + mov [eax+RECT.bottom],ebx + @@: + jmp newdw8 + .az: + + mov eax,edi + add eax,draw_data-window_data + + mov ebx,[dlx] ; set limits + mov [eax + RECT.left], ebx + mov ebx,[dly] + mov [eax + RECT.top], ebx + mov ebx,[dlxe] + mov [eax + RECT.right], ebx + mov ebx,[dlye] + mov [eax + RECT.bottom], ebx + + sub eax,draw_data-window_data + + cmp dword [esp],1 + jne nobgrd + mov byte [REDRAW_BACKGROUND], 1 + + newdw8: + nobgrd: + + mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw + + ricino: + + not_this_task: + + pop ecx + + cmp ecx,[TASK_COUNT] + jle newdw2 + + pop eax + popad + + ret + +calculatebackground: ; background + + mov edi, [_WinMapAddress] ; set os to use all pixels + mov eax,0x01010101 + mov ecx, [_WinMapSize] + shr ecx, 2 + rep stosd + + mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! + + ret + +uglobal + imax dd 0x0 +endg + + + +delay_ms: ; delay in 1/1000 sec + + + push eax + push ecx + + mov ecx,esi + ; + imul ecx, 33941 + shr ecx, 9 + ; + + in al,0x61 + and al,0x10 + mov ah,al + cld + + cnt1: in al,0x61 + and al,0x10 + cmp al,ah + jz cnt1 + + mov ah,al + loop cnt1 + + pop ecx + pop eax + + ret + + +set_app_param: + mov edi, [TASK_BASE] + mov eax, [edi + TASKDATA.event_mask] + mov [edi + TASKDATA.event_mask], ebx + mov [esp+32], eax + ret + + + +delay_hs: ; delay in 1/100 secs +; ebx = delay time + push ecx + push edx + + mov edx,[timer_ticks] + + newtic: + mov ecx,[timer_ticks] + sub ecx,edx + cmp ecx,ebx + jae zerodelay + + call change_task + + jmp newtic + + zerodelay: + pop edx + pop ecx + + ret + +align 16 ;very often call this subrutine +memmove: ; memory move in bytes + +; eax = from +; ebx = to +; ecx = no of bytes + test ecx, ecx + jle .ret + + push esi edi ecx + + mov edi, ebx + mov esi, eax + + test ecx, not 11b + jz @f + + push ecx + shr ecx, 2 + rep movsd + pop ecx + and ecx, 11b + jz .finish + @@: + rep movsb + + .finish: + pop ecx edi esi + .ret: + ret + + +; Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead. +;align 4 +; +;read_floppy_file: +; +;; as input +;; +;; eax pointer to file +;; ebx file lenght +;; ecx start 512 byte block number +;; edx number of blocks to read +;; esi pointer to return/work area (atleast 20 000 bytes) +;; +;; +;; on return +;; +;; eax = 0 command succesful +;; 1 no fd base and/or partition defined +;; 2 yet unsupported FS +;; 3 unknown FS +;; 4 partition not defined at hd +;; 5 file not found +;; ebx = size of file +; +; mov edi,[TASK_BASE] +; add edi,0x10 +; add esi,[edi] +; add eax,[edi] +; +; pushad +; mov edi,esi +; add edi,1024 +; mov esi,0x100000+19*512 +; sub ecx,1 +; shl ecx,9 +; add esi,ecx +; shl edx,9 +; mov ecx,edx +; cld +; rep movsb +; popad +; +; mov [esp+36],eax +; mov [esp+24],ebx +; ret + + + +align 4 + +sys_programirq: + + mov eax, [TASK_BASE] + add ebx, [eax + TASKDATA.mem_start] + + cmp ecx, 16 + jae .not_owner + mov edi, [eax + TASKDATA.pid] + cmp edi, [irq_owner + 4 * ecx] + je .spril1 +.not_owner: + xor ecx, ecx + inc ecx + jmp .end + .spril1: + + shl ecx, 6 + mov esi, ebx + lea edi, [irq00read + ecx] + push 16 + pop ecx + + cld + rep movsd + .end: + mov [esp+32], ecx + ret + + +align 4 + +get_irq_data: + movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data + xor bh, bh + cmp ebx, 16 + jae .not_owner + mov edx, [4 * ebx + irq_owner] ; check for irq owner + + mov eax,[TASK_BASE] + + cmp edx,[eax+TASKDATA.pid] + je gidril1 +.not_owner: + xor edx, edx + dec edx + jmp gid1 + + gidril1: + + shl ebx, 12 + lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size + mov edx, [eax] ; + 0x4 - data offset + dec esi + jz gid1 + test edx, edx ; check if buffer is empty + jz gid1 + + mov ebx, [eax + 0x4] + mov edi, ecx + + mov ecx, 4000 ; buffer size, used frequently + + cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again + jb @f + + xor ebx, ebx + + @@: + + lea esi, [ebx + edx] ; calculate data size and offset + cld + cmp esi, ecx ; if greater than the buffer size, begin cycle again + jbe @f + + sub ecx, ebx + sub edx, ecx + + lea esi, [eax + ebx + 0x10] + rep movsb + + xor ebx, ebx + @@: + lea esi, [eax + ebx + 0x10] + mov ecx, edx + add ebx, edx + + rep movsb + mov edx, [eax] + mov [eax], ecx ; set data size to zero + mov [eax + 0x4], ebx ; set data offset + + gid1: + mov [esp+32], edx ; eax + ret + + +set_io_access_rights: + push edi eax + mov edi, tss._io_map_0 +; mov ecx,eax +; and ecx,7 ; offset in byte +; shr eax,3 ; number of byte +; add edi,eax +; mov ebx,1 +; shl ebx,cl + test ebp,ebp +; cmp ebp,0 ; enable access - ebp = 0 + jnz siar1 +; not ebx +; and [edi],byte bl + btr [edi], eax + pop eax edi + ret +siar1: + bts [edi], eax + ; or [edi],byte bl ; disable access - ebp = 1 + pop eax edi + ret +;reserve/free group of ports +; * eax = 46 - number function +; * ebx = 0 - reserve, 1 - free +; * ecx = number start arrea of ports +; * edx = number end arrea of ports (include last number of port) +;Return value: +; * eax = 0 - succesful +; * eax = 1 - error +; * The system has reserve this ports: +; 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (include last number of port). +;destroys eax,ebx, ebp +r_f_port_area: + + test ebx, ebx + jnz free_port_area +; je r_port_area +; jmp free_port_area + +; r_port_area: + +; pushad + + cmp ecx,edx ; beginning > end ? + ja rpal1 + cmp edx,65536 + jae rpal1 + mov eax,[RESERVED_PORTS] + test eax,eax ; no reserved areas ? + je rpal2 + cmp eax,255 ; max reserved + jae rpal1 + rpal3: + mov ebx,eax + shl ebx,4 + add ebx,RESERVED_PORTS + cmp ecx,[ebx+8] + ja rpal4 + cmp edx,[ebx+4] + jae rpal1 +; jb rpal4 +; jmp rpal1 + rpal4: + dec eax + jnz rpal3 + jmp rpal2 + rpal1: +; popad +; mov eax,1 + xor eax,eax + inc eax + ret + rpal2: +; popad + ; enable port access at port IO map + cli + pushad ; start enable io map + + cmp edx,65536 ;16384 + jae no_unmask_io ; jge + mov eax,ecx +; push ebp + xor ebp,ebp ; enable - eax = port +new_port_access: +; pushad + call set_io_access_rights +; popad + inc eax + cmp eax,edx + jbe new_port_access +; pop ebp +no_unmask_io: + popad ; end enable io map + sti + + mov eax,[RESERVED_PORTS] + add eax,1 + mov [RESERVED_PORTS],eax + shl eax,4 + add eax,RESERVED_PORTS + mov ebx,[TASK_BASE] + mov ebx,[ebx+TASKDATA.pid] + mov [eax],ebx + mov [eax+4],ecx + mov [eax+8],edx + + xor eax, eax + ret + +free_port_area: + +; pushad + mov eax,[RESERVED_PORTS] ; no reserved areas ? + test eax,eax + jz frpal2 + mov ebx,[TASK_BASE] + mov ebx,[ebx+TASKDATA.pid] + frpal3: + mov edi,eax + shl edi,4 + add edi,RESERVED_PORTS + cmp ebx,[edi] + jne frpal4 + cmp ecx,[edi+4] + jne frpal4 + cmp edx,[edi+8] + jne frpal4 + jmp frpal1 + frpal4: + dec eax + jnz frpal3 + frpal2: +; popad + inc eax + ret + frpal1: + push ecx + mov ecx,256 + sub ecx,eax + shl ecx,4 + mov esi,edi + add esi,16 + cld + rep movsb + + dec dword [RESERVED_PORTS] +;popad +;disable port access at port IO map + +; pushad ; start disable io map + pop eax ;start port + cmp edx,65536 ;16384 + jge no_mask_io + +; mov eax,ecx + xor ebp,ebp + inc ebp +new_port_access_disable: +; pushad +; mov ebp,1 ; disable - eax = port + call set_io_access_rights +; popad + inc eax + cmp eax,edx + jbe new_port_access_disable +no_mask_io: +; popad ; end disable io map + xor eax, eax + ret + + +reserve_free_irq: + + xor esi, esi + inc esi + cmp ecx, 16 + jae ril1 + + push ecx + lea ecx, [irq_owner + 4 * ecx] + mov edx, [ecx] + mov eax, [TASK_BASE] + mov edi, [eax + TASKDATA.pid] + pop eax + dec ebx + jnz reserve_irq + + cmp edx, edi + jne ril1 + dec esi + mov [ecx], esi + + jmp ril1 + + reserve_irq: + + cmp dword [ecx], 0 + jne ril1 + + mov ebx, [f_irqs + 4 * eax] + + stdcall attach_int_handler, eax, ebx, dword 0 + + mov [ecx], edi + + dec esi + ril1: + mov [esp+32], esi ; return in eax + ret + +iglobal +f_irqs: + dd 0x0 + dd 0x0 + dd p_irq2 + dd p_irq3 + dd p_irq4 + dd p_irq5 + dd p_irq6 + dd p_irq7 + dd p_irq8 + dd p_irq9 + dd p_irq10 + dd p_irq11 + dd 0x0 + dd 0x0 + dd p_irq14 + dd p_irq15 + +endg + +drawbackground: + inc [mouse_pause] + cmp [SCR_MODE],word 0x12 + je dbrv20 + dbrv12: + cmp [SCR_MODE],word 0100000000000000b + jge dbrv20 + cmp [SCR_MODE],word 0x13 + je dbrv20 + call vesa12_drawbackground + dec [mouse_pause] + call [draw_pointer] + ret + dbrv20: + cmp [BgrDrawMode],dword 1 + jne bgrstr + call vesa20_drawbackground_tiled + dec [mouse_pause] + call [draw_pointer] + ret + bgrstr: + call vesa20_drawbackground_stretch + dec [mouse_pause] + call [draw_pointer] + ret + +align 4 + +syscall_putimage: ; PutImage +sys_putimage: + test ecx,0x80008000 + jnz .exit + test ecx,0x0000FFFF + jz .exit + test ecx,0xFFFF0000 + jnz @f + .exit: + ret + @@: + mov edi,[current_slot] + add dx,word[edi+APPDATA.wnd_clientbox.top] + rol edx,16 + add dx,word[edi+APPDATA.wnd_clientbox.left] + rol edx,16 + .forced: + push ebp esi 0 + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp +sys_putimage_bpp: +; call [disable_mouse] ; this will be done in xxx_putimage +; mov eax, vga_putimage + cmp [SCR_MODE], word 0x12 + jz @f ;.doit + mov eax, vesa12_putimage + cmp [SCR_MODE], word 0100000000000000b + jae @f + cmp [SCR_MODE], word 0x13 + jnz .doit +@@: + mov eax, vesa20_putimage +.doit: + inc [mouse_pause] + call eax + dec [mouse_pause] + pop ebp esi ebp + jmp [draw_pointer] + +syscall_putimage_palette: + mov edi, esi + mov esi, edx + mov edx, ecx + mov ecx, ebx + mov ebx, eax +sys_putimage_palette: +; ebx = pointer to image +; ecx = [xsize]*65536 + [ysize] +; edx = [xstart]*65536 + [ystart] +; esi = number of bits per pixel, must be 8, 24 or 32 +; edi = pointer to palette +; ebp = row delta + mov eax, [CURRENT_TASK] + shl eax, 8 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol edx, 16 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol edx, 16 +.forced: + cmp esi, 1 + jnz @f + push edi + mov eax, [edi+4] + sub eax, [edi] + push eax + push dword [edi] + push 0ffffff80h + mov edi, esp + call put_mono_image + add esp, 12 + pop edi + ret +@@: + cmp esi, 2 + jnz @f + push edi + push 0ffffff80h + mov edi, esp + call put_2bit_image + pop eax + pop edi + ret +@@: + cmp esi, 4 + jnz @f + push edi + push 0ffffff80h + mov edi, esp + call put_4bit_image + pop eax + pop edi + ret +@@: + push ebp esi ebp + cmp esi, 8 + jnz @f + mov ebp, putimage_get8bpp + mov esi, putimage_init8bpp + jmp sys_putimage_bpp +@@: + cmp esi, 15 + jnz @f + mov ebp, putimage_get15bpp + mov esi, putimage_init15bpp + jmp sys_putimage_bpp +@@: + cmp esi, 16 + jnz @f + mov ebp, putimage_get16bpp + mov esi, putimage_init16bpp + jmp sys_putimage_bpp +@@: + cmp esi, 24 + jnz @f + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp + jmp sys_putimage_bpp +@@: + cmp esi, 32 + jnz @f + mov ebp, putimage_get32bpp + mov esi, putimage_init32bpp + jmp sys_putimage_bpp +@@: + pop ebp esi ebp + ret + +put_mono_image: + push ebp esi ebp + mov ebp, putimage_get1bpp + mov esi, putimage_init1bpp + jmp sys_putimage_bpp +put_2bit_image: + push ebp esi ebp + mov ebp, putimage_get2bpp + mov esi, putimage_init2bpp + jmp sys_putimage_bpp +put_4bit_image: + push ebp esi ebp + mov ebp, putimage_get4bpp + mov esi, putimage_init4bpp + jmp sys_putimage_bpp + +putimage_init24bpp: + lea eax, [eax*3] +putimage_init8bpp: + ret + +align 16 +putimage_get24bpp: + movzx eax, byte [esi+2] + shl eax, 16 + mov ax, [esi] + add esi, 3 + ret 4 +align 16 +putimage_get8bpp: + movzx eax, byte [esi] + push edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + pop edx + inc esi + ret 4 + +putimage_init1bpp: + add eax, ecx + push ecx + add eax, 7 + add ecx, 7 + shr eax, 3 + shr ecx, 3 + sub eax, ecx + pop ecx + ret +align 16 +putimage_get1bpp: + push edx + mov edx, [esp+8] + mov al, [edx] + add al, al + jnz @f + lodsb + adc al, al +@@: + mov [edx], al + sbb eax, eax + and eax, [edx+8] + add eax, [edx+4] + pop edx + ret 4 + +putimage_init2bpp: + add eax, ecx + push ecx + add ecx, 3 + add eax, 3 + shr ecx, 2 + shr eax, 2 + sub eax, ecx + pop ecx + ret +align 16 +putimage_get2bpp: + push edx + mov edx, [esp+8] + mov al, [edx] + mov ah, al + shr al, 6 + shl ah, 2 + jnz .nonewbyte + lodsb + mov ah, al + shr al, 6 + shl ah, 2 + add ah, 1 +.nonewbyte: + mov [edx], ah + mov edx, [edx+4] + movzx eax, al + mov eax, [edx+eax*4] + pop edx + ret 4 + +putimage_init4bpp: + add eax, ecx + push ecx + add ecx, 1 + add eax, 1 + shr ecx, 1 + shr eax, 1 + sub eax, ecx + pop ecx + ret +align 16 +putimage_get4bpp: + push edx + mov edx, [esp+8] + add byte [edx], 80h + jc @f + movzx eax, byte [edx+1] + mov edx, [edx+4] + and eax, 0x0F + mov eax, [edx+eax*4] + pop edx + ret 4 +@@: + movzx eax, byte [esi] + add esi, 1 + mov [edx+1], al + shr eax, 4 + mov edx, [edx+4] + mov eax, [edx+eax*4] + pop edx + ret 4 + +putimage_init32bpp: + shl eax, 2 + ret +align 16 +putimage_get32bpp: + lodsd + ret 4 + +putimage_init15bpp: +putimage_init16bpp: + add eax, eax + ret +align 16 +putimage_get15bpp: +; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000 + push ecx edx + movzx eax, word [esi] + add esi, 2 + mov ecx, eax + mov edx, eax + and eax, 0x1F + and ecx, 0x1F shl 5 + and edx, 0x1F shl 10 + shl eax, 3 + shl ecx, 6 + shl edx, 9 + or eax, ecx + or eax, edx + pop edx ecx + ret 4 + +align 16 +putimage_get16bpp: +; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000 + push ecx edx + movzx eax, word [esi] + add esi, 2 + mov ecx, eax + mov edx, eax + and eax, 0x1F + and ecx, 0x3F shl 5 + and edx, 0x1F shl 11 + shl eax, 3 + shl ecx, 5 + shl edx, 8 + or eax, ecx + or eax, edx + pop edx ecx + ret 4 + +; eax x beginning +; ebx y beginning +; ecx x end + ; edx y end +; edi color + +__sys_drawbar: + mov esi,[current_slot] + add eax,[esi+APPDATA.wnd_clientbox.left] + add ecx,[esi+APPDATA.wnd_clientbox.left] + add ebx,[esi+APPDATA.wnd_clientbox.top] + add edx,[esi+APPDATA.wnd_clientbox.top] + .forced: + inc [mouse_pause] +; call [disable_mouse] + cmp [SCR_MODE],word 0x12 + je dbv20 + sdbv20: + cmp [SCR_MODE],word 0100000000000000b + jge dbv20 + cmp [SCR_MODE],word 0x13 + je dbv20 + call vesa12_drawbar + dec [mouse_pause] + call [draw_pointer] + ret + dbv20: + call vesa20_drawbar + dec [mouse_pause] + call [draw_pointer] + ret + + + +kb_read: + + push ecx edx + + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kr_loop: + in al,0x64 + test al,1 + jnz kr_ready + loop kr_loop + mov ah,1 + jmp kr_exit + kr_ready: + push ecx + mov ecx,32 + kr_delay: + loop kr_delay + pop ecx + in al,0x60 + xor ah,ah + kr_exit: + + pop edx ecx + + ret + + +kb_write: + + push ecx edx + + mov dl,al +; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's +; kw_loop1: +; in al,0x64 +; test al,0x20 +; jz kw_ok1 +; loop kw_loop1 +; mov ah,1 +; jmp kw_exit +; kw_ok1: + in al,0x60 + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop: + in al,0x64 + test al,2 + jz kw_ok + loop kw_loop + mov ah,1 + jmp kw_exit + kw_ok: + mov al,dl + out 0x60,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop3: + in al,0x64 + test al,2 + jz kw_ok3 + loop kw_loop3 + mov ah,1 + jmp kw_exit + kw_ok3: + mov ah,8 + kw_loop4: + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop5: + in al,0x64 + test al,1 + jnz kw_ok4 + loop kw_loop5 + dec ah + jnz kw_loop4 + kw_ok4: + xor ah,ah + kw_exit: + + pop edx ecx + + ret + + +kb_cmd: + + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + c_wait: + in al,0x64 + test al,2 + jz c_send + loop c_wait + jmp c_error + c_send: + mov al,bl + out 0x64,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + c_accept: + in al,0x64 + test al,2 + jz c_ok + loop c_accept + c_error: + mov ah,1 + jmp c_exit + c_ok: + xor ah,ah + c_exit: + ret + + +setmouse: ; set mousepicture -pointer + ; ps2 mouse enable + + mov [MOUSE_PICTURE],dword mousepointer + + cli + + ret + +if used _rdtsc +_rdtsc: + bt [cpu_caps], CAPS_TSC + jnc ret_rdtsc + rdtsc + ret + ret_rdtsc: + mov edx,0xffffffff + mov eax,0xffffffff + ret +end if + +rerouteirqs: + + cli + + mov al,0x11 ; icw4, edge triggered + out 0x20,al + call pic_delay + out 0xA0,al + call pic_delay + + mov al,0x20 ; generate 0x20 + + out 0x21,al + call pic_delay + mov al,0x28 ; generate 0x28 + + out 0xA1,al + call pic_delay + + mov al,0x04 ; slave at irq2 + out 0x21,al + call pic_delay + mov al,0x02 ; at irq9 + out 0xA1,al + call pic_delay + + mov al,0x01 ; 8086 mode + out 0x21,al + call pic_delay + out 0xA1,al + call pic_delay + + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay + + mov ecx,0x1000 + cld +picl1: call pic_delay + loop picl1 + + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay + + cli + + ret + + +pic_delay: + + jmp pdl1 +pdl1: ret + + +sys_msg_board_str: + + pushad + @@: + cmp [esi],byte 0 + je @f + mov eax,1 + movzx ebx,byte [esi] + call sys_msg_board + inc esi + jmp @b + @@: + popad + ret + +sys_msg_board_byte: +; in: al = byte to display +; out: nothing +; destroys: nothing + pushad + mov ecx, 2 + shl eax, 24 + jmp @f + +sys_msg_board_word: +; in: ax = word to display +; out: nothing +; destroys: nothing + pushad + mov ecx, 4 + shl eax, 16 + jmp @f + +sys_msg_board_dword: +; in: eax = dword to display +; out: nothing +; destroys: nothing + pushad + mov ecx, 8 +@@: + push ecx + rol eax, 4 + push eax + and al, 0xF + cmp al, 10 + sbb al, 69h + das + mov bl, al + xor eax, eax + inc eax + call sys_msg_board + pop eax + pop ecx + loop @b + popad + ret + +uglobal + msg_board_data: times 4096 db 0 + msg_board_count dd 0x0 +endg + +sys_msg_board: + +; eax=1 : write : bl byte to write +; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al + + mov ecx, [msg_board_count] + cmp eax, 1 + jne .smbl1 + +if defined debug_com_base + + push dx ax + + @@: ; Wait for empty transmit register (yes, this slows down system..) + mov dx, debug_com_base+5 + in al, dx + test al, 1 shl 5 + jz @r + + mov dx, debug_com_base ; Output the byte + mov al, bl + out dx, al + + pop ax dx + +end if + + mov [msg_board_data+ecx],bl + inc ecx + and ecx, 4095 + mov [msg_board_count], ecx + mov [check_idle_semaphore], 5 + ret +.smbl1: + cmp eax, 2 + jne .smbl2 + test ecx, ecx + jz .smbl21 + mov eax, msg_board_data+1 + mov ebx, msg_board_data + movzx edx, byte [ebx] + call memmove + dec [msg_board_count] + mov [esp + 36], edx ;eax + mov [esp + 24], dword 1 + ret +.smbl21: + mov [esp+36], ecx + mov [esp+24], ecx +.smbl2: + ret + + + +sys_process_def: + mov edi, [CURRENT_TASK] + + dec eax ; 1 = set keyboard mode + jne no_set_keyboard_setup + + shl edi,8 + mov [edi+SLOT_BASE + APPDATA.keyboard_mode],bl + + ret + + no_set_keyboard_setup: + + dec eax ; 2 = get keyboard mode + jne no_get_keyboard_setup + + shl edi,8 + movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode] + + mov [esp+36],eax + + ret + + no_get_keyboard_setup: + + dec eax ; 3 = get keyboard ctrl, alt, shift + jne no_get_keyboard_cas + +; xor eax,eax +; movzx eax,byte [shift] +; movzx ebx,byte [ctrl] +; shl ebx,2 +; add eax,ebx +; movzx ebx,byte [alt] +; shl ebx,3 +; add eax,ebx + + ;// mike.dld [ + mov eax, [kb_state] + ;// mike.dld ] + + mov [esp+36],eax + + ret + + no_get_keyboard_cas: + + dec eax + jnz no_add_keyboard_hotkey + + mov eax, hotkey_list +@@: + cmp dword [eax+8], 0 + jz .found_free + add eax, 16 + cmp eax, hotkey_list+16*256 + jb @b + mov dword [esp+36], 1 + ret +.found_free: + mov [eax+8], edi + mov [eax+4], ecx + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov ecx, [ebx] + mov [eax], ecx + mov [ebx], eax + mov [eax+12], ebx + jecxz @f + mov [ecx+12], eax +@@: + and dword [esp+36], 0 + ret + +no_add_keyboard_hotkey: + + dec eax + jnz no_del_keyboard_hotkey + + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov eax, [ebx] +.scan: + test eax, eax + jz .notfound + cmp [eax+8], edi + jnz .next + cmp [eax+4], ecx + jz .found +.next: + mov eax, [eax] + jmp .scan +.notfound: + mov dword [esp+36], 1 + ret +.found: + mov ecx, [eax] + jecxz @f + mov edx, [eax+12] + mov [ecx+12], edx +@@: + mov ecx, [eax+12] + mov edx, [eax] + mov [ecx], edx + xor edx, edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax], edx + mov [esp+36], edx + ret + +no_del_keyboard_hotkey: + ret + + +align 4 + +sys_gs: ; direct screen access + + cmp eax,1 ; resolution + jne no_gs1 + mov eax,[Screen_Max_X] + shl eax,16 + mov ax,[Screen_Max_Y] + add eax,0x00010001 + mov [esp+36],eax + ret + no_gs1: + + cmp eax,2 ; bits per pixel + jne no_gs2 + movzx eax,byte [ScreenBPP] + mov [esp+36],eax + ret + no_gs2: + + cmp eax,3 ; bytes per scanline + jne no_gs3 + mov eax,[BytesPerScanLine] + mov [esp+36],eax + ret + no_gs3: + + or [esp+36],dword -1 + ret + + +align 4 ; PCI functions + +sys_pci: + + call pci_api + mov [esp+36],eax + ret + + +align 4 ; system functions + +syscall_setpixel: ; SetPixel + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, [TASK_BASE] + add eax, [edx-twdw+WDATA.box.left] + add ebx, [edx-twdw+WDATA.box.top] + mov edi, [current_slot] + add eax, [edi+APPDATA.wnd_clientbox.left] + add ebx, [edi+APPDATA.wnd_clientbox.top] + xor edi, edi ; no force +; mov edi, 1 + call [_display.disable_mouse] + jmp [putpixel] + +align 4 + +syscall_writetext: ; WriteText + + mov eax,[TASK_BASE] + mov ebp,[eax-twdw+WDATA.box.left] + push esi + mov esi,[current_slot] + add ebp,[esi+APPDATA.wnd_clientbox.left] + shl ebp,16 + add ebp,[eax-twdw+WDATA.box.top] + add bp,word[esi+APPDATA.wnd_clientbox.top] + pop esi + add ebx,ebp + mov eax,edi + xor edi,edi + jmp dtext + +align 4 + +syscall_openramdiskfile: ; OpenRamdiskFile + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, 12 + call fileread + mov [esp+32], eax + ret + +align 4 + +syscall_drawrect: ; DrawRect + + mov edi, edx ; color + gradient + and edi, 0x80FFFFFF + test bx, bx ; x.size + je .drectr + test cx, cx ; y.size + je .drectr + + mov eax, ebx ; bad idea + mov ebx, ecx + + movzx ecx, ax ; ecx - x.size + shr eax, 16 ; eax - x.coord + movzx edx, bx ; edx - y.size + shr ebx, 16 ; ebx - y.coord + mov esi, [current_slot] + + add eax, [esi + APPDATA.wnd_clientbox.left] + add ebx, [esi + APPDATA.wnd_clientbox.top] + add ecx, eax + add edx, ebx + jmp [drawbar] +.drectr: + ret + +align 4 +syscall_getscreensize: ; GetScreenSize + mov ax, [Screen_Max_X] + shl eax, 16 + mov ax, [Screen_Max_Y] + mov [esp + 32], eax + ret + +align 4 + +syscall_cdaudio: ; CD + + cmp ebx, 4 + jb .audio + jz .eject + cmp ebx, 5 + jnz .ret +.load: + call .reserve + call LoadMedium + ;call .free + jmp .free +; ret +.eject: + call .reserve + call clear_CD_cache + call allow_medium_removal + call EjectMedium +; call .free + jmp .free +; ret +.audio: + call sys_cd_audio + mov [esp+36-4],eax +.ret: + ret + +.reserve: + call reserve_cd + mov eax, ecx + shr eax, 1 + and eax, 1 + inc eax + mov [ChannelNumber], ax + mov eax, ecx + and eax, 1 + mov [DiskNumber], al + call reserve_cd_channel + and ebx, 3 + inc ebx + mov [cdpos], ebx + add ebx, ebx + mov cl, 8 + sub cl, bl + mov al, [DRIVE_DATA+1] + shr al, cl + test al, 2 + jz .free;.err + ret +.free: + call free_cd_channel + and [cd_status], 0 + ret +.err: + call .free +; pop eax + ret + +align 4 + +syscall_getpixel: ; GetPixel + mov ecx, [Screen_Max_X] + inc ecx + xor edx, edx + mov eax, ebx + div ecx + mov ebx, edx + xchg eax, ebx + call dword [GETPIXEL] ; eax - x, ebx - y + mov [esp + 32], ecx + ret + +align 4 + +syscall_getarea: +;eax = 36 +;ebx = pointer to bufer for img BBGGRRBBGGRR... +;ecx = [size x]*65536 + [size y] +;edx = [start x]*65536 + [start y] + pushad + inc [mouse_pause] +; Check of use of the hardware cursor. + cmp [_display.disable_mouse],__sys_disable_mouse + jne @f +; Since the test for the coordinates of the mouse should not be used, +; then use the call [disable_mouse] is not possible! + cmp dword [MOUSE_VISIBLE],dword 0 + jne @f + pushf + cli + call draw_mouse_under + popf + mov [MOUSE_VISIBLE],dword 1 +@@: + mov edi,ebx + mov eax,edx + shr eax,16 + mov ebx,edx + and ebx,0xffff + dec eax + dec ebx + ; eax - x, ebx - y + mov edx,ecx + + shr ecx,16 + and edx,0xffff + mov esi,ecx + ; ecx - size x, edx - size y + + mov ebp,edx + dec ebp + lea ebp,[ebp*3] + + imul ebp,esi + + mov esi,ecx + dec esi + lea esi,[esi*3] + + add ebp,esi + add ebp,edi + + add ebx,edx + +.start_y: + push ecx edx +.start_x: + push eax ebx ecx + add eax,ecx + + call dword [GETPIXEL] ; eax - x, ebx - y + + mov [ebp],cx + shr ecx,16 + mov [ebp+2],cl + + pop ecx ebx eax + sub ebp,3 + dec ecx + jnz .start_x + pop edx ecx + dec ebx + dec edx + jnz .start_y + dec [mouse_pause] +; Check of use of the hardware cursor. + cmp [_display.disable_mouse],__sys_disable_mouse + jne @f + call [draw_pointer] +@@: + popad + ret + +align 4 + +syscall_drawline: ; DrawLine + + mov edi, [TASK_BASE] + movzx eax, word[edi-twdw+WDATA.box.left] + mov ebp, eax + mov esi, [current_slot] + add ebp, [esi+APPDATA.wnd_clientbox.left] + add ax, word[esi+APPDATA.wnd_clientbox.left] + add ebp,ebx + shl eax, 16 + movzx ebx, word[edi-twdw+WDATA.box.top] + add eax, ebp + mov ebp, ebx + add ebp, [esi+APPDATA.wnd_clientbox.top] + add bx, word[esi+APPDATA.wnd_clientbox.top] + add ebp, ecx + shl ebx, 16 + xor edi, edi + add ebx, ebp + mov ecx, edx + jmp [draw_line] + +align 4 + +syscall_getirqowner: ; GetIrqOwner + + cmp ebx,16 + jae .err + + cmp [irq_rights + 4 * ebx], dword 2 + je .err + + mov eax,[4 * ebx + irq_owner] + mov [esp+32],eax + + ret +.err: + or dword [esp+32], -1 + ret + +align 4 + +syscall_reserveportarea: ; ReservePortArea and FreePortArea + + call r_f_port_area + mov [esp+32],eax + ret + +align 4 + +syscall_threads: ; CreateThreads + + call sys_threads + mov [esp+36],eax + ret + +align 4 + +stack_driver_stat: + + call app_stack_handler ; Stack status + +; mov [check_idle_semaphore],5 ; enable these for zero delay +; call change_task ; between sent packet + + mov [esp+36],eax + ret + +align 4 + +socket: ; Socket interface + call app_socket_handler + +; mov [check_idle_semaphore],5 ; enable these for zero delay +; call change_task ; between sent packet + + mov [esp+36],eax + mov [esp+24],ebx + ret + +align 4 + +read_from_hd: ; Read from hd - fn not in use + + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start + add eax,[edi] + add ecx,[edi] + add edx,[edi] + call file_read + + mov [esp+36],eax + mov [esp+24],ebx + + ret + +paleholder: + ret + +align 4 +set_screen: + cmp eax, [Screen_Max_X] + jne .set + + cmp edx, [Screen_Max_Y] + jne .set + ret +.set: + pushfd + cli + + mov [Screen_Max_X], eax + mov [Screen_Max_Y], edx + mov [BytesPerScanLine], ecx + + mov [screen_workarea.right],eax + mov [screen_workarea.bottom], edx + + push ebx + push esi + push edi + + pushad + + stdcall kernel_free, [_WinMapAddress] + + mov eax, [_display.width] + mul [_display.height] + mov [_WinMapSize], eax + + stdcall kernel_alloc, eax + mov [_WinMapAddress], eax + test eax, eax + jz .epic_fail + + popad + + call repos_windows + xor eax, eax + xor ebx, ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + pop edi + pop esi + pop ebx + + popfd + ret + +.epic_fail: + hlt ; Houston, we've had a problem + +; --------------- APM --------------------- +apm_entry dp 0 +apm_vf dd 0 +align 4 +sys_apm: + cmp word [apm_vf], 0 ; Check APM BIOS enable + jne @f + or [esp + 48], byte 1 ; error + mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported + ret + +@@: + xchg eax, ecx + xchg ebx, ecx + + cmp al, 3 + ja @f + and [esp + 48], byte 0xfe ; emulate func 0..3 as func 0 + mov eax, [apm_vf] + mov [esp + 36], eax + shr eax, 16 + mov [esp + 32], eax + ret + +@@: + + mov esi, [master_tab+(OS_BASE shr 20)] + xchg [master_tab], esi + push esi + mov edi, cr3 + mov cr3, edi ;flush TLB + + call pword [apm_entry] ; call APM BIOS + + xchg eax, [esp] + mov [master_tab], eax + mov eax, cr3 + mov cr3, eax + pop eax + + mov [esp + 8 ], edi + mov [esp + 12], esi + mov [esp + 24], ebx + mov [esp + 28], edx + mov [esp + 32], ecx + mov [esp + 36], eax + setc al + and [esp + 48], byte 0xfe + or [esp + 48], al + + + ret +; ----------------------------------------- + +align 4 + +undefined_syscall: ; Undefined system call + mov [esp + 32], dword -1 + ret + +align 4 +system_shutdown: ; shut down the system + + cmp byte [BOOT_VAR+0x9030], 1 + jne @F + ret +@@: + call stop_all_services + push 3 ; stop playing cd + pop eax + call sys_cd_audio + +yes_shutdown_param: + cli + + mov eax, kernel_file ; load kernel.mnt to 0x7000:0 + push 12 + pop esi + xor ebx,ebx + or ecx,-1 + mov edx, OS_BASE+0x70000 + call fileread + + mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0 + mov edi,OS_BASE+0x40000 + mov ecx,1000 + rep movsb + + mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff + mov edi, OS_BASE + mov ecx,0x10000/4 + cld + rep movsd + + call restorefatchain + + mov al, 0xFF + out 0x21, al + out 0xA1, al + +if 0 + mov word [OS_BASE+0x467+0],pr_mode_exit + mov word [OS_BASE+0x467+2],0x1000 + + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al + + mov al,0xFE + out 0x64,al + + hlt + jmp $-1 + +else + cmp byte [OS_BASE + 0x9030], 2 + jnz no_acpi_power_off + +; scan for RSDP +; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA). + movzx eax, word [OS_BASE + 0x40E] + shl eax, 4 + jz @f + mov ecx, 1024/16 + call scan_rsdp + jnc .rsdp_found +@@: +; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh. + mov eax, 0xE0000 + mov ecx, 0x2000 + call scan_rsdp + jc no_acpi_power_off +.rsdp_found: + mov esi, [eax+16] ; esi contains physical address of the RSDT + mov ebp, [ipc_tmp] + stdcall map_page, ebp, esi, PG_MAP + lea eax, [esi+1000h] + lea edx, [ebp+1000h] + stdcall map_page, edx, eax, PG_MAP + and esi, 0xFFF + add esi, ebp + cmp dword [esi], 'RSDT' + jnz no_acpi_power_off + mov ecx, [esi+4] + sub ecx, 24h + jbe no_acpi_power_off + shr ecx, 2 + add esi, 24h +.scan_fadt: + lodsd + mov ebx, eax + lea eax, [ebp+2000h] + stdcall map_page, eax, ebx, PG_MAP + lea eax, [ebp+3000h] + add ebx, 0x1000 + stdcall map_page, eax, ebx, PG_MAP + and ebx, 0xFFF + lea ebx, [ebx+ebp+2000h] + cmp dword [ebx], 'FACP' + jz .fadt_found + loop .scan_fadt + jmp no_acpi_power_off +.fadt_found: +; ebx is linear address of FADT + mov edi, [ebx+40] ; physical address of the DSDT + lea eax, [ebp+4000h] + stdcall map_page, eax, edi, PG_MAP + lea eax, [ebp+5000h] + lea esi, [edi+0x1000] + stdcall map_page, eax, esi, PG_MAP + and esi, 0xFFF + sub edi, esi + cmp dword [esi+ebp+4000h], 'DSDT' + jnz no_acpi_power_off + mov eax, [esi+ebp+4004h] ; DSDT length + sub eax, 36+4 + jbe no_acpi_power_off + add esi, 36 +.scan_dsdt: + cmp dword [esi+ebp+4000h], '_S5_' + jnz .scan_dsdt_cont + cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode + jnz .scan_dsdt_cont + mov dl, [esi+ebp+4000h+6] + cmp dl, 4 ; _S5_ package must contain 4 bytes + ; ...in theory; in practice, VirtualBox has 2 bytes + ja .scan_dsdt_cont + cmp dl, 1 + jb .scan_dsdt_cont + lea esi, [esi+ebp+4000h+7] + xor ecx, ecx + cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx + jz @f + cmp byte [esi], 0xA + jnz no_acpi_power_off + inc esi + mov cl, [esi] +@@: + inc esi + cmp dl, 2 + jb @f + cmp byte [esi], 0 + jz @f + cmp byte [esi], 0xA + jnz no_acpi_power_off + inc esi + mov ch, [esi] +@@: + jmp do_acpi_power_off +.scan_dsdt_cont: + inc esi + cmp esi, 0x1000 + jb @f + sub esi, 0x1000 + add edi, 0x1000 + push eax + lea eax, [ebp+4000h] + stdcall map_page, eax, edi, PG_MAP + push PG_MAP + lea eax, [edi+1000h] + push eax + lea eax, [ebp+5000h] + push eax + stdcall map_page + pop eax +@@: + dec eax + jnz .scan_dsdt + jmp no_acpi_power_off +do_acpi_power_off: + mov edx, [ebx+48] + test edx, edx + jz .nosmi + mov al, [ebx+52] + out dx, al + mov edx, [ebx+64] +@@: + in ax, dx + test al, 1 + jz @b +.nosmi: + and cx, 0x0707 + shl cx, 2 + or cx, 0x2020 + mov edx, [ebx+64] + in ax, dx + and ax, 203h + or ah, cl + out dx, ax + mov edx, [ebx+68] + test edx, edx + jz @f + in ax, dx + and ax, 203h + or ah, ch + out dx, ax +@@: + jmp $ + + +no_acpi_power_off: + mov word [OS_BASE+0x467+0],pr_mode_exit + mov word [OS_BASE+0x467+2],0x1000 + + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al + + mov al,0xFE + out 0x64,al + + hlt + jmp $-1 + +scan_rsdp: + add eax, OS_BASE +.s: + cmp dword [eax], 'RSD ' + jnz .n + cmp dword [eax+4], 'PTR ' + jnz .n + xor edx, edx + xor esi, esi +@@: + add dl, [eax+esi] + inc esi + cmp esi, 20 + jnz @b + test dl, dl + jz .ok +.n: + add eax, 10h + loop .s + stc +.ok: + ret +end if + +include "data32.inc" + +__REV__ = __REV + +uglobals_size = $ - endofcode +diff16 "end of kernel code",0,$ diff --git a/kernel/tags/kolibri0.7.7.0/kernel32.inc b/kernel/tags/kolibri0.7.7.0/kernel32.inc new file mode 100644 index 000000000..195c722d4 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/kernel32.inc @@ -0,0 +1,279 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; KERNEL32.INC ;; +;; ;; +;; Included 32 bit kernel files for MenuetOS ;; +;; ;; +;; This file is kept separate as it will be easier to ;; +;; maintain and compile with an automated SETUP program ;; +;; in the future. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;struc db [a] { common . db a +; if ~used . +; display 'not used db: ',`.,13,10 +; end if } +;struc dw [a] { common . dw a +; if ~used . +; display 'not used dw: ',`.,13,10 +; end if } +;struc dd [a] { common . dd a +; if ~used . +; display 'not used dd: ',`.,13,10 +; end if } +;struc dp [a] { common . dp a +; if ~used . +; display 'not used dp: ',`.,13,10 +; end if } +;struc dq [a] { common . dq a +; if ~used . +; display 'not used dq: ',`.,13,10 +; end if } +;struc dt [a] { common . dt a +; if ~used . +; display 'not used dt: ',`.,13,10 +; end if } + +struc RECT { + .left dd ? + .top dd ? + .right dd ? + .bottom dd ? +} +virtual at 0 + RECT RECT +end virtual + +struc BOX { + .left dd ? + .top dd ? + .width dd ? + .height dd ? +} +virtual at 0 + BOX BOX +end virtual + +struc DISPMODE { + .width rw 1 + .height rw 1 + .bpp rw 1 + .freq rw 1 +} + +; constants definition +WSTATE_NORMAL = 00000000b +WSTATE_MAXIMIZED = 00000001b +WSTATE_MINIMIZED = 00000010b +WSTATE_ROLLEDUP = 00000100b + +WSTATE_REDRAW = 00000001b +WSTATE_WNDDRAWN = 00000010b + +WSTYLE_HASCAPTION = 00010000b +WSTYLE_CLIENTRELATIVE = 00100000b + +struc TASKDATA +{ + .event_mask dd ? + .pid dd ? + dw ? + .state db ? + db ? + dw ? + .wnd_number db ? + db ? + .mem_start dd ? + .counter_sum dd ? + .counter_add dd ? + .cpu_usage dd ? +} +virtual at 0 + TASKDATA TASKDATA +end virtual + +; structures definition +struc WDATA { + .box BOX + .cl_workarea dd ? + .cl_titlebar dd ? + .cl_frames dd ? + .reserved db ? + .fl_wstate db ? + .fl_wdrawn db ? + .fl_redraw db ? +} +virtual at 0 + WDATA WDATA +end virtual +label WDATA.fl_wstyle byte at 0x13 + +struc APPDATA +{ + .app_name db 11 dup(?) + db 5 dup(?) + + .fpu_state dd ? ;+16 + .ev_count_ dd ? ;unused ;+20 + .exc_handler dd ? ;+24 + .except_mask dd ? ;+28 + .pl0_stack dd ? ;unused ;+32 + .heap_base dd ? ;+36 + .heap_top dd ? ;+40 + .cursor dd ? ;+44 + .fd_ev dd ? ;+48 + .bk_ev dd ? ;+52 + .fd_obj dd ? ;+56 + .bk_obj dd ? ;+60 + .saved_esp dd ? ;+64 + .io_map rd 2 ;+68 + .dbg_state dd ? ;+76 + .cur_dir dd ? ;+80 + .wait_timeout dd ? ;+84 + .saved_esp0 dd ? ;+88 + .wait_begin dd ? ;+92 +++ + .wait_test dd ? ;+96 +++ + .wait_param dd ? ;+100 +++ + .tls_base dd ? ;+104 + .dlls_list_ptr dd ? ;+108 + db 16 dup(?) ;+112 + + .wnd_shape dd ? ;+128 + .wnd_shape_scale dd ? ;+132 + dd ? ;+136 + .mem_size dd ? ;+140 + .saved_box BOX + .ipc_start dd ? + .ipc_size dd ? + .event_mask dd ? + .debugger_slot dd ? + dd ? + .keyboard_mode db ? + db 3 dup(?) + .dir_table dd ? + .dbg_event_mem dd ? + .dbg_regs: + .dbg_regs.dr0 dd ? + .dbg_regs.dr1 dd ? + .dbg_regs.dr2 dd ? + .dbg_regs.dr3 dd ? + .dbg_regs.dr7 dd ? + .wnd_caption dd ? + .wnd_clientbox BOX +} +virtual at 0 + APPDATA APPDATA +end virtual + +;// mike.dld, 2006-29-01 ] + + +; Core functions +include "core/sync.inc" ; macros for synhronization objects +include "core/sys32.inc" ; process management +include "core/sched.inc" ; process scheduling +include "core/syscall.inc" ; system call +include "core/fpu.inc" ; all fpu/sse support +include "core/memory.inc" +include "core/heap.inc" ; kernel and app heap +include "core/malloc.inc" ; small kernel heap +include "core/taskman.inc" +include "core/dll.inc" +include "core/peload.inc" ; +include "core/exports.inc" +include "core/string.inc" +include "core/v86.inc" ; virtual-8086 manager + +; GUI stuff +include "gui/window.inc" +include "gui/event.inc" +include "gui/font.inc" +include "gui/button.inc" + +; shutdown + +; file system + +include "fs/fs.inc" ; syscall +include "fs/fat32.inc" ; read / write for fat32 filesystem +include "fs/ntfs.inc" ; read / write for ntfs filesystem +include "fs/fat12.inc" ; read / write for fat12 filesystem +include "blkdev/rd.inc" ; ramdisk read /write +include "fs/fs_lfn.inc" ; syscall, version 2 +include "fs/iso9660.inc" ; read for iso9660 filesystem CD + +; sound + +include "sound/playnote.inc" ; player Note for Speaker PC + +; display + +include "video/vesa12.inc" ; Vesa 1.2 functions +include "video/vesa20.inc" ; Vesa 2.0 functions +include "video/vga.inc" ; VGA 16 color functions +include "video/cursors.inc" ; cursors functions + +; Network Interface & TCPIP Stack + +include "network/stack.inc" + +;include "drivers/uart.inc" + + +; Mouse pointer + +include "gui/mouse.inc" + +; Window skinning + +include "gui/skincode.inc" + +; Pci functions + +include "bus/pci/pci32.inc" + +; Floppy drive controller + +include "blkdev/fdc.inc" +include "blkdev/flp_drv.inc" + +; IDE cache +include "blkdev/ide_cache.inc" + +; HD drive controller +include "blkdev/hd_drv.inc" + +; CD drive controller + +include "blkdev/cdrom.inc" +include "blkdev/cd_drv.inc" + +; Character devices + +include "hid/keyboard.inc" +include "hid/mousedrv.inc" + +; setting date,time,clock and alarm-clock + +include "hid/set_dtc.inc" + +;% -include + +;parser file names +include "fs/parse_fn.inc" + +; work with conf lib +include "core/conf_lib.inc" + +; load external lib +include "core/ext_lib.inc" + +; list of external functions +include "imports.inc" diff --git a/kernel/tags/kolibri0.7.7.0/kglobals.inc b/kernel/tags/kolibri0.7.7.0/kglobals.inc new file mode 100644 index 000000000..3299a5ebe --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/kglobals.inc @@ -0,0 +1,69 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;------------------------------------------------------------------ +; use "iglobal" for inserting initialized global data definitions. +;------------------------------------------------------------------ +macro iglobal { + IGlobals equ IGlobals, + macro __IGlobalBlock { } + +macro iglobal_nested { + IGlobals equ IGlobals, + macro __IGlobalBlock \{ } + +;------------------------------------------------------------- +; use 'uglobal' for inserting uninitialized global definitions. +; even when you define some data values, these variables +; will be stored as uninitialized data. +;------------------------------------------------------------- +macro uglobal { + UGlobals equ UGlobals, + macro __UGlobalBlock { } + +macro uglobal_nested { + UGlobals equ UGlobals, + macro __UGlobalBlock \{ } + +endg fix } ; Use endg for ending iglobal and uglobal blocks. +endg_nested fix \} + +macro IncludeIGlobals{ + macro IGlobals dummy,[n] \{ __IGlobalBlock + purge __IGlobalBlock \} + match I, IGlobals \{ I \} } + + +macro IncludeUGlobals{ + macro UGlobals dummy,[n] \{ + \common + \local begin, size + begin = $ + virtual at $ + \forward + __UGlobalBlock + purge __UGlobalBlock + \common + size = $ - begin + end virtual + rb size + \} + match U, UGlobals \{ U \} } + +macro IncludeAllGlobals { + IncludeIGlobals + IncludeUGlobals +} + +iglobal +endg + +uglobal +endg diff --git a/kernel/tags/kolibri0.7.7.0/macros.inc b/kernel/tags/kolibri0.7.7.0/macros.inc new file mode 100644 index 000000000..e99a17ec9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/macros.inc @@ -0,0 +1,106 @@ + +__REV = 0 + +macro $Revision a { + match =: Num =$,a \{ + if __REV < Num + __REV = Num + end if + \} +} + +$Revision$ + + +; structure definition helper +macro struct name, [arg] + { + common + name@struct equ name + struc name arg { + } + +macro struct_helper name + { + match xname,name + \{ + virtual at 0 + xname xname + sizeof.#xname = $ - xname + name equ sizeof.#xname + end virtual + \} + } + +ends fix } struct_helper name@struct + +;// mike.dld, 2006-29-01 [ + +; macros definition +macro diff16 title,l1,l2 +{ + local s,d + s = l2-l1 + display title,': 0x' + repeat 16 + d = 48 + s shr ((16-%) shl 2) and $0F + if d > 57 + d = d + 65-57-1 + end if + display d + end repeat + display 13,10 +} +macro diff10 title,l1,l2 + { + local s,d,z,m + s = l2-l1 + z = 0 + m = 1000000000 + display title,': ' + repeat 10 + d = '0' + s / m + s = s - (s/m)*m + m = m / 10 + if d <> '0' + z = 1 + end if + if z <> 0 + display d + end if + end repeat + display 13,10 + } + +include 'kglobals.inc' + +; \begin{diamond}[29.09.2006] +; may be useful for kernel debugging +; example 1: +; dbgstr 'Hello, World!' +; example 2: +; dbgstr 'Hello, World!', save_flags +macro dbgstr string*, f +{ +local a +iglobal_nested +a db 'K : ',string,13,10,0 +endg_nested +if ~ f eq + pushfd +end if + push esi + mov esi, a + call sys_msg_board_str + pop esi +if ~ f eq + popfd +end if +} +; \end{diamond}[29.09.2006] + +macro Mov op1,op2,op3 ; op1 = op2 = op3 + { + mov op2,op3 + mov op1,op2 + } diff --git a/kernel/tags/kolibri0.7.7.0/make.sh b/kernel/tags/kolibri0.7.7.0/make.sh new file mode 100755 index 000000000..d49fd1221 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/make.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# This script does for linux the same as build.bat for DOS, +# it compiles the KoOS kernel, hopefully ;-) + +CLANG=$1; + +usage() +{ + echo "Usage: make.sh [en|ru|ge|et]" + exit 1 +} + +compile() +{ + fasm -m 65536 kernel.asm bin/kernel.mnt + rm -f lang.inc + exit 0 +} + + +if [ ! $CLANG ] ; then + usage +fi + +for i in "en" "ru" "ge" "et"; do + if [ $i == $CLANG ] ; then + echo "lang fix $i" > lang.inc + compile + fi +done +usage + + diff --git a/kernel/tags/kolibri0.7.7.0/makefile b/kernel/tags/kolibri0.7.7.0/makefile new file mode 100644 index 000000000..f2d916f76 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/makefile @@ -0,0 +1,48 @@ +FASM=fasm +FLAGS=-m 65536 +languages=en|ru|ge|et +drivers_src=sound sis infinity uart ati2d vmode com_mouse +skins_src=default + +.PHONY: all kernel drivers skins clean + +all: kernel drivers skins + +kernel: check_lang + @echo "*** building kernel with language '$(lang)' ..." + @mkdir -p bin + @echo "lang fix $(lang)" > lang.inc + @echo "--- building 'bin/kernel.mnt' ..." + @$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt + @rm -f lang.inc + +drivers: + @echo "*** building drivers ..." + @mkdir -p bin/drivers + @cd drivers; for f in $(drivers_src); do \ + echo "--- building 'bin/drivers/$${f}.obj' ..."; \ + $(FASM) $(FLAGS) $${f}.asm ../bin/drivers/$${f}.obj; \ + done + @mv bin/drivers/vmode.obj bin/drivers/vmode.mdr + +skins: + @echo "*** building skins ..." + @mkdir -p bin/skins + @cd skin; for f in $(skins_src); do \ + echo "--- building 'bin/skins/$${f}.skn' ..."; \ + $(FASM) $(FLAGS) $${f}.asm ../bin/skins/$${f}.skn; \ + done + +check_lang: + @case "$(lang)" in \ + $(languages)) \ + ;; \ + *) \ + echo "*** error: language is incorrect or not specified"; \ + exit 1; \ + ;; \ + esac + +clean: + rm -rf bin + rm -f lang.inc diff --git a/kernel/tags/kolibri0.7.7.0/memmap.inc b/kernel/tags/kolibri0.7.7.0/memmap.inc new file mode 100644 index 000000000..e54718c0f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/memmap.inc @@ -0,0 +1,248 @@ +; +; MEMORY MAP +; +; Boot: +; +; 0:9000 byte bits per pixel +; 0:9001 word scanline length +; 0:9008 word vesa video mode +; 0:900A word X res +; 0:900C word Y res +; 0:9010 byte mouse port - not used +; 0:9014 dword Vesa 1.2 pm bank switch +; 0:9018 dword Vesa 2.0 LFB address +; 0:901C byte 0 or 1 : enable MTRR graphics acceleration +; 0:901D byte not used anymore (0 or 1 : enable system log display) +; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled +; 0:901F byte DMA write : 1=yes, 2=no +; 0:9020 8bytes pci data +; 0:9030 byte VRR start enabled 1, 2-no +; 0:9031 word IDEContrRegsBaseAddr +; 0x9040 - dword - entry point of APM BIOS +; 0x9044 - word - version (BCD) +; 0x9046 - word - flags +; 0:907F byte number of BIOS hard disks +; 0:9080 Nbytes BIOS hard disks +; 0:9100 word available physical memory map: number of blocks +; 0:9104 available physical memory map: blocks +; +; Runtime: +; +; 0x00000000 -> 0x7FFFFFFF application 2Gb + +; 0x80000000 -> 0FFF physical page zero - do not write +; (used by int 13h in some configurations) +; +; 0x80001000 -> 2FFF window_data - 256 entries +; +; 0000 dword x start +; 0004 dword y start +; 0008 dword x size +; 000C dword y size +; 0010 dword color of work area +; 0014 dword color of grab bar +; 0018 dword color of frames +; 001C dword window flags, +30 = window drawn, +31 redraw flag +; +; 3000 -> 4FFF task list - 256 entries +; +; 00 dword process count +; 04 dword no of processes +; 10 dword base of running process at 0x3000+ +; +; 20 dword application event mask +; 24 dword PID - process identification number +; 2a byte slot state: 0=running, 1,2=suspended +; 3=zombie, 4=terminate, +; 5=waiting for event, 9 = not used +; 2e byte window number on screen +; 30 dword exact position in memory +; 34 dword counter sum +; 38 dword time stamp counter add +; 3c dword cpu usage in cpu timer tics +; +; +; 5000 -> 68FF free +; 6900 -> 6EFF saved picture under mouse pointer +; +; 6F00 -> 6FFF free +; +; 7000 -> 7FFF used CD driver +; +; 8000 -> A3FF used FLOPPY driver +; +; A400 -> B0FF free + +; B100 -> B307 IDT for int_0x00..int_0x40 + +; B308 -> BFFF free + +; C000 -> C3FF window stack C000 no of windows - all in words +; C402 -> C7FF window position in stack +; D000 -> D1FF FDC controller +; D200 -> D3FF FDC controller for Fat12 +; D400 -> DFFF free +; E000 byte multitasking started +; E020 dword putpixel address +; E024 dword getpixel address +; E030 dword Vesa 1.2 pm bank switch address +; F200 dword mousepicture -pointer +; F204 dword mouse appearance counter +; F300 dword x & y temp for windowmove +; F400 byte no of keys in buffer +; F401 byte 'buffer' +; F402 -> F4FF reserved for keys +; F500 byte no of buttons in buffer +; F501 dword 'buffer' +; F502 -> F5FF reserved for buttons +; F600 dword tsc / second +; F604 byte mouse port: 1 ps2, 2 com1, 3 com2 +; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y +; FB10 -> FB17 mouse color mem +; FB21 x move +; FB22 y move +; FB28 high bits temp +; FB30 color temp +; FB40 byte buttons down +; FB44 byte 0 mouse down -> do not draw +; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under +; FBF1 byte bits per pixel +; FC00 -> FCFE com1/ps2 buffer +; FCFF com1/ps2 buffer count starting from FC00 +; FE00 dword screen x size +; FE04 dword screen y size +; FE08 dword screen y multiplier +; FE0C dword screen mode +; FE80 dword address of LFB in physical +; FE84 dword address of applications memory start in physical +; FE88 dword address of button list +; FE8C dword memory to use +; FF00 byte 1 = system shutdown request +; FF01 dword free +; FFF0 byte 1 = redraw background request from app +; FFF1 byte 1 = diskette int occur +; FFF2 write and read bank in screen +; FFF4 byte 0 if first mouse draw & do not return picture under +; FFF5 byte 1 do not draw pointer +; FFFF byte do not change task for 1/100 sec. +; +; 0x80010000 -> 6CBFF kernel, 32-bit run-time code (up to 371 Kb) + +; 0x8006CC00 -> 6DBFF stack at boot time (4Kb) +; +; 0x8006DC00 -> 6E5FF basic text font II +; 0x8006E600 -> 6Efff basic text font I +; 0x8006F000 -> 6FFFF main page directory + +; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79) +; 0x80080000 -> 8FFFF additional app info, in 256 byte steps - 256 entries +; +; 00 11db name of app running +; 0x10 dword pointer to fpu save area +; 0x14 dword event count +; 0x18 dword user fpu exceptoins handler +; 0x1c dword user sse exceptions handler +; 20 dword PL0 stack base +; 24 dword user heap base +; 28 dword user heap top +; 2c dword window cursor handle +; 30 dword first event in list +; 34 dword last event in list +; 38 dword first kernel object in list +; 3c dword last kernel object in list +; 40 dword thread esp +; 44 dword io permission map page 0 +; 48 dword io permission map page 1 +; 4c dword debug state: 1= load debug registers +; 50 dword current directory ptr +; 54 dword wait timeout +; 58 dword thread TSS._esp0 (= pl0 stack base + size except for V86) +; 5C-7F unused +; +; 80 dword address of random shaped window area +; 84 byte shape area scale +; 88 dword free +; 8C dword application memory size +; 90 dword window X position save +; 94 dword window Y position save +; 98 dword window X size save +; 9C dword window Y size save +; A0 dword IPC memory start +; A4 dword IPC memory size +; A8 dword event bits: mouse, stack,.. +; AC dword 0 or debugger slot +; B0 dword free +; B4 byte keyboard mode: 0 = keymap, 1 = scancodes +; B8 dword physical address of directory table +; BC dword address of debug event memory +; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 +; +; 0x80090000 -> 9FFFF tmp +; 0x800A0000 -> AFFFF screen access area +; 0x800B0000 -> FFFFF bios rest in peace -area +; 0x80100000 -> 27FFFF diskette image +; 0x80280000 -> 281FFF ramdisk fat +; 0x80282000 -> 283FFF floppy fat +; +; 0x80284000 -> 28BFFF HDD DMA AREA +; 0x8028C000 -> 297FFF free (48 Kb) +; +; 0x80298000 -> 29ffff auxiliary table for background smoothing code +; +; 0x802A0000 -> 2B00ff wav device data +; 0x802C0000 -> 2C3fff button info +; +; 0000 word number of buttons +; first button entry at 0x10 +; +0000 word process number +; +0002 word button id number : bits 00-15 +; +0004 word x start +; +0006 word x size +; +0008 word y start +; +000A word y size +; +000C word button id number : bits 16-31 +; +; 0x802C4000 -> 2CFFFF free (48Kb) +; +; 0x802D0000 -> 2DFFFF reserved port area +; +; 0000 dword no of port areas reserved +; 0010 dword process id +; dword start port +; dword end port +; dword 0 +; +; 0x802E0000 -> 2EFFFF irq data area +; 0x802F0000 -> 2FFFFF low memory save +; +; 0x80300000 -> 31FFFF tcp memory 128 Kb +; 0x80320000 -> 327FFF tcp memory 32 Kb +; +; 0x80328000 -> 32FFFF !vrr driver 32 Kb + +; 0x80330000 -> 377FFF skin data + +; 0x80338000 -> 33AFFF draw data - 256 entries +; 00 dword draw limit - x start +; 04 dword draw limit - y start +; 08 dword draw limit - x end +; 0C dword draw limit - y end + +; 0x8033C000 -> 47BFFF display info + +; 0x8047CF80 -> 47CFFF TSS 128 bytes +; 0x8047D000 -> 47EFFF IO map for (8192*8)=65536 ports + +; 0x8047F000 -> 48FFFF page map max 128 Kb +; + +; 0x80800000 -> kernel heap +; 0x81FFFFFF heap min limit +; 0xFDBFFFFF heap max limit + +; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb +; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb +; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb +; 0xFE800000 -> 0xFFFFFFFF kernel LFB part 24 Mb + + diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/arp.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/arp.inc new file mode 100644 index 000000000..e98734d96 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/arp.inc @@ -0,0 +1,556 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ARP.INC ;; +;; ;; +;; Address Resolution Protocol ;; +;; ;; +;; This file contains the following: ;; +;; arp_table_manager - Manages an ARPTable ;; +;; arp_request - Sends an ARP request on the ethernet ;; +;; arp_handler - Called when an ARP packet is received ;; +;; ;; +;; Changes history: ;; +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; +;; 11.11.2006 - [Johnny_B] and [smb] ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +ARP_NO_ENTRY equ 0 +ARP_VALID_MAPPING equ 1 +ARP_AWAITING_RESPONSE equ 2 +ARP_RESPONSE_TIMEOUT equ 3 + +struc ARP_ENTRY ;=14 bytes +{ .IP dd ? ;+00 + .MAC dp ? ;+04 + .Status dw ? ;+10 + .TTL dw ? ;+12 : ( in seconds ) +} + +virtual at 0 + ARP_ENTRY ARP_ENTRY +end virtual + +; The TTL field is decremented every second, and is deleted when it +; reaches 0. It is refreshed every time a packet is received +; If the TTL field is 0xFFFF it is a static entry and is never deleted +; The status field can be the following values: +; 0x0000 entry not used +; 0x0001 entry holds a valid mapping +; 0x0002 entry contains an IP address, awaiting ARP response +; 0x0003 No response received to ARP request. +; The last status value is provided to allow the network layer to delete +; a packet that is queued awaiting an ARP response + + +; The follow is the ARP Table. +; This table must be manually updated and the kernel recompilied if +; changes are made to it. +; Empty entries are filled with zeros + +ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry +ARP_TABLE_SIZE equ 20 ; Size of table +ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table + +;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!! +;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!! +uglobal + ARPTable: +;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF + times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 +endg + +iglobal + NumARP: dd ARP_TABLE_ENTRIES + ARPTable_ptr dd ARPTable ;pointer to ARPTable +endg + +ARP_REQ_OPCODE equ 0x0100 ;request +ARP_REP_OPCODE equ 0x0200 ;reply + +struc ARP_PACKET +{ .HardwareType dw ? ;+00 + .ProtocolType dw ? ;+02 + .HardwareSize db ? ;+04 + .ProtocolSize db ? ;+05 + .Opcode dw ? ;+06 + .SenderMAC dp ? ;+08 + .SenderIP dd ? ;+14 + .TargetMAC dp ? ;+18 + .TargetIP dd ? ;+24 +} + +virtual at 0 + ARP_PACKET ARP_PACKET +end virtual + + + +;*************************************************************************** +; Function +; arp_table_manager [by Johnny_B] +; +; Description +; Does a most required operations with ARP-table +; IN: +; Operation: see Opcode's constants below +; Index: Index of entry in the ARP-table +; Extra: Extra parameter for some Opcodes +; OUT: +; EAX = Returned value depends on opcodes, more detailed see below +; +;*************************************************************************** +;Opcode's constants +ARP_TABLE_ADD equ 1 +ARP_TABLE_DEL equ 2 +ARP_TABLE_GET equ 3 +ARP_TABLE_GET_ENTRIES_NUMBER equ 4 +ARP_TABLE_IP_TO_MAC equ 5 +ARP_TABLE_TIMER equ 6 + +;Index's constants +EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET +EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY + +align 4 +proc arp_table_manager stdcall uses ebx esi edi ecx edx,\ + Opcode:DWORD,Index:DWORD,Extra:DWORD + + mov ebx, dword[ARPTable_ptr] ;ARPTable base + mov ecx, dword[NumARP] ;ARP-entries counter + + mov eax, dword[Opcode] + cmp eax, ARP_TABLE_TIMER + je .timer + cmp eax, ARP_TABLE_ADD + je .add + cmp eax, ARP_TABLE_DEL + je .del + cmp eax, ARP_TABLE_GET + je .get + cmp eax, ARP_TABLE_IP_TO_MAC + je .ip_to_mac + cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER + je .get_entries_number + jmp .exit ;if unknown opcode + + +;;BEGIN TIMER +;;Description: it must be callback every second. It is responsible for removing expired routes. +;;IN: Operation: ARP_TABLE_TIMER +;; Index: must be zero +;; Extra: must be zero +;;OUT: +;; EAX=not defined +;; +.timer: + test ecx, ecx + jz .exit ;if NumARP=0 nothing to do + sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number + jz .exit ;if NumARP=number of static entries then exit + + add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base + + .timer_loop: + movsx esi, word [ebx + ARP_ENTRY.TTL] + cmp esi, 0xFFFFFFFF + je .timer_loop_end ;if TTL==0xFFFF then it's static entry + + test esi, esi + jnz .timer_loop_end_with_dec ;if TTL!=0 + + ; Ok, TTL is 0 + ;if Status==AWAITING_RESPONSE and TTL==0 + ;then we have to change it to ARP_RESPONSE_TIMEOUT + cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE + jne @f + + mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT + mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec + jmp .timer_loop_end + + @@: + ;if TTL==0 and Status==VALID_MAPPING, we have to delete it + ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too + mov esi, dword[NumARP] + sub esi, ecx ;esi=index of entry, will be deleted + stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra + jmp .timer_loop_end + + + .timer_loop_end_with_dec: + dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL + .timer_loop_end: + add ebx, ARP_ENTRY_SIZE + loop .timer_loop + + jmp .exit +;;END TIMER + +;;BEGIN ADD +;;Description: it adds an entry in the table. If ARP-table already +;; contains same IP, it will be updated. +;;IN: Operation: ARP_TABLE_ADD +;; Index: specifies what contains Extra-parameter +;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR, +;; then Extra contains pointer to ARP_PACKET, +;; otherwise Extra contains pointer to ARP_ENTRY +;;OUT: +;; EAX=index of entry, that has been added +;; +.add: + + sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack + + mov esi, [Extra] ;pointer + mov edi, [Index] ;opcode + + cmp edi, EXTRA_IS_ARP_PACKET_PTR + je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry + ;else it contain ptr to arp-entry + + cld + ; esi already has been loaded + mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) + mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! + rep movsw ;copy + jmp .search + + .arp_packet_to_entry: + mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET + mov [esp + ARP_ENTRY.IP], edx + + cld + lea esi, [esi + ARP_PACKET.SenderMAC] + lea edi, [esp + ARP_ENTRY.MAC] + movsd + movsw + mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry + mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour + + .search: + mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search + mov ecx, dword[NumARP] ;ecx=ARP-entries counter + jecxz .add_to_end ;if ARP-entries number == 0 + imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes) + @@: + sub eax, ARP_ENTRY_SIZE + cmp dword[ebx + eax + ARP_ENTRY.IP], edx + loopnz @b + jz .replace ; found, replace existing entry, ptr to it is in eax + + .add_to_end: + ;else add to end + or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible + mov ecx, dword[NumARP] + cmp ecx, ARP_TABLE_SIZE + je .add_exit ;if arp-entries number is equal to arp-table maxsize + + imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable + inc dword [NumARP] ;increase ARP-entries counter + + .replace: + cld + mov esi, esp ;esp=base of ARP-entry, that will be added + lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) + mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! + rep movsw + + mov ecx, ARP_ENTRY_SIZE + xor edx, edx ;"div" takes operand from EDX:EAX + div ecx ;eax=index of entry, which has been added + +.add_exit: + add esp, ARP_ENTRY_SIZE ;free stack + jmp .exit +;;END ADD + +;;BEGIN DEL +;;Description: it deletes an entry in the table. +;;IN: Operation: ARP_TABLE_DEL +;; Index: index of entry, that should be deleted +;; Extra: must be zero +;;OUT: +;; EAX=not defined +;; +.del: + mov esi, [Index] + imul esi, ARP_ENTRY_SIZE + + mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE + sub ecx, esi + + lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted + lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry + + shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! + cld + rep movsw + + dec dword[NumARP] ;decrease arp-entries counter + jmp .exit +;;END DEL + +;;BEGIN GET +;;Description: it reads an entry of table into buffer. +;;IN: Operation: ARP_TABLE_GET +;; Index: index of entry, that should be read +;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) +;;OUT: +;; EAX=not defined +;; +.get: + mov esi, [Index] + imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY + mov edi, [Extra] ;edi=buffer for reading + mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!! + cld + rep movsw + jmp .exit +;;END GET + +;;BEGIN IP_TO_MAC +;;Description: it gets an IP from Index, scans each entry in the table and writes +;; MAC, that relates to specified IP, into buffer specified in Extra. +;; And if it cannot find an IP-address in the table, it does an ARP-request of that. +;;IN: Operation: ARP_TABLE_IP_TO_MAC +;; Index: IP that should be transformed into MAC +;; Extra: pointer to buffer where will be written the MAC-address. +;;OUT: +;; EAX=ARP table entry status code. +;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. +;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. +;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. +;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. +;; +;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet +;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this +;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. +;; +.ip_to_mac: + + xor eax, eax + mov edi, dword[Extra] + cld + stosd + stosw + + + ; first, check destination IP to see if it is on 'this' network. + ; The test is: + ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) + ; destination is local + ; else + ; destination is remote, so pass to gateway + + mov eax, [Index] ;eax=required IP + mov esi, eax + and esi, [subnet_mask] + mov ecx, [stack_ip] + and ecx, [subnet_mask] + cmp esi, ecx + je @f ;if we and target IP are located in the same network + mov eax, [gateway_ip] + mov [Index], eax + @@: + + cmp dword[NumARP], 0 + je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. + ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY + + mov ecx, dword[NumARP] + imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size + + @@: + sub esi, ARP_ENTRY_SIZE + cmp [ebx + esi], eax ; ebx=ARPTable base + loopnz @b ; Return back if non match + jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table + + ; Return the entry status in eax + movzx eax, word[ebx + esi + ARP_ENTRY.Status] + + ; esi holds index + cld + lea esi, [ebx + esi + ARP_ENTRY.MAC] + mov edi, [Extra] ;edi=ptr to buffer for write MAC + movsd + movsw + jmp .exit + + .ip_to_mac_send_request: + stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr + mov eax, ARP_NO_ENTRY + jmp .exit + +;;END IP_TO_MAC + +;;BEGIN GET_ENTRIES_NUMBER +;;Description: returns an ARP-entries number in the ARPTable +;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER +;; Index: must be zero +;; Extra: must be zero +;;OUT: +;; EAX=ARP-entries number in the ARPTable + .get_entries_number: + mov eax, dword[NumARP] + jmp .exit +;;END GET_ENTRIES_NUMBER + +.exit: + ret +endp + + +;*************************************************************************** +; Function +; arp_handler +; +; Description +; Called when an ARP packet is received on the ethernet +; Header + Data is in Ether_buffer[] +; It looks to see if the packet is a request to resolve this Hosts +; IP address. If it is, send the ARP reply packet. +; This Hosts IP address is in dword [stack_ip] ( in network format ) +; This Hosts MAC address is in node_addr[6] +; All registers may be destroyed +; +;*************************************************************************** +arp_handler: + ; Is this a REQUEST? + ; Is this a request for My Host IP + ; Yes - So construct a response message. + ; Send this message to the ethernet card for transmission + + stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET + + inc dword[arp_rx_count] ;increase ARP-packets counter + + cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet? + jne .exit ; No - so exit + + mov eax, [stack_ip] + cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address? + jne .exit ; No - so quit now + + ; OK, it is a request for my MAC address. Build the frame and send it + ; We can reuse the packet. + + mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE + + cld + mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC + movsd + movsw + + mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP + movsd + + mov esi, node_addr + mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC + movsd + movsw + + mov esi, stack_ip + mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP + movsd + + ; Now, send it! + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address + mov bx, ETHER_ARP ;type of protocol + mov ecx, 28 ;data size + mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data + push ebp + call dword [drvr_transmit] ;transmit packet + pop ebp + + .exit: + ret + + +;*************************************************************************** +; Function +; arp_request [by Johnny_B] +; +; Description +; Sends an ARP request on the ethernet +; IN: +; TargetIP : requested IP address +; SenderIP_ptr : POINTER to sender's IP address(our system's address) +; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) +; OUT: +; EAX=0 (if all is ok), otherwise EAX is not defined +; +; EBX,ESI,EDI will be saved +; +;*************************************************************************** +proc arp_request stdcall uses ebx esi edi,\ + TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD + + inc dword[arp_tx_count] ; increase counter + + sub esp, 28 ; allocate memory for ARP_PACKET + + mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet + mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP + mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length + mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length + mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request + + cld + mov esi,[SenderMAC_ptr] + lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr + movsd + movsw + + mov esi,[SenderIP_ptr] + lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr + movsd + + xor eax, eax + lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed) + stosd + stosw + + mov esi, dword[TargetIP] + mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter) + + ; Now, send it! + mov edi, broadcast_add ; Pointer to 48 bit destination address + mov bx, ETHER_ARP ; Type of packet + mov ecx, 28 ; size of packet + lea esi, [esp + ARP_PACKET]; pointer to packet data + push ebp + call dword [drvr_transmit] ; Call the drivers transmit function + pop ebp + + add esp, 28 ; free memory, allocated before for ARP_PACKET + + ; Add an entry in the ARP table, awaiting response + sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry + + mov esi, dword[TargetIP] + mov dword[esp + ARP_ENTRY.IP],esi + + lea edi, [esp + ARP_ENTRY.MAC] + xor eax, eax + stosd + stosw + + mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE + mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds + + stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp + add esp, ARP_ENTRY_SIZE ; free memory + +.exit: + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/3c59x.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/3c59x.inc new file mode 100644 index 000000000..a61d8297a --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/3c59x.inc @@ -0,0 +1,2378 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;; Copyright (c) 2004, Endre Kozma +;; All rights reserved. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions are +;; met: +;; +;; 1. Redistributions of source code must retain the above copyright notice, +;; this list of conditions and the following disclaimer. +;; +;; 2. Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in the +;; documentation and/or other materials provided with the distribution. +;; +;; 3. The name of the author may not be used to endorse or promote products +;; derived from this software without specific prior written permission. +;; +;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 3C59X.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Driver for 3Com fast etherlink 3c59x and ;; +;; etherlink XL 3c900 and 3c905 cards ;; +;; References: ;; +;; www.3Com.com - data sheets ;; +;; DP83840A.pdf - ethernet physical layer ;; +;; 3c59x.c - linux driver ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; Credits ;; +;; Mike Hibbett, ;; +;; who kindly supplied me with a 3Com905C-TX-M card ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; History +;; ======= +;; $Log: 3C59X.INC,v $ +;; Revision 1.3 2004/07/11 12:21:12 kozma +;; Support of vortex chips (3c59x) added. +;; Support of 3c920 and 3c982 added. +;; Corrections. +;; +;; Revision 1.2 2004/06/12 19:40:20 kozma +;; Function e3c59x_set_available_media added in order to set +;; the default media in case auto detection finds no valid link. +;; Incorrect mii check removed (3c900 Cyclone works now). +;; Cleanups. +;; +;; Revision 1.1 2004/06/12 18:27:15 kozma +;; Initial revision +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; comment the next line out if you don't want debug info printed +; on the debug board. This option adds a lot of bytes to the driver +; so it's worth to comment it out. +; E3C59X_DEBUG equ 1 + +; forcing full duplex mode makes sense at some cards and link types + E3C59X_FORCE_FD equ 1 + +macro virt_to_dma reg +{ +sub reg, OS_BASE +} + +macro dma_to_virt reg +{ +add reg, OS_BASE +} + +macro zero_to_virt reg +{ + +} + +macro virt_to_zero reg +{ + +} + +macro zero_to_dma reg +{ +sub reg, OS_BASE +} + +macro dma_to_zero reg +{ +add reg, OS_BASE +} + +macro strtbl name, [string] +{ +common + label name dword +forward + local label + dd label +forward + label db string, 0 +} + +; Ethernet frame symbols + ETH_ALEN equ 6 + ETH_HLEN equ (2*ETH_ALEN+2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length +; PCI programming + PCI_REG_COMMAND equ 0x4 ; command register + PCI_REG_STATUS equ 0x6 ; status register + PCI_REG_LATENCY equ 0xd ; latency timer register + PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer + PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block + PCI_REG_PM_STATUS equ 0x4 ; power management status register + PCI_REG_PM_CTRL equ 0x4 ; power management control register + PCI_BIT_PIO equ 0 ; bit0: io space control + PCI_BIT_MMIO equ 1 ; bit1: memory space control + PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master +; Registers + E3C59X_REG_POWER_MGMT_CTRL equ 0x7c + E3C59X_REG_UP_LIST_PTR equ 0x38 + E3C59X_REG_UP_PKT_STATUS equ 0x30 + E3C59X_REG_TX_FREE_THRESH equ 0x2f + E3C59X_REG_DN_LIST_PTR equ 0x24 + E3C59X_REG_DMA_CTRL equ 0x20 + E3C59X_REG_TX_STATUS equ 0x1b + E3C59X_REG_RX_STATUS equ 0x18 + E3C59X_REG_TX_DATA equ 0x10 +; Common window registers + E3C59X_REG_INT_STATUS equ 0xe + E3C59X_REG_COMMAND equ 0xe +; Register window 7 + E3C59X_REG_MASTER_STATUS equ 0xc + E3C59X_REG_POWER_MGMT_EVENT equ 0xc + E3C59X_REG_MASTER_LEN equ 0x6 + E3C59X_REG_VLAN_ETHER_TYPE equ 0x4 + E3C59X_REG_VLAN_MASK equ 0x0 + E3C59X_REG_MASTER_ADDRESS equ 0x0 +; Register window 6 + E3C59X_REG_BYTES_XMITTED_OK equ 0xc + E3C59X_REG_BYTES_RCVD_OK equ 0xa + E3C59X_REG_UPPER_FRAMES_OK equ 0x9 + E3C59X_REG_FRAMES_DEFERRED equ 0x8 + E3C59X_REG_FRAMES_RCVD_OK equ 0x7 + E3C59X_REG_FRAMES_XMITTED_OK equ 0x6 + E3C59X_REG_RX_OVERRUNS equ 0x5 + E3C59X_REG_LATE_COLLISIONS equ 0x4 + E3C59X_REG_SINGLE_COLLISIONS equ 0x3 + E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2 + E3C59X_REG_SQE_ERRORS equ 0x1 + E3C59X_REG_CARRIER_LOST equ 0x0 +; Register window 5 + E3C59X_REG_INDICATION_ENABLE equ 0xc + E3C59X_REG_INTERRUPT_ENABLE equ 0xa + E3C59X_REG_TX_RECLAIM_THRESH equ 0x9 + E3C59X_REG_RX_FILTER equ 0x8 + E3C59X_REG_RX_EARLY_THRESH equ 0x6 + E3C59X_REG_TX_START_THRESH equ 0x0 +; Register window 4 + E3C59X_REG_UPPER_BYTES_OK equ 0xe + E3C59X_REG_BAD_SSD equ 0xc + E3C59X_REG_MEDIA_STATUS equ 0xa + E3C59X_REG_PHYSICAL_MGMT equ 0x8 + E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6 + E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4 + E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported +; Bits in register window 4 + E3C59X_BIT_AUTOSELECT equ 24 +; Register window 3 + E3C59X_REG_TX_FREE equ 0xc + E3C59X_REG_RX_FREE equ 0xa + E3C59X_REG_MEDIA_OPTIONS equ 0x8 + E3C59X_REG_MAC_CONTROL equ 0x6 + E3C59X_REG_MAX_PKT_SIZE equ 0x4 + E3C59X_REG_INTERNAL_CONFIG equ 0x0 +; Register window 2 + E3C59X_REG_RESET_OPTIONS equ 0xc + E3C59X_REG_STATION_MASK_HI equ 0xa + E3C59X_REG_STATION_MASK_MID equ 0x8 + E3C59X_REG_STATION_MASK_LO equ 0x6 + E3C59X_REG_STATION_ADDRESS_HI equ 0x4 + E3C59X_REG_STATION_ADDRESS_MID equ 0x2 + E3C59X_REG_STATION_ADDRESS_LO equ 0x0 +; Register window 1 + E3C59X_REG_TRIGGER_BITS equ 0xc + E3C59X_REG_SOS_BITS equ 0xa + E3C59X_REG_WAKE_ON_TIMER equ 0x8 + E3C59X_REG_SMB_RXBYTES equ 0x7 + E3C59X_REG_SMB_DIAG equ 0x5 + E3C59X_REG_SMB_ARB equ 0x4 + E3C59X_REG_SMB_STATUS equ 0x2 + E3C59X_REG_SMB_ADDRESS equ 0x1 + E3C59X_REG_SMB_FIFO_DATA equ 0x0 +; Register window 0 + E3C59X_REG_EEPROM_DATA equ 0xc + E3C59X_REG_EEPROM_COMMAND equ 0xa + E3C59X_REG_BIOS_ROM_DATA equ 0x8 + E3C59X_REG_BIOS_ROM_ADDR equ 0x4 +; Physical management bits + E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData + E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit + E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock +; MII commands + E3C59X_MII_CMD_MASK equ (1111b shl 10) + E3C59X_MII_CMD_READ equ (0110b shl 10) + E3C59X_MII_CMD_WRITE equ (0101b shl 10) +; MII registers + E3C59X_REG_MII_BMCR equ 0 ; basic mode control register + E3C59X_REG_MII_BMSR equ 1 ; basic mode status register + E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register + E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register + E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register +; MII bits + E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete + E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6 +; eeprom bits and commands + E3C59X_EEPROM_CMD_READ equ 0x80 + E3C59X_EEPROM_BIT_BUSY equ 15 +; eeprom registers + E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa + E3C59X_EEPROM_REG_CAPABILITIES equ 0x10 +; Commands for command register + E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11) + + IS_VORTEX equ 0x1 + IS_BOOMERANG equ 0x2 + IS_CYCLONE equ 0x4 + IS_TORNADO equ 0x8 + EEPROM_8BIT equ 0x10 + HAS_PWR_CTRL equ 0x20 + HAS_MII equ 0x40 + HAS_NWAY equ 0x80 + HAS_CB_FNS equ 0x100 + INVERT_MII_PWR equ 0x200 + INVERT_LED_PWR equ 0x400 + MAX_COLLISION_RESET equ 0x800 + EEPROM_OFFSET equ 0x1000 + HAS_HWCKSM equ 0x2000 + EXTRA_PREAMBLE equ 0x4000 + +iglobal + align 4 +e3c59x_hw_versions: + dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps + dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex + dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex + dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx + dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4 + dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII + dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT + dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo + dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO + dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo + dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC + dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL + dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx + dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4 + dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx + dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC + dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx + dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado + dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone + dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone + dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane + dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane + dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \ + or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado + dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \ + or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane + dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus + dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus + dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus + dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus + dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus + dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus + dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus + dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado + dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado + dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A + dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B + dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4 + dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado +E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions +endg + +; RX/TX buffers sizes + E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size + E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number + E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number + E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC) + E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC) +; Download Packet Descriptor + E3C59X_DPD_DN_NEXT_PTR equ 0 + E3C59X_DPD_FRAME_START_HDR equ 4 + E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data + E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data + E3C59X_DPD_SIZE equ 16 ; a power of 2 number +; Upload Packet Descriptor + E3C59X_UPD_UP_NEXT_PTR equ 0 + E3C59X_UPD_PKT_STATUS equ 4 + E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data + E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data + E3C59X_UPD_SIZE equ 16 + +; RX/TX buffers +if defined E3C59X_LINUX + E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment + e3c59x_rx_buff = 0 +else + E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment + e3c59x_rx_buff = eth_data_start +end if + + e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE + e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE + e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC) + +uglobal +e3c59x_curr_upd: dd 0 +e3c59x_prev_dpd: dd 0 +e3c59x_prev_tx_frame: dd 0 +e3c59x_transmit_function: dd 0 +e3c59x_receive_function: dd 0 +endg + +iglobal +e3c59x_ver_id: db 17 +endg + +uglobal +e3c59x_full_bus_master: db 0 +e3c59x_has_hwcksm: db 0 +e3c59x_preamble: db 0 +e3c59x_dn_list_ptr_cleared: db 0 +e3c59x_self_directed_packet: rb 6 +endg + +if defined E3C59X_DEBUG +e3c59x_hw_type_str: db "Detected hardware type : ", 0 +e3c59x_device_str: db "Device ID : 0x" +e3c59x_device_id_str: db "ffff", 13, 10, 0 +e3c59x_vendor_str: db "Vendor ID : 0x" +e3c59x_vendor_id_str: db "ffff", 13, 10, 0 +e3c59x_io_info_str: db "IO address : 0x" +e3c59x_io_addr_str: db "ffff", 13, 10, 0 +e3c59x_mac_info_str: db "MAC address : " +e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0 +e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0 +e3c59x_vortex_str: db " (vortex)", 13, 10, 0 +e3c59x_link_type_str: db "Established link type : ", 0 +e3c59x_new_line_str: db 13, 10, 0 +e3c59x_link_type: dd 0 + +e3c59x_charset: db '0123456789abcdef' + +strtbl e3c59x_link_str, \ + "No valid link type detected", \ + "10BASE-T half duplex", \ + "10BASE-T full-duplex", \ + "100BASE-TX half duplex", \ + "100BASE-TX full duplex", \ + "100BASE-T4", \ + "100BASE-FX", \ + "10Mbps AUI", \ + "10Mbps COAX (BNC)", \ + "miiDevice - not supported" + +strtbl e3c59x_hw_str, \ + "3c590 Vortex 10Mbps", \ + "3c592 EISA 10Mbps Demon/Vortex", \ + "3c597 EISA Fast Demon/Vortex", \ + "3c595 Vortex 100baseTx", \ + "3c595 Vortex 100baseT4", \ + "3c595 Vortex 100base-MII", \ + "3c900 Boomerang 10baseT", \ + "3c900 Boomerang 10Mbps Combo", \ + "3c900 Cyclone 10Mbps TPO", \ + "3c900 Cyclone 10Mbps Combo", \ + "3c900 Cyclone 10Mbps TPC", \ + "3c900B-FL Cyclone 10base-FL", \ + "3c905 Boomerang 100baseTx", \ + "3c905 Boomerang 100baseT4", \ + "3c905B Cyclone 100baseTx", \ + "3c905B Cyclone 10/100/BNC", \ + "3c905B-FX Cyclone 100baseFx", \ + "3c905C Tornado", \ + "3c980 Cyclone", \ + "3c982 Dual Port Server Cyclone", \ + "3cSOHO100-TX Hurricane", \ + "3c555 Laptop Hurricane", \ + "3c556 Laptop Tornado", \ + "3c556B Laptop Hurricane", \ + "3c575 [Megahertz] 10/100 LAN CardBus", \ + "3c575 Boomerang CardBus", \ + "3CCFE575BT Cyclone CardBus", \ + "3CCFE575CT Tornado CardBus", \ + "3CCFE656 Cyclone CardBus", \ + "3CCFEM656B Cyclone+Winmodem CardBus", \ + "3CXFEM656C Tornado+Winmodem CardBus", \ + "3c450 HomePNA Tornado", \ + "3c920 Tornado", \ + "3c982 Hydra Dual Port A", \ + "3c982 Hydra Dual Port B", \ + "3c905B-T4", \ + "3c920B-EMB-WNM Tornado" + +end if ; defined E3C59X_DEBUG + +;*************************************************************************** +; Function +; e3c59x_debug +; Description +; prints debug info to the debug board +; Parameters +; ebp - io_addr +; Return value +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** +if defined E3C59X_DEBUG + align 4 +e3c59x_debug: + pushad +; print device type + mov esi, e3c59x_hw_type_str + call sys_msg_board_str + movzx ecx, byte [e3c59x_ver_id] + mov esi, [e3c59x_hw_str+ecx*4] + call sys_msg_board_str + mov esi, e3c59x_boomerang_str + cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit + jz .boomerang + mov esi, e3c59x_vortex_str +.boomerang: + call sys_msg_board_str +; print device/vendor + mov ax, [pci_data+2] + mov cl, 2 + mov ebx, e3c59x_device_id_str + call e3c59x_print_hex + mov esi, e3c59x_device_str + call sys_msg_board_str + mov ax, [pci_data] + mov cl, 2 + mov ebx, e3c59x_vendor_id_str + call e3c59x_print_hex + mov esi, e3c59x_vendor_str + call sys_msg_board_str +; print io address + mov ax, [io_addr] + mov ebx, e3c59x_io_addr_str + mov cl, 2 + call e3c59x_print_hex + mov esi, e3c59x_io_info_str + call sys_msg_board_str +; print MAC address + mov ebx, e3c59x_mac_addr_str + xor ecx, ecx +.mac_loop: + push ecx + mov al, [node_addr+ecx] + mov cl, 1 + call e3c59x_print_hex + inc ebx + pop ecx + inc cl + cmp cl, 6 + jne .mac_loop + mov esi, e3c59x_mac_info_str + call sys_msg_board_str +; print link type + mov esi, e3c59x_link_type_str + call sys_msg_board_str + xor eax, eax + bsr ax, word [e3c59x_link_type] + jz @f + sub ax, 4 +@@: + mov esi, [e3c59x_link_str+eax*4] + call sys_msg_board_str + mov esi, e3c59x_new_line_str + call sys_msg_board_str + popad + ret + +;*************************************************************************** +; Function +; e3c59x_print_hex +; Description +; prints a hexadecimal value +; Parameters +; eax - value to be printed out +; ebx - where to print +; cl - value size (1, 2, 4) +; Return value +; ebx - end address after the print +; Destroyed registers +; eax, ebx +; +;*************************************************************************** + align 4 +e3c59x_print_hex: + cmp cl, 1 + je .print_byte + cmp cl, 2 + jz .print_word +.print_dword: + push eax + bswap eax + xchg ah, al + call .print_word + pop eax +.print_word: + push eax + xchg ah, al + call .print_byte + pop eax +.print_byte: + movzx eax, al + push eax + and al, 0xf0 + shr al, 4 + mov al, byte [eax+e3c59x_charset] + mov [ebx], al + inc ebx + pop eax + and al, 0x0f + mov al, byte [eax+e3c59x_charset] + mov [ebx], al + inc ebx + ret +end if ; defined E3C59X_DEBUG + +;*************************************************************************** +; Function +; e3c59x_try_link_detect +; Description +; e3c59x_try_link_detect checks if link exists +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no link detected +; al - 1 ; link detected +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_try_link_detect: +; download self-directed packet + mov edi, node_addr + mov bx, 0x0608 ; packet type + mov esi, e3c59x_self_directed_packet + mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes + call dword [e3c59x_transmit_function] +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; program RxFilter for promiscuous operation + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1111b + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; switch to register window 4 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; check loop + xor ebx, ebx + mov ecx, 0xffff ; 65535 tries +.loop: + push ecx ebx + call dword [e3c59x_receive_function] + pop ebx ecx + test al, al + jnz .finish +.no_packet_received: +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; read linkbeatdetect + lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] + in ax, dx + test ah, 1000b ; test linkBeatDetect + jnz .link_detected + xor al, al + jmp .finish +.link_detected: +; test carrierSense + test al, 100000b + jz .no_carrier_sense + inc ebx +.no_carrier_sense: + dec ecx + jns .loop +; assume the link is good if 0 < ebx < 25 % + test ebx, ebx + setnz al + jz .finish + cmp ebx, 16384 ; 25% + setb al +.finish: +if defined E3C59X_DEBUG + test al, al + jz @f + or byte [e3c59x_link_type+1], 100b +@@: +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_try_phy +; Description +; e3c59x_try_phy checks the auto-negotiation function +; in the PHY at PHY index. It can also be extended to +; include link detection for non-IEEE 802.3u +; auto-negotiation devices, for instance the BCM5000. +; Parameters +; ah - PHY index +; ebp - io_addr +; Return value +; al - 0 link is auto-negotiated +; al - 1 no link is auto-negotiated +; Destroyed registers +; eax, ebx, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_try_phy: + mov al, E3C59X_REG_MII_BMCR + push eax + call e3c59x_mdio_read ; returns with window #4 + or ah, 0x80 ; software reset + mov ebx, eax + pop eax + push eax + call e3c59x_mdio_write ; returns with window #4 +; wait for reset to complete + mov esi, 2000 ; 2000ms = 2s + call delay_ms + pop eax + push eax + call e3c59x_mdio_read ; returns with window #4 + test ah, 0x80 + jnz .fail_finish + pop eax + push eax +; wait for a while after reset + mov esi, 20 ; 20ms + call delay_ms + pop eax + push eax + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read ; returns with window #4 + test al, 1 ; extended capability supported? + jz .no_ext_cap +; auto-neg capable? + test al, 1000b + jz .fail_finish ; not auto-negotiation capable +; auto-neg complete? + test al, 100000b + jnz .auto_neg_ok +; restart auto-negotiation + pop eax + push eax + mov al, E3C59X_REG_MII_ANAR + push eax + call e3c59x_mdio_read ; returns with window #4 + or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX + mov ebx, eax + pop eax + call e3c59x_mdio_write ; returns with window #4 + pop eax + push eax + call e3c59x_mdio_read ; returns with window #4 + mov ebx, eax + or bh, 10010b ; restart auto-negotiation + pop eax + push eax + call e3c59x_mdio_write ; returns with window #4 + mov esi, 4000 ; 4000ms = 4 seconds + call delay_ms + pop eax + push eax + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read ; returns with window #4 + test al, 100000b ; auto-neg complete? + jnz .auto_neg_ok + jmp .fail_finish +.auto_neg_ok: +; compare advertisement and link partner ability registers + pop eax + push eax + mov al, E3C59X_REG_MII_ANAR + call e3c59x_mdio_read ; returns with window #4 + xchg eax, [esp] + mov al, E3C59X_REG_MII_ANLPAR + call e3c59x_mdio_read ; returns with window #4 + pop ebx + and eax, ebx + and eax, 1111100000b + push eax +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], ax +end if ; defined E3C59X_DEBUG +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; set full-duplex mode + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + and ax, not 0x120 ; clear full duplex and flow control + pop ebx + test ebx, (1010b shl 5) ; check for full-duplex + jz .half_duplex + or ax, 0x120 ; set full duplex and flow control +.half_duplex: + out dx, ax + mov al, 1 + ret +.no_ext_cap: +; not yet implemented BCM5000 +.fail_finish: + pop eax + xor al, al + ret + +;*************************************************************************** +; Function +; e3c59x_try_mii +; Description +; e3c59x_try_MII checks the on-chip auto-negotiation logic +; or an off-chip MII PHY, depending upon what is set in +; xcvrSelect by the caller. +; It exits when it finds the first device with a good link. +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_try_mii: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, (1111b shl 20) + cmp eax, (1000b shl 20) ; is auto-negotiation set? + jne .mii_device +; auto-negotiation is set +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; PHY==24 is the on-chip auto-negotiation logic +; it supports only 10base-T and 100base-TX + mov ah, 24 + call e3c59x_try_phy + test al, al + jz .fail_finish + mov cl, 24 + jmp .check_preamble +.mii_device: + cmp eax, (0110b shl 20) + jne .fail_finish + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + in ax, dx + and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA) + cmp al, (1 shl E3C59X_BIT_MGMT_DATA) + je .serch_for_phy + xor al, al + ret +.serch_for_phy: +; search for PHY + mov cl, 31 +.search_phy_loop: + cmp cl, 24 + je .next_phy + mov ah, cl ; ah = phy + mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register + push ecx + call e3c59x_mdio_read + pop ecx + test ax, ax + jz .next_phy + cmp ax, 0xffff + je .next_phy + mov ah, cl ; ah = phy + push ecx + call e3c59x_try_phy + pop ecx + test al, al + jnz .check_preamble +.next_phy: + dec cl + jns .search_phy_loop +.fail_finish: + xor al, al + ret +; epilog +.check_preamble: + push eax ; eax contains the return value of e3c59x_try_phy +; check hard coded preamble forcing + movzx eax, byte [e3c59x_ver_id] + test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE + setnz [e3c59x_preamble] ; force preamble + jnz .finish +; check mii for preamble suppression + mov ah, cl + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read + test al, 1000000b ; preamble suppression? + setz [e3c59x_preamble] ; no +.finish: + pop eax + ret + +;*************************************************************************** +; Function +; e3c59x_test_packet +; Description +; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_test_packet: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; set fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + or ax, 0x120 + out dx, ax +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; set RxFilter to enable individual address matches + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1 + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; issue RxEnable and TxEnable + call e3c59x_rx_reset + call e3c59x_tx_reset +; download a self-directed test packet + mov edi, node_addr + mov bx, 0x0608 ; packet type + mov esi, e3c59x_self_directed_packet + mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes + call dword [e3c59x_transmit_function] +; wait for 2s + mov esi, 2000 ; 2000ms = 2s + call delay_ms +; check if self-directed packet is received + call dword [e3c59x_receive_function] + test al, al + jnz .finish +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; clear fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + and ax, not 0x120 + out dx, ax + xor al, al +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_try_loopback +; Description +; tries a loopback packet for 10BASE2 or AUI port +; Parameters +; al - 0: 10Mbps AUI connector +; 1: 10BASE-2 +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_try_loopback: + push eax +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + pop eax + push eax +if defined E3C59X_DEBUG + mov bl, al + inc bl + shl bl, 3 + or byte [e3c59x_link_type+1], bl +end if ; defined E3C59X_DEBUG + test al, al ; aui or coax? + jz .complete_loopback +; enable 100BASE-2 DC-DC converter + mov ax, (10b shl 11) ; EnableDcConverter + out dx, ax +.complete_loopback: + mov cl, 2 ; give a port 3 chances to complete a loopback +.next_try: + push ecx + call e3c59x_test_packet + pop ecx + test al, al + jnz .finish + dec cl + jns .next_try +.finish: + xchg eax, [esp] + test al, al + jz .aui_finish +; issue DisableDcConverter command + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10111b shl 11) + out dx, ax +.aui_finish: + pop eax ; al contains the result of operation +if defined E3C59X_DEBUG + test al, al + jnz @f + and byte [e3c59x_link_type+1], not 11000b +@@: +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_set_available_media +; Description +; sets the first available media +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, edx +; +;*************************************************************************** + align 4 +e3c59x_set_available_media: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + push eax + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 10b + jz @f +; baseTXAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (100b shl 20) +if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD + mov word [e3c59x_link_type], (1 shl 8) +else if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 7) +end if + jmp .set_media +@@: + test al, 100b + jz @f +; baseFXAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (101b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 10) +end if + jmp .set_media +@@: + test al, 1000000b + jz @f +; miiDevice + pop eax + and eax, not (1111b shl 20) + or eax, (0110b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 13) +end if + jmp .set_media +@@: + test al, 1000b + jz @f +.set_default: +; 10bTAvailable + pop eax + and eax, not (1111b shl 20) +if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD + mov word [e3c59x_link_type], (1 shl 6) +else if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 5) +end if ; E3C59X_FORCE_FD + jmp .set_media +@@: + test al, 10000b + jz @f +; coaxAvailable + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10b shl 11) ; EnableDcConverter + out dx, ax + pop eax + and eax, not (1111b shl 20) + or eax, (11b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 12) +end if ; defined E3C59X_DEBUG + jmp .set_media +@@: + test al, 10000b + jz .set_default +; auiAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (1 shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 11) +end if ; defined E3C59X_DEBUG +.set_media: + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + out dx, eax +if defined E3C59X_FORCE_FD +; set fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + or ax, 0x120 + out dx, ax +end if ; E3C59X_FORCE_FD + mov al, 1 + ret + +;*************************************************************************** +; Function +; e3c59x_set_active_port +; Description +; It selects the media port (transceiver) to be used +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_set_active_port: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + test eax, (1 shl 24) ; check if autoselect enable + jz .set_first_available_media +; check 100BASE-TX and 10BASE-T + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 1010b ; check whether 100BASE-TX or 10BASE-T available + jz .mii_device ; they are not available +; set auto-negotiation + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (1000b shl 20) + out dx, eax + call e3c59x_try_mii + test al, al + jz .mii_device + ret +.mii_device: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for off-chip mii device + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 1000000b ; check miiDevice + jz .base_fx + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0110b shl 20) ; set MIIDevice + out dx, eax + call e3c59x_try_mii + test al, al + jz .base_fx + ret +.base_fx: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for 100BASE-FX + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 100b ; check 100BASE-FX + jz .aui_enable + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0101b shl 20) ; set 100base-FX + out dx, eax + call e3c59x_try_link_detect + test al, al + jz .aui_enable + ret +.aui_enable: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for 10Mbps AUI connector + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 100000b ; check 10Mbps AUI connector + jz .coax_available + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0001b shl 20) ; set 10Mbps AUI connector + out dx, eax + xor al, al ; try 10Mbps AUI connector + call e3c59x_try_loopback + test al, al + jz .coax_available + ret +.coax_available: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for coaxial 10BASE-2 port + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 10000b ; check 10BASE-2 + jz .set_first_available_media + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0011b shl 20) ; set 10BASE-2 + out dx, eax + mov al, 1 + call e3c59x_try_loopback + test al, al + jz .set_first_available_media + ret +.set_first_available_media: + jmp e3c59x_set_available_media + +;*************************************************************************** +; Function +; e3c59x_wake_up +; Description +; set the power state to D0 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_wake_up: +; wake up - we directly do it by programming PCI +; check if the device is power management capable + mov al, 2 + mov ah, [pci_bus] + mov bl, PCI_REG_STATUS + mov bh, [pci_dev] + push eax ebx + call pci_read_reg + test al, 10000b ; is there "new capabilities" linked list? + pop ebx eax + jz .device_awake +; search for power management register + mov al, 1 + mov bl, PCI_REG_CAP_PTR + push eax ebx + call pci_read_reg + mov cl, al + cmp cl, 0x3f + pop ebx eax + jbe .device_awake +; traverse the list + mov al, 2 +.pm_loop: + mov bl, cl + push eax ebx + call pci_read_reg + cmp al, 1 + je .set_pm_state + test ah, ah + mov cl, ah + pop ebx eax + jnz .pm_loop + jmp .device_awake +; waku up the device if necessary +.set_pm_state: + pop ebx eax + add bl, PCI_REG_PM_CTRL + push eax ebx + call pci_read_reg + mov cx, ax + test cl, 3 + pop ebx eax + jz .device_awake + and cl, not 11b ; set state to D0 + call pci_write_reg +.device_awake: + ret + +;*************************************************************************** +; Function +; e3c59x_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_probe: + movzx ebp, word [io_addr] + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + push ebp eax ebx + call pci_read_reg + mov cx, ax + or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) + and cl, not (1 shl PCI_BIT_MMIO) + pop ebx eax + call pci_write_reg +; wake up the card + call e3c59x_wake_up + pop ebp +; get chip version + mov ax, [pci_data+2] + mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1 +.chip_ver_loop: + cmp ax, [e3c59x_hw_versions+ecx*4] + jz .chip_ver_found + dec ecx + jns .chip_ver_loop + xor ecx, ecx +.chip_ver_found: + mov [e3c59x_ver_id], cl + test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM + setnz [e3c59x_has_hwcksm] +; set pci latency for vortex cards + test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX + jz .not_vortex + mov cx, 11111000b ; 248 = max latency + mov al, 1 + mov ah, [pci_bus] + mov bl, PCI_REG_LATENCY + mov bh, [pci_dev] + call pci_write_reg +.not_vortex: +; set RX/TX functions + mov ax, E3C59X_EEPROM_REG_CAPABILITIES + call e3c59x_read_eeprom + test al, 100000b ; full bus master? + setnz [e3c59x_full_bus_master] + jnz .boomerang_func + mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit + mov dword [e3c59x_receive_function], e3c59x_vortex_poll + jmp @f +.boomerang_func: ; full bus master, so use boomerang functions + mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit + mov dword [e3c59x_receive_function], e3c59x_boomerang_poll +@@: +; read MAC from eeprom + mov ecx, 2 +.mac_loop: + lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] + call e3c59x_read_eeprom + xchg ah, al ; htons + mov [node_addr+ecx*2], ax + dec ecx + jns .mac_loop + test byte [e3c59x_full_bus_master], 0xff + jz .set_preamble +; switch to register window 2 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 + out dx, ax +; activate xcvr by setting some magic bits + lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] + in ax, dx + and ax, not 0x4010 + movzx ebx, byte [e3c59x_ver_id] + test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR + jz @f + or al, 0x10 +@@: + test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR + jz @f + or ah, 0x40 +@@: + out dx, ax +.set_preamble: +; use preamble as default + mov byte [e3c59x_preamble], 1 ; enable preamble + +;*************************************************************************** +; Function +; e3c59x_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** +e3c59x_reset: +; issue global reset + call e3c59x_global_reset +; disable interrupts + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (1110b shl 11) + out dx, ax +; enable Statistics + mov ax, (10101b shl 11) + out dx, ax +; set indication + mov ax, (1111b shl 11) or 0x6c6 + out dx, ax +; acknowledge (clear) every interrupt indicator + mov ax, (1101b shl 11) or 0x661 + out dx, ax +; switch to register window 2 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 + out dx, ax +; write MAC addres back into the station address registers + lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] + mov esi, node_addr + cld + outsw + add edx, 2 + outsw + add edx, 2 + outsw + add edx, 2 +; clear station mask + xor eax, eax + out dx, ax + add edx, 2 + out dx, ax + add edx, 2 + out dx, ax +; switch to register window 6 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 + out dx, ax +; clear all statistics by reading + lea edx, [ebp+E3C59X_REG_CARRIER_LOST] + mov cl, 9 +.stat_clearing_loop: + in al, dx + inc edx + dec cl + jns .stat_clearing_loop + in ax, dx + add dx, 2 + in ax, dx +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; clear BadSSD + lea edx, [ebp+E3C59X_REG_BAD_SSD] + in al, dx +; clear extra statistics bit in NetworkDiagnostic + lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] + in ax, dx + or ax, 0x0040 + out dx, ax +; SetRxEarlyThreshold + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) + out dx, ax + test byte [e3c59x_full_bus_master], 0xff + jz .skip_boomerang_setting +; set upRxEarlyEnable + lea edx, [ebp+E3C59X_REG_DMA_CTRL] + in eax, dx + or eax, 0x20 + out dx, eax +; TxFreeThreshold + lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] + mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) + out dx, al +; program DnListPtr + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + xor eax, eax + out dx, eax +.skip_boomerang_setting: +; initialization + call e3c59x_rx_reset + call e3c59x_tx_reset + call e3c59x_set_active_port + call e3c59x_rx_reset + call e3c59x_tx_reset +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; program RxFilter for promiscuous operation + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1111b + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; switch to register window 4 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; wait for linkDetect + lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] + mov cl, 20 ; wait for max 2s + mov esi, 100 ; 100ms +.link_detect_loop: + call delay_ms + in ax, dx + test ah, 1000b ; linkDetect + jnz @f + dec cl + jnz .link_detect_loop +@@: +; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax +if defined E3C59X_DEBUG + call e3c59x_debug +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_global_reset +; Description +; resets the device +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; ax, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_global_reset: +; GlobalReset + lea edx, [ebp+E3C59X_REG_COMMAND] + xor eax, eax +; or al, 0x14 + out dx, ax +; wait for GlobalReset to complete + mov ecx, 64000 +.global_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .finish + dec ecx + jnz .global_reset_loop +.finish: +; wait for 2 seconds for NIC to boot + mov esi, 2000 ; 2000ms = 2s + push ebp + call delay_ms + pop ebp + ret + +;*************************************************************************** +; Function +; e3c59x_tx_reset +; Description +; resets and enables transmitter engine +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; ax, ecx, edx +; +;*************************************************************************** + align 4 +e3c59x_tx_reset: +; TxReset + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01011b shl 11) + out dx, ax +; Wait for TxReset to complete + mov ecx, 200000 +.tx_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .tx_set_prev + dec ecx + jns .tx_reset_loop +.tx_set_prev: + test byte [e3c59x_full_bus_master], 0xff + jz .tx_enable +; init last_dpd + mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE + mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE +.tx_enable: + mov ax, (01001b shl 11) ; TxEnable + out dx, ax + ret + +;*************************************************************************** +; Function +; e3c59x_rx_reset +; Description +; resets and enables receiver engine +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_rx_reset: + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (0101b shl 11) or 0x4 ; RxReset + out dx, ax +; wait for RxReset to complete + mov ecx, 200000 +.rx_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .setup_upd + dec ecx + jns .rx_reset_loop +.setup_upd: +; check if full bus mastering + test byte [e3c59x_full_bus_master], 0xff + jz .rx_enable +; create upd ring + mov eax, e3c59x_upd_buff + zero_to_virt eax + mov [e3c59x_curr_upd], eax + mov esi, eax + virt_to_dma esi + mov edi, e3c59x_rx_buff + zero_to_dma edi + mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE + zero_to_virt ebx + mov cl, E3C59X_NUM_RX_DESC-1 +.upd_loop: + mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi + mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31) + add edi, E3C59X_MAX_ETH_FRAME_SIZE + add esi, E3C59X_UPD_SIZE + mov ebx, eax + add eax, E3C59X_UPD_SIZE + dec cl + jns .upd_loop + mov eax, e3c59x_upd_buff + zero_to_dma eax + lea edx, [ebp+E3C59X_REG_UP_LIST_PTR] + out dx, eax ; write E3C59X_REG_UP_LIST_PTR + lea edx, [ebp+E3C59X_REG_COMMAND] +.rx_enable: + mov ax, (00100b shl 11) ; RxEnable + out dx, ax + ret + +;*************************************************************************** +; Function +; e3c59x_write_eeprom +; Description +; reads eeprom +; Note : the caller must switch to the register window 0 +; before calling this function +; Parameters: +; ax - register to be read (only the first 63 words can be read) +; cx - value to be read into the register +; Return value: +; ax - word read +; Destroyed registers +; ax, ebx, edx +; +;*************************************************************************** +; align 4 +;e3c59x_write_eeprom: +; mov edx, [io_addr] +; add edx, E3C59X_REG_EEPROM_COMMAND +; cmp ah, 11b +; ja .finish ; address may have a value of maximal 1023 +; shl ax, 2 +; shr al, 2 +; push eax +;; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .write_enable +; dec ebx +; jns @r +;; write enable +;.write_enable: +; xor eax, eax +; mov eax, (11b shl 4) +; out dx, ax +;; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .erase_loop +; dec ebx +; jns @r +;.erase_loop: +; pop eax +; push eax +; or ax, (11b shl 6) ; erase register +; out dx, ax +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .write_reg +; dec ebx +; jns @r +;.write_reg: +; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND +; mov eax, ecx +; out dx, ax +;; write enable +; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA +; xor eax, eax +; mov eax, (11b shl 4) +; out dx, ax +; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .issue_write_reg +; dec ebx +; jns @r +;.issue_write_reg: +; pop eax +; or ax, 01b shl 6 +; out dx, ax +;.finish: +; ret +;*************************************************************************** +; Function +; e3c59x_read_eeprom +; Description +; reads eeprom +; Parameters: +; ax - register to be read (only the first 63 words can be read) +; ebp - io_addr +; Return value: +; ax - word read +; Destroyed registers +; ax, ebx, edx, ebp +; +;*************************************************************************** + align 4 +e3c59x_read_eeprom: + push eax +; switch to register window 0 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+0 + out dx, ax + pop eax + and ax, 111111b ; take only the first 6 bits into account + movzx ebx, byte [e3c59x_ver_id] + test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT + jz @f + add ax, 0x230 ; hardware constant + jmp .read +@@: + add ax, E3C59X_EEPROM_CMD_READ + test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET + jz .read + add ax, 0x30 +.read: + lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND] + out dx, ax + mov ebx, 0xffff ; duration of about 162 us ;-) +.wait_for_reading: + in ax, dx + test ah, 0x80 ; check bit eepromBusy + jz .read_data + dec ebx + jns .wait_for_reading +.read_data: + lea edx, [ebp+E3C59X_REG_EEPROM_DATA] + in ax, dx + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_sync +; Description +; initial synchronization +; Parameters +; ebp - io_addr +; Return value +; Destroyed registers +; ax, edx, cl +; +;*************************************************************************** + align 4 +e3c59x_mdio_sync: +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax + cmp byte [e3c59x_preamble], 0 + je .no_preamble +; send 32 logic ones + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + mov cl, 31 +.loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR) + out dx, ax + in ax, dx ; delay + mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \ + or (1 shl E3C59X_BIT_MGMT_DIR) \ + or (1 shl E3C59X_BIT_MGMT_CLK) + out dx, ax + in ax, dx ; delay + dec cl + jns .loop +.no_preamble: + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_read +; Description +; read MII register +; see page 16 in D83840A.pdf +; Parameters +; ah - PHY addr +; al - register addr +; ebp - io_addr +; Return value +; ax - register read +; Destroyed registers +; eax, ebx, cx, edx +; +;*************************************************************************** + align 4 +e3c59x_mdio_read: + push eax + call e3c59x_mdio_sync ; returns with window #4 + pop eax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + shl al, 3 + shr ax, 3 + and ax, not E3C59X_MII_CMD_MASK + or ax, E3C59X_MII_CMD_READ + mov ebx, eax + xor ecx, ecx + mov cl, 13 +.cmd_loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii + bt ebx, ecx + jnc .zero_bit + or al, (1 shl E3C59X_BIT_MGMT_DATA) +.zero_bit: + out dx, ax + push eax + in ax, dx ; delay + pop eax + or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write + out dx, ax + in ax, dx ; delay + dec cl + jns .cmd_loop +; read data (18 bits with the two transition bits) + mov cl, 17 + xor ebx, ebx +.read_loop: + shl ebx, 1 + xor eax, eax ; read comand + out dx, ax + in ax, dx ; delay + in ax, dx + test al, (1 shl E3C59X_BIT_MGMT_DATA) + jz .dont_set + inc ebx +.dont_set: + mov ax, (1 shl E3C59X_BIT_MGMT_CLK) + out dx, ax + in ax, dx ; delay + dec cl + jns .read_loop + mov eax, ebx + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_write +; Description +; write MII register +; see page 16 in D83840A.pdf +; Parameters +; ah - PHY addr +; al - register addr +; bx - word to be written +; ebp - io_addr +; Return value +; ax - register read +; Destroyed registers +; eax, ebx, cx, edx +; +;*************************************************************************** + align 4 +e3c59x_mdio_write: + push eax + call e3c59x_mdio_sync + pop eax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + shl al, 3 + shr ax, 3 + and ax, not E3C59X_MII_CMD_MASK + or ax, E3C59X_MII_CMD_WRITE + shl eax, 2 + or eax, 10b ; transition bits + shl eax, 16 + mov ax, bx + mov ebx, eax + mov ecx, 31 +.cmd_loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii + bt ebx, ecx + jnc .zero_bit + or al, (1 shl E3C59X_BIT_MGMT_DATA) +.zero_bit: + out dx, ax + push eax + in ax, dx ; delay + pop eax + or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write + out dx, ax + in ax, dx ; delay + dec ecx + jns .cmd_loop + ret + +;*************************************************************************** +; Function +; e3c59x_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, ecx, edx, ebp +; +;*************************************************************************** + align 4 +e3c59x_transmit: + jmp dword [e3c59x_transmit_function] + +;*************************************************************************** +; Function +; e3c59x_check_tx_status +; Description +; Checks TxStatus queue. +; Return value +; al - 0 no error was found +; al - 1 error was found TxReset is needed +; Destroyed registers +; eax, ecx, edx, ebp +; +;*************************************************************************** +e3c59x_check_tx_status: + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +; clear TxStatus queue + lea edx, [ebp+E3C59X_REG_TX_STATUS] + mov cl, 31 ; max number of queue entries +.tx_status_loop: + in al, dx + test al, al + jz .finish ; no error + test al, 0x3f + jnz .finish ; error +.no_error_found: +; clear current TxStatus entry which advances the next one + xor al, al + out dx, al + dec cl + jns .tx_status_loop +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_vortex_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_vortex_transmit: + push ecx + call e3c59x_check_tx_status + pop ecx + test al, al + jz .no_error_found + jmp e3c59x_tx_reset +.no_error_found: +; switch to register window 7 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 + out dx, ax +; check for master operation in progress + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jnz .finish ; no DMA for sending +; dword boundary correction + cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE + ja .finish ; packet is too long +; write Frame Start Header + mov eax, ecx +; add header length and extend the complete length to dword boundary + add eax, ETH_HLEN+3 + and eax, not 3 + lea edx, [ebp+E3C59X_REG_TX_DATA] + out dx, eax +; prepare the complete frame + push esi + mov esi, edi + mov edi, e3c59x_tx_buff + zero_to_virt edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy packet data + pop esi + push ecx + shr ecx, 2 + rep movsd + pop ecx + and ecx, 3 + rep movsb + mov ecx, eax +; program frame address to be sent + lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] + mov eax, e3c59x_tx_buff + zero_to_dma eax + out dx, eax +; program frame length + lea edx, [ebp+E3C59X_REG_MASTER_LEN] + mov eax, ecx + out dx, ax +; start DMA Down + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10100b shl 11) + 1 ; StartDMADown + out dx, ax +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_boomerang_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, ebx, ecx, edx, esi, edi, ebp +; +;*************************************************************************** + align 4 +e3c59x_boomerang_transmit: + push ecx + call e3c59x_check_tx_status + pop ecx + test al, al + jz .no_error_found + jmp e3c59x_tx_reset +.no_error_found: + cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE + ja .finish ; packet is too long +; calculate descriptor address + mov eax, [e3c59x_prev_dpd] + cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE + jb @f +; wrap around + mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE +@@: + add eax, E3C59X_DPD_SIZE + zero_to_virt eax + push eax +; check DnListPtr + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + in eax, dx +; mark if Dn_List_Ptr is cleared + test eax, eax + setz [e3c59x_dn_list_ptr_cleared] +; finish if no more free descriptor is available - FIXME! + cmp eax, [esp] + pop eax + jz .finish + push eax esi + mov esi, edi +; calculate tx_buffer address + mov edi, [e3c59x_prev_tx_frame] + cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE + jb @f +; wrap around + mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE +@@: + add edi, E3C59X_MAX_ETH_FRAME_SIZE + zero_to_virt edi + mov eax, edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy packet data + pop esi + push ecx + shr ecx, 2 + rep movsd + pop ecx + push ecx + and ecx, 3 + rep movsb +; padding, do we really need it? + pop ecx + add ecx, ETH_HLEN + cmp ecx, ETH_ZLEN + jae @f + mov ecx, ETH_ZLEN +@@: +; calculate + mov ebx, ecx + ;test byte [e3c59x_has_hwcksm], 0xff + ;jz @f + ;or ebx, (1 shl 26) ; set AddTcpChecksum +;@@: + or ebx, 0x8000 ; transmission complete notification + or ecx, 0x80000000 ; last fragment +; program DPD + mov edi, eax + pop eax + and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0 + mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx + virt_to_dma edi + mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi + mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx +; calculate physical address + virt_to_dma eax + push eax + cmp byte [e3c59x_dn_list_ptr_cleared], 0 + jz .add_to_list +; write Dn_List_Ptr + out dx, eax + jmp .finish +.add_to_list: +; DnStall + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+2) + out dx, ax +; wait for DnStall to complete + mov ecx, 6000 +.wait_for_stall: + in ax, dx ; read E3C59X_REG_INT_STATUS + test ah, 10000b + jz .dnstall_ok + dec ecx + jnz .wait_for_stall +.dnstall_ok: + pop eax + push eax + mov ebx, [e3c59x_prev_dpd] + zero_to_virt ebx + mov [ebx], eax + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + in eax, dx + test eax, eax + jnz .dnunstall +; if Dn_List_Ptr has been cleared fill it up + pop eax + push eax + out dx, eax +.dnunstall: +; DnUnStall + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+3) + out dx, ax +.finish: + pop eax + dma_to_zero eax + mov [e3c59x_prev_dpd], eax + dma_to_zero edi + mov [e3c59x_prev_tx_frame], edi + ret + +;*************************************************************************** +; Function +; e3c59x_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed registers +; eax, ebx, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_poll: + jmp dword [e3c59x_receive_function] + +;*************************************************************************** +; Function +; e3c59x_vortex_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no packet received +; al - 1 ; packet received +; Destroyed registers +; eax, ebx, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_vortex_poll: + and word [eth_rx_data_len], 0 ; assume no packet received + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +.rx_status_loop: +; examine RxStatus + lea edx, [ebp+E3C59X_REG_RX_STATUS] + in ax, dx + test ax, ax + jz .finish + test ah, 0x80 ; rxIncomplete + jz .check_error + jmp .finish +.check_error: + test ah, 0x40 + jz .check_length +; discard the top frame received advancing the next one + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01000b shl 11) + out dx, ax + jmp .rx_status_loop +.check_length: + and eax, 0x1fff + cmp eax, E3C59X_MAX_ETH_PKT_SIZE + ja .discard_frame ; frame is too long discard it +.check_dma: + push eax +; switch to register window 7 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 + out dx, ax +; check for master operation in progress + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jz .read_frame ; no DMA for receiving + pop eax + jmp .finish +.read_frame: +; program buffer address to read in + lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] +if defined E3C59X_LINUX + mov eax, e3c59x_rx_buff + zero_to_dma eax +else + mov eax, Ether_buffer +end if + out dx, eax +; program frame length + lea edx, [ebp+E3C59X_REG_MASTER_LEN] + mov ax, 1560 + out dx, ax +; start DMA Up + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10100b shl 11) ; StartDMAUp + out dx, ax +; check for master operation in progress +.dma_loop: + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jnz .dma_loop +; registrate the received packet length + pop eax + mov word [eth_rx_data_len], ax +; discard the top frame received +.discard_frame: + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01000b shl 11) + out dx, ax +.finish: +; set return value + cmp word [eth_rx_data_len], 0 + setne al + ret + +;*************************************************************************** +; Function +; e3c59x_boomerang_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no packet received +; al - 1 ; packet received +; Destroyed registers +; eax, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_boomerang_poll: + and word [eth_rx_data_len], 0 ; assume no packet received + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +; check if packet is uploaded + mov eax, [e3c59x_curr_upd] + test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete + jnz .check_error + jmp .finish +; packet is uploaded check for any error +.check_error: + test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError + jz .copy_packet_length + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + jmp .finish +.copy_packet_length: + mov ecx, [eax+E3C59X_UPD_PKT_STATUS] + and ecx, 0x1fff + cmp ecx, E3C59X_MAX_ETH_PKT_SIZE + jbe .copy_packet + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + jmp .finish +.copy_packet: + push ecx + mov word [eth_rx_data_len], cx + mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR] + dma_to_virt esi + mov edi, Ether_buffer + shr ecx, 2 ; first copy dword-wise + cld + rep movsd ; copy the dwords + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes + mov eax, [e3c59x_curr_upd] + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + virt_to_zero eax + cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE + jb .no_wrap +; wrap around + mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE +.no_wrap: + add eax, E3C59X_UPD_SIZE + zero_to_virt eax + mov [e3c59x_curr_upd], eax +.finish: +; check if the NIC is in the upStall state + lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS] + in eax, dx + test ah, 0x20 ; UpStalled + jz .noUpUnStall +; issue upUnStall command + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+1) ; upUnStall + out dx, ax +.noUpUnStall: +; set return value + cmp word [eth_rx_data_len], 0 + setnz al + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/forcedeth.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/forcedeth.inc new file mode 100644 index 000000000..a520b9b0d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/forcedeth.inc @@ -0,0 +1,2692 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; FORCEDETH.INC ;; +;; ;; +;; Ethernet driver for Kolibri OS ;; +;; ;; +;; Version 0.1 24 June 2008 - 23 Sep 2008 ;; +;; ;; +;; Driver for chips of NVIDIA nForce2 ;; +;; References: ;; +;; forcedeth.c - linux driver (etherboot project) ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2008 shurf, ;; +;; cit.utc@gmail.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +;******************************************************************** +; Interface +; forcedeth_reset +; forcedeth_probe +; forcedeth_poll +; forcedeth_transmit +; forcedeth_cable +; +;******************************************************************** + +;************************************************************************** +; forcedeth Register Definitions +;************************************************************************** + +PCI_REG_COMMAND equ 0x04 ; command register + +PCI_COMMAND_IO equ 0x01 ; Enable response in I/O space +PCI_COMMAND_MASTER equ 0x04 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits + +PCI_VENDOR_ID equ 0x00 ; 16 bit +PCI_REVISION_ID equ 0x08 ; 8 bits + +PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits +PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits +PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits +PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits +PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits +PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits + +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) +PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) + +PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 +PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address +PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] +PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address + +; NIC specific static variables go here +PCI_DEVICE_ID_NVIDIA_NVENET_1 equ 0x01c3 +PCI_DEVICE_ID_NVIDIA_NVENET_2 equ 0x0066 +PCI_DEVICE_ID_NVIDIA_NVENET_4 equ 0x0086 +PCI_DEVICE_ID_NVIDIA_NVENET_5 equ 0x008c +PCI_DEVICE_ID_NVIDIA_NVENET_3 equ 0x00d6 +PCI_DEVICE_ID_NVIDIA_NVENET_7 equ 0x00df +PCI_DEVICE_ID_NVIDIA_NVENET_6 equ 0x00e6 +PCI_DEVICE_ID_NVIDIA_NVENET_8 equ 0x0056 +PCI_DEVICE_ID_NVIDIA_NVENET_9 equ 0x0057 +PCI_DEVICE_ID_NVIDIA_NVENET_10 equ 0x0037 +PCI_DEVICE_ID_NVIDIA_NVENET_11 equ 0x0038 +PCI_DEVICE_ID_NVIDIA_NVENET_12 equ 0x0268 +PCI_DEVICE_ID_NVIDIA_NVENET_13 equ 0x0269 +PCI_DEVICE_ID_NVIDIA_NVENET_14 equ 0x0372 +PCI_DEVICE_ID_NVIDIA_NVENET_15 equ 0x0373 + +ETH_DATA_LEN equ 1500 + +; rx/tx mac addr + type + vlan + align + slack +RX_NIC_BUFSIZE equ (ETH_DATA_LEN + 64) +; even more slack +RX_ALLOC_BUFSIZE equ (ETH_DATA_LEN + 128) + +NvRegIrqStatus equ 0x00 +NvRegIrqMask equ 0x04 +NvRegUnknownSetupReg6 equ 0x08 +NvRegPollingInterval equ 0x0c +NvRegMacReset equ 0x3c +NvRegMisc1 equ 0x80 +NvRegTransmitterControl equ 0x84 +NvRegTransmitterStatus equ 0x88 +NvRegPacketFilterFlags equ 0x8c +NvRegOffloadConfig equ 0x90 +NvRegReceiverControl equ 0x94 +NvRegReceiverStatus equ 0x98 +NvRegRandomSeed equ 0x9c +NvRegUnknownSetupReg1 equ 0xA0 +NvRegUnknownSetupReg2 equ 0xA4 +NvRegMacAddrA equ 0xA8 ; MAC address low +NvRegMacAddrB equ 0xAC ; MAC address high +NvRegMulticastAddrA equ 0xB0 +NvRegMulticastAddrB equ 0xB4 +NvRegMulticastMaskA equ 0xB8 +NvRegMulticastMaskB equ 0xBC +NvRegPhyInterface equ 0xC0 +NvRegTxRingPhysAddr equ 0x100 +NvRegRxRingPhysAddr equ 0x104 +NvRegRingSizes equ 0x108 +NvRegUnknownTransmitterReg equ 0x10c +NvRegLinkSpeed equ 0x110 +NvRegUnknownSetupReg5 equ 0x130 +NvRegUnknownSetupReg3 equ 0x13c +NvRegTxRxControl equ 0x144 +NvRegMIIStatus equ 0x180 +NvRegUnknownSetupReg4 equ 0x184 +NvRegAdapterControl equ 0x188 +NvRegMIISpeed equ 0x18c +NvRegMIIControl equ 0x190 +NvRegMIIData equ 0x194 +NvRegWakeUpFlags equ 0x200 +NvRegPowerState equ 0x26c +NvRegPowerState2 equ 0x600 + +NVREG_UNKSETUP1_VAL equ 0x16070f +NVREG_UNKSETUP2_VAL equ 0x16 +NVREG_UNKSETUP3_VAL1 equ 0x200010 +NVREG_UNKSETUP4_VAL equ 8 +NVREG_UNKSETUP5_BIT31 equ (1 shl 31) +NVREG_UNKSETUP6_VAL equ 3 + +NVREG_TXRXCTL_RXCHECK equ 0x0400 +NVREG_MIISTAT_ERROR equ 0x0001 +NVREG_MIISTAT_MASK equ 0x000f +NVREG_MIISTAT_MASK2 equ 0x000f +NVREG_MIICTL_INUSE equ 0x08000 +NVREG_MIICTL_WRITE equ 0x00400 +NVREG_MIICTL_ADDRSHIFT equ 5 + +NVREG_MIISPEED_BIT8 equ (1 shl 8) +NVREG_MIIDELAY equ 5 + +NVREG_IRQ_RX_ERROR equ 0x0001 +NVREG_IRQ_RX equ 0x0002 +NVREG_IRQ_RX_NOBUF equ 0x0004 +NVREG_IRQ_LINK equ 0x0040 +NVREG_IRQ_TIMER equ 0x0020 +NVREG_IRQMASK_WANTED_2 equ 0x0147 + +NVREG_IRQ_RX_ALL equ (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) +NVREG_IRQ_TX_ALL equ 0 ; ??????????? +NVREG_IRQ_OTHER_ALL equ (NVREG_IRQ_LINK or NVREG_IRQ_TIMER) + +NVREG_IRQSTAT_MASK equ 0x1ff + +NVREG_TXRXCTL_KICK equ 0x0001 +NVREG_TXRXCTL_BIT1 equ 0x0002 +NVREG_TXRXCTL_BIT2 equ 0x0004 +NVREG_TXRXCTL_IDLE equ 0x0008 +NVREG_TXRXCTL_RESET equ 0x0010 +NVREG_TXRXCTL_RXCHECK equ 0x0400 + +NVREG_MCASTADDRA_FORCE equ 0x01 + +NVREG_MAC_RESET_ASSERT equ 0x0F3 + +NVREG_MISC1_HD equ 0x02 +NVREG_MISC1_FORCE equ 0x3b0f3c + +NVREG_PFF_ALWAYS equ 0x7F0008 +NVREG_PFF_PROMISC equ 0x80 +NVREG_PFF_MYADDR equ 0x20 + +NVREG_OFFLOAD_HOMEPHY equ 0x601 +NVREG_OFFLOAD_NORMAL equ RX_NIC_BUFSIZE + +NVREG_RNDSEED_MASK equ 0x00ff +NVREG_RNDSEED_FORCE equ 0x7f00 +NVREG_RNDSEED_FORCE2 equ 0x2d00 +NVREG_RNDSEED_FORCE3 equ 0x7400 + +; NVREG_POLL_DEFAULT is the interval length of the timer source on the nic +; NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms +NVREG_POLL_DEFAULT equ 970 + +NVREG_ADAPTCTL_START equ 0x02 +NVREG_ADAPTCTL_LINKUP equ 0x04 +NVREG_ADAPTCTL_PHYVALID equ 0x40000 +NVREG_ADAPTCTL_RUNNING equ 0x100000 +NVREG_ADAPTCTL_PHYSHIFT equ 24 + +NVREG_WAKEUPFLAGS_VAL equ 0x7770 + +NVREG_POWERSTATE_POWEREDUP equ 0x8000 +NVREG_POWERSTATE_VALID equ 0x0100 +NVREG_POWERSTATE_MASK equ 0x0003 +NVREG_POWERSTATE_D0 equ 0x0000 +NVREG_POWERSTATE_D1 equ 0x0001 +NVREG_POWERSTATE_D2 equ 0x0002 +NVREG_POWERSTATE_D3 equ 0x0003 + +NVREG_POWERSTATE2_POWERUP_MASK equ 0x0F11 +NVREG_POWERSTATE2_POWERUP_REV_A3 equ 0x0001 + +NVREG_RCVCTL_START equ 0x01 +NVREG_RCVSTAT_BUSY equ 0x01 + +NVREG_XMITCTL_START equ 0x01 + +NVREG_LINKSPEED_FORCE equ 0x10000 +NVREG_LINKSPEED_10 equ 1000 +NVREG_LINKSPEED_100 equ 100 +NVREG_LINKSPEED_1000 equ 50 + +NVREG_RINGSZ_TXSHIFT equ 0 +NVREG_RINGSZ_RXSHIFT equ 16 + +LPA_1000FULL equ 0x0800 + +; Link partner ability register. +LPA_SLCT equ 0x001f ; Same as advertise selector +LPA_10HALF equ 0x0020 ; Can do 10mbps half-duplex +LPA_10FULL equ 0x0040 ; Can do 10mbps full-duplex +LPA_100HALF equ 0x0080 ; Can do 100mbps half-duplex +LPA_100FULL equ 0x0100 ; Can do 100mbps full-duplex +LPA_100BASE4 equ 0x0200 ; Can do 100mbps 4k packets +LPA_RESV equ 0x1c00 ; Unused... +LPA_RFAULT equ 0x2000 ; Link partner faulted +LPA_LPACK equ 0x4000 ; Link partner acked us +LPA_NPAGE equ 0x8000 ; Next page bit + +MII_READ equ (-1) +MII_PHYSID1 equ 0x02 ; PHYS ID 1 +MII_PHYSID2 equ 0x03 ; PHYS ID 2 +MII_BMCR equ 0x00 ; Basic mode control register +MII_BMSR equ 0x01 ; Basic mode status register +MII_ADVERTISE equ 0x04 ; Advertisement control reg +MII_LPA equ 0x05 ; Link partner ability reg +MII_SREVISION equ 0x16 ; Silicon revision +MII_RESV1 equ 0x17 ; Reserved... +MII_NCONFIG equ 0x1c ; Network interface config + +; PHY defines +PHY_OUI_MARVELL equ 0x5043 +PHY_OUI_CICADA equ 0x03f1 +PHYID1_OUI_MASK equ 0x03ff +PHYID1_OUI_SHFT equ 6 +PHYID2_OUI_MASK equ 0xfc00 +PHYID2_OUI_SHFT equ 10 +PHY_INIT1 equ 0x0f000 +PHY_INIT2 equ 0x0e00 +PHY_INIT3 equ 0x01000 +PHY_INIT4 equ 0x0200 +PHY_INIT5 equ 0x0004 +PHY_INIT6 equ 0x02000 +PHY_GIGABIT equ 0x0100 + +PHY_TIMEOUT equ 0x1 +PHY_ERROR equ 0x2 + +PHY_100 equ 0x1 +PHY_1000 equ 0x2 +PHY_HALF equ 0x100 + +PHY_RGMII equ 0x10000000 + +; desc_ver values: +; This field has two purposes: +; - Newer nics uses a different ring layout. The layout is selected by +; comparing np->desc_ver with DESC_VER_xy. +; - It contains bits that are forced on when writing to NvRegTxRxControl. +DESC_VER_1 equ 0x0 +DESC_VER_2 equ (0x02100 or NVREG_TXRXCTL_RXCHECK) + +MAC_ADDR_LEN equ 6 + +NV_TX_LASTPACKET equ (1 shl 16) +NV_TX_RETRYERROR equ (1 shl 19) +NV_TX_LASTPACKET1 equ (1 shl 24) +NV_TX_DEFERRED equ (1 shl 26) +NV_TX_CARRIERLOST equ (1 shl 27) +NV_TX_LATECOLLISION equ (1 shl 28) +NV_TX_UNDERFLOW equ (1 shl 29) +NV_TX_ERROR equ (1 shl 30) +NV_TX_VALID equ (1 shl 31) + +NV_TX2_LASTPACKET equ (1 shl 29) +NV_TX2_RETRYERROR equ (1 shl 18) +NV_TX2_LASTPACKET1 equ (1 shl 23) +NV_TX2_DEFERRED equ (1 shl 25) +NV_TX2_CARRIERLOST equ (1 shl 26) +NV_TX2_LATECOLLISION equ (1 shl 27) +NV_TX2_UNDERFLOW equ (1 shl 28) +; error and valid are the same for both +NV_TX2_ERROR equ (1 shl 30) +NV_TX2_VALID equ (1 shl 31) + +NV_RX_DESCRIPTORVALID equ (1 shl 16) +NV_RX_AVAIL equ (1 shl 31) + +NV_RX2_DESCRIPTORVALID equ (1 shl 29) + +RX_RING equ 4 +TX_RING equ 2 + +FLAG_MASK_V1 equ 0xffff0000 +FLAG_MASK_V2 equ 0xffffc000 +LEN_MASK_V1 equ (0xffffffff xor FLAG_MASK_V1) +LEN_MASK_V2 equ (0xffffffff xor FLAG_MASK_V2) + +; Miscelaneous hardware related defines: +NV_PCI_REGSZ_VER1 equ 0x270 +NV_PCI_REGSZ_VER2 equ 0x604 +; various timeout delays: all in usec +NV_TXRX_RESET_DELAY equ 4 +NV_TXSTOP_DELAY1 equ 10 +NV_TXSTOP_DELAY1MAX equ 500000 +NV_TXSTOP_DELAY2 equ 100 +NV_RXSTOP_DELAY1 equ 10 +NV_RXSTOP_DELAY1MAX equ 500000 +NV_RXSTOP_DELAY2 equ 100 +NV_SETUP5_DELAY equ 5 +NV_SETUP5_DELAYMAX equ 50000 +NV_POWERUP_DELAY equ 5 +NV_POWERUP_DELAYMAX equ 5000 +NV_MIIBUSY_DELAY equ 50 +NV_MIIPHY_DELAY equ 10 +NV_MIIPHY_DELAYMAX equ 10000 +NV_MAC_RESET_DELAY equ 64 +NV_WAKEUPPATTERNS equ 5 +NV_WAKEUPMASKENTRIES equ 4 + +; Advertisement control register. +ADVERTISE_SLCT equ 0x001f ; Selector bits +ADVERTISE_CSMA equ 0x0001 ; Only selector supported +ADVERTISE_10HALF equ 0x0020 ; Try for 10mbps half-duplex +ADVERTISE_10FULL equ 0x0040 ; Try for 10mbps full-duplex +ADVERTISE_100HALF equ 0x0080 ; Try for 100mbps half-duplex +ADVERTISE_100FULL equ 0x0100 ; Try for 100mbps full-duplex +ADVERTISE_100BASE4 equ 0x0200 ; Try for 100mbps 4k packets +ADVERTISE_RESV equ 0x1c00 ; Unused... +ADVERTISE_RFAULT equ 0x2000 ; Say we can detect faults +ADVERTISE_LPACK equ 0x4000 ; Ack link partners response +ADVERTISE_NPAGE equ 0x8000 ; Next page bit + +ADVERTISE_FULL equ (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA) +ADVERTISE_ALL equ (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL) + +MII_1000BT_CR equ 0x09 +MII_1000BT_SR equ 0x0a +ADVERTISE_1000FULL equ 0x0200 +ADVERTISE_1000HALF equ 0x0100 + +BMCR_ANRESTART equ 0x0200 ; Auto negotiation restart +BMCR_ANENABLE equ 0x1000 ; Enable auto negotiation +BMCR_SPEED100 equ 0x2000 ; Select 100Mbps +BMCR_LOOPBACK equ 0x4000 ; TXD loopback bits +BMCR_RESET equ 0x8000 ; Reset the DP83840 + +; Basic mode status register. +BMSR_ERCAP equ 0x0001 ; Ext-reg capability +BMSR_JCD equ 0x0002 ; Jabber detected +BMSR_LSTATUS equ 0x0004 ; Link status +BMSR_ANEGCAPABLE equ 0x0008 ; Able to do auto-negotiation +BMSR_RFAULT equ 0x0010 ; Remote fault detected +BMSR_ANEGCOMPLETE equ 0x0020 ; Auto-negotiation complete +BMSR_RESV equ 0x07c0 ; Unused... +BMSR_10HALF equ 0x0800 ; Can do 10mbps, half-duplex +BMSR_10FULL equ 0x1000 ; Can do 10mbps, full-duplex +BMSR_100HALF equ 0x2000 ; Can do 100mbps, half-duplex +BMSR_100FULL equ 0x4000 ; Can do 100mbps, full-duplex +BMSR_100BASE4 equ 0x8000 ; Can do 100mbps, 4k packets + +ETH_ALEN equ 6 +ETH_HLEN equ (2 * ETH_ALEN + 2) +ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length + +uglobal +forcedeth_mmio_addr dd 0 ; memory map physical address +forcedeth_mmio_size dd 0 ; size of memory bar +forcedeth_vendor_id dw 0 ; Vendor ID +forcedeth_device_id dw 0 ; Device ID +forcedeth_orig_mac0 dd 0 ; MAC +forcedeth_orig_mac1 dd 0 ; MAC +forcedeth_mapio_addr dd 0 ; mapped IO address +forcedeth_txflags dd 0 ; +forcedeth_desc_ver dd 0 ; +forcedeth_irqmask dd 0 ; IRQ-mask +forcedeth_wolenabled dd 0 ; WOL +forcedeth_in_shutdown dd 0 ; +forcedeth_cur_rx dd 0 ; +forcedeth_refill_rx dd 0 ; +forcedeth_phyaddr dd 0 ; +forcedeth_phy_oui dd 0 ; +forcedeth_gigabit dd 0 ; +forcedeth_needs_mac_reset dd 0 ; +forcedeth_linkspeed dd 0 ; +forcedeth_duplex dd 0 ; +forcedeth_next_tx dd 0 ; next TX descriptor number +forcedeth_nic_tx dd 0 ; ??? d'nt used ??? +forcedeth_packetlen dd 0 ; +forcedeth_nocable dd 0 ; no cable present +endg + +struc forcedeth_TxDesc { + .PacketBuffer dd ? + .FlagLen dd ? +} +virtual at 0 + forcedeth_TxDesc forcedeth_TxDesc + sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc +end virtual + +struc forcedeth_RxDesc { + .PacketBuffer dd ? + .FlagLen dd ? +} +virtual at 0 + forcedeth_RxDesc forcedeth_RxDesc + sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc +end virtual + +virtual at eth_data_start + ; Define the TX Descriptor + align 256 + forcedeth_tx_ring rb TX_RING * sizeof.forcedeth_TxDesc + ; Create a static buffer of size RX_BUF_SZ for each + ; TX Descriptor. All descriptors point to a + ; part of this buffer + align 256 + forcedeth_txb rb TX_RING * RX_NIC_BUFSIZE + + ; Define the RX Descriptor + align 256 + forcedeth_rx_ring rb RX_RING * sizeof.forcedeth_RxDesc + ; Create a static buffer of size RX_BUF_SZ for each + ; RX Descriptor. All descriptors point to a + ; part of this buffer + align 256 + forcedeth_rxb rb RX_RING * RX_NIC_BUFSIZE +end virtual + + +;*************************************************************************** +; Function +; forcedeth_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +forcedeth_reset: + + ; 1) erase previous misconfiguration + ; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill + + ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE + + ; writel(0, base + NvRegMulticastAddrB) + mov dword [edi+NvRegMulticastAddrB], 0 + + ; writel(0, base + NvRegMulticastMaskA) + mov dword [edi+NvRegMulticastMaskA], 0 + + ; writel(0, base + NvRegMulticastMaskB) + mov dword [edi+NvRegMulticastMaskB], 0 + + ; writel(0, base + NvRegPacketFilterFlags) + mov dword [edi+NvRegPacketFilterFlags], 0 + + ; writel(0, base + NvRegTransmitterControl) + mov dword [edi+NvRegTransmitterControl], 0 + + ; writel(0, base + NvRegReceiverControl) + mov dword [edi+NvRegReceiverControl], 0 + + ; writel(0, base + NvRegAdapterControl) + mov dword [edi+NvRegAdapterControl], 0 + + + ; 2) initialize descriptor rings + ; init_ring(nic) + call forcedeth_init_ring + + ; writel(0, base + NvRegLinkSpeed) + mov dword [edi+NvRegLinkSpeed], 0 + + ; writel(0, base + NvRegUnknownTransmitterReg) + mov dword [edi+NvRegUnknownTransmitterReg], 0 + + ; txrx_reset(nic) + call forcedeth_txrx_reset + + ; writel(0, base + NvRegUnknownSetupReg6) + mov dword [edi+NvRegUnknownSetupReg6], 0 + + ; np->in_shutdown = 0 + mov dword [forcedeth_in_shutdown], 0 + + + ; 3) set mac address + ; writel(mac[0], base + NvRegMacAddrA) + mov eax, dword [forcedeth_orig_mac0] + mov dword [edi+NvRegMacAddrA], eax + + ; writel(mac[1], base + NvRegMacAddrB) + mov eax, dword [forcedeth_orig_mac1] + mov dword [edi+NvRegMacAddrB], eax + + + ; 4) give hw rings + ; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr) + mov eax, forcedeth_rx_ring + +;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax + + sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dword [edi+NvRegRxRingPhysAddr], eax + + ; writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr) + mov eax, forcedeth_tx_ring + sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dword [edi+NvRegTxRingPhysAddr], eax + + ; writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes) + mov dword [edi+NvRegRingSizes], (((RX_RING - 1) shl NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) shl NVREG_RINGSZ_TXSHIFT)) + + ; 5) continue setup + ; np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 + mov dword [forcedeth_linkspeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + + ; np->duplex = 0 + mov dword [forcedeth_duplex], 0 + + ; writel(np->linkspeed, base + NvRegLinkSpeed) + mov dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + + ; writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3) + mov dword [edi+NvRegUnknownSetupReg3], NVREG_UNKSETUP3_VAL1 + + ; writel(np->desc_ver, base + NvRegTxRxControl) + mov eax, dword [forcedeth_desc_ver] + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base) + call forcedeth_pci_push + + ; writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl) + or eax, NVREG_TXRXCTL_BIT1 + mov dword [edi+NvRegTxRxControl], eax + + ; reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n") + push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; + stdcall forcedeth_reg_delay,NvRegUnknownSetupReg5,NVREG_UNKSETUP5_BIT31,NVREG_UNKSETUP5_BIT31,NV_SETUP5_DELAY,NV_SETUP5_DELAYMAX,0 + pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; + + ; writel(0, base + NvRegUnknownSetupReg4) + mov dword [edi+NvRegUnknownSetupReg4], 0 + + ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) + mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 + + + ; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half") +;;;;;;;;;;; DEBUGF + + ; 6) continue setup + + ; writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1) + mov dword [edi+NvRegMisc1], (NVREG_MISC1_FORCE or NVREG_MISC1_HD) + + ; writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus) + mov eax, dword [edi+NvRegTransmitterStatus] + mov dword [edi+NvRegTransmitterStatus], eax + + ; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags) + mov dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS + + ; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig) + mov dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL + + ; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus) + mov eax, dword [edi+NvRegReceiverStatus] + mov dword [edi+NvRegReceiverStatus], eax + + ; Get a random number + ; i = random() + push edi + stdcall sys_clock ; eax = 0x00SSMMHH (current system time) + pop edi + + ; writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed) + and eax, NVREG_RNDSEED_MASK + or eax, NVREG_RNDSEED_FORCE + mov dword [edi+NvRegRandomSeed], eax + + ; writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1) + mov dword [edi+NvRegUnknownSetupReg1], NVREG_UNKSETUP1_VAL + + ; writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2) + mov dword [edi+NvRegUnknownSetupReg2], NVREG_UNKSETUP2_VAL + + ; writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval) + mov dword [edi+NvRegPollingInterval], NVREG_POLL_DEFAULT + + ; writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6) + mov dword [edi+NvRegUnknownSetupReg6], NVREG_UNKSETUP6_VAL + + ; writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING, + ; base + NvRegAdapterControl) + mov eax, dword [forcedeth_phyaddr] + shl eax, NVREG_ADAPTCTL_PHYSHIFT + or eax, (NVREG_ADAPTCTL_PHYVALID or NVREG_ADAPTCTL_RUNNING) + mov dword [edi+NvRegAdapterControl], eax + + ; writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed) + mov dword [edi+NvRegMIISpeed], (NVREG_MIISPEED_BIT8 or NVREG_MIIDELAY) + + ; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4) + mov dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL + + ; writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags) + mov dword [edi+NvRegWakeUpFlags], NVREG_WAKEUPFLAGS_VAL + + ; i = readl(base + NvRegPowerState) + mov eax, dword [edi+NvRegPowerState] + + ; if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) + test eax, NVREG_POWERSTATE_POWEREDUP + jnz @f + ; writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState) + or eax, NVREG_POWERSTATE_POWEREDUP + mov dword [edi+NvRegPowerState], eax + +@@: + + ; pci_push(base) + call forcedeth_pci_push + + ; nv_udelay(10) + mov esi, 10 + call forcedeth_nv_udelay + + ; writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState) + mov eax, dword [edi+NvRegPowerState] + or eax, NVREG_POWERSTATE_VALID + mov dword [edi+NvRegPowerState], eax + + ; ??? disable all interrupts ??? + ; writel(0, base + NvRegIrqMask) + mov dword [edi+NvRegIrqMask], 0 + +;;; ; ??? Mask RX interrupts +;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_RX_ALL +;;; ; ??? Mask TX interrupts +;;; ;mov dword [edi+NvRegIrqMask], NVREG_IRQ_TX_ALL +;;; ; ??? Mask OTHER interrupts +;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_OTHER_ALL + + ; pci_push(base) + call forcedeth_pci_push + + ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) + mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 + + ; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus) + mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK + + ; pci_push(base) + call forcedeth_pci_push + + + ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) + mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE + + ; writel(0, base + NvRegMulticastAddrB) + mov dword [edi+NvRegMulticastAddrB], 0 + + ; writel(0, base + NvRegMulticastMaskA) + mov dword [edi+NvRegMulticastMaskA], 0 + + ; writel(0, base + NvRegMulticastMaskB) + mov dword [edi+NvRegMulticastMaskB], 0 + + ; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags) + mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR) + + ; set_multicast(nic) + call forcedeth_set_multicast + + ; One manual link speed update: Interrupts are enabled, future link + ; speed changes cause interrupts and are handled by nv_link_irq(). + + ; miistat = readl(base + NvRegMIIStatus) + mov eax, dword [edi+NvRegMIIStatus] + + ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); + mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK + + ; dprintf(("startup: got 0x%hX.\n", miistat)); +;;; DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax + + + ; ret = update_linkspeed(nic) + call forcedeth_update_linkspeed + push eax + + ; start_tx(nic) + call forcedeth_start_tx + + pop eax + +; if (ret) { +; //Start Connection netif_carrier_on(dev); +; } else { +; printf("no link during initialization.\n"); +; } + + ;*** added by shurf (21.09.2008) + mov dword [forcedeth_nocable], 0 + ;*** + + test eax, eax + jnz .return + DEBUGF 1," K : FORCEDETH: no link during initialization.\n" + + ;*** added by shurf (21.09.2008) + mov dword [forcedeth_nocable], 1 + ;*** + +.return: + +; Indicate that we have successfully reset the card + mov eax, dword [pci_data] + mov dword [eth_status], eax + ret + + + +;*************************************************************************** +; Function +; forcedeth_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; +;*************************************************************************** +forcedeth_probe: + +; DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + mov dword [forcedeth_needs_mac_reset], 0 + +; BEGIN of adjust_pci_device() + ; read word from PCI-device + mov al, 1 ;;;;;;;;;;;;;;2 + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_REG_COMMAND + call pci_read_reg + mov bx, ax ; new command + or bx, PCI_COMMAND_MASTER + or bx, PCI_COMMAND_IO + cmp bx, ax + je @f + ; Enabling PCI-device (make card as bus master) + DEBUGF 1," K : FORCEDETH: Updating PCI command 0x%x->0x%x\n", ax, bx + mov cx, bx + mov al, 1 ;;;;;;;;;;;;2 + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_REG_COMMAND + call pci_write_reg + + ; Check latency settings +@@: + ; Get current latency settings from Latency timer register (byte) + mov al, 0 ;;;;;;;;;1 + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_LATENCY_TIMER + call pci_read_reg + + ; see if its at least 32 + cmp al, 32 + jge @f + ; set latency to 32 + DEBUGF 1, "K : FORCEDETH: PCI latency timer (CFLT) is unreasonably low at %d.\n", al + DEBUGF 1, "K : FORCEDETH: Setting to 32 clocks.\n" + mov cl, 32 + mov al, 0 ;;;;;;;1 + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_LATENCY_TIMER + call pci_write_reg +; END of adjust_pci_device() + +@@: +; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0)) + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + call pci_read_reg + test eax, PCI_BASE_ADDRESS_SPACE_IO + jz @f + and eax, PCI_BASE_ADDRESS_IO_MASK + jmp .next +@@: push eax + and eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK + cmp eax, PCI_BASE_ADDRESS_MEM_TYPE_64 + jne .not64 + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + 4 + call pci_read_reg + or eax, eax + jz .not64 + DEBUGF 1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n" + or eax, -1 + jmp .next +.not64: + pop eax + and eax, PCI_BASE_ADDRESS_MEM_MASK +.next: +; END of pci_bar_start +; addr = eax + mov dword [forcedeth_mmio_addr], eax + + +; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0)) + + ; Save original bar + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + call pci_read_reg + mov dword [forcedeth_tmp_start], eax + ; Compute which bits can be set + ; (ecx - value to write) + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + mov ecx, (not 0) + call pci_write_reg + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + call pci_read_reg + push eax + ; Restore the original size + mov al, 2 ; dword + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_BASE_ADDRESS_0 + mov ecx, dword [forcedeth_tmp_start] + call pci_write_reg + ; Find the significant bits + pop eax + test dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO + jz @f + and eax, PCI_BASE_ADDRESS_IO_MASK + jmp .next2 +@@: and eax, PCI_BASE_ADDRESS_MEM_MASK +.next2: + ; Find the lowest bit set + mov ecx, eax + sub eax, 1 + not eax + and ecx, eax + +; END of pci_bar_start + mov dword [forcedeth_mmio_size], ecx + + DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8 + + ; Get Vendor and Device ID + mov al, 2 + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_VENDOR_ID + call pci_read_reg + mov word [forcedeth_vendor_id], ax + shr eax, 16 + mov word [forcedeth_device_id], ax + + DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 + + ; handle different descriptor versions + mov eax, dword [forcedeth_device_id] + cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_1 + je .ver1 + cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_2 + je .ver1 + cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_3 + je .ver1 + mov dword [forcedeth_desc_ver], DESC_VER_2 + jmp @f +.ver1: mov dword [forcedeth_desc_ver], DESC_VER_1 +@@: + ; read the mac address + ; map memory + stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE) + test eax, eax + jz .fail + + mov dword [forcedeth_mapio_addr], eax + mov edi, eax + mov eax, dword [edi+NvRegMacAddrA] + mov dword [forcedeth_orig_mac0], eax + mov edx, dword [edi+NvRegMacAddrB] + mov dword [forcedeth_orig_mac1], edx + + ; save MAC-address to global variable node_addr + mov dword [node_addr], eax + mov word [node_addr+4], dx + + ; reverse if desired + cmp word [forcedeth_device_id], 0x03E5 + jae .no_reverse_mac + mov al, byte [node_addr] + xchg al, byte [node_addr+5] + mov byte [node_addr], al + mov al, byte [node_addr+1] + xchg al, byte [node_addr+4] + mov byte [node_addr+4], al + mov al, byte [node_addr+2] + xchg al, byte [node_addr+3] + mov byte [node_addr+3], al +.no_reverse_mac: + +; DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8 +; DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8 + DEBUGF 1," K : FORCEDETH: MAC = %x-%x-%x-%x-%x-%x\n", [node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2, + + ; disable WOL + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegWakeUpFlags], 0 + mov dword [forcedeth_wolenabled], 0 + + mov dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID) + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + mov dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID) +@@: + +; BEGIN of switch (pci->dev_id) + + cmp word [forcedeth_device_id], 0x01C3 + jne .next_0x0066 + ; nforce + mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) + jmp .end_switch + +.next_0x0066: + cmp word [forcedeth_device_id], 0x0066 + je @f + cmp word [forcedeth_device_id], 0x00D6 + je @f + jmp .next_0x0086 +@@: + mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + or dword [forcedeth_txflags], NV_TX_LASTPACKET1 + jmp .end_switch +@@: or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 + jmp .end_switch + +.next_0x0086: + cmp word [forcedeth_device_id], 0x0086 + je @f + cmp word [forcedeth_device_id], 0x008c + je @f + cmp word [forcedeth_device_id], 0x00e6 + je @f + cmp word [forcedeth_device_id], 0x00df + je @f + cmp word [forcedeth_device_id], 0x0056 + je @f + cmp word [forcedeth_device_id], 0x0057 + je @f + cmp word [forcedeth_device_id], 0x0037 + je @f + cmp word [forcedeth_device_id], 0x0038 + je @f + jmp .next_0x0268 +@@: + ; np->irqmask = NVREG_IRQMASK_WANTED_2; + ; np->irqmask |= NVREG_IRQ_TIMER; + mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) + + ; if (np->desc_ver == DESC_VER_1) + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + ; np->tx_flags |= NV_TX_LASTPACKET1; + or dword [forcedeth_txflags], NV_TX_LASTPACKET1 + jmp .end_switch + ; else +@@: + ; np->tx_flags |= NV_TX2_LASTPACKET1; + or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 + + ; break; + jmp .end_switch + +.next_0x0268: +; cmp word [forcedeth_device_id], 0x0268 +; je @f +; cmp word [forcedeth_device_id], 0x0269 +; je @f +; cmp word [forcedeth_device_id], 0x0372 +; je @f +; cmp word [forcedeth_device_id], 0x0373 +; je @f +; jmp .default_switch +;@@: + cmp word [forcedeth_device_id], 0x0268 + jb .default_switch + ; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id); + mov al, 0 ; byte + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, PCI_REVISION_ID + call pci_read_reg + mov ecx, eax ; cl = revision_id + + ; take phy and nic out of low power mode + ; powerstate = readl(base + NvRegPowerState2); + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi+NvRegPowerState2] ; eax = powerstate + + ; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; + and eax, not NVREG_POWERSTATE2_POWERUP_MASK + + ; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3) + cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12 + je @f + cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13 + je @f + jmp .end_if +@@: + cmp cl, 0xA3 + jl .end_if + ; powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; + or eax, NVREG_POWERSTATE2_POWERUP_REV_A3 + +.end_if: + + ; writel(powerstate, base + NvRegPowerState2); + mov dword [edi+NvRegPowerState2], eax + + ; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ + ; np->irqmask = NVREG_IRQMASK_WANTED_2; + ; np->irqmask |= NVREG_IRQ_TIMER; + mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) + + ; needs_mac_reset = 1; + mov dword [forcedeth_needs_mac_reset], 1 + + ; if (np->desc_ver == DESC_VER_1) + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + ; np->tx_flags |= NV_TX_LASTPACKET1; + or dword [forcedeth_txflags], NV_TX_LASTPACKET1 + jmp .end_if2 +@@: + ; else + ; np->tx_flags |= NV_TX2_LASTPACKET1; + or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 + +.end_if2: + ; break; + jmp .end_switch + +.default_switch: + DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n" + DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n" + +.end_switch: + +; END of switch (pci->dev_id) + + + ; Find a suitable phy + mov dword [forcedeth_tmp_i], 1 +.for_loop: + ; for (i = 1; i <= 32; i++) + ; phyaddr = i & 0x1f + mov ebx, dword [forcedeth_tmp_i] + and ebx, 0x1f + + ; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ) + ;EBX - addr, EAX - miireg, ECX - value + mov eax, MII_PHYSID1 + mov ecx, MII_READ + call forcedeth_mii_rw ; id1 = eax + + ; if (id1 < 0 || id1 == 0xffff) + cmp eax, 0xffffffff + je .continue_for + test eax, 0x80000000 + jnz .continue_for + mov dword [forcedeth_tmp_id1], eax + + ; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ) + mov eax, MII_PHYSID2 + mov ecx, MII_READ + call forcedeth_mii_rw ; id2 = eax + + ; if (id2 < 0 || id2 == 0xffff) + cmp eax, 0xffffffff + je .continue_for + test eax, 0x80000000 + jnz .continue_for + mov dword [forcedeth_tmp_id2], eax + + jmp .break_for +.continue_for: + inc dword [forcedeth_tmp_i] + cmp dword [forcedeth_tmp_i], 32 + jle .for_loop + jmp .end_for + +.break_for: + +;;;; DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8 + + ; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT + mov eax, dword [forcedeth_tmp_id1] + and eax, PHYID1_OUI_MASK + shl eax, PHYID1_OUI_SHFT + mov dword [forcedeth_tmp_id1], eax + + ; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT + mov eax, dword [forcedeth_tmp_id2] + and eax, PHYID2_OUI_MASK + shr eax, PHYID2_OUI_SHFT + mov dword [forcedeth_tmp_id2], eax + + DEBUGF 1," K : FORCEDETH: Found PHY 0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx + + ; np->phyaddr = phyaddr; + mov dword [forcedeth_phyaddr], ebx + + ; np->phy_oui = id1 | id2; + mov eax, dword [forcedeth_tmp_id1] + or eax, dword [forcedeth_tmp_id2] + mov dword [forcedeth_phy_oui], eax + +.end_for: + + ; if (i == 33) + cmp dword [forcedeth_tmp_i], 33 + jne @f + ; PHY in isolate mode? No phy attached and user wants to + ; test loopback? Very odd, but can be correct. + + DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n" + + jmp .next3 + +@@: + + ; if (i != 33) + ; reset it + call forcedeth_phy_init + +.next3: + +; dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n", +; pci->name, pci->vendor, pci->dev_id, pci->name)); + DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 + + +; if(needs_mac_reset) mac_reset(nic); + cmp dword [forcedeth_needs_mac_reset], 0 + je @f + call forcedeth_mac_reset + +@@: + + ; if(!forcedeth_reset(nic)) return 0; // no valid link + call forcedeth_reset + test eax, eax + jnz @f + mov eax, 0 + jmp .return + +@@: + + ; point to NIC specific routines + ; dev->disable = forcedeth_disable; + ; nic->poll = forcedeth_poll; + ; nic->transmit = forcedeth_transmit; + ; nic->irq = forcedeth_irq; + ;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0 + + ; return 1 + mov eax, 1 + jmp .return + +.fail: + mov eax, 0 + +.return: + ret + +uglobal +forcedeth_tmp_start dd ? +forcedeth_tmp_reg dd ? +forcedeth_tmp_i dd ? +forcedeth_tmp_id1 dd ? +forcedeth_tmp_id2 dd ? +forcedeth_tmp_phyinterface dd ? +forcedeth_tmp_newls dd ? +forcedeth_tmp_newdup dd ? +forcedeth_tmp_retval dd ? +forcedeth_tmp_control_1000 dd ? +forcedeth_tmp_lpa dd ? +forcedeth_tmp_adv dd ? +forcedeth_tmp_len dd ? +forcedeth_tmp_valid dd ? +forcedeth_tmp_nr dd ? +forcedeth_tmp_ptxb dd ? +endg + +;*************************************************************************** +; Function +; forcedeth_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; +;*************************************************************************** +forcedeth_poll: + + mov word [eth_rx_data_len], 0 + + ; ???????????????????????????? + ; ??? Clear events? ??? + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK + ; ???????????????????????????? + +.top: + + ; i = np->cur_rx % RX_RING + mov eax, dword [forcedeth_cur_rx] + and eax, (RX_RING-1) + mov dword [forcedeth_tmp_i], eax + + ; Flags = le32_to_cpu(rx_ring[i].FlagLen) + ; Flags = rx_ring[i].FlagLen + mov cl, sizeof.forcedeth_RxDesc + mul cl + add eax, forcedeth_rx_ring + mov ebx, eax + mov eax, [ebx + forcedeth_RxDesc.FlagLen] + + + ; if (Flags & NV_RX_AVAIL) + test eax, NV_RX_AVAIL + ; return 0; /* still owned by hardware, */ + ; still owned by hardware + jnz .return0 + +;;;;; DEBUGF 1,"poll: FlagLen = %x\n", eax + + ; if (np->desc_ver == DESC_VER_1) { + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + ; if (!(Flags & NV_RX_DESCRIPTORVALID)) + test eax, NV_RX_DESCRIPTORVALID + ; return 0; + jz .return0 + jmp .next + ; } else { +@@: + ; if (!(Flags & NV_RX2_DESCRIPTORVALID)) + test eax, NV_RX2_DESCRIPTORVALID + ; return 0; + jz .return0 + ; } + +.next: + + ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) + ; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); + ; eax = FlagLen + cmp dword [forcedeth_desc_ver], DESC_VER_1 + jne @f + and eax, LEN_MASK_V1 + jmp .next2 +@@: + and eax, LEN_MASK_V2 + +.next2: + + ; mov dword [forcedeth_tmp_len], eax + + ; valid = 1 + mov dword [forcedeth_tmp_valid], 1 + + ; got a valid packet - forward it to the network core + ; nic->packetlen = len; + mov dword [forcedeth_packetlen], eax + ; + mov word [eth_rx_data_len], ax +;;;;;;;;; DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen] + + + ; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen); + ; Copy packet to system buffer (Ether_buffer) + ;???? ecx = (len-4) + mov ecx, eax + push ecx + shr ecx, 2 + + ; rxb + (i * RX_NIC_BUFSIZE) + mov eax, dword [forcedeth_tmp_i] + mov bx, RX_NIC_BUFSIZE + mul bx + add eax, forcedeth_rxb + + mov esi, eax + mov edi, Ether_buffer + cld ; set to increment + rep movsd ; mov dword from [esi++] to [edi++] + pop ecx + and ecx, 3 ; copy rest 1-3 bytes + rep movsb + + ; wmb(); + ; ??? + + ; np->cur_rx++; + inc dword [forcedeth_cur_rx] + + ; if (!valid) + cmp dword [forcedeth_tmp_valid], 0 + jne @f + ; goto top; + jmp .top +@@: + ; alloc_rx(nic); + call forcedeth_alloc_rx + + ; return 1; + jmp .return1 + +;;;;; DEBUGF 1,"K : FORCEDETH: poll: ...\n" + + +.return0: + mov eax, 0 + jmp .return +.return1: + mov eax, 1 +.return: + ;;push eax + + ; ???????????????????????????????????????????????? + ; ????? clear interrupt mask/status + ; read IRQ status + ;;mov edi, dword [forcedeth_mapio_addr] + ;;mov eax, dword [edi+NvRegIrqStatus] + + ; clear events + ;;and eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER) + + ; write IRQ status + ;;mov dword [edi+NvRegIrqStatus], eax + ; ???????????????????????????????????????????????? + + ;;pop eax + ret + + +;*************************************************************************** +; Function +; forcedeth_transmit +; +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +forcedeth_transmit: + + ; send the packet to destination +;pusha +;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx +;DEBUGF 1,"K : FORCEDETH: transmit: packet len = 0x%x\n", ecx +;mov eax, dword [edi] +;DEBUGF 1,"K : FORCEDETH: transmit: dest adr = 0x%x\n", eax +;mov eax, dword [edi+4] +;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2 = 0x%x\n", eax +;mov eax, dword [node_addr] +;DEBUGF 1,"K : FORCEDETH: transmit: src adr = 0x%x\n", eax +;mov eax, dword [node_addr+4] +;DEBUGF 1,"K : FORCEDETH: transmit: src adr2 = 0x%x\n", eax +;popa + + ; int nr = np->next_tx % TX_RING + mov eax, dword [forcedeth_next_tx] + and eax, (TX_RING-1) + mov dword [forcedeth_tmp_nr], eax + + ; point to the current txb incase multiple tx_rings are used + ; ptxb = txb + (nr * RX_NIC_BUFSIZE) + push ecx + mov cx, RX_NIC_BUFSIZE + mul cx ; AX*CX, result to DX:AX + add eax, forcedeth_txb + mov dword [forcedeth_tmp_ptxb], eax + push esi + mov esi, edi ; dst MAC + mov edi, eax ; packet buffer + cld ; set to increment + + ; copy the packet to ring buffer + ; memcpy(ptxb, d, ETH_ALEN); /* dst */ + movsd + movsw + + ; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ + mov esi, node_addr + movsd + movsw + + ; nstype = htons((u16) t); /* type */ + ; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ + mov word [edi], bx + add edi, 2 + + ; memcpy(ptxb + ETH_HLEN, p, s); + pop esi + pop ecx + push ecx + shr ecx, 2 ; count in dwords + rep movsd ; copy dwords from [esi+=4] to [edi+=4] + pop ecx + push ecx + and ecx, 3 ; copy rest 1-3 bytes + rep movsb ; copy bytess from [esi++] to [edi++] + + + ; s += ETH_HLEN; + ; while (s < ETH_ZLEN) /* pad to min length */ + ; ptxb[s++] = '\0'; + ; pad to min length + pop ecx + add ecx, ETH_HLEN + push ecx ; header length + data length + cmp ecx, ETH_ZLEN + jge @f + mov eax, ETH_ZLEN + sub eax, ecx + xchg eax, ecx + mov al, 0 + rep stosb ; copy byte from al to [edi++] + +@@: + + ; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb); + mov eax, dword [forcedeth_tmp_nr] + mov cl, sizeof.forcedeth_TxDesc + mul cl + add eax, forcedeth_tx_ring + mov ebx, eax + mov eax, dword [forcedeth_tmp_ptxb] + sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov [ebx + forcedeth_TxDesc.PacketBuffer], eax + +;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax +;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8 + + ; wmb(); + ; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags); + pop eax ; header length + data length + mov ecx, dword [forcedeth_txflags] + or eax, ecx + mov [ebx + forcedeth_TxDesc.FlagLen], eax + + ; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl); + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [forcedeth_desc_ver] + or eax, NVREG_TXRXCTL_KICK + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base); + call forcedeth_pci_push + + ; np->next_tx++ + inc dword [forcedeth_next_tx] ; may be need to reset? Overflow? + + ret + +;*************************************************************************** +; Function +; forcedeth_cable +; +; Description +; Return AL=0, if cable is not connected +; Returm AL=1, if cable is connected +; +;*************************************************************************** +forcedeth_cable: + + mov al, 1 + cmp dword [forcedeth_nocable], 1 + jne .return + mov al, 0 + +.return: + ret + +;*************************************************************************** + + +; read/write a register on the PHY. +; Caller must guarantee serialization +; Input: EAX - miireg, EBX - addr, ECX - value +; Output: EAX - retval +forcedeth_mii_rw: + push ebx + push eax ; save miireg + ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus) + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK + + ; reg = readl(base + NvRegMIIControl) + mov eax, dword [edi+NvRegMIIControl] + test eax, NVREG_MIICTL_INUSE + jz @f + ; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl) + mov dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE + ; nv_udelay(NV_MIIBUSY_DELAY) + mov esi, NV_MIIBUSY_DELAY + call forcedeth_nv_udelay +@@: + ; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg + pop edx ; restore miireg + mov eax, ebx + shl eax, NVREG_MIICTL_ADDRSHIFT + or eax, edx + mov dword [forcedeth_tmp_reg], eax + + cmp ecx, MII_READ + je @f + ; writel(value, base + NvRegMIIData) + mov dword [edi+NvRegMIIData], ecx + ; reg |= NVREG_MIICTL_WRITE + or dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE +@@: + ; writel(reg, base + NvRegMIIControl) + mov eax, dword [forcedeth_tmp_reg] + mov dword [edi+NvRegMIIControl], eax + + push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; + + ; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL) + stdcall forcedeth_reg_delay,NvRegMIIControl,NVREG_MIICTL_INUSE,0,NV_MIIPHY_DELAY,NV_MIIPHY_DELAYMAX,0 + + pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; + + test eax, eax + jz @f +;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx + mov eax, 0xffffffff + jmp .return +@@: + cmp ecx, MII_READ + je @f + ;it was a write operation - fewer failures are detectable +;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx + mov eax, 0 + jmp .return +@@: + ; readl(base + NvRegMIIStatus) + mov eax, dword [edi+NvRegMIIStatus] + test eax, NVREG_MIISTAT_ERROR + jz @f +;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx + mov eax, 0xffffffff + jmp .return +@@: + ; retval = readl(base + NvRegMIIData) + mov eax, dword [edi+NvRegMIIData] +;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax +.return: + pop ebx + ret + + + +; Input: ESI - delay +; Output: none +forcedeth_nv_udelay: + + push ebx + cmp dword [forcedeth_in_shutdown], 0 + jne @f + call forcedeth_udelay ; delay on ESI + jmp .return +@@: + +.loop: + cmp esi, 0 + je .return + ; Don't allow an rx_ring overflow to happen + ; while shutting down the NIC it will + ; kill the receive function. + + call forcedeth_drop_rx + mov ebx, 3 ; sleep = 3 + cmp ebx, esi ; if(sleep > delay) + jle @f + mov ebx, esi ; sleep = delay +@@: + push esi + mov esi, ebx + ; udelay(sleep) + call forcedeth_udelay ; delay on ESI + pop esi + sub esi, ebx ; delay -= sleep + jmp .loop + +.return: + pop ebx + ret + + +; Input: none +; Output: none +forcedeth_drop_rx: + + push eax ebx ecx edi + + ; events = readl(base + NvRegIrqStatus) + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi+NvRegIrqStatus] + + test eax, eax + jz @f + ; writel(events, base + NvRegIrqStatus) + mov dword [edi+NvRegIrqStatus], eax +@@: + ;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF))) + test eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) + jz .return + +.loop: + ; i = np->cur_rx % RX_RING + mov eax, dword [forcedeth_cur_rx] + and eax, (RX_RING-1) + ; //Flags = le32_to_cpu(rx_ring[i].FlagLen) + ; Flags = rx_ring[i].FlagLen + mov cl, sizeof.forcedeth_RxDesc + mul cl + add eax, forcedeth_rx_ring + mov ebx, eax + mov eax, [ebx + forcedeth_RxDesc.FlagLen] + ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) + ; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2) + ; ??? len don't used later !!! ??? + ; ... + test eax, NV_RX_AVAIL + jnz .return ; still owned by hardware, + ; wmb() + ; ??? may be empty function ??? + ; np->cur_rx++ + inc dword [forcedeth_cur_rx] + ; alloc_rx(NULL) + call forcedeth_alloc_rx +.return: + pop edi ecx ebx eax + ret + + +; Fill rx ring entries. +; Return 1 if the allocations for the skbs failed and the +; rx engine is without Available descriptors +; Input: none +; Output: none +forcedeth_alloc_rx: + + push eax ebx ecx edx + ; refill_rx = np->refill_rx + mov ecx, dword [forcedeth_refill_rx] +.loop: + cmp dword [forcedeth_cur_rx], ecx + je .loop_end + ; nr = refill_rx % RX_RING + mov eax, ecx + and eax, (RX_RING-1) ; nr + ; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE] + push ecx + push eax + mov cl, sizeof.forcedeth_RxDesc + mul cl + add eax, forcedeth_rx_ring + mov ebx, eax + pop eax + mov cx, RX_NIC_BUFSIZE + mul cx + pop ecx + add eax, forcedeth_rxb + sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov [ebx + forcedeth_RxDesc.PacketBuffer], eax + ; wmb() + ; ... + ; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL + mov [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL) + inc ecx + jmp .loop + +.loop_end: + ; np->refill_rx = refill_rx + mov [forcedeth_refill_rx], ecx +.return: + pop edx ecx ebx eax + ret + + +; Delay in millisec +; Input: ESI - delay in ms +; Output: none +forcedeth_udelay: + call delay_ms + ret + +; Input: offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword +; Output: EAX - 0|1 +;;;;proc forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword +proc forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword + + push ebx esi edi + ; pci_push(base) + call forcedeth_pci_push +.loop: + ; nv_udelay(delay) + mov esi, dword [delay] + call forcedeth_nv_udelay ; delay in esi + mov eax, dword [delaymax] + sub eax, dword [delay] + mov dword [delaymax], eax + ; if (delaymax < 0) + test dword [delaymax], 0x80000000 + jz @f + ; return 1 + mov eax, 1 + jmp .return +@@: + ; while ((readl(base + offset) & mask) != target) + mov edi, dword [forcedeth_mapio_addr] + mov ebx, dword [offset] + mov eax, dword [edi+ebx] + and eax, dword [mask] + cmp eax, dword [target] + jne .loop + xor eax, eax +.return: + pop edi esi ebx + ret +endp + + +; Input: none +; Output: none +forcedeth_pci_push: + push eax edi + ;force out pending posted writes + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi] + pop edi eax + ret + + +; Input: none +; Output: EAX - result (0 = OK, other = error) +forcedeth_phy_init: + + push ebx ecx + + ; set advertise register + ; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_ADVERTISE + mov ecx, MII_READ + call forcedeth_mii_rw ; reg = eax + + ; reg |= + ; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | + ; ADVERTISE_100FULL | 0x800 | 0x400); + or eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400) + + ; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) + ; EBX - addr, EAX - miireg, ECX - value + mov ecx, eax ; reg + mov eax, MII_ADVERTISE + call forcedeth_mii_rw ; eax -> return + + test eax, eax + jz @f + ; printf("phy write to advertise failed.\n"); + DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n" + + ; return PHY_ERROR; + mov eax, PHY_ERROR + jmp .return +@@: + ; get phy interface type + ; phyinterface = readl(base + NvRegPhyInterface); + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi+NvRegPhyInterface] ; phyinterface = eax + mov dword [forcedeth_tmp_phyinterface], eax + +;;;;;;;;;;;;;;;;;;;;;;;;; +DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8 +;;;;;;;;;;;;;;;;;;;;;;;;; + + ; see if gigabit phy + ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_BMSR + mov ecx, MII_READ + call forcedeth_mii_rw ; mii_status = eax + + ; if (mii_status & PHY_GIGABIT) + test eax, PHY_GIGABIT + jnz .gigabit + ; np->gigabit = 0; + mov dword [forcedeth_gigabit], 0 + jmp .next_if + +.gigabit: + ; np->gigabit = PHY_GIGABIT; + mov dword [forcedeth_gigabit], PHY_GIGABIT + + ; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_1000BT_CR + mov ecx, MII_READ + call forcedeth_mii_rw ; mii_control_1000 = eax + + ; mii_control_1000 &= ~ADVERTISE_1000HALF; + and eax, (not ADVERTISE_1000HALF) + + ; if (phyinterface & PHY_RGMII) + test dword [forcedeth_tmp_phyinterface], PHY_RGMII + jz @f + ; mii_control_1000 |= ADVERTISE_1000FULL + or eax, ADVERTISE_1000FULL + jmp .next +@@: + ; mii_control_1000 &= ~ADVERTISE_1000FULL + and eax, (not ADVERTISE_1000FULL) + +.next: + ; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000)) + ; EBX - addr, EAX - miireg, ECX - value + mov ecx, eax + mov eax, MII_1000BT_CR + call forcedeth_mii_rw ; eax -> return + + test eax, eax + jz .next_if + + ; printf("phy init failed.\n"); + DEBUGF 1," K : FORCEDETH: phy init failed.\n" + + ; return PHY_ERROR; + mov eax, PHY_ERROR + jmp .return + +.next_if: + + ; reset the phy + ; if (phy_reset(nic)) + call forcedeth_phy_reset + test eax, eax + jz @f + ; printf("phy reset failed\n") + DEBUGF 1," K : FORCEDETH: phy reset failed.\n" + ; return PHY_ERROR + mov eax, PHY_ERROR + jmp .return +@@: + + ; phy vendor specific configuration + ; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) + cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA + jne .next_if2 + test dword [forcedeth_tmp_phyinterface], PHY_RGMII + jz .next_if2 + + ; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ) + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_RESV1 + mov ecx, MII_READ + call forcedeth_mii_rw ; phy_reserved = eax + + ; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2) + and eax, (not (PHY_INIT1 or PHY_INIT2)) + ; phy_reserved |= (PHY_INIT3 | PHY_INIT4) + or eax, (PHY_INIT3 or PHY_INIT4) + + ; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) + ; EBX - addr, EAX - miireg, ECX - value + mov ecx, eax + mov eax, MII_RESV1 + call forcedeth_mii_rw ; eax -> return + test eax, eax + jz @f + ; printf("phy init failed.\n") + DEBUGF 1," K : FORCEDETH: phy init failed.\n" + ; return PHY_ERROR + mov eax, PHY_ERROR + jmp .return +@@: + ; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_NCONFIG + mov ecx, MII_READ + call forcedeth_mii_rw ; phy_reserved = eax + + ; phy_reserved |= PHY_INIT5 + or eax, PHY_INIT5 + + ; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) + ; EBX - addr, EAX - miireg, ECX - value + mov ecx, eax + mov eax, MII_NCONFIG + call forcedeth_mii_rw ; eax -> return + test eax, eax + jz .next_if2 + ; printf("phy init failed.\n") + DEBUGF 1," K : FORCEDETH: phy init failed.\n" + ; return PHY_ERROR + mov eax, PHY_ERROR + jmp .return + +.next_if2: + + ; if (np->phy_oui == PHY_OUI_CICADA) + cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA + jne .restart + + ; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ) + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_SREVISION + mov ecx, MII_READ + call forcedeth_mii_rw ; phy_reserved = eax + + ; phy_reserved |= PHY_INIT6 + or eax, PHY_INIT6 + + ; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) + mov ecx, eax + mov eax, MII_SREVISION + call forcedeth_mii_rw ; eax -> return + test eax, eax + jz .restart + ; printf("phy init failed.\n"); + DEBUGF 1," K : FORCEDETH: phy init failed.\n" + ; return PHY_ERROR; + jmp .return + +.restart: + ; restart auto negotiation + ; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ) + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_BMCR + mov ecx, MII_READ + call forcedeth_mii_rw ; mii_control = eax + + ; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE) + or eax, (BMCR_ANRESTART or BMCR_ANENABLE) + + ; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) + mov ecx, eax + mov eax, MII_BMCR + call forcedeth_mii_rw ; eax -> return + test eax, eax + jz .ok + + ; return PHY_ERROR; + mov eax, PHY_ERROR + jmp .return + +.ok: + mov eax, 0 +.return: + pop ecx ebx + ret + + +; Input: none +; Output: EAX - result (0 = OK, other = error) +forcedeth_phy_reset: + + push ebx ecx edx + + ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_BMCR + mov ecx, MII_READ + call forcedeth_mii_rw ; miicontrol = eax + + ; miicontrol |= BMCR_RESET; + or eax, BMCR_RESET + push eax + + ; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) + ; EBX - addr, EAX - miireg, ECX - value + mov ecx, eax + mov eax, MII_BMCR + call forcedeth_mii_rw ; miicontrol = eax + + test eax, eax + jz @f + pop eax + mov eax, 0xffffffff + jmp .return +@@: + pop eax + + ; wait for 500ms + ; mdelay(500) + mov esi, 500 + call forcedeth_udelay + + ; must wait till reset is deasserted + ; while (miicontrol & BMCR_RESET) { + mov edx, 100 +.while_loop: + test eax, BMCR_RESET + jz .while_loop_exit + + ; mdelay(10); + mov esi, 10 + call forcedeth_udelay + + ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); + ; EBX - addr, EAX - miireg, ECX - value + mov eax, MII_BMCR + mov ecx, MII_READ + call forcedeth_mii_rw ; miicontrol = eax + + ; FIXME: 100 tries seem excessive + ; if (tries++ > 100) + dec edx + jnz .while_loop + ; return -1; + mov eax, 0xffffffff + jmp .return +.while_loop_exit: + ; return 0 + mov eax, 0 +.return: + pop edx ecx ebx + ret + +; Input: none +; Output: none +forcedeth_mac_reset: + push esi edi + + ; dprintf("mac_reset\n") + DEBUGF 1," K : FORCEDETH: mac_reset.\n" + + ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [forcedeth_desc_ver] + or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base) + call forcedeth_pci_push + + ; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset) + mov dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT + + ; pci_push(base) + call forcedeth_pci_push + + ; udelay(NV_MAC_RESET_DELAY) + mov esi, NV_MAC_RESET_DELAY + call forcedeth_nv_udelay + + ; writel(0, base + NvRegMacReset) + mov dword [edi+NvRegMacReset], 0 + + ; pci_push(base) + call forcedeth_pci_push + + ; udelay(NV_MAC_RESET_DELAY) + mov esi, NV_MAC_RESET_DELAY + call forcedeth_nv_udelay + + ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) + mov eax, dword [forcedeth_desc_ver] + or eax, NVREG_TXRXCTL_BIT2 + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base) + call forcedeth_pci_push + + pop edi esi + ret + +; Input: none +; Output: none +forcedeth_init_ring: + push eax ebx ecx + + ; np->next_tx = np->nic_tx = 0 + mov dword[forcedeth_next_tx], 0 + mov dword[forcedeth_nic_tx], 0 + + ; for (i = 0; i < TX_RING; i++) + mov ecx, TX_RING + +.for_loop: + ; tx_ring[i].FlagLen = 0; + mov eax, ecx + dec eax + mov bl, sizeof.forcedeth_TxDesc + mul bl + add eax, forcedeth_tx_ring + mov ebx, eax + mov dword [ebx + forcedeth_TxDesc.FlagLen], 0 + loop .for_loop + + ; np->cur_rx = RX_RING; + mov dword [forcedeth_cur_rx], RX_RING + ; np->refill_rx = 0; + mov dword [forcedeth_refill_rx], 0 + + ;for (i = 0; i < RX_RING; i++) + mov ecx, RX_RING + +.for_loop2: + ; rx_ring[i].FlagLen = 0; + mov eax, ecx + dec eax + mov bl, sizeof.forcedeth_RxDesc + mul bl + add eax, forcedeth_rx_ring + mov ebx, eax + mov dword [ebx + forcedeth_RxDesc.FlagLen], 0 + loop .for_loop2 + + ; alloc_rx(nic); + call forcedeth_alloc_rx + +.return: + pop ecx ebx eax + ret + +; Input: none +; Output: none +forcedeth_txrx_reset: + push eax esi edi + + ; dprintf(("txrx_reset\n")) + DEBUGF 1," K : FORCEDETH: txrx_reset.\n" + + ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [forcedeth_desc_ver] + or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base) + call forcedeth_pci_push + + ; nv_udelay(NV_TXRX_RESET_DELAY) + mov esi, NV_TXRX_RESET_DELAY + call forcedeth_nv_udelay + + ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) + mov eax, dword [forcedeth_desc_ver] + or eax, NVREG_TXRXCTL_BIT2 + mov dword [edi+NvRegTxRxControl], eax + + ; pci_push(base) + call forcedeth_pci_push + +.return: + pop edi esi eax + ret + +; Input: none +; Output: none +forcedeth_set_multicast: + push edi + + ; u32 addr[2]; + ; u32 mask[2]; + ; u32 pff; + ; u32 alwaysOff[2]; + ; u32 alwaysOn[2]; + ; + ; memset(addr, 0, sizeof(addr)); + ; memset(mask, 0, sizeof(mask)); + ; + ; pff = NVREG_PFF_MYADDR; + ; + ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0; + ; + ; addr[0] = alwaysOn[0]; + ; addr[1] = alwaysOn[1]; + ; mask[0] = alwaysOn[0] | alwaysOff[0]; + ; mask[1] = alwaysOn[1] | alwaysOff[1]; + ; + ; addr[0] |= NVREG_MCASTADDRA_FORCE; + ; pff |= NVREG_PFF_ALWAYS; + ; stop_rx(); + call forcedeth_stop_rx + ; writel(addr[0], base + NvRegMulticastAddrA); + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE + ; writel(addr[1], base + NvRegMulticastAddrB); + mov dword [edi+NvRegMulticastAddrB], 0 + ; writel(mask[0], base + NvRegMulticastMaskA); + mov dword [edi+NvRegMulticastMaskA], 0 + ; writel(mask[1], base + NvRegMulticastMaskB); + mov dword [edi+NvRegMulticastMaskB], 0 + ; writel(pff, base + NvRegPacketFilterFlags); + mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS) + ; start_rx(nic); + call forcedeth_start_rx + +.return: + pop edi + ret + +; Input: none +; Output: none +forcedeth_start_rx: + push edi + + ; dprintf(("start_rx\n")) + DEBUGF 1," K : FORCEDETH: start_rx.\n" + + ; Already running? Stop it. + ; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi+NvRegReceiverControl] + test eax, NVREG_RCVCTL_START + jz @f + ; writel(0, base + NvRegReceiverControl) + mov dword [edi+NvRegReceiverControl], 0 + ; pci_push(base) + call forcedeth_pci_push + +@@: + + ; writel(np->linkspeed, base + NvRegLinkSpeed); + mov eax, dword [forcedeth_linkspeed] + mov dword [edi+NvRegLinkSpeed], eax + ; pci_push(base); + call forcedeth_pci_push + ; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); + mov dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START + ; pci_push(base); + call forcedeth_pci_push + +.return: + pop edi + ret + +; Input: none +; Output: none +forcedeth_stop_rx: + push esi edi + + ; dprintf(("stop_rx\n")) + DEBUGF 1," K : FORCEDETH: stop_rx.\n" + + ; writel(0, base + NvRegReceiverControl) + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegReceiverControl], 0 + + push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; + ; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy"); + stdcall forcedeth_reg_delay,NvRegReceiverStatus,NVREG_RCVSTAT_BUSY,0,NV_RXSTOP_DELAY1,NV_RXSTOP_DELAY1MAX,0 + pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; + + + ; nv_udelay(NV_RXSTOP_DELAY2) + mov esi, NV_RXSTOP_DELAY2 + call forcedeth_nv_udelay + + ; writel(0, base + NvRegLinkSpeed) + mov dword [edi+NvRegLinkSpeed], 0 + +.return: + pop edi esi + ret + +; Input: none +; Output: EAX +forcedeth_update_linkspeed: + push ebx ecx esi edi + + ; BMSR_LSTATUS is latched, read it twice: + ; we want the current value. + + ; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) + ;EBX - addr, EAX - miireg, ECX - value + mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_BMSR + mov ecx, MII_READ + call forcedeth_mii_rw + + + ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) + ;EBX - addr, EAX - miireg, ECX - value + mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_BMSR + mov ecx, MII_READ + call forcedeth_mii_rw ; mii_status = eax + + ; yhlu + + ; for(i=0;i<30;i++) { + mov ecx, 30 +.for_loop: + push ecx + + ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); + ;EBX - addr, EAX - miireg, ECX - value + ;mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_BMSR + mov ecx, MII_READ + call forcedeth_mii_rw ; mii_status = eax + + ; if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break; + test eax, BMSR_LSTATUS + jz @f + test eax, BMSR_ANEGCOMPLETE + jz @f + ; break + pop ecx + jmp .break + +@@: + + ; mdelay(100); + push eax ; ??? + mov esi, 100 + call forcedeth_udelay + pop eax ; ??? + + pop ecx + loop .for_loop + +.break: + + ; if (!(mii_status & BMSR_LSTATUS)) { + test eax, BMSR_LSTATUS + jnz @f + + ; printf("no link detected by phy - falling back to 10HD.\n") + DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n" + + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + + ; newdup = 0; + mov dword [forcedeth_tmp_newdup], 0 + ; retval = 0; + mov dword [forcedeth_tmp_retval], 0 + + ; goto set_speed; + jmp .set_speed + +@@: + + ; check auto negotiation is complete + ; if (!(mii_status & BMSR_ANEGCOMPLETE)) { + test eax, BMSR_ANEGCOMPLETE + jnz @f + + ; still in autonegotiation - configure nic for 10 MBit HD and wait. + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + + ; newdup = 0 + mov dword [forcedeth_tmp_newdup], 0 + + ; retval = 0 + mov dword [forcedeth_tmp_retval], 0 + + ; printf("autoneg not completed - falling back to 10HD.\n") + DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n" + + ; goto set_speed + jmp .set_speed + +@@: + + ; retval = 1 + mov dword [forcedeth_tmp_retval], 1 + + ; if (np->gigabit == PHY_GIGABIT) { + cmp dword [forcedeth_gigabit], PHY_GIGABIT + jne .end_if + ; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ) + ;EBX - addr, EAX - miireg, ECX - value + ;mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_1000BT_CR + mov ecx, MII_READ + call forcedeth_mii_rw ; control_1000 = eax + mov dword [forcedeth_tmp_control_1000], eax + + ; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ) + ;EBX - addr, EAX - miireg, ECX - value + ;mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_1000BT_SR + mov ecx, MII_READ + call forcedeth_mii_rw ; status_1000 = eax + ;mov dword [forcedeth_tmp_status_1000], eax + + ; if ((control_1000 & ADVERTISE_1000FULL) && + ; (status_1000 & LPA_1000FULL)) { + test eax, LPA_1000FULL + jz .end_if + test dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL + jz .end_if + + ; printf ("update_linkspeed: GBit ethernet detected.\n") + DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n" + + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000) + + ; newdup = 1 + mov dword [forcedeth_tmp_newdup], 1 + + ; goto set_speed + jmp .set_speed + +.end_if: + + ; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); + ;EBX - addr, EAX - miireg, ECX - value + ;mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_ADVERTISE + mov ecx, MII_READ + call forcedeth_mii_rw ; adv = eax + mov dword [forcedeth_tmp_adv], eax + + ; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ); + ;EBX - addr, EAX - miireg, ECX - value + ;mov ebx, dword [forcedeth_phyaddr] + mov eax, MII_LPA + mov ecx, MII_READ + call forcedeth_mii_rw ; lpa = eax + mov dword [forcedeth_tmp_lpa], eax + + ; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa)); + DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8 + + ; FIXME: handle parallel detection properly, handle gigabit ethernet + ; lpa = lpa & adv + mov eax, dword [forcedeth_tmp_adv] + and dword [forcedeth_tmp_lpa], eax + + mov eax, dword [forcedeth_tmp_lpa] + + ; if (lpa & LPA_100FULL) { + test eax, LPA_100FULL + jz @f + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) + ; newdup = 1 + mov dword [forcedeth_tmp_newdup], 1 + jmp .set_speed +@@: + ; } else if (lpa & LPA_100HALF) { + test eax, LPA_100HALF + jz @f + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) + ; newdup = 0 + mov dword [forcedeth_tmp_newdup], 0 + jmp .set_speed +@@: + ; } else if (lpa & LPA_10FULL) { + test eax, LPA_10FULL + jz @f + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + ; newdup = 1 + mov dword [forcedeth_tmp_newdup], 1 + jmp .set_speed +@@: + ; } else if (lpa & LPA_10HALF) { + test eax, LPA_10HALF + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + ; newdup = 0; + mov dword [forcedeth_tmp_newdup], 0 + jmp .set_speed +@@: + ; } else { + ; printf("bad ability %hX - falling back to 10HD.\n", lpa) + DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax + + ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 + mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) + ; newdup = 0 + mov dword [forcedeth_tmp_newdup], 0 + ; } + +.set_speed: + + ; if (np->duplex == newdup && np->linkspeed == newls) + mov eax, dword [forcedeth_tmp_newdup] + cmp eax, dword [forcedeth_duplex] + jne .end_if2 + mov eax, dword [forcedeth_tmp_newls] + cmp eax, dword [forcedeth_linkspeed] + jne .end_if2 + ; return retval; + jmp .return + +.end_if2: + + ; dprintf(("changing link setting from %d/%s to %d/%s.\n", + ; np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex")) + DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ; np->duplex = newdup + mov eax, dword [forcedeth_tmp_newdup] + mov dword [forcedeth_duplex], eax + + ; np->linkspeed = newls + mov eax, [forcedeth_tmp_newls] + mov dword [forcedeth_linkspeed], eax + + ; if (np->gigabit == PHY_GIGABIT) { + cmp dword [forcedeth_gigabit], PHY_GIGABIT + jne .end_if3 + + ; phyreg = readl(base + NvRegRandomSeed); + mov edi, dword [forcedeth_mapio_addr] + mov eax, dword [edi+NvRegRandomSeed] + + ; phyreg &= ~(0x3FF00); + and eax, not (0x3FF00) + mov ecx, eax ; phyreg = ecx + + ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) + mov eax, dword [forcedeth_linkspeed] + and eax, 0xFFF + cmp eax, NVREG_LINKSPEED_10 + jne @f + ; phyreg |= NVREG_RNDSEED_FORCE3 + or ecx, NVREG_RNDSEED_FORCE3 + jmp .end_if4 +@@: + ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + cmp eax, NVREG_LINKSPEED_100 + jne @f + ; phyreg |= NVREG_RNDSEED_FORCE2 + or ecx, NVREG_RNDSEED_FORCE2 + jmp .end_if4 +@@: + ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + cmp eax, NVREG_LINKSPEED_1000 + jne .end_if4 + ; phyreg |= NVREG_RNDSEED_FORCE + or ecx, NVREG_RNDSEED_FORCE +.end_if4: + ; writel(phyreg, base + NvRegRandomSeed) + mov dword [edi+NvRegRandomSeed], ecx + +.end_if3: + + ; phyreg = readl(base + NvRegPhyInterface) + mov ecx, dword [edi+NvRegPhyInterface] + + ; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000) + and ecx, not (PHY_HALF or PHY_100 or PHY_1000) + + ; if (np->duplex == 0) + cmp dword [forcedeth_duplex], 0 + jne @f + ; phyreg |= PHY_HALF + or ecx, PHY_HALF +@@: + ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + mov eax, dword [forcedeth_linkspeed] + and eax, 0xFFF + cmp eax, NVREG_LINKSPEED_100 + jne @f + ; phyreg |= PHY_100 + or ecx, PHY_100 + jmp .end_if5 +@@: + ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + cmp eax, NVREG_LINKSPEED_1000 + jne .end_if5 + ; phyreg |= PHY_1000 + or ecx, PHY_1000 + +.end_if5: + + ; writel(phyreg, base + NvRegPhyInterface) + mov dword [edi+NvRegPhyInterface], ecx + + ; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); + cmp dword [forcedeth_duplex], 0 + je @f + mov ecx, 0 + jmp .next +@@: + mov ecx, NVREG_MISC1_HD +.next: + or ecx, NVREG_MISC1_FORCE + mov dword [edi+NvRegMisc1], ecx + + ; pci_push(base) + call forcedeth_pci_push + + ; writel(np->linkspeed, base + NvRegLinkSpeed) + mov eax, dword [forcedeth_linkspeed] + mov dword [edi+NvRegLinkSpeed], eax + + ; pci_push(base) + call forcedeth_pci_push + +.return: + ; return retval + mov eax, dword [forcedeth_tmp_retval] + pop edi esi ecx ebx + ret + + +; Input: none +; Output: none +forcedeth_start_tx: + push edi + ; dprintf(("start_tx\n")) + DEBUGF 1," K : FORCEDETH: start_tx.\n" + + ; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl) + mov edi, dword [forcedeth_mapio_addr] + mov dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START + + ; pci_push(base) + call forcedeth_pci_push + +.return: + pop edi + ret + +; Interrupt handler +forcedeth_int_handler: + DEBUGF 1," K : FORCEDETH: interrupt handler.\n" + + ret + diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/i8255x.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/i8255x.inc new file mode 100644 index 000000000..3ab4d0628 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/i8255x.inc @@ -0,0 +1,760 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; I8255X.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.3 11 August 2003 ;; +;; ;; +;; This driver is based on the eepro100 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett, ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************** +; Interface +; I8255x_reset +; I8255x_probe +; I8255x_poll +; I8255x_transmit +; +; These functions are referenced in ethernet.inc +; +;******************************************************************** + + +rxfd_status equ eth_data_start +rxfd_command equ eth_data_start + 2 +rxfd_link equ eth_data_start + 4 +rxfd_rx_buf_addr equ eth_data_start + 8 +rxfd_count equ eth_data_start + 12 +rxfd_size equ eth_data_start + 14 +rxfd_packet equ eth_data_start + 16 + + + +uglobal +eeprom_data: times 16 dd 0 + +align 4 + +lstats: +tx_good_frames: dd 0 +tx_coll16_errs: dd 0 +tx_late_colls: dd 0 +tx_underruns: dd 0 +tx_lost_carrier: dd 0 +tx_deferred: dd 0 +tx_one_colls: dd 0 +tx_multi_colls: dd 0 +tx_total_colls: dd 0 +rx_good_frames: dd 0 +rx_crc_errs: dd 0 +rx_align_errs: dd 0 +rx_resource_errs: dd 0 +rx_overrun_errs: dd 0 +rx_colls_errs: dd 0 +rx_runt_errs: dd 0 +done_marker: dd 0 + +align 4 + +confcmd: +confcmd_status: dw 0 +confcmd_command: dw 0 +confcmd_link: dd 0 +endg + +iglobal +confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 + db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 + db 0x80, 0x3f, 0x05 +endg + +uglobal +align 4 + +txfd: +txfd_status: dw 0 +txfd_command: dw 0 +txfd_link: dd 0 +txfd_tx_desc_addr: dd 0 +txfd_count: dd 0 +txfd_tx_buf_addr0: dd 0 +txfd_tx_buf_size0: dd 0 +txfd_tx_buf_addr1: dd 0 +txfd_tx_buf_size1: dd 0 + +align 4 + +hdr: +hdr_dst_addr: times 6 db 0 +hdr_src_addr: times 6 db 0 +hdr_type: dw 0 +endg + + +;*************************************************************************** +; Function +; wait_for_cmd_done +; +; Description +; waits for the hardware to complete a command +; port address in edx +; +; al destroyed +;*************************************************************************** +wait_for_cmd_done: + in al, dx + cmp al, 0 + jne wait_for_cmd_done + ret + + + +;*************************************************************************** +; Function +; mdio_read +; +; Description +; This probably reads a register in the "physical media interface chip" +; Phy_id in ebx +; location in ecx +; +; Data returned in eax +; +;*************************************************************************** +mdio_read: + mov edx, [io_addr] + add edx, 16 ; SCBCtrlMDI + + mov eax, 0x08000000 + shl ecx, 16 + or eax, ecx + shl ebx, 21 + or eax, ebx + + out dx, eax + +mrlp: + call delay_us + in eax, dx + mov ecx, eax + and ecx, 0x10000000 + jz mrlp + + and eax, 0xffff + ret + + + +;*************************************************************************** +; Function +; mdio_write +; +; Description +; This probably writes a register in the "physical media interface chip" +; Phy_id in ebx +; location in ecx +; data in edx +; Data returned in eax +; +;*************************************************************************** +mdio_write: + mov eax, 0x04000000 + shl ecx, 16 + or eax, ecx + shl ebx, 21 + or eax, ebx + or eax, edx + + mov edx, [io_addr] + add edx, 16 ; SCBCtrlMDI + out dx, eax + +mwlp: + call delay_us + in eax, dx + mov ecx, eax + and ecx, 0x10000000 + jz mwlp + + and eax, 0xffff + ret + + + +;/***********************************************************************/ +;/* I82557 related defines */ +;/***********************************************************************/ + +; Serial EEPROM section. +; A "bit" grungy, but we work our way through bit-by-bit :->. +; EEPROM_Ctrl bits. +EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. +EE_CS equ 0x02 ; EEPROM chip select. +EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. +EE_DATA_READ equ 0x08 ; EEPROM chip data out. +EE_WRITE_0 equ 0x4802 +EE_WRITE_1 equ 0x4806 +EE_ENB equ 0x4802 + + +; The EEPROM commands include the alway-set leading bit. +EE_READ_CMD equ 6 + +; The SCB accepts the following controls for the Tx and Rx units: +CU_START equ 0x0010 +CU_RESUME equ 0x0020 +CU_STATSADDR equ 0x0040 +CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. +CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. +CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. + +RX_START equ 0x0001 +RX_RESUME equ 0x0002 +RX_ABORT equ 0x0004 +RX_ADDR_LOAD equ 0x0006 +RX_RESUMENR equ 0x0007 +INT_MASK equ 0x0100 +DRVR_INT equ 0x0200 ; Driver generated interrupt. + + +;*************************************************************************** +; Function +; do_eeprom_cmd +; +; Description +; writes a cmd to the ethernet cards eeprom, by bit bashing +; cmd in ebx +; cmd length in ecx +; return in eax +;*************************************************************************** +do_eeprom_cmd: + mov edx, [io_addr] ; We only require the value in dx + add dx, 14 ; the value SCBeeprom + + mov ax, EE_ENB + out dx, ax + call delay_us + + mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK + out dx, ax + call delay_us + + ; dx holds ee_addr + ; ecx holds count + ; eax holds cmd + xor edi, edi ; this will be the receive data + +dec_001: + mov esi, 1 + + dec ecx + shl esi, cl + inc ecx + and esi, ebx + mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. + cmp esi,0 + jz dec_002 + mov eax, EE_WRITE_1 + +dec_002: + out dx, ax + call delay_us + + or ax, EE_SHIFT_CLK + out dx, ax + call delay_us + + shl edi,1 + + in ax, dx + and ax, EE_DATA_READ + cmp ax,0 + jz dec_003 + inc edi + +dec_003: + loop dec_001 + + mov ax, EE_ENB + out dx, ax + call delay_us + + mov ax, 0x4800 + out dx, ax + call delay_us + + mov eax, edi + + ret + + +;*************************************************************************** +; Function +; I8255x_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; +;*************************************************************************** +I8255x_probe: + DEBUGF 1," K : Probing i8255x device \n" + mov eax, [io_addr] + + mov ebx, [pci_bus] + mov ecx, [pci_dev] + mov edx, 0x04 ; PCI_COMMAND + call pcibios_read_config_word + + or ax, 0x05 + mov ebx, [pci_bus] + mov ecx, [pci_dev] + mov edx, 0x04 ; PCI_COMMAND + call pcibios_write_config_word + + mov ebx, 0x6000000 + mov ecx, 27 + call do_eeprom_cmd + and eax, 0xffe0000 + cmp eax, 0xffe0000 + je bige + + mov ebx, 0x1800000 + mov ecx, 0x40 + jmp doread + +bige: + mov ebx, 0x6000000 + mov ecx, 0x100 + +doread: + ; do-eeprom-cmd will destroy all registers + ; we have eesize in ecx + ; read_cmd in ebx + + ; Ignore full eeprom - just load the mac address + mov ecx, 0 + +drlp: + push ecx ; save count + push ebx + mov eax, ecx + shl eax, 16 + or ebx, eax + mov ecx, 27 + call do_eeprom_cmd + + pop ebx + pop ecx + + mov edx, ecx + shl edx, 2 + mov esi, eeprom_data + add esi, edx + mov [esi], eax + + inc ecx + cmp ecx, 16 + jne drlp + + ; OK, we have the MAC address. + ; Now reset the card + + mov edx, [io_addr] + add dx, 8 ; SCBPort + xor eax, eax ; The reset cmd == 0 + out dx, eax + + mov esi, 10 + call delay_ms ; Give the card time to warm up. + + mov eax, lstats + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0140 ; INT_MASK | CU_STATSADDR + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + mov eax, 0 + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + ; build rxrd structure + mov ax, 0x0001 + mov [rxfd_status], ax + mov ax, 0x0000 + mov [rxfd_command], ax + + mov eax, rxfd_status + sub eax, OS_BASE + mov [rxfd_link], eax + + mov eax, Ether_buffer + sub eax, OS_BASE + mov [rxfd_rx_buf_addr], eax + + mov ax, 0 + mov [rxfd_count], ax + + mov ax, 1528 + mov [rxfd_size], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + sub eax, OS_BASE + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + call wait_for_cmd_done + + ; start the reciver + + mov ax, 0 + mov [rxfd_status], ax + + mov ax, 0xc000 + mov [rxfd_command], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + sub eax, OS_BASE + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + ; Init TX Stuff + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, 0 + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE + out dx, ax + + call wait_for_cmd_done + + ; Set TX Base address + + ; First, set up confcmd values + + mov ax, 2 + mov [confcmd_command], ax + mov eax, txfd + sub eax, OS_BASE + mov [confcmd_link], eax + + mov ax, 1 + mov [txfd_command], ax ; CmdIASetup + + mov ax, 0 + mov [txfd_status], ax + + mov eax, confcmd + sub eax, OS_BASE + mov [txfd_link], eax + + + + ; ETH_ALEN is 6 bytes + + mov esi, eeprom_data + mov edi, node_addr + mov ecx, 3 +drp000: + mov eax, [esi] + mov [edi], al + shr eax, 8 + inc edi + mov [edi], al + inc edi + add esi, 4 + loop drp000 + + ; Hard code your MAC address into node_addr at this point, + ; If you cannot read the MAC address from the eeprom in the previous step. + ; You also have to write the mac address into txfd_tx_desc_addr, rather + ; than taking data from eeprom_data + + mov esi, eeprom_data + mov edi, txfd_tx_desc_addr + mov ecx, 3 +drp001: + mov eax, [esi] + mov [edi], al + shr eax, 8 + inc edi + mov [edi], al + inc edi + add esi, 4 + loop drp001 + + + mov esi, eeprom_data + (6 * 4) + mov eax, [esi] + shr eax, 8 + and eax, 0x3f + cmp eax, 4 ; DP83840 + je drp002 + cmp eax, 10 ; DP83840A + je drp002 + jmp drp003 + +drp002: + mov ebx, [esi] + and ebx, 0x1f + push ebx + mov ecx, 23 + call mdio_read + pop ebx + or eax, 0x0422 + mov ecx, 23 + mov edx, eax + call mdio_write + +drp003: + mov ax, 0x4002 ; Cmdsuspend | CmdConfigure + mov [confcmd_command], ax + mov ax, 0 + mov [confcmd_status], ax + mov eax, txfd + mov [confcmd_link], eax + mov ebx, confcmd_data + mov al, 0x88 ; fifo of 8 each + mov [ebx + 1], al + mov al, 0 + mov [ebx + 4], al + mov al, 0x80 + mov [ebx + 5], al + mov al, 0x48 + mov [ebx + 15], al + mov al, 0x80 + mov [ebx + 19], al + mov al, 0x05 + mov [ebx + 21], al + + mov eax, txfd + sub eax, OS_BASE + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0110 ; INT_MASK | CU_START + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done +jmp skip + + ; wait for thing to start +drp004: + mov ax, [txfd_status] + cmp ax, 0 + je drp004 + +skip: + ; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + +I8255x_exit: + ret + + + +;*************************************************************************** +; Function +; I8255x_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +I8255x_reset: + ret + + + +;*************************************************************************** +; Function +; I8255x_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; +;*************************************************************************** +I8255x_poll: + mov ax, 0 ; assume no data + mov [eth_rx_data_len], ax + + mov ax, [rxfd_status] + cmp ax, 0 + je i8p_exit + + mov ax, 0 + mov [rxfd_status], ax + + mov ax, 0xc000 + mov [rxfd_command], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + sub eax, OS_BASE + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + call wait_for_cmd_done + + mov esi, rxfd_packet + mov edi, Ether_buffer + mov ecx, 1518 + cld + rep movsb + + mov ax, [rxfd_count] + and ax, 0x3fff + mov [eth_rx_data_len], ax + +i8p_exit: + ret + + + +;*************************************************************************** +; Function +; I8255x_transmit +; +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +I8255x_transmit: + + mov [hdr_type], bx + + mov eax, [edi] + mov [hdr_dst_addr], eax + mov ax, [edi+4] + mov [hdr_dst_addr+4], ax + + mov eax, [node_addr] + mov [hdr_src_addr], eax + mov ax, [node_addr+4] + mov [hdr_src_addr+4], ax + + mov edx, [io_addr] + in ax, dx + and ax, 0xfc00 + out dx, ax + + xor ax, ax + mov [txfd_status], ax + mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex + mov [txfd_command], ax + mov eax, txfd + mov [txfd_link], eax + mov eax, 0x02208000 + mov [txfd_count], eax + mov eax, txfd_tx_buf_addr0 + sub eax, OS_BASE + mov [txfd_tx_desc_addr], eax + mov eax, hdr + sub eax, OS_BASE + mov [txfd_tx_buf_addr0], eax + mov eax, 14 ; sizeof hdr + mov [txfd_tx_buf_size0], eax + + ; Copy the buffer address and size in + mov eax, esi + sub eax, OS_BASE + mov [txfd_tx_buf_addr1], eax + mov eax, ecx + mov [txfd_tx_buf_size1], eax + + mov eax, txfd + sub eax, OS_BASE + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov ax, 0x0110 ; INT_MASK | CU_START + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + mov edx, [io_addr] + in ax, dx + +I8t_001: + mov ax, [txfd_status] + cmp ax, 0 + je I8t_001 + + mov edx, [io_addr] + in ax, dx + + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/pcnet32.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/pcnet32.inc new file mode 100644 index 000000000..f328e7105 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/pcnet32.inc @@ -0,0 +1,848 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; PCNET32.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; - Version 1.0 31 July 2004: ;; +;; Initial release ;; +;; ;; +;; - Version 1.01 29 March 2008: ;; +;; Adapted to work with kolibrios flat kernel ;; +;; Debug info is updated, and now uses DEBUGF macro ;; +;; by hidnplayr@kolibrios.org ;; +;; ;; +;; This driver is based on the PCNet32 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2004 Jarek Pelczar, ;; +;; jpelczar@interia.pl ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +PCNET32_PORT_AUI equ 0x00 +PCNET32_PORT_10BT equ 0x01 +PCNET32_PORT_GPSI equ 0x02 +PCNET32_PORT_MII equ 0x03 +PCNET32_PORT_PORTSEL equ 0x03 +PCNET32_PORT_ASEL equ 0x04 +PCNET32_PORT_100 equ 0x40 +PCNET32_PORT_FD equ 0x80 +PCNET32_DMA_MASK equ 0xffffffff + +PCNET32_LOG_TX_BUFFERS equ 1 +PCNET32_LOG_RX_BUFFERS equ 2 + +PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) +PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) +PCNET32_TX_RING_LEN_BITS equ 0 +PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) +PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) +PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) +PCNET32_PKT_BUF_SZ equ 1544 +PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 + +pcnet32_txb equ (eth_data_start) +pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) + +virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_private: +.mode dw ? +.tlen_rlen dw ? +.phys_addr db ?,?,?,?,?,? +.reserved dw ? +.filter dd ?,? +.rx_ring dd ? +.tx_ring dd ? +.cur_rx dd ? +.cur_tx dd ? +.dirty_rx dd ? +.dirty_tx dd ? +.tx_full db ? +.options dd ? +.full_duplex db ? +.chip_version dd ? +.mii db ? +.ltint db ? +.dxsuflo db ? +.fset db ? +.fdx db ? +end virtual + +virtual at 0 +pcnet32_rx_head: +.base dd ? +.buf_length dw ? +.status dw ? +.msg_length dd ? +.reserved dd ? +end virtual + +virtual at 0 +pcnet32_tx_head: +.base dd ? +.length dw ? +.status dw ? +.misc dd ? +.reserved dd ? +end virtual + +uglobal +pcnet32_access: +.read_csr dd ? +.write_csr dd ? +.read_bcr dd ? +.write_bcr dd ? +.read_rap dd ? +.write_rap dd ? +.reset dd ? +endg + +iglobal +pcnet32_options_mapping: +dd PCNET32_PORT_ASEL ; 0 Auto-select +dd PCNET32_PORT_AUI ; 1 BNC/AUI +dd PCNET32_PORT_AUI ; 2 AUI/BNC +dd PCNET32_PORT_ASEL ; 3 not supported +dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD +dd PCNET32_PORT_ASEL ; 5 not supported +dd PCNET32_PORT_ASEL ; 6 not supported +dd PCNET32_PORT_ASEL ; 7 not supported +dd PCNET32_PORT_ASEL ; 8 not supported +dd PCNET32_PORT_MII ; 9 MII 10baseT +dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD +dd PCNET32_PORT_MII ; 11 MII (autosel) +dd PCNET32_PORT_10BT ; 12 10BaseT +dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx +dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD +dd PCNET32_PORT_ASEL ; 15 not supported +endg + +PCNET32_WIO_RDP equ 0x10 +PCNET32_WIO_RAP equ 0x12 +PCNET32_WIO_RESET equ 0x14 +PCNET32_WIO_BDP equ 0x16 +PCNET32_DWIO_RDP equ 0x10 +PCNET32_DWIO_RAP equ 0x14 +PCNET32_DWIO_RESET equ 0x18 +PCNET32_DWIO_BDP equ 0x1C +PCNET32_TOTAL_SIZE equ 0x20 +; ebx - index +; return: +; eax - data +pcnet32_wio_read_csr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + mov ax,bx + out dx,ax + lea edx,[ebp+PCNET32_WIO_RDP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - data +; ebx - index +pcnet32_wio_write_csr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + xchg eax,ebx + out dx,ax + xchg eax,ebx + lea edx,[ebp+PCNET32_WIO_RDP] + out dx,ax + pop edx + ret +; ebx - index +; return: +; eax - data +pcnet32_wio_read_bcr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + mov ax,bx + out dx,ax + lea edx,[ebp+PCNET32_WIO_BDP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - data +; ebx - index +pcnet32_wio_write_bcr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + xchg eax,ebx + out dx,ax + xchg eax,ebx + lea edx,[ebp+PCNET32_WIO_BDP] + out dx,ax + pop edx + ret +pcnet32_wio_read_rap: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - val +pcnet32_wio_write_rap: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + out dx,ax + pop edx + ret +pcnet32_wio_reset: + push edx + push eax + lea edx,[ebp+PCNET32_WIO_RESET] + in ax,dx + pop eax + pop edx + ret +pcnet32_wio_check: + push edx + mov ax,88 + lea edx,[ebp+PCNET32_WIO_RAP] + out dx,ax + nop + nop + in ax,dx + cmp ax,88 + sete al + pop edx + ret + +iglobal +pcnet32_wio: + dd pcnet32_wio_read_csr + dd pcnet32_wio_write_csr + dd pcnet32_wio_read_bcr + dd pcnet32_wio_write_bcr + dd pcnet32_wio_read_rap + dd pcnet32_wio_write_rap + dd pcnet32_wio_reset +endg + +; ebx - index +; return: +; eax - data +pcnet32_dwio_read_csr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + mov ebx,eax + out dx,eax + lea edx,[ebp+PCNET32_DWIO_RDP] + in eax,dx + and eax,0xffff + pop edx + ret +; ebx - index +; eax - data +pcnet32_dwio_write_csr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + xchg eax,ebx + out dx,eax + lea edx,[ebp+PCNET32_DWIO_RDP] + xchg eax,ebx + out dx,eax + pop edx + ret +; ebx - index +; return: +; eax - data +pcnet32_dwio_read_bcr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + mov ebx,eax + out dx,eax + lea edx,[ebp+PCNET32_DWIO_BDP] + in eax,dx + and eax,0xffff + pop edx + ret +; ebx - index +; eax - data +pcnet32_dwio_write_bcr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + xchg eax,ebx + out dx,eax + lea edx,[ebp+PCNET32_DWIO_BDP] + xchg eax,ebx + out dx,eax + pop edx + ret +pcnet32_dwio_read_rap: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + in eax,dx + and eax,0xffff + pop edx + ret +; eax - val +pcnet32_dwio_write_rap: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + out dx,eax + pop edx + ret +pcnet32_dwio_reset: + push edx + push eax + lea edx,[ebp+PCNET32_DWIO_RESET] + in eax,dx + pop eax + pop edx + ret +pcnet32_dwio_check: + push edx + lea edx,[PCNET32_DWIO_RAP] + mov eax,88 + out dx,eax + nop + nop + in eax,dx + and eax,0xffff + cmp eax,88 + sete al + pop edx + ret + +iglobal +pcnet32_dwio: + dd pcnet32_dwio_read_csr + dd pcnet32_dwio_write_csr + dd pcnet32_dwio_read_bcr + dd pcnet32_dwio_write_bcr + dd pcnet32_dwio_read_rap + dd pcnet32_dwio_write_rap + dd pcnet32_dwio_reset +endg + + + +pcnet32_init_ring: + mov [pcnet32_private.tx_full],0 + mov [pcnet32_private.cur_rx],0 + mov [pcnet32_private.cur_tx],0 + mov [pcnet32_private.dirty_rx],0 + mov [pcnet32_private.dirty_tx],0 + mov edi,pcnet32_rx_ring + mov ecx,PCNET32_RX_RING_SIZE + mov ebx,pcnet32_rxb + sub ebx,OS_BASE +.rx_init: + mov [edi+pcnet32_rx_head.base],ebx + mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG + mov [edi+pcnet32_rx_head.status],word 0x8000 + add ebx,PCNET32_PKT_BUF_SZ +; inc ebx + add edi,16 + loop .rx_init + mov edi,pcnet32_tx_ring + mov ecx,PCNET32_TX_RING_SIZE +.tx_init: + mov [edi+pcnet32_tx_head.base],dword 0 + mov [edi+pcnet32_tx_head.status],word 0 + add edi,16 + loop .tx_init + mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) + mov esi,node_addr + mov edi,pcnet32_private.phys_addr + cld + movsd + movsw + mov eax,pcnet32_rx_ring + sub eax,OS_BASE + mov dword [pcnet32_private.rx_ring],eax + + mov eax,pcnet32_tx_ring + sub eax,OS_BASE + mov dword [pcnet32_private.tx_ring],eax + ret + + + +pcnet32_reset: + ; Reset PCNET32 + mov ebp,[io_addr] + call dword [pcnet32_access.reset] + ; set 32bit mode + mov ebx,20 + mov eax,2 + call dword [pcnet32_access.write_bcr] + ; set/reset autoselect bit + mov ebx,2 + call dword [pcnet32_access.read_bcr] + and eax,not 2 + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L1 + or eax,2 +.L1: + call dword [pcnet32_access.write_bcr] + ; Handle full duplex setting + cmp byte [pcnet32_private.full_duplex],0 + je .L2 + mov ebx,9 + call dword [pcnet32_access.read_bcr] + and eax,not 3 + test [pcnet32_private.options],PCNET32_PORT_FD + jz .L3 + or eax,1 + cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI + jne .L4 + or eax,2 + jmp .L4 +.L3: + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L4 + cmp [pcnet32_private.chip_version],0x2627 + jne .L4 + or eax,3 +.L4: + mov ebx,9 + call dword [pcnet32_access.write_bcr] +.L2: + ; set/reset GPSI bit + mov ebx,124 + call dword [pcnet32_access.read_csr] + mov ecx,[pcnet32_private.options] + and ecx,PCNET32_PORT_PORTSEL + cmp ecx,PCNET32_PORT_GPSI + jne .L5 + or eax,0x10 +.L5: + call dword [pcnet32_access.write_csr] + cmp [pcnet32_private.mii],0 + je .L6 + test [pcnet32_private.options],PCNET32_PORT_ASEL + jnz .L6 + mov ebx,32 + call dword [pcnet32_access.read_bcr] + and eax,not 0x38 + test [pcnet32_private.options],PCNET32_PORT_FD + jz .L7 + or eax,0x10 +.L7: + test [pcnet32_private.options],PCNET32_PORT_100 + jz .L8 + or eax,0x08 +.L8: + call dword [pcnet32_access.write_bcr] + jmp .L9 +.L6: + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L9 + mov ebx,32 +; DEBUGF 1," K : ASEL, enable auto-negotiation\n" + call dword [pcnet32_access.read_bcr] + and eax,not 0x98 + or eax,0x20 + call dword [pcnet32_access.write_bcr] +.L9: + cmp [pcnet32_private.ltint],0 + je .L10 + mov ebx,5 + call dword [pcnet32_access.read_csr] + or eax,(1 shl 14) + call dword [pcnet32_access.write_csr] +.L10: + mov eax,[pcnet32_private.options] + and eax,PCNET32_PORT_PORTSEL + shl eax,7 + mov [pcnet32_private.mode],ax + mov [pcnet32_private.filter],dword 0xffffffff + mov [pcnet32_private.filter+4],dword 0xffffffff + call pcnet32_init_ring + mov ebx,1 + mov eax,pcnet32_private + sub eax,OS_BASE + and eax,0xffff + call dword [pcnet32_access.write_csr] + mov eax,pcnet32_private + sub eax,OS_BASE + mov ebx,2 + shr eax,16 + call dword [pcnet32_access.write_csr] + mov ebx,4 + mov eax,0x0915 + call dword [pcnet32_access.write_csr] + mov ebx,0 + mov eax,1 + call dword [pcnet32_access.write_csr] + mov ecx,100 +.L11: + xor ebx,ebx + call dword [pcnet32_access.read_csr] + test ax,0x100 + jnz .L12 + loop .L11 +.L12: +; DEBUGF 1," K : hardware reset\n" + xor ebx,ebx + mov eax,0x0002 + call dword [pcnet32_access.write_csr] + xor ebx,ebx + call dword [pcnet32_access.read_csr] +; DEBUGF 1," K : PCNET reset complete\n" + ret + + + +pcnet32_adjust_pci_device: + ;*******Get current setting************************ + mov al, 2 ;read a word + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x04 ;from command Register + call pci_read_reg + ;******see if its already set as bus master******** + mov bx, ax + and bx,5 + cmp bx,5 + je pcnet32_adjust_pci_device_Latency + ;******Make card a bus master******* + mov cx, ax ;value to write + mov bh, [pci_dev] + mov al, 2 ;write a word + or cx,5 + mov ah, [pci_bus] + mov bl, 0x04 ;to command register + call pci_write_reg + ;******Check latency setting*********** +pcnet32_adjust_pci_device_Latency: + ;*******Get current latency setting************************ +; mov al, 1 ;read a byte +; mov bh, [pci_dev] +; mov ah, [pci_bus] +; mov bl, 0x0D ;from Lantency Timer Register +; call pci_read_reg + ;******see if its aat least 64 clocks******** +; cmp ax,64 +; jge pcnet32_adjust_pci_device_Done + ;******Set latency to 32 clocks******* +; mov cx, 64 ;value to write +; mov bh, [pci_dev] +; mov al, 1 ;write a byte +; mov ah, [pci_bus] +; mov bl, 0x0D ;to Lantency Timer Register +; call pci_write_reg + ;******Check latency setting*********** +pcnet32_adjust_pci_device_Done: + ret + + + + +pcnet32_probe: + mov ebp,[io_addr] + call pcnet32_wio_reset + xor ebx,ebx + call pcnet32_wio_read_csr + cmp eax,4 + jne .try_dwio + call pcnet32_wio_check + and al,al + jz .try_dwio +; DEBUGF 1," K : Using WIO\n" + mov esi,pcnet32_wio + jmp .L1 +.try_dwio: + call pcnet32_dwio_reset + xor ebx,ebx + call pcnet32_dwio_read_csr + cmp eax,4 + jne .no_dev + call pcnet32_dwio_check + and al,al + jz .no_dev +; DEBUGF 1," K : Using DWIO\n" + mov esi,pcnet32_dwio + jmp .L1 +.no_dev: + DEBUGF 1," K : PCNET32 not found\n" + ret +.L1: + mov edi,pcnet32_access + mov ecx,7 + cld + rep movsd + mov ebx,88 + call dword [pcnet32_access.read_csr] + mov ecx,eax + mov ebx,89 + call dword [pcnet32_access.read_csr] + shl eax,16 + or eax,ecx + mov ecx,eax + and ecx,0xfff + cmp ecx,3 + jne .no_dev + shr eax,12 + and eax,0xffff + mov [pcnet32_private.chip_version],eax +; DEBUGF 1," K : PCNET32 chip version OK\n" + mov [pcnet32_private.fdx],0 + mov [pcnet32_private.mii],0 + mov [pcnet32_private.fset],0 + mov [pcnet32_private.dxsuflo],0 + mov [pcnet32_private.ltint],0 + mov eax,[pcnet32_private.chip_version] + cmp eax,0x2420 + je .L2 + cmp eax,0x2430 + je .L3 + cmp eax,0x2621 + je .L4 + cmp eax,0x2623 + je .L5 + cmp eax,0x2624 + je .L6 + cmp eax,0x2625 + je .L7 + cmp eax,0x2626 + je .L8 + cmp eax,0x2627 + je .L9 + DEBUGF 1," K : Invalid chip rev\n" + jmp .no_dev +.L2: +; DEBUGF 1," K : PCnet/PCI 79C970\n" + jmp .L10 +.L3: +; DEBUGF 1," K : PCnet/PCI 79C970\n" + jmp .L10 +.L4: +; DEBUGF 1," K : PCnet/PCI II 79C970A\n" + mov [pcnet32_private.fdx],1 + jmp .L10 +.L5: +; DEBUGF 1," K : PCnet/FAST 79C971\n" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + mov [pcnet32_private.ltint],1 + jmp .L10 +.L6: +; DEBUGF 1," K : PCnet/FAST+ 79C972\n" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + jmp .L10 +.L7: +; DEBUGF 1," K : PCnet/FAST III 79C973\n" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + jmp .L10 +.L8: +; DEBUGF 1," K : PCnet/Home 79C978\n" + mov [pcnet32_private.fdx],1 + mov ebx,49 + call dword [pcnet32_access.read_bcr] + call dword [pcnet32_access.write_bcr] + jmp .L10 +.L9: +; DEBUGF 1," K : PCnet/FAST III 79C975\n" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 +.L10: + cmp [pcnet32_private.fset],1 + jne .L11 + mov ebx,18 + call dword [pcnet32_access.read_bcr] + or eax,0x800 + call dword [pcnet32_access.write_bcr] + mov ebx,80 + call dword [pcnet32_access.read_csr] + and eax,0xc00 + or eax,0xc00 + call dword [pcnet32_access.write_csr] + mov [pcnet32_private.dxsuflo],1 + mov [pcnet32_private.ltint],1 +.L11: + ; read MAC + mov edi,node_addr + mov edx,ebp + mov ecx,6 +.Lmac: + in al,dx + stosb + inc edx + loop .Lmac +; DEBUGF 1," K : MAC read\n" + call pcnet32_adjust_pci_device +; DEBUGF 1," K : PCI done\n" + mov eax,PCNET32_PORT_ASEL + mov [pcnet32_private.options],eax + mov [pcnet32_private.mode],word 0x0003 + mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) + mov esi,node_addr + mov edi,pcnet32_private.phys_addr + cld + movsd + movsw + mov [pcnet32_private.filter],dword 0 + mov [pcnet32_private.filter+4],dword 0 + mov eax,pcnet32_rx_ring + sub eax,OS_BASE + mov dword [pcnet32_private.rx_ring],eax + + mov eax,pcnet32_tx_ring + sub eax,OS_BASE + mov dword [pcnet32_private.tx_ring],eax +; DEBUGF 1," K : Switching to 32\n" + mov ebx,20 + mov eax,2 + call dword [pcnet32_access.write_bcr] + mov ebx,1 + mov eax,(pcnet32_private and 0xffff) + call dword [pcnet32_access.write_csr] + mov ebx,2 + mov eax,(pcnet32_private shr 16) and 0xffff + call dword [pcnet32_access.write_csr] + mov ebx,0 + mov eax,1 + call dword [pcnet32_access.write_csr] + mov esi,1 + call delay_ms + call pcnet32_reset + mov eax, [pci_data] + mov [eth_status], eax + ret + + + +pcnet32_poll: + xor ax,ax + mov [eth_rx_data_len],ax + mov eax,[pcnet32_private.cur_rx] + and eax,PCNET32_RX_RING_MOD_MASK + mov ebx,eax + imul esi,eax,PCNET32_PKT_BUF_SZ + add esi,pcnet32_rxb + shl ebx,4 + add ebx,pcnet32_rx_ring + mov cx,[ebx+pcnet32_rx_head.status] + test cx,0x8000 + jnz .L1 + cmp ch,3 + jne .L1 + mov ecx,[ebx+pcnet32_rx_head.msg_length] + and ecx,0xfff + sub ecx,4 + mov [eth_rx_data_len],cx +; DEBUGF 1," K : PCNETRX: %ub\n",cx + push ecx + shr ecx,2 + mov edi,Ether_buffer + cld + rep movsd + pop ecx + and ecx,3 + rep movsb + mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG + or [ebx+pcnet32_rx_head.status],word 0x8000 + inc [pcnet32_private.cur_rx] +.L1: + ret + + + + +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +pcnet32_xmit: + push edi + push esi + push ebx + push ecx +; DEBUGF 1," K : PCNETTX\n" + mov esi,edi + mov edi,[pcnet32_private.cur_tx] + imul edi,PCNET32_PKT_BUF_SZ + add edi,pcnet32_txb ; edi=ptxb + mov eax,edi + cld ; copy MAC + movsd + movsw + mov esi,node_addr + cld + movsd + movsw + mov [edi],bx + add edi,2 + mov esi,[esp+8] + mov ecx,[esp] + push ecx + shr ecx,2 + cld + rep movsd + pop ecx + and ecx,3 + rep movsb +; mov ecx,[esp] +; add ecx,14 ; ETH_HLEN +; xor eax,eax +; pad to min length (60=ETH_ZLEN) +; cmp ecx,60 +; jae .L1 +; sub ecx,60 +; cld +; rep stosb +;.L1: + mov edi,pcnet32_tx_ring+0 ; entry=0 + mov ecx,[esp] + add ecx,14 + cmp cx,60 + jae .L1 + mov cx,60 +.L1: + neg cx + mov [edi+pcnet32_tx_head.length],cx + mov [edi+pcnet32_tx_head.misc],dword 0 + sub eax,OS_BASE + mov [edi+pcnet32_tx_head.base],eax + mov [edi+pcnet32_tx_head.status],word 0x8300 + ; trigger an immediate send poll + mov ebx,0 + mov eax,0x0008 ; 0x0048 + mov ebp,[io_addr] + call dword [pcnet32_access.write_csr] + mov dword [pcnet32_private.cur_tx],0 + ; wait for TX to complete + mov ecx,[timer_ticks];[0xfdf0] + add ecx,100 +.L2: + mov ax,[edi+pcnet32_tx_head.status] + test ax,0x8000 + jz .L3 + cmp ecx,[timer_ticks];[0xfdf0] + jb .L4 + mov esi,10 + call delay_ms + jnz .L2 +.L4: + DEBUGF 1," K : PCNET: Send timeout\n" +.L3: + mov dword [edi+pcnet32_tx_head.base],0 + pop ecx + pop ebx + pop esi + pop edi + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8029.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8029.inc new file mode 100644 index 000000000..6b66b54ed --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8029.inc @@ -0,0 +1,959 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; RTL8029.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.2 31 July 2002 ;; +;; ;; +;; This driver is based on the ns8390 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett, ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; While this implementation handles only PCI bus RTL8029 ;; +;; hardware, it can be easily adapted to other NE2000 clone ;; +;; products. I just dont have any to try! ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************** +; Interface +; rtl8029_reset +; rtl8029_probe +; rtl8029_poll +; rtl8029_transmit +; +;******************************************************************** + + + + +;************************************************************************** +; 8390 Register Definitions +;************************************************************************** +D8390_P0_COMMAND equ 0x00 +D8390_P0_PSTART equ 0x01 +D8390_P0_PSTOP equ 0x02 +D8390_P0_BOUND equ 0x03 +D8390_P0_TSR equ 0x04 +D8390_P0_TPSR equ 0x04 +D8390_P0_TBCR0 equ 0x05 +D8390_P0_TBCR1 equ 0x06 +D8390_P0_ISR equ 0x07 +D8390_P0_RSAR0 equ 0x08 +D8390_P0_RSAR1 equ 0x09 +D8390_P0_RBCR0 equ 0x0A +D8390_P0_RBCR1 equ 0x0B +D8390_P0_RSR equ 0x0C +D8390_P0_RCR equ 0x0C +D8390_P0_TCR equ 0x0D +D8390_P0_DCR equ 0x0E +D8390_P0_IMR equ 0x0F +D8390_P1_COMMAND equ 0x00 +D8390_P1_PAR0 equ 0x01 +D8390_P1_PAR1 equ 0x02 +D8390_P1_PAR2 equ 0x03 +D8390_P1_PAR3 equ 0x04 +D8390_P1_PAR4 equ 0x05 +D8390_P1_PAR5 equ 0x06 +D8390_P1_CURR equ 0x07 +D8390_P1_MAR0 equ 0x08 + +D8390_COMMAND_PS0 equ 0x0 ; Page 0 select +D8390_COMMAND_PS1 equ 0x40 ; Page 1 select +D8390_COMMAND_PS2 equ 0x80 ; Page 2 select +D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control +D8390_COMMAND_RD1 equ 0x10 +D8390_COMMAND_RD0 equ 0x08 +D8390_COMMAND_TXP equ 0x04 ; transmit packet +D8390_COMMAND_STA equ 0x02 ; start +D8390_COMMAND_STP equ 0x01 ; stop + +D8390_COMMAND_RD2_STA equ 0x22 +D8390_COMMAND_RD2_STP equ 0x21 +D8390_COMMAND_RD1_STA equ 0x12 +D8390_COMMAND_RD0_STA equ 0x0A +D8390_COMMAND_PS0_RD2_STP equ 0x21 +D8390_COMMAND_PS1_RD2_STP equ 0x61 +D8390_COMMAND_PS0_RD2_STA equ 0x22 +D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 + +D8390_RCR_MON equ 0x20 ; monitor mode + +D8390_DCR_FT1 equ 0x40 +D8390_DCR_LS equ 0x08 ; Loopback select +D8390_DCR_WTS equ 0x01 ; Word transfer select + +D8390_DCR_FT1_LS equ 0x48 +D8390_DCR_WTS_FT1_LS equ 0x49 + +D8390_ISR_PRX equ 0x01 ; successful recv +D8390_ISR_PTX equ 0x02 ; successful xmit +D8390_ISR_RXE equ 0x04 ; receive error +D8390_ISR_TXE equ 0x08 ; transmit error +D8390_ISR_OVW equ 0x10 ; Overflow +D8390_ISR_CNT equ 0x20 ; Counter overflow +D8390_ISR_RDC equ 0x40 ; Remote DMA complete +D8390_ISR_RST equ 0x80 ; reset + +D8390_RSTAT_PRX equ 0x01 ; successful recv +D8390_RSTAT_CRC equ 0x02 ; CRC error +D8390_RSTAT_FAE equ 0x04 ; Frame alignment error +D8390_RSTAT_OVER equ 0x08 ; FIFO overrun + +D8390_TXBUF_SIZE equ 6 +D8390_RXBUF_END equ 32 +D8390_PAGE_SIZE equ 256 + +ETH_ALEN equ 6 +ETH_HLEN equ 14 +ETH_ZLEN equ 60 +ETH_FRAME_LEN equ 1514 + +FLAG_PIO equ 0x01 +FLAG_16BIT equ 0x02 +ASIC_PIO equ 0 + +VENDOR_NONE equ 0 +VENDOR_WD equ 1 +VENDOR_NOVELL equ 2 +VENDOR_3COM equ 3 + +NE_ASIC_OFFSET equ 0x10 +NE_RESET equ 0x0F ; Used to reset card +NE_DATA equ 0x00 ; Used to read/write NIC mem + +MEM_8192 equ 32 +MEM_16384 equ 64 +MEM_32768 equ 128 + +ISA_MAX_ADDR equ 0x400 + +uglobal +eth_flags: db 0 +eth_vendor: db 0 +eth_nic_base: dw 0 +eth_asic_base: dw 0 +eth_memsize: db 0 +eth_rx_start: db 0 +eth_tx_start: db 0 +eth_bmem: dd 0 +eth_rmem: dd 0 +romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +endg + +iglobal +test_data: db 'NE*000 memory',0 +test_buffer: db ' ',0 +endg + +uglobal +eth_type: dw 0 +pkthdr: db 0,0,0,0 ; status, next, (short) len +pktoff: dw 0 +eth_rx_data_ptr: dd 0 +eth_tmp_len: dw 0 +endg + + + +;*************************************************************************** +; Function +; eth_pio_read +; +; Description +; Read a frame from the ethernet card via Programmed I/O +; src in ebx +; cnt in ecx +; dst in edi +;*************************************************************************** +eth_pio_read: + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epr_001 + + inc ecx + and ecx, 0xFFFFFFFE + +epr_001: + mov al, D8390_COMMAND_RD2_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov al, cl + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR0 + out dx, al + + mov al, ch + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR1 + out dx, al + + mov al, bl + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR0 + out dx, al + + mov al, bh + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR1 + out dx, al + + mov al, D8390_COMMAND_RD0_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov dx, [eth_asic_base] + add dx, ASIC_PIO + + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epr_003 + + shr ecx, 1 + +epr_002: + ; 2 bytes at a time + in ax, dx + mov [edi], ax + add edi, 2 + loop epr_002 + ret + +epr_003: + ; 1 byte at a time + in al, dx + mov [edi], al + inc edi + loop epr_003 + ret + + + + +;*************************************************************************** +; Function +; eth_pio_write +; +; Description +; writes a frame to the ethernet card via Programmed I/O +; dst in ebx +; cnt in ecx +; src in esi +;*************************************************************************** +eth_pio_write: + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epw_001 + + inc ecx + and ecx, 0xFFFFFFFE + +epw_001: + mov al, D8390_COMMAND_RD2_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov al, D8390_ISR_RDC + mov dx, [eth_nic_base] + add dx, D8390_P0_ISR + out dx, al + + + mov al, cl + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR0 + out dx, al + + mov al, ch + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR1 + out dx, al + + mov al, bl + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR0 + out dx, al + + mov al, bh + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR1 + out dx, al + + mov al, D8390_COMMAND_RD1_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov dx, [eth_asic_base] + add dx, ASIC_PIO + + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epw_003 + + shr ecx, 1 + +epw_002: + ; 2 bytes at a time + mov ax, [esi] + add esi, 2 + out dx, ax + + loop epw_002 + jmp epw_004 + +epw_003: + ; 1 byte at a time + mov al, [esi] + inc esi + out dx, al + loop epw_003 + +epw_004: + mov dx, [eth_nic_base] + add dx, D8390_P0_ISR + +epw_005: + in al, dx + and al, D8390_ISR_RDC + cmp al, D8390_ISR_RDC + jne epw_005 + + ret + + + +;*************************************************************************** +; Function +; rtl8029_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +rtl8029_reset: + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P0_DCR + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, FLAG_16BIT + jne nsr_001 + + mov al, 0x49 + jmp nsr_002 + +nsr_001: + mov al, 0x48 + +nsr_002: + out dx, al + + xor al, al + + mov dx, bx + add dx, D8390_P0_RBCR0 + out dx, al + + mov dx, bx + add dx, D8390_P0_RBCR1 + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, 0x20 + out dx, al + + mov dx, bx + add dx, D8390_P0_TCR + mov al, 2 + out dx, al + + mov dx, bx + add dx, D8390_P0_TPSR + mov al, [eth_tx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, [eth_rx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, [eth_memsize] + out dx, al + + mov dx, bx + add dx, D8390_P0_BOUND + mov al, [eth_memsize] + dec al + out dx, al + + mov dx, bx + add dx, D8390_P0_ISR + mov al, 0xff + out dx, al + + mov dx, bx + add dx, D8390_P0_IMR + xor al, al + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS1_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P1_PAR0 + mov esi, node_addr + mov ecx, ETH_ALEN + +nsr_003: + mov al, [esi] + out dx, al + + inc esi + inc dx + loop nsr_003 + + mov dx, bx + add dx, D8390_P1_MAR0 + mov ecx, ETH_ALEN + + mov al, 0xff + +nsr_004: + out dx, al + inc dx + loop nsr_004 + + mov dx, bx + add dx, D8390_P1_CURR + mov al, [eth_rx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STA + out dx, al + + mov dx, bx + add dx, D8390_P0_ISR + mov al, 0xff + out dx, al + + mov dx, bx + add dx, D8390_P0_TCR + mov al, 0 + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, 4 + out dx, al + + ret + + + +;*************************************************************************** +; Function +; rtl8029_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; +;*************************************************************************** +rtl8029_probe: + mov eax, [io_addr] + mov [eth_nic_base], ax ; The IO address space is 16 bit only + + mov al, VENDOR_NONE + mov [eth_vendor], al + + mov al, [eth_vendor] + cmp al, VENDOR_NONE + + jne ep_check_have_vendor + xor eax, eax + mov [eth_bmem], eax + + mov al, FLAG_PIO + mov [eth_flags], al + + mov ax, [eth_nic_base] + add ax, NE_ASIC_OFFSET + mov [eth_asic_base], ax + + mov al, MEM_16384 + mov [eth_memsize], al + + mov al, 32 + mov [eth_tx_start], al + + add al, D8390_TXBUF_SIZE + mov [eth_rx_start], al + + mov dx, [eth_asic_base] + add dx, NE_RESET + + in al, dx + out dx, al + + in al, 0x84 + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, D8390_RCR_MON + out dx, al + + mov dx, bx + add dx, D8390_P0_DCR + mov al, D8390_DCR_FT1_LS + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, MEM_8192 + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, MEM_16384 + out dx, al + + mov esi, test_data + mov ebx, 8192 + mov ecx, 14 + call eth_pio_write + + mov ebx, 8192 + mov ecx, 14 + mov edi, test_buffer + call eth_pio_read + + mov esi, test_buffer + mov edi, test_data + mov ecx, 13 + cld + rep cmpsb + + je ep_set_vendor + + mov al, [eth_flags] + or al, FLAG_16BIT + mov [eth_flags], al + + mov al, MEM_32768 + mov [eth_memsize], al + + mov al, 64 + mov [eth_tx_start], al + + add al, D8390_TXBUF_SIZE + mov [eth_rx_start], al + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_DCR + mov al, D8390_DCR_WTS_FT1_LS + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, MEM_16384 + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, MEM_32768 + out dx, al + + mov esi, test_data + mov ebx, 16384 + mov ecx, 14 + call eth_pio_write + + mov ebx, 16384 + mov ecx, 14 + mov edi, test_buffer + call eth_pio_read + + mov esi, test_buffer + mov edi, test_data + mov ecx, 13 + cld + rep cmpsb + +ep_set_vendor: + ; this bit is odd - probably left over from my hacking + mov ax, [eth_nic_base] + cmp ax, 0 + je rtl8029_exit + cmp ax, ISA_MAX_ADDR + jbe ep_001 + mov al, [eth_flags] + or al, FLAG_16BIT + mov [eth_flags], al + +ep_001: + mov al, VENDOR_NOVELL + mov [eth_vendor], al + + mov ebx, 0 + mov ecx, 16 + mov edi, romdata + call eth_pio_read + + + mov ecx, ETH_ALEN + mov esi, romdata + mov edi, node_addr + + mov bl, [eth_flags] + and bl, FLAG_16BIT + +ep_002: + mov al, [esi] + mov [edi], al + + inc edi + inc esi + cmp bl, FLAG_16BIT + jne ep_003 + + inc esi + +ep_003: + loop ep_002 + +ep_check_have_vendor: + mov al, [eth_vendor] + cmp al, VENDOR_NONE + je rtl8029_exit + + cmp al, VENDOR_3COM + je ep_reset_card + + mov eax, [eth_bmem] + mov [eth_rmem], eax + +ep_reset_card: + ; Reset the card + call rtl8029_reset + + ; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + +rtl8029_exit: + ret + + + +;*************************************************************************** +; Function +; rtl8029_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; +;*************************************************************************** +rtl8029_poll: + mov eax, Ether_buffer + mov [eth_rx_data_ptr], eax + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_RSR + in al, dx + + and al, D8390_RSTAT_PRX + cmp al, D8390_RSTAT_PRX + jne nsp_exit + + mov dx, bx + add dx, D8390_P0_BOUND + in al, dx + inc al + + cmp al, [eth_memsize] + jb nsp_001 + + mov al, [eth_rx_start] + +nsp_001: + mov ch, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS1 + out dx, al + + mov dx, bx + add dx, D8390_P1_CURR + in al, dx ; get current page + mov cl, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0 + out dx, al + + cmp cl, [eth_memsize] + jb nsp_002 + + mov cl, [eth_rx_start] + +nsp_002: + cmp cl, ch + je nsp_exit + + xor ax, ax + mov ah, ch + + mov [pktoff], ax + + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_003 + + movzx ebx, word [pktoff] + mov edi, pkthdr + mov ecx, 4 + call eth_pio_read + jmp nsp_004 + +nsp_003: + mov edi, [eth_rmem] + movzx eax, word [pktoff] + add edi, eax + mov eax, [edi] + mov [pkthdr], eax + +nsp_004: + mov ax, [pktoff] + add ax, 4 + mov [pktoff], ax + + mov ax, [pkthdr + 2] + sub ax, 4 + + mov [eth_tmp_len], ax + + cmp ax, ETH_ZLEN + jb nsp_exit + + cmp ax, ETH_FRAME_LEN + ja nsp_exit + + mov al, [pkthdr] + and al, D8390_RSTAT_PRX + cmp al, D8390_RSTAT_PRX + jne nsp_exit + + ; Right, we can now get the data + + mov ax, [eth_tmp_len] + mov [eth_rx_data_len], ax + + xor ebx, ebx + mov bh, [eth_memsize] + sub bx, [pktoff] + + cmp [eth_tmp_len], bx + jbe nsp_005 + + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_006 + + push ebx + mov ecx, ebx + xor ebx, ebx + mov bx, [pktoff] + mov edi, [eth_rx_data_ptr] + call eth_pio_read + pop ebx + jmp nsp_007 + +nsp_006: + ; Not implemented, as we are using PIO mode on this card + +nsp_007: + xor ax, ax + mov ah, [eth_rx_start] + mov [pktoff], ax + + mov eax, [eth_rx_data_ptr] + add eax, ebx + mov [eth_rx_data_ptr], eax + + mov ax, [eth_tmp_len] + sub ax, bx + mov [eth_tmp_len], ax + +nsp_005: + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_008 + + xor ebx, ebx + mov bx, [pktoff] + xor ecx, ecx + mov cx, [eth_tmp_len] + mov edi, [eth_rx_data_ptr] + call eth_pio_read + jmp nsp_009 + +nsp_008: + ; Not implemented, as we are using PIO mode on this card + +nsp_009: + mov al, [pkthdr+1] + cmp al, [eth_rx_start] + jne nsp_010 + + mov al, [eth_memsize] + +nsp_010: + mov dx, [eth_nic_base] + add dx, D8390_P0_BOUND + dec al + out dx, al + +nsp_exit: + ret + + + +;*************************************************************************** +; Function +; rtl8029_transmit +; +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +rtl8029_transmit: + mov [eth_type], bx + + pusha + + mov esi, edi + xor bx, bx + mov bh, [eth_tx_start] + mov ecx, ETH_ALEN + call eth_pio_write + + mov esi, node_addr + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_ALEN + mov ecx, ETH_ALEN + call eth_pio_write + + mov esi, eth_type + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_ALEN + add bx, ETH_ALEN + mov ecx, 2 + call eth_pio_write + + popa + + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_HLEN + push ecx + call eth_pio_write + pop ecx + + add ecx, ETH_HLEN + cmp ecx, ETH_ZLEN + jae nst_001 + + mov ecx, ETH_ZLEN + +nst_001: + push ecx + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STA + out dx, al + + mov dx, bx + add dx, D8390_P0_TPSR + mov al, [eth_tx_start] + out dx, al + + pop ecx + + mov dx, bx + add dx, D8390_P0_TBCR0 + mov al, cl + out dx, al + + mov dx, bx + add dx, D8390_P0_TBCR1 + mov al, ch + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_TXP_RD2_STA + out dx, al + + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8139.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8139.inc new file mode 100644 index 000000000..e63169f84 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8139.inc @@ -0,0 +1,621 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; RTL8139.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.2 11 August 2003 ;; +;; ;; +;; Driver for chips of RealTek 8139 family ;; +;; References: ;; +;; www.realtek.com.hw - data sheets ;; +;; rtl8139.c - linux driver ;; +;; 8139too.c - linux driver ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2003 Endre Kozma, ;; +;; endre.kozma@axelero.hu ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + + ETH_ALEN equ 6 + ETH_HLEN equ (2 * ETH_ALEN + 2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length + + PCI_REG_COMMAND equ 0x04 ; command register + PCI_BIT_PIO equ 0 ; bit0: io space control + PCI_BIT_MMIO equ 1 ; bit1: memory space control + PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master + + RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 + RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 + RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor + RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor + RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address + RTL8139_REG_COMMAND equ 0x37 ; command register + RTL8139_REG_CAPR equ 0x38 ; current address of packet read + RTL8139_REG_IMR equ 0x3c ; interrupt mask register + RTL8139_REG_ISR equ 0x3e ; interrupt status register + RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register + RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 + RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 + RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 + RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 + RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 + RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 + RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 + RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 + RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 + RTL8139_REG_MPC equ 0x4c ; missed packet counter + RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register + RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 + RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 + RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register + RTL8139_REG_BMCR equ 0x62 ; basic mode control register + RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register + +; 5.1 packet header + RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes + RTL8139_BIT_LONG equ 3 ; total packet length > 4k + RTL8139_BIT_CRC equ 2 ; crc error occured + RTL8139_BIT_FAE equ 1 ; frame alignment error occured + RTL8139_BIT_ROK equ 0 ; received packet is ok +; 5.4 command register + RTL8139_BIT_RST equ 4 ; reset bit + RTL8139_BIT_RE equ 3 ; receiver enabled + RTL8139_BIT_TE equ 2 ; transmitter enabled + RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored +; 5.6 interrupt status register + RTL8139_BIT_ISR_TOK equ 2 ; transmit ok + RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt + RTL8139_BIT_ISR_ROK equ 0 ; receive ok +; 5.7 transmit configyration register + RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst + RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) +; 5.8 receive configuration register + RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold + RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator + RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst + RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping + RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 + RTL8139_BIT_AER equ 5 ; accept error packets + RTL8139_BIT_AR equ 4 ; accept runt packets + RTL8139_BIT_AB equ 3 ; accept broadcast packets + RTL8139_BIT_AM equ 2 ; accept multicast packets + RTL8139_BIT_APM equ 1 ; accept physical match packets + RTL8139_BIT_AAP equ 0 ; accept all packets +; 5.9 93C46/93C56 command register + RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 + RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 + RTL8139_BIT_93C46_EECS equ 3 ; chip select + RTL8139_BIT_93C46_EESK equ 2 ; serial data clock + RTL8139_BIT_93C46_EEDI equ 1 ; serial data input + RTL8139_BIT_93C46_EEDO equ 0 ; serial data output +; 5.11 configuration register 1 + RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 + RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips + RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips + RTL8139_BIT_PMEn equ 0 ; power management enabled +; 5.14 configuration register 4 + RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 +; 6.2 transmit status register + RTL8139_BIT_ERTXTH equ 16 ; early TX threshold + RTL8139_BIT_TOK equ 15 ; transmit ok + RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed +; 6.18 basic mode control register + RTL8139_BIT_ANE equ 12 ; auto negotiation enable +; 6.20 auto negotiation advertisement register + RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex + RTL8139_BIT_TX equ 7 ; 100base-T + RTL8139_BIT_10FD equ 6 ; 10base-T full duplex + RTL8139_BIT_10 equ 5 ; 10base-T + RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 +; RX/TX buffer size + RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k + RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) + MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC + RTL8139_NUM_TX_DESC equ 4 + RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) + RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) + RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==2048 + RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 + RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==unlimited + RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==no threshold + RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ + or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ + or (1 shl RTL8139_BIT_NOWRAP) \ + or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ + or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ + or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ + or (1 shl RTL8139_BIT_AM)) + RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout + + EE_93C46_REG_ETH_ID equ 7 ; MAC offset + EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address + EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address + EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address + EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress + + VER_RTL8139 equ 1100000b + VER_RTL8139A equ 1110000b +; VER_RTL8139AG equ 1110100b + VER_RTL8139B equ 1111000b + VER_RTL8130 equ VER_RTL8139B + VER_RTL8139C equ 1110100b + VER_RTL8100 equ 1111010b + VER_RTL8100B equ 1110101b + VER_RTL8139D equ VER_RTL8100B + VER_RTL8139CP equ 1110110b + VER_RTL8101 equ 1110111b + + IDX_RTL8139 equ 0 + IDX_RTL8139A equ 1 + IDX_RTL8139B equ 2 + IDX_RTL8139C equ 3 + IDX_RTL8100 equ 4 + IDX_RTL8139D equ 5 + IDX_RTL8139D equ 6 + IDX_RTL8101 equ 7 + + +; These two must be 4 byte aligned ( which they are ) +rtl8139_rx_buff equ eth_data_start +rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) + +uglobal + align 4 +rtl8139_rx_buff_offset: dd 0 +curr_tx_desc dd 0 +endg + +iglobal +hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C + db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 +HW_VER_ARRAY_SIZE = $-hw_ver_array +endg + +uglobal +hw_ver_id: db 0 +endg + +;*************************************************************************** +; Function +; rtl8139_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +rtl8139_probe: +; enable the device + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + call pci_read_reg + mov cx, ax + or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) + and cl, not (1 shl PCI_BIT_MMIO) + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + call pci_write_reg +; get chip version + mov edx, [io_addr] + add edx, RTL8139_REG_TXCONFIG_2 + in ax, dx + shr ah, 2 + shr ax, 6 + and al, 01111111b + mov ecx, HW_VER_ARRAY_SIZE-1 +.chip_ver_loop: + cmp al, [hw_ver_array+ecx] + je .chip_ver_found + dec ecx + jns .chip_ver_loop + xor cl, cl ; default RTL8139 +.chip_ver_found: + mov [hw_ver_id], cl +; wake up the chip + mov edx, [io_addr] + add edx, RTL8139_REG_HLTCLK + mov al, 'R' ; run the clock + out dx, al +; unlock config and BMCR registers + add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) + out dx, al +; enable power management + add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR + in al, dx + cmp byte [hw_ver_id], IDX_RTL8139B + jl .old_chip +; set LWAKE pin to active high (default value). +; it is for Wake-On-LAN functionality of some motherboards. +; this signal is used to inform the motherboard to execute a wake-up process. +; only at newer chips. + or al, (1 shl RTL8139_BIT_PMEn) + and al, not (1 shl RTL8139_BIT_LWACT) + out dx, al + add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 + in al, dx + and al, not (1 shl RTL8139_BIT_LWPTN) + out dx, al + jmp .finish_wake_up +.old_chip: +; wake up older chips + and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) + out dx, al +.finish_wake_up: +; lock config and BMCR registers + xor al, al + mov edx, [io_addr] + add edx, RTL8139_REG_9346CR + out dx, al +;*************************************************************************** +; Function +; rt8139_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +rtl8139_reset: + mov edx, [io_addr] + add edx, RTL8139_REG_COMMAND + mov al, 1 shl RTL8139_BIT_RST + out dx, al + mov cx, 1000 ; wait no longer for the reset +.wait_for_reset: + in al, dx + test al, 1 shl RTL8139_BIT_RST + jz .reset_completed ; RST remains 1 during reset + dec cx + jns .wait_for_reset +.reset_completed: +; get MAC (hardware address) + mov ecx, 2 +.mac_read_loop: + lea eax, [EE_93C46_REG_ETH_ID+ecx] + push ecx + call rtl8139_read_eeprom + pop ecx + mov [node_addr+ecx*2], ax + dec ecx + jns .mac_read_loop +; unlock config and BMCR registers + mov edx, [io_addr] + add edx, RTL8139_REG_9346CR + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) + out dx, al +; initialize multicast registers (no filtering) + mov eax, 0xffffffff + add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR + out dx, eax + add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 + out dx, eax +; enable Rx/Tx + mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) + add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 + out dx, al +; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold +; accept broadcast packets, accept physical match packets + mov ax, RTL8139_RX_CONFIG + add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND + out dx, ax +; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 + mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ + or (RTL8139_TXRR shl RTL8139_BIT_TXRR) + add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG + out dx, ax +; enable auto negotiation + add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG + in ax, dx + or ax, (1 shl RTL8139_BIT_ANE) + out dx, ax +; set auto negotiation advertisement + add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR + in ax, dx + or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ + or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ + or (1 shl RTL8139_BIT_TXFD) + out dx, ax +; lock config and BMCR registers + xor eax, eax + add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR + out dx, al +; init RX/TX pointers + mov [rtl8139_rx_buff_offset], eax + mov [curr_tx_desc], eax +; clear missing packet counter + add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR + out dx, eax +; disable all interrupts + add edx, RTL8139_REG_IMR - RTL8139_REG_MPC + out dx, ax +; set RxBuffer address, init RX buffer offset, init TX ring + mov eax, rtl8139_rx_buff ; simba + sub eax,OS_BASE + add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR + out dx, eax +; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + ret + +;*************************************************************************** +; Function +; rtl8139_read_eeprom +; Description +; reads eeprom type 93c46 and 93c56 +; Parameters +; al - word to be read (6bit in case of 93c46 and 8bit otherwise) +; Return value +; ax - word read in +; Destroyed register(s) +; eax, cx, ebx, edx +; +;*************************************************************************** +rtl8139_read_eeprom: + movzx ebx, al + mov edx, [io_addr] + add edx, RTL8139_REG_RXCONFIG + in al, dx + test al, (1 shl RTL8139_BIT_9356SEL) + jz .type_93c46 +; and bl, 01111111b ; don't care first bit + or bx, EE_93C56_READ_CMD ; it contains start bit + mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter + jmp .read_eeprom +.type_93c46: + and bl, 00111111b + or bx, EE_93C46_READ_CMD ; it contains start bit + mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter +.read_eeprom: + add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 +; mov al, (1 shl RTL8139_BIT_93C46_EEM1) +; out dx, al + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom + out dx, al +.cmd_loop: + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) + bt bx, cx + jnc .zero_bit + or al, (1 shl RTL8139_BIT_93C46_EEDI) +.zero_bit: + out dx, al +; push eax +; in eax, dx ; eeprom delay +; pop eax + or al, (1 shl RTL8139_BIT_93C46_EESK) + out dx, al +; in eax, dx ; eeprom delay + dec cx + jns .cmd_loop +; in eax, dx ; eeprom delay + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) + out dx, al + mov cl, 0xf +.read_loop: + shl ebx, 1 + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) \ + or (1 shl RTL8139_BIT_93C46_EESK) + out dx, al +; in eax, dx ; eeprom delay + in al, dx + and al, (1 shl RTL8139_BIT_93C46_EEDO) + jz .dont_set + inc ebx +.dont_set: + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) + out dx, al +; in eax, dx ; eeprom delay + dec cl + jns .read_loop + xor al, al + out dx, al + mov ax, bx + ret + +;*************************************************************************** +; Function +; rtl8139_transmit +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; Size of packet in ecx +; Pointer to packet data in esi +; Destroyed registers +; eax, edx, esi, edi +; ToDo +; for waiting of timeout the rtl8139 internal timer +; should be used +; +;*************************************************************************** +rtl8139_transmit: + cmp ecx, MAX_ETH_FRAME_SIZE + jg .finish ; packet is too long + push ecx +; check descriptor + mov ecx, [curr_tx_desc] + mov edx, [io_addr] + lea edx, [edx+ecx*4+RTL8139_REG_TSD0] + push edx ebx + in ax, dx + test ax, 0x1fff ; or no size given + jz .send_packet + and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + jz .send_packet +; wait for timeout + mov ebx, RTL8139_TX_TIMEOUT + mov eax, 0x5 ; delay x/100 secs + int 0x40 + in ax, dx + and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + jz .send_packet +; chip hung, reset it + call rtl8139_reset +; reset the card +.send_packet: +; calculate tx_buffer address + pop ebx + push esi + mov eax, MAX_ETH_FRAME_SIZE + mul dword [curr_tx_desc] + mov esi, edi + lea edi, [rtl8139_tx_buff+eax] + mov eax, edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy the packet data + pop esi edx ecx + push ecx + shr ecx, 2 + rep movsd + pop ecx + push ecx + and ecx, 3 + rep movsb +; set address + sub eax,OS_BASE + add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 + out dx, eax +; set size and early threshold + pop eax ; pick up the size + add eax, ETH_HLEN + cmp eax, ETH_ZLEN + jnc .no_pad + mov eax, ETH_ZLEN +.no_pad: + or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) + add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 + out dx, eax +; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... + inc dword [curr_tx_desc] + and dword [curr_tx_desc], 3 +.finish: + ret + +;*************************************************************************** +; Function +; rtl8139_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed register(s) +; eax, edx, ecx +; +;*************************************************************************** +rtl8139_poll: + mov word [eth_rx_data_len], 0 + mov edx, [io_addr] + add edx, RTL8139_REG_COMMAND + in al, dx + test al, (1 shl RTL8139_BIT_BUFE) + jnz .finish +; new packet received copy it from rx_buffer into Ether_buffer + mov eax, rtl8139_rx_buff + add eax, [rtl8139_rx_buff_offset] +; check if packet is ok + test byte [eax], (1 shl RTL8139_BIT_ROK) + jz .reset_rx +; packet is ok copy it into the Ether_buffer + movzx ecx, word [eax+2] ; packet length + sub ecx, 4 ; don't copy CRC + mov word [eth_rx_data_len], cx + push ecx + shr ecx, 2 ; first copy dword-wise + lea esi, [eax+4] ; don't copy the packet header + mov edi, Ether_buffer + cld + rep movsd ; copy the dwords + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes +; update rtl8139_rx_buff_offset + movzx eax, word [eax+2] ; packet length + add eax, [rtl8139_rx_buff_offset] + add eax, 4+3 ; packet header is 4 bytes long + dword alignment + and eax, not 3 ; dword alignment + cmp eax, RTL8139_RX_BUFFER_SIZE + jl .no_wrap + sub eax, RTL8139_RX_BUFFER_SIZE +.no_wrap: + mov [rtl8139_rx_buff_offset], eax +; update CAPR register + sub eax, 0x10 ; value 0x10 is a constant for CAPR + add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND + out dx, ax +.finish: +; clear active interrupt sources + mov edx, [io_addr] + add edx, RTL8139_REG_ISR + in ax, dx + out dx, ax + ret +.reset_rx: + in al, dx ; read command register + push eax + and al, not (1 shl RTL8139_BIT_RE) + out dx, al + pop eax + out dx, al + add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND + mov ax, RTL8139_RX_CONFIG + out dx, ax + ret + +rtl8139_cable: + pusha + mov edx, [io_addr] + add edx, 0x58 + in al,dx + test al,1 SHL 2 + jnz .notconnected + popa + xor al,al + inc al + ret + .notconnected: + popa + xor al,al + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8169.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8169.inc new file mode 100644 index 000000000..498fd1545 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/rtl8169.inc @@ -0,0 +1,1219 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; RTL8169.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.1 11 February 2007 ;; +;; ;; +;; Driver for chips of RealTek 8169 family ;; +;; References: ;; +;; r8169.c - linux driver (etherboot project) ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2007 mike.dld, ;; +;; mike.dld@gmail.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + + ETH_ALEN equ 6 + ETH_HLEN equ (2 * ETH_ALEN + 2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length + + RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address + RTL8169_REG_MAR0 equ 0x8 ; Multicast filter + RTL8169_REG_TxDescStartAddr equ 0x20 + RTL8169_REG_TxHDescStartAddr equ 0x28 + RTL8169_REG_FLASH equ 0x30 + RTL8169_REG_ERSR equ 0x36 + RTL8169_REG_ChipCmd equ 0x37 + RTL8169_REG_TxPoll equ 0x38 + RTL8169_REG_IntrMask equ 0x3C + RTL8169_REG_IntrStatus equ 0x3E + RTL8169_REG_TxConfig equ 0x40 + RTL8169_REG_RxConfig equ 0x44 + RTL8169_REG_RxMissed equ 0x4C + RTL8169_REG_Cfg9346 equ 0x50 + RTL8169_REG_Config0 equ 0x51 + RTL8169_REG_Config1 equ 0x52 + RTL8169_REG_Config2 equ 0x53 + RTL8169_REG_Config3 equ 0x54 + RTL8169_REG_Config4 equ 0x55 + RTL8169_REG_Config5 equ 0x56 + RTL8169_REG_MultiIntr equ 0x5C + RTL8169_REG_PHYAR equ 0x60 + RTL8169_REG_TBICSR equ 0x64 + RTL8169_REG_TBI_ANAR equ 0x68 + RTL8169_REG_TBI_LPAR equ 0x6A + RTL8169_REG_PHYstatus equ 0x6C + RTL8169_REG_RxMaxSize equ 0xDA + RTL8169_REG_CPlusCmd equ 0xE0 + RTL8169_REG_RxDescStartAddr equ 0xE4 + RTL8169_REG_ETThReg equ 0xEC + RTL8169_REG_FuncEvent equ 0xF0 + RTL8169_REG_FuncEventMask equ 0xF4 + RTL8169_REG_FuncPresetState equ 0xF8 + RTL8169_REG_FuncForceEvent equ 0xFC + + ; InterruptStatusBits + RTL8169_ISB_SYSErr equ 0x8000 + RTL8169_ISB_PCSTimeout equ 0x4000 + RTL8169_ISB_SWInt equ 0x0100 + RTL8169_ISB_TxDescUnavail equ 0x80 + RTL8169_ISB_RxFIFOOver equ 0x40 + RTL8169_ISB_LinkChg equ 0x20 + RTL8169_ISB_RxOverflow equ 0x10 + RTL8169_ISB_TxErr equ 0x08 + RTL8169_ISB_TxOK equ 0x04 + RTL8169_ISB_RxErr equ 0x02 + RTL8169_ISB_RxOK equ 0x01 + + ; RxStatusDesc + RTL8169_SD_RxRES equ 0x00200000 + RTL8169_SD_RxCRC equ 0x00080000 + RTL8169_SD_RxRUNT equ 0x00100000 + RTL8169_SD_RxRWT equ 0x00400000 + + ; ChipCmdBits + RTL8169_CMD_Reset equ 0x10 + RTL8169_CMD_RxEnb equ 0x08 + RTL8169_CMD_TxEnb equ 0x04 + RTL8169_CMD_RxBufEmpty equ 0x01 + + ; Cfg9346Bits + RTL8169_CFG_9346_Lock equ 0x00 + RTL8169_CFG_9346_Unlock equ 0xC0 + + ; rx_mode_bits + RTL8169_RXM_AcceptErr equ 0x20 + RTL8169_RXM_AcceptRunt equ 0x10 + RTL8169_RXM_AcceptBroadcast equ 0x08 + RTL8169_RXM_AcceptMulticast equ 0x04 + RTL8169_RXM_AcceptMyPhys equ 0x02 + RTL8169_RXM_AcceptAllPhys equ 0x01 + + ; RxConfigBits + RTL8169_RXC_FIFOShift equ 13 + RTL8169_RXC_DMAShift equ 8 + + ; TxConfigBits + RTL8169_TXC_InterFrameGapShift equ 24 + RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits + + ; rtl8169_PHYstatus + RTL8169_PHYS_TBI_Enable equ 0x80 + RTL8169_PHYS_TxFlowCtrl equ 0x40 + RTL8169_PHYS_RxFlowCtrl equ 0x20 + RTL8169_PHYS_1000bpsF equ 0x10 + RTL8169_PHYS_100bps equ 0x08 + RTL8169_PHYS_10bps equ 0x04 + RTL8169_PHYS_LinkStatus equ 0x02 + RTL8169_PHYS_FullDup equ 0x01 + + ; GIGABIT_PHY_registers + RTL8169_PHY_CTRL_REG equ 0 + RTL8169_PHY_STAT_REG equ 1 + RTL8169_PHY_AUTO_NEGO_REG equ 4 + RTL8169_PHY_1000_CTRL_REG equ 9 + + ; GIGABIT_PHY_REG_BIT + RTL8169_PHY_Restart_Auto_Nego equ 0x0200 + RTL8169_PHY_Enable_Auto_Nego equ 0x1000 + + ; PHY_STAT_REG = 1; + RTL8169_PHY_Auto_Neco_Comp equ 0x0020 + + ; PHY_AUTO_NEGO_REG = 4; + RTL8169_PHY_Cap_10_Half equ 0x0020 + RTL8169_PHY_Cap_10_Full equ 0x0040 + RTL8169_PHY_Cap_100_Half equ 0x0080 + RTL8169_PHY_Cap_100_Full equ 0x0100 + + ; PHY_1000_CTRL_REG = 9; + RTL8169_PHY_Cap_1000_Full equ 0x0200 + RTL8169_PHY_Cap_1000_Half equ 0x0100 + + RTL8169_PHY_Cap_PAUSE equ 0x0400 + RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800 + + RTL8169_PHY_Cap_Null equ 0x0 + + ; _MediaType + RTL8169_MT_10_Half equ 0x01 + RTL8169_MT_10_Full equ 0x02 + RTL8169_MT_100_Half equ 0x04 + RTL8169_MT_100_Full equ 0x08 + RTL8169_MT_1000_Full equ 0x10 + + ; _TBICSRBit + RTL8169_TBI_LinkOK equ 0x02000000 + + ; _DescStatusBit + RTL8169_DSB_OWNbit equ 0x80000000 + RTL8169_DSB_EORbit equ 0x40000000 + RTL8169_DSB_FSbit equ 0x20000000 + RTL8169_DSB_LSbit equ 0x10000000 + +; MAC address length +MAC_ADDR_LEN equ 6 + +; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) +MAX_ETH_FRAME_SIZE equ 1536 + +TX_FIFO_THRESH equ 256 ; In bytes + +RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer +RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +ETTh equ 0x3F ; 0x3F means NO threshold + +EarlyTxThld equ 0x3F ; 0x3F means NO early transmit +RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1 +InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one + +NUM_TX_DESC equ 1 ; Number of Tx descriptor registers +NUM_RX_DESC equ 4 ; Number of Rx descriptor registers +RX_BUF_SIZE equ 1536 ; Rx Buffer size + +HZ equ 1000 + +RTL_MIN_IO_SIZE equ 0x80 +TX_TIMEOUT equ (6*HZ) + +RTL8169_TIMER_EXPIRE_TIME equ 100 + +ETH_HDR_LEN equ 14 +DEFAULT_MTU equ 1500 +DEFAULT_RX_BUF_LEN equ 1536 + + +;#ifdef RTL8169_JUMBO_FRAME_SUPPORT +;#define MAX_JUMBO_FRAME_MTU ( 10000 ) +;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) +;#else +MAX_RX_SKBDATA_SIZE equ 1600 +;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +;#ifdef RTL8169_USE_IO +;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) +macro RTL_W8 reg,val8 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val8 eq al + mov al,val8 + end if + out dx,al +} +;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) +macro RTL_W16 reg,val16 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val16 eq ax + mov ax,val16 + end if + out dx,ax +} +;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) +macro RTL_W32 reg,val32 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val32 eq eax + mov eax,val32 + end if + out dx,eax +} +;!!!#define RTL_R8(reg) inb (ioaddr + (reg)) +macro RTL_R8 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in al,dx +} +;!!!#define RTL_R16(reg) inw (ioaddr + (reg)) +macro RTL_R16 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in ax,dx +} +;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) +macro RTL_R32 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in eax,dx +} +;#else +; write/read MMIO register +;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) +;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) +;#define RTL_R8(reg) readb (ioaddr + (reg)) +;#define RTL_R16(reg) readw (ioaddr + (reg)) +;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +;#endif + +MCFG_METHOD_01 equ 0x01 +MCFG_METHOD_02 equ 0x02 +MCFG_METHOD_03 equ 0x03 +MCFG_METHOD_04 equ 0x04 +MCFG_METHOD_05 equ 0x05 +MCFG_METHOD_11 equ 0x0b +MCFG_METHOD_12 equ 0x0c +MCFG_METHOD_13 equ 0x0d +MCFG_METHOD_14 equ 0x0e +MCFG_METHOD_15 equ 0x0f + +PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000 +PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001 +PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002 + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +struc rtl8169_TxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_TxDesc rtl8169_TxDesc + sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc +end virtual + +struc rtl8169_RxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_RxDesc rtl8169_RxDesc + sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc +end virtual + +virtual at eth_data_start + +; Define the TX Descriptor +align 256 +rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; TX Descriptor. All descriptors point to a +; part of this buffer +align 256 +rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE + +; Define the RX Descriptor +align 256 +rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_RxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; RX Descriptor All descriptors point to a +; part of this buffer +align 256 +rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE + +rtl8169_tpc: + .mmio_addr dd ? ; memory map physical address + .chipset dd ? + .pcfg dd ? + .mcfg dd ? + .cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt + .cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt + .TxDescArrays dd ? ; Index of Tx Descriptor buffer + .RxDescArrays dd ? ; Index of Rx Descriptor buffer + .TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer + .RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer + .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array + .Tx_skbuff rd NUM_TX_DESC + +end virtual + +rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK +rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E + +iglobal + +;static struct { +; const char *name; +; u8 mcfg; /* depend on RTL8169 docs */ +; u32 RxConfigMask; /* should clear the bits supported by this chip */ +;} +rtl_chip_info dd \ + MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169 + MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb + MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc + MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139 + MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139 + MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139 + +mac_info dd \ + 0x38800000, MCFG_METHOD_15, \ + 0x38000000, MCFG_METHOD_12, \ + 0x34000000, MCFG_METHOD_13, \ + 0x30800000, MCFG_METHOD_14, \ + 0x30000000, MCFG_METHOD_11, \ + 0x18000000, MCFG_METHOD_05, \ + 0x10000000, MCFG_METHOD_04, \ + 0x04000000, MCFG_METHOD_03, \ + 0x00800000, MCFG_METHOD_02, \ + 0x00000000, MCFG_METHOD_01 ; catch-all + +endg + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +PCI_VENDOR_ID equ 0x00 ; 16 bits +PCI_DEVICE_ID equ 0x02 ; 16 bits +PCI_COMMAND equ 0x04 ; 16 bits + +PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits +PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits +PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits +PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits +PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits +PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits + +PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 +PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address +PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] +PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address + +PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) +PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_ROM_ADDRESS equ 0x30 ; 32 bits + +proc CONFIG_CMD,where:byte + movzx eax,byte[pci_bus] + shl eax,8 + mov al,[pci_dev] + shl eax,8 + mov al,[where] + and al,not 3 + or eax,0x80000000 + ret +endp + +proc pci_read_config_byte,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + in al,dx + pop edx + ret +endp + +proc pci_read_config_word,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + in ax,dx + pop edx + ret +endp + +proc pci_read_config_dword,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + in eax,dx + pop edx + ret +endp + +proc pci_write_config_byte,where:dword,value:byte + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + mov al,[value] + out dx,al + pop edx + ret +endp + +proc pci_write_config_word,where:dword,value:word + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + mov ax,[value] + out dx,ax + pop edx + ret +endp + +proc pci_write_config_dword,where:dword,value:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + mov eax,[value] + out dx,eax + pop edx + ret +endp + +; Set device to be a busmaster in case BIOS neglected to do so. +; Also adjust PCI latency timer to a reasonable value, 32. +proc adjust_pci_device + +; DEBUGF 1,"K : adjust_pci_device\n" + + stdcall pci_read_config_word,PCI_COMMAND + mov bx,ax + or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO + cmp ax,bx + je @f +; DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2 + stdcall pci_write_config_word,PCI_COMMAND,ebx + @@: + stdcall pci_read_config_byte,PCI_LATENCY_TIMER + cmp al,32 + jae @f +; DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al + stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32 + @@: + ret +endp + +; Find the start of a pci resource +proc pci_bar_start,index:dword + stdcall pci_read_config_dword,[index] + test eax,PCI_BASE_ADDRESS_SPACE_IO + jz @f + and eax,PCI_BASE_ADDRESS_IO_MASK + jmp .exit + @@: push eax + and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK + cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64 + jne .not64 + mov eax,[index] + add eax,4 + stdcall pci_read_config_dword,eax + or eax,eax + jz .not64 +; DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n" + add esp,4 + or eax,-1 + ret + .not64: + pop eax + and eax,PCI_BASE_ADDRESS_MEM_MASK + .exit: + ret +endp + +proc rtl8169_init_board + +; DEBUGF 1,"K : rtl8169_init_board\n" + + call adjust_pci_device + + stdcall pci_bar_start,PCI_BASE_ADDRESS_0 + mov [rtl8169_tpc.mmio_addr],eax + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + test al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + ; identify config method + RTL_R32 RTL8169_REG_TxConfig + and eax,0x7c800000 +; DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax + mov esi,mac_info-8 + @@: add esi,8 + mov ecx,eax + and ecx,[esi] + cmp ecx,[esi] + jne @b + mov eax,[esi+4] + mov [rtl8169_tpc.mcfg],eax + + mov [rtl8169_tpc.pcfg],PCFG_METHOD_3 + stdcall RTL8169_READ_GMII_REG,3 + and al,0x0f + or al,al + jnz @f + mov [rtl8169_tpc.pcfg],PCFG_METHOD_1 + jmp .pconf + @@: dec al + jnz .pconf + mov [rtl8169_tpc.pcfg],PCFG_METHOD_2 + .pconf: + + ; identify chip attached to board + mov ecx,10 + mov eax,[rtl8169_tpc.mcfg] + @@: dec ecx + js @f + cmp eax,[rtl_chip_info+ecx*8] + jne @b + mov [rtl8169_tpc.chipset],ecx + jmp .match + @@: + ; if unknown chip, assume array element #0, original RTL-8169 in this case +; DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n" + RTL_R32 RTL8169_REG_TxConfig +; DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax + + mov [rtl8169_tpc.chipset],0 + + xor eax,eax + inc eax + ret + + .match: + xor eax,eax + ret +endp + +proc rtl8169_hw_PHY_config + +; DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg] + +; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg); + + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04 + jne .not_4 +; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 +; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e +; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb +; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + jmp .exit + .not_4: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + je @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne .not_2_or_3 + @@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 + stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1 + stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000 + jmp .exit + .not_2_or_3: +; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg); +; DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg] + .exit: + ret +endp + +;proc pci_write_config_byte +; ret +;endp + +proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword + +;;; DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value] + + movzx eax,[RegAddr] + shl eax,16 + or eax,[value] + or eax,0x80000000 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1 ;;;1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed writing to the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jz .exit + stdcall udelay,1 ;;;100 + loop @b + .exit: + ret +endp + +proc RTL8169_READ_GMII_REG,RegAddr:byte + +;;; DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2 + + push ecx + movzx eax,[RegAddr] + shl eax,16 +; or eax,0x0 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1 ;;;1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed retrieving data from the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jnz .exit + stdcall udelay,1 ;;;100 + loop @b + + or eax,-1 + pop ecx + ret + .exit: + RTL_R32 RTL8169_REG_PHYAR + and eax,0xFFFF + pop ecx + ret +endp + +proc rtl8169_set_rx_mode + +; DEBUGF 1,"K : rtl8169_set_rx_mode\n" + + ; IFF_ALLMULTI + ; Too many to filter perfectly -- accept all multicasts + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys) + RTL_W32 RTL8169_REG_RxConfig,eax + + ; Multicast hash filter + RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff + RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff + ret +endp + +proc rtl8169_init_ring + +; DEBUGF 1,"K : rtl8169_init_ring\n" + + xor eax,eax + mov [rtl8169_tpc.cur_rx],eax + mov [rtl8169_tpc.cur_tx],eax + + mov edi,[rtl8169_tpc.TxDescArray] + mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4 + cld + rep stosd + mov edi,[rtl8169_tpc.RxDescArray] + mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4 + rep stosd + + mov edi,rtl8169_tpc.Tx_skbuff + mov eax,rtl8169_txb + mov ecx,NUM_TX_DESC + @@: stosd + inc eax ; add eax,RX_BUF_SIZE ??? + loop @b + +;!!! for (i = 0; i < NUM_RX_DESC; i++) { +;!!! if (i == (NUM_RX_DESC - 1)) +;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE; +;!!! else +;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE; +;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; +;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]); +;!!! } + mov esi,rtl8169_tpc.RxBufferRing + mov edi,[rtl8169_tpc.RxDescArray] + mov eax,rtl8169_rxb + mov ecx,NUM_RX_DESC + @@: mov [esi],eax + mov [edi+rtl8169_RxDesc.buf_addr],eax + sub [edi+rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 + mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE + add esi,4 + add edi,sizeof.rtl8169_RxDesc + add eax,RX_BUF_SIZE + loop @b + + or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit + + ret +endp + +proc rtl8169_hw_start + +; DEBUGF 1,"K : rtl8169_hw_start\n" + + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + and al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb + RTL_W8 RTL8169_REG_ETThReg,ETTh + ; For gigabit rtl8169 + RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize + ; Set Rx Config register + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config + RTL_W32 RTL8169_REG_RxConfig,eax + ; Set DMA burst size and Interframe Gap Time + RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift) + RTL_R16 RTL8169_REG_CPlusCmd + RTL_W16 RTL8169_REG_CPlusCmd,ax + + RTL_R16 RTL8169_REG_CPlusCmd + or ax,1 shl 3 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne @f + or ax,1 shl 14 +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n" + jmp .set + @@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n" + .set: RTL_W16 RTL8169_REG_CPlusCmd,ax + +; RTL_W16 0xE2,0x1517 +; RTL_W16 0xE2,0x152a +; RTL_W16 0xE2,0x282a + RTL_W16 0xE2,0x0000 + + MOV [rtl8169_tpc.cur_rx],0 + push eax ; shurf 28.09.2008 + mov eax, [rtl8169_tpc.TxDescArray] ; shurf 28.09.2008 + sub eax, OS_BASE ; shurf 28.09.2008 + RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray] ; shurf 28.09.2008 + mov eax, [rtl8169_tpc.RxDescArray] ; shurf 28.09.2008 + sub eax, OS_BASE ; shurf 28.09.2008 + RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray] ; shurf 28.09.2008 + pop eax ; shurf 28.09.2008 + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock + stdcall udelay,10 + RTL_W32 RTL8169_REG_RxMissed,0 + call rtl8169_set_rx_mode + ; no early-rx interrupts + RTL_R16 RTL8169_REG_MultiIntr + and ax,0xF000 + RTL_W16 RTL8169_REG_MultiIntr,ax + RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask + ret +endp + +proc udelay,msec:dword + push esi + mov esi,[msec] + call delay_ms + pop esi + ret +endp + +;*************************************************************************** +; Function +; rtl8169_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +proc rtl8169_probe + +; DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + call rtl8169_init_board + + mov ecx,MAC_ADDR_LEN + mov edx,[rtl8169_tpc.mmio_addr] + add edx,RTL8169_REG_MAC0 + xor ebx,ebx + ; Get MAC address. FIXME: read EEPROM + @@: RTL_R8 dx + mov [node_addr+ebx],al + inc edx + inc ebx + loop @b + +; DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2 + + ; Config PHY + stdcall rtl8169_hw_PHY_config +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jae @f +; DEBUGF 1,"K : Set PCI Latency=0x40\n" +; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40 + @@: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 +; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n" + stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0 + @@: + ; if TBI is not enabled + RTL_R8 RTL8169_REG_PHYstatus + test al,RTL8169_PHYS_TBI_Enable + jz .tbi_dis + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG + ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + and eax,0x0C1F + or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax + ; enable 1000 Full Mode + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168 + ; Enable auto-negotiation and restart auto-nigotiation + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego + stdcall udelay,100 + mov ecx,10000 + ; wait for auto-negotiation process + @@: dec ecx + jz @f + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG + stdcall udelay,100 + test eax,RTL8169_PHY_Auto_Neco_Comp + jz @b + RTL_R8 RTL8169_REG_PHYstatus + jmp @f + .tbi_dis: + stdcall udelay,100 + @@: + call rtl8169_reset + ret +endp + +;*************************************************************************** +; Function +; rt8169_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +proc rtl8169_reset + +; DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring + ; Tx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring + + mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring + ; Rx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring + + call rtl8169_init_ring + call rtl8169_hw_start + ; Construct a perfect filter frame with the mac address as first match + ; and broadcast for all others + mov edi,rtl8169_txb + or al,-1 + mov ecx,192 + cld + rep stosb + + mov esi,node_addr + mov edi,rtl8169_txb + movsd + movsw + + mov eax,[pci_data] + mov [eth_status],eax + ret +endp + +;*************************************************************************** +; Function +; rtl8169_transmit +; Description +; Transmits a packet of data via the ethernet card +; d - edi - Pointer to 48 bit destination address +; t - bx - Type of packet +; s - ecx - size of packet +; p - esi - pointer to packet data +; Destroyed registers +; eax, edx, esi, edi +; +;*************************************************************************** +proc rtl8169_transmit + +; DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi + + push ecx edx esi + mov eax,MAX_ETH_FRAME_SIZE + mul [rtl8169_tpc.cur_tx] + mov esi,edi + ; point to the current txb incase multiple tx_rings are used + mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4] + mov eax,edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi,node_addr + movsd + movsw +; copy packet type + mov [edi],bx + add edi,2 +; copy the packet data + pop esi edx ecx + push ecx + shr ecx,2 + rep movsd + pop ecx + push ecx + and ecx,3 + rep movsb + +;!!! s += ETH_HLEN; +;!!! s &= 0x0FFF; +;!!! while (s < ETH_ZLEN) +;!!! ptxb[s++] = '\0'; + mov edi,eax + pop ecx + push eax + add ecx,ETH_HLEN + and ecx,0x0FFF + xor al,al + add edi,ecx + @@: cmp ecx,ETH_ZLEN + jae @f + stosb + inc ecx + jmp @b + @@: pop eax + + mov ebx,eax + mov eax,sizeof.rtl8169_TxDesc + mul [rtl8169_tpc.cur_tx] + add eax,[rtl8169_tpc.TxDescArray] + xchg eax,ebx + mov [ebx + rtl8169_TxDesc.buf_addr],eax + sub [ebx + rtl8169_TxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 + + mov eax,ecx + cmp eax,ETH_ZLEN + jae @f + mov eax,ETH_ZLEN + @@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit + cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_TxDesc.status],eax + + RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit + + inc [rtl8169_tpc.cur_tx] + and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + +;!!! to = currticks() + TX_TIMEOUT; +;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ + mov ecx,TX_TIMEOUT / 10 + @@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit + jnz @f + stdcall udelay,10 + loop @b +; DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n" + @@: + + ret +endp + +;*************************************************************************** +; Function +; rtl8169_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed register(s) +; eax, edx, ecx +; +;*************************************************************************** +proc rtl8169_poll + +; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8 + + mov word[eth_rx_data_len],0 + + mov eax,sizeof.rtl8169_RxDesc + mul [rtl8169_tpc.cur_rx] + add eax,[rtl8169_tpc.RxDescArray] + mov ebx,eax + +; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status] + + test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600 + jnz .exit + +; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx] + + ; h/w no longer present (hotplug?) or major error, bail + RTL_R16 RTL8169_REG_IntrStatus + +; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax + + cmp ax,0xFFFF + je .exit + + push eax + and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK) + RTL_W16 RTL8169_REG_IntrStatus,ax + + mov eax,[ebx + rtl8169_RxDesc.status] + +; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax + + test eax,RTL8169_SD_RxRES + jnz .else + and eax,0x00001FFF +; jz .exit.pop + add eax,-4 + mov [eth_rx_data_len],ax + +; DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax + + push eax + mov ecx,eax + shr ecx,2 + mov eax,[rtl8169_tpc.cur_rx] + mov edx,[rtl8169_tpc.RxBufferRing + eax * 4] + mov esi,edx + mov edi,Ether_buffer + cld + rep movsd + pop ecx + and ecx,3 + rep movsb + + mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE + cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_RxDesc.status],eax + + mov [ebx + rtl8169_RxDesc.buf_addr],edx + sub [ebx + rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008 + jmp @f + .else: +; DEBUGF 1,"K : rtl8169_poll: Rx Error\n" + ; FIXME: shouldn't I reset the status on an error + @@: + inc [rtl8169_tpc.cur_rx] + and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + .exit.pop: + pop eax + and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK + RTL_W16 RTL8169_REG_IntrStatus,ax + .exit: + ret +endp + +proc rtl8169_cable + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/sis900.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/sis900.inc new file mode 100644 index 000000000..8f160e0c7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/drivers/sis900.inc @@ -0,0 +1,1158 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; SIS900.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.4 26 April 2004 ;; +;; ;; +;; This driver is based on the SIS900 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2004 Jason Delozier, ;; +;; cordata51@hotmail.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; Updates: ;; +;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************** +; Interface +; SIS900_reset +; SIS900_probe +; SIS900_poll +; SIS900_transmit +; +;******************************************************************** +;******************************************************************** +; Comments: +; Known to work with the following SIS900 ethernet cards: +; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 +; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 +; +; If your card is not listed, try it and let me know if it +; functions properly and it will be aded to the list. If not +; we may be able to add support for it. +; +; How To Use: +; Add the following lines to Ethernet.inc in their appropriate locations +; +; include "Sis900.INC" +; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, +; SIS900_transmit +; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, +; SIS900_transmit ;untested +; +; ToDo: +; - Enable MII interface for reading speed +; and duplex settings. +; +; - Update Poll routine to support packet fragmentation. +; +; - Add additional support for other sis900 based cards +; +;******************************************************************** + +; comment the next line out if you don't want debug info printed +; on the debug board. This option adds a lot of bytes to the driver +; so it's worth to comment it out. +; SIS900_DEBUG equ 1 + + +;* buffers and descriptors +cur_rx db 0 +NUM_RX_DESC equ 4 ;* Number of RX descriptors * +NUM_TX_DESC equ 1 ;* Number of TX descriptors * +RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * +TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * + +uglobal +align 4 +txd: times (3 * NUM_TX_DESC) dd 0 +rxd: times (3 * NUM_RX_DESC) dd 0 +endg + +txb equ eth_data_start +rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ) +SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * +SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * +SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * +SIS900_DSIZE equ 0x00000fff +SIS900_CRC_SIZE equ 4 +SIS900_RFADDR_shift equ 16 +;SIS900 Symbolic offsets to registers. + SIS900_cr equ 0x0 ; Command Register + SIS900_cfg equ 0x4 ; Configuration Register + SIS900_mear equ 0x8 ; EEPROM Access Register + SIS900_ptscr equ 0xc ; PCI Test Control Register + SIS900_isr equ 0x10 ; Interrupt Status Register + SIS900_imr equ 0x14 ; Interrupt Mask Register + SIS900_ier equ 0x18 ; Interrupt Enable Register + SIS900_epar equ 0x18 ; Enhanced PHY Access Register + SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register + SIS900_txcfg equ 0x24 ; Transmit Configuration Register + SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register + SIS900_rxcfg equ 0x34 ; Receive Configuration Register + SIS900_flctrl equ 0x38 ; Flow Control Register + SIS900_rxlen equ 0x3c ; Receive Packet Length Register + SIS900_rfcr equ 0x48 ; Receive Filter Control Register + SIS900_rfdr equ 0x4C ; Receive Filter Data Register + SIS900_pmctrl equ 0xB0 ; Power Management Control Register + SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register +;SIS900 Command Register Bits + SIS900_RELOAD equ 0x00000400 + SIS900_ACCESSMODE equ 0x00000200 + SIS900_RESET equ 0x00000100 + SIS900_SWI equ 0x00000080 + SIS900_RxRESET equ 0x00000020 + SIS900_TxRESET equ 0x00000010 + SIS900_RxDIS equ 0x00000008 + SIS900_RxENA equ 0x00000004 + SIS900_TxDIS equ 0x00000002 + SIS900_TxENA equ 0x00000001 +;SIS900 Configuration Register Bits + SIS900_DESCRFMT equ 0x00000100 ; 7016 specific + SIS900_REQALG equ 0x00000080 + SIS900_SB equ 0x00000040 + SIS900_POW equ 0x00000020 + SIS900_EXD equ 0x00000010 + SIS900_PESEL equ 0x00000008 + SIS900_LPM equ 0x00000004 + SIS900_BEM equ 0x00000001 + SIS900_RND_CNT equ 0x00000400 + SIS900_FAIR_BACKOFF equ 0x00000200 + SIS900_EDB_MASTER_EN equ 0x00002000 +;SIS900 Eeprom Access Reigster Bits + SIS900_MDC equ 0x00000040 + SIS900_MDDIR equ 0x00000020 + SIS900_MDIO equ 0x00000010 ; 7016 specific + SIS900_EECS equ 0x00000008 + SIS900_EECLK equ 0x00000004 + SIS900_EEDO equ 0x00000002 + SIS900_EEDI equ 0x00000001 +;SIS900 TX Configuration Register Bits + SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding + SIS900_MLB equ 0x20000000 ;Mac Loopback Enable + SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) + SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du +;SIS900 RX Configuration Register Bits + SIS900_AJAB equ 0x08000000 ; + SIS900_ATX equ 0x10000000 ;Accept Transmit Packets + SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) + SIS900_AEP equ 0x80000000 ;accept error packets +;SIS900 Interrupt Reigster Bits + SIS900_WKEVT equ 0x10000000 + SIS900_TxPAUSEEND equ 0x08000000 + SIS900_TxPAUSE equ 0x04000000 + SIS900_TxRCMP equ 0x02000000 + SIS900_RxRCMP equ 0x01000000 + SIS900_DPERR equ 0x00800000 + SIS900_SSERR equ 0x00400000 + SIS900_RMABT equ 0x00200000 + SIS900_RTABT equ 0x00100000 + SIS900_RxSOVR equ 0x00010000 + SIS900_HIBERR equ 0x00008000 + SIS900_SWINT equ 0x00001000 + SIS900_MIBINT equ 0x00000800 + SIS900_TxURN equ 0x00000400 + SIS900_TxIDLE equ 0x00000200 + SIS900_TxERR equ 0x00000100 + SIS900_TxDESC equ 0x00000080 + SIS900_TxOK equ 0x00000040 + SIS900_RxORN equ 0x00000020 + SIS900_RxIDLE equ 0x00000010 + SIS900_RxEARLY equ 0x00000008 + SIS900_RxERR equ 0x00000004 + SIS900_RxDESC equ 0x00000002 + SIS900_RxOK equ 0x00000001 +;SIS900 Interrupt Enable Reigster Bits + SIS900_IE equ 0x00000001 +;SIS900 Revision ID + SIS900B_900_REV equ 0x03 + SIS630A_900_REV equ 0x80 + SIS630E_900_REV equ 0x81 + SIS630S_900_REV equ 0x82 + SIS630EA1_900_REV equ 0x83 + SIS630ET_900_REV equ 0x84 + SIS635A_900_REV equ 0x90 + SIS900_960_REV equ 0x91 +;SIS900 Receive Filter Control Register Bits + SIS900_RFEN equ 0x80000000 + SIS900_RFAAB equ 0x40000000 + SIS900_RFAAM equ 0x20000000 + SIS900_RFAAP equ 0x10000000 + SIS900_RFPromiscuous equ 0x70000000 +;SIS900 Reveive Filter Data Mask + SIS900_RFDAT equ 0x0000FFFF +;SIS900 Eeprom Address + SIS900_EEPROMSignature equ 0x00 + SIS900_EEPROMVendorID equ 0x02 + SIS900_EEPROMDeviceID equ 0x03 + SIS900_EEPROMMACAddr equ 0x08 + SIS900_EEPROMChecksum equ 0x0b +;The EEPROM commands include the alway-set leading bit. +;SIS900 Eeprom Command + SIS900_EEread equ 0x0180 + SIS900_EEwrite equ 0x0140 + SIS900_EEerase equ 0x01C0 + SIS900_EEwriteEnable equ 0x0130 + SIS900_EEwriteDisable equ 0x0100 + SIS900_EEeraseAll equ 0x0120 + SIS900_EEwriteAll equ 0x0110 + SIS900_EEaddrMask equ 0x013F + SIS900_EEcmdShift equ 16 +;For SiS962 or SiS963, request the eeprom software access + SIS900_EEREQ equ 0x00000400 + SIS900_EEDONE equ 0x00000200 + SIS900_EEGNT equ 0x00000100 +;General Varibles + SIS900_pci_revision: db 0 + SIS900_Status dd 0x03000000 +sis900_specific_table: +; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 +; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 + dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN + dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS900_960_REV,SIS960_get_mac_addr,0 + dd SIS900B_900_REV,SIS900_get_mac_addr,0 + dd 0,0,0,0 ; end of list +sis900_get_mac_func: dd 0 +sis900_special_func: dd 0 +sis900_table_entries: db 8 + +;*************************************************************************** +; Function +; SIS900_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +;not done - still need to probe mii transcievers +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 +end if +SIS900_probe: +;******Wake Up Chip******* + mov al, 4 + mov bh, [pci_dev] + mov ecx, 0 + mov ah, [pci_bus] + mov bl, 0x40 + call pci_write_reg +;*******Set some PCI Settings********* + call SIS900_adjust_pci_device +;*****Get Card Revision****** + mov al, 1 ;one byte to read + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x08 ;Revision Register + call pci_read_reg + mov [SIS900_pci_revision], al ;save the revision for later use +;****** Look up through the sis900_specific_table + mov esi,sis900_specific_table +.probe_loop: + cmp dword [esi],0 ; Check if we reached end of the list + je .probe_loop_failed + cmp al,[esi] ; Check if revision is OK + je .probe_loop_ok + add esi,12 ; Advance to next entry + jmp .probe_loop +.probe_loop_failed: + jmp SIS900_Probe_Unsupported +;*********Find Get Mac Function********* +.probe_loop_ok: + mov eax,[esi+4] ; Get pointer to "get MAC" function + mov [sis900_get_mac_func],eax + mov eax,[esi+8] ; Get pointer to special initialization fn + mov [sis900_special_func],eax +;******** Get MAC ******** + call dword [sis900_get_mac_func] +;******** Call special initialization fn if requested ******** + cmp dword [sis900_special_func],0 + je .no_special_init + call dword [sis900_special_func] +.no_special_init: +;******** Set table entries ******** + mov al,[SIS900_pci_revision] + cmp al,SIS635A_900_REV + jae .ent16 + cmp al,SIS900B_900_REV + je .ent16 + jmp .ent8 +.ent16: + mov byte [sis900_table_entries],16 +.ent8: +;*******Probe for mii transceiver******* +;TODO!!********************* +;*******Initialize Device******* + call sis900_init + ret + +SIS900_Probe_Unsupported: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Str_Unsupported + call sys_msg_board_str +end if + ret +;*************************************************************************** +; Function: sis900_init +; +; Description: resets the ethernet controller chip and various +; data structures required for sending and receiving packets. +; +; Arguments: +; +; returns: none +;not done +;*************************************************************************** +sis900_init: + call SIS900_reset ;Done + call SIS900_init_rxfilter ;Done + call SIS900_init_txd ;Done + call SIS900_init_rxd ;Done + call SIS900_set_rx_mode ;done + call SIS900_set_tx_mode + ;call SIS900_check_mode + ret + +;*************************************************************************** +; Function +; SIS900_reset +; Description +; disables interrupts and soft resets the controller chip +; +;done+ +;*************************************************************************** +if defined SIS900_DEBUG + SIS900_Debug_Reset_Failed db 'Reset Failed ',0 +end if +SIS900_reset: + ;******Disable Interrupts and reset Receive Filter******* + mov ebp, [io_addr] ; base address + xor eax, eax ; 0 to initialize + lea edx,[ebp+SIS900_ier] + out dx, eax ; Write 0 to location + lea edx,[ebp+SIS900_imr] + out dx, eax ; Write 0 to location + lea edx,[ebp+SIS900_rfcr] + out dx, eax ; Write 0 to location + ;*******Reset Card*********************************************** + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_RESET ; set flags + or eax, SIS900_RxRESET ; + or eax, SIS900_TxRESET ; + out dx, eax ; Write new Command Register + ;*******Wait Loop************************************************ + lea edx,[ebp+SIS900_isr] + mov ecx, [SIS900_Status] ; Status we would like to see from card + mov ebx, 2001 ; only loop 1000 times +SIS900_Wait: + dec ebx ; 1 less loop + jz SIS900_DoneWait_e ; 1000 times yet? + in eax, dx ; move interrup status to eax + and eax, ecx + xor ecx, eax + jz SIS900_DoneWait + jmp SIS900_Wait +SIS900_DoneWait_e: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Reset_Failed + call sys_msg_board_str +end if +SIS900_DoneWait: + ;*******Set Configuration Register depending on Card Revision******** + lea edx,[ebp+SIS900_cfg] + mov eax, SIS900_PESEL ; Configuration Register Bit + mov bl, [SIS900_pci_revision] ; card revision + mov cl, SIS635A_900_REV ; Check card revision + cmp bl, cl + je SIS900_RevMatch + mov cl, SIS900B_900_REV ; Check card revision + cmp bl, cl + je SIS900_RevMatch + out dx, eax ; no revision match + jmp SIS900_Reset_Complete +SIS900_RevMatch: ; Revision match + or eax, SIS900_RND_CNT ; Configuration Register Bit + out dx, eax +SIS900_Reset_Complete: + mov eax, [pci_data] + mov [eth_status], eax + ret + +;*************************************************************************** +; Function: sis_init_rxfilter +; +; Description: sets receive filter address to our MAC address +; +; Arguments: +; +; returns: +;done+ +;*************************************************************************** +SIS900_init_rxfilter: + ;****Get Receive Filter Control Register ******** + mov ebp, [io_addr] ; base address + lea edx,[ebp+SIS900_rfcr] + in eax, dx ; get register + push eax + ;****disable packet filtering before setting filter******* + mov eax, SIS900_RFEN ;move receive filter enable flag + not eax ;1s complement + pop ebx ;and with our saved register + and eax, ebx ;disable receiver + push ebx ;save filter for another use + out dx, eax ;set receive disabled + ;********load MAC addr to filter data register********* + xor ecx, ecx +SIS900_RXINT_Mac_Write: + ;high word of eax tells card which mac byte to write + mov eax, ecx + lea edx,[ebp+SIS900_rfcr] + shl eax, 16 ; + out dx, eax ; + lea edx,[ebp+SIS900_rfdr] + mov ax, word [node_addr+ecx*2] ; Get Mac ID word + out dx, ax ; Send Mac ID + inc cl ; send next word + cmp cl, 3 ; more to send? + jne SIS900_RXINT_Mac_Write + ;********enable packet filitering ***** + pop eax ;old register value + lea edx,[ebp+SIS900_rfcr] + or eax, SIS900_RFEN ;enable filtering + out dx, eax ;set register + ret + +;*************************************************************************** +;* +;* Function: sis_init_txd +;* +;* Description: initializes the Tx descriptor +;* +;* Arguments: +;* +;* returns: +;*done +;*************************************************************************** +SIS900_init_txd: + ;********** initialize TX descriptor ************** + mov [txd], dword 0 ;put link to next descriptor in link field + mov [txd+4],dword 0 ;clear status field + mov [txd+8], dword txb - OS_BASE ;save address to buffer ptr field + ;*************** load Transmit Descriptor Register *************** + mov dx, [io_addr] ; base address + add dx, SIS900_txdp ; TX Descriptor Pointer + mov eax, txd - OS_BASE ; First Descriptor + out dx, eax ; move the pointer + ret + +;*************************************************************************** +;* Function: sis_init_rxd +;* +;* Description: initializes the Rx descriptor ring +;* +;* Arguments: +;* +;* Returns: +;*done +;*************************************************************************** +SIS900_init_rxd: + xor ecx,ecx + mov [cur_rx], cl ;Set cuurent rx discriptor to 0 + ;******** init RX descriptors ******** +SIS900_init_rxd_Loop: + mov eax, ecx ;current descriptor + imul eax, 12 ; + mov ebx, ecx ;determine next link descriptor + inc ebx ; + cmp ebx, NUM_RX_DESC ; + jne SIS900_init_rxd_Loop_0 ; + xor ebx, ebx ; +SIS900_init_rxd_Loop_0: ; + imul ebx, 12 ; + add ebx, rxd - OS_BASE ; + mov [rxd+eax], ebx ;save link to next descriptor + mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size + mov ebx, ecx ;find where the buf is located + imul ebx,RX_BUFF_SZ ; + add ebx, rxb - OS_BASE ; + mov [rxd+eax+8], ebx ;save buffer pointer + inc ecx ;next descriptor + cmp ecx, NUM_RX_DESC ; + jne SIS900_init_rxd_Loop ; + ;********* load Receive Descriptor Register with address of first + ; descriptor********* + mov dx, [io_addr] + add dx, SIS900_rxdp + mov eax, rxd - OS_BASE + out dx, eax + ret + +;*************************************************************************** +;* Function: sis900_set_tx_mode +;* +;* Description: +;* sets the transmit mode to allow for full duplex +;* +;* +;* Arguments: +;* +;* Returns: +;* +;* Comments: +;* If you are having problems transmitting packet try changing the +;* Max DMA Burst, Possible settings are as follows: +;* 0x00000000 = 512 bytes +;* 0x00100000 = 4 bytes +;* 0x00200000 = 8 bytes +;* 0x00300000 = 16 bytes +;* 0x00400000 = 32 bytes +;* 0x00500000 = 64 bytes +;* 0x00600000 = 128 bytes +;* 0x00700000 = 256 bytes +;*************************************************************************** +SIS900_set_tx_mode: + mov ebp,[io_addr] + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_TxENA ;Enable Receive + out dx, eax + lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset + mov eax, SIS900_ATP ;allow automatic padding + or eax, SIS900_HBI ;allow heartbeat ignore + or eax, SIS900_CSI ;allow carrier sense ignore + or eax, 0x00600000 ;Max DMA Burst + or eax, 0x00000100 ;TX Fill Threshold + or eax, 0x00000020 ;TX Drain Threshold + out dx, eax + ret + +;*************************************************************************** +;* Function: sis900_set_rx_mode +;* +;* Description: +;* sets the receive mode to accept all broadcast packets and packets +;* with our MAC address, and reject all multicast packets. Also allows +;* full-duplex +;* +;* Arguments: +;* +;* Returns: +;* +;* Comments: +;* If you are having problems receiving packet try changing the +;* Max DMA Burst, Possible settings are as follows: +;* 0x00000000 = 512 bytes +;* 0x00100000 = 4 bytes +;* 0x00200000 = 8 bytes +;* 0x00300000 = 16 bytes +;* 0x00400000 = 32 bytes +;* 0x00500000 = 64 bytes +;* 0x00600000 = 128 bytes +;* 0x00700000 = 256 bytes +;*************************************************************************** +SIS900_mc_filter: times 16 dw 0 +SIS900_set_rx_mode: + mov ebp,[io_addr] + ;**************update Multicast Hash Table in Receive Filter + mov ebx, 0xffff + xor cl, cl +SIS900_set_rx_mode_Loop: + mov eax, ecx + shl eax, 1 + mov [SIS900_mc_filter+eax], bx + lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset + mov eax, 4 ;determine table entry + add al, cl + shl eax, 16 + out dx, eax ;tell card which entry to modify + lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset + mov eax, ebx ;entry value + out dx, ax ;write value to table in card + inc cl ;next entry + cmp cl,[sis900_table_entries] ; + jl SIS900_set_rx_mode_Loop + ;*******Set Receive Filter Control Register************* + lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset + mov eax, SIS900_RFAAB ;accecpt all broadcast packets + or eax, SIS900_RFAAM ;accept all multicast packets + or eax, SIS900_RFAAP ;Accept all packets + or eax, SIS900_RFEN ;enable receiver filter + out dx, eax + ;******Enable Receiver************ + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_RxENA ;Enable Receive + out dx, eax + ;*********Set + lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset + mov eax, SIS900_ATX ;Accept Transmit Packets + ; (Req for full-duplex and PMD Loopback) + or eax, 0x00600000 ;Max DMA Burst + or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes + out dx, eax ; + ret + +;*************************************************************************** +; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model +; * @pci_dev: the sis900 pci device +; * @net_dev: the net device to get address for +; * +; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM +; * is shared by +; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first +; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access +; * by LAN, otherwise is not. After MAC address is read from EEPROM, send +; * EEDONE signal to refuse EEPROM access by LAN. +; * The EEPROM map of SiS962 or SiS963 is different to SiS900. +; * The signature field in SiS962 or SiS963 spec is meaningless. +; * MAC address is read into @net_dev->dev_addr. +; *done +;* +;* Return 0 is EAX = failure +;*Done+ +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 +SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 +SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 +SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 +end if +SIS960_get_mac_addr: + mov ebp,[io_addr] + ;**********Send Request for eeprom access********************* + lea edx,[ebp+SIS900_mear] ; Eeprom access register + mov eax, SIS900_EEREQ ; Request access to eeprom + out dx, eax ; Send request + xor ebx,ebx ; + ;******Loop 4000 times and if access not granted error out***** +SIS96X_Get_Mac_Wait: + in eax, dx ;get eeprom status + and eax, SIS900_EEGNT ;see if eeprom access granted flag is set + jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom + inc ebx ;else keep waiting + cmp ebx, 4000 ;have we tried 4000 times yet? + jl SIS96X_Get_Mac_Wait ;if not ask again + xor eax, eax ;return zero in eax indicating failure + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Failed + call sys_msg_board_str +end if + jmp SIS960_get_mac_addr_done + ;**********EEprom access granted, read MAC from card************* +SIS900_Got_EEP_Access: + ; zero based so 3-16 bit reads will take place + mov ecx, 2 +SIS96x_mac_read_loop: + mov eax, SIS900_EEPROMMACAddr ;Base Mac Address + add eax, ecx ;Current Mac Byte Offset + push ecx + call sis900_read_eeprom ;try to read 16 bits + pop ecx + mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible + dec ecx ;one less word to read + jns SIS96x_mac_read_loop ;if more read more + mov eax, 1 ;return non-zero indicating success + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address2 + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ;**********Tell EEPROM We are Done Accessing It********************* +SIS960_get_mac_addr_done: + lea edx,[ebp+SIS900_mear] ; Eeprom access register + mov eax, SIS900_EEDONE ;tell eeprom we are done + out dx,eax + ret +;*************************************************************************** +;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model +;* @pci_dev: the sis900 pci device +;* @net_dev: the net device to get address for +;* +;* Older SiS900 and friends, use EEPROM to store MAC address. +;* MAC address is read from read_eeprom() into @net_dev->dev_addr. +;* done/untested +;*************************************************************************** +SIS900_get_mac_addr: + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Start + call sys_msg_board_str +end if + ;******** check to see if we have sane EEPROM ******* + mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature + call sis900_read_eeprom ;try to read 16 bits + cmp ax, 0xffff + je SIS900_Bad_Eeprom + cmp ax, 0 + je SIS900_Bad_Eeprom + ;**************Read MacID************** + ; zero based so 3-16 bit reads will take place + mov ecx, 2 +SIS900_mac_read_loop: + mov eax, SIS900_EEPROMMACAddr ;Base Mac Address + add eax, ecx ;Current Mac Byte Offset + push ecx + call sis900_read_eeprom ;try to read 16 bits + pop ecx + mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage + dec ecx ;one less word to read + jns SIS900_mac_read_loop ;if more read more + mov eax, 1 ;return non-zero indicating success + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ret + +SIS900_Bad_Eeprom: + xor eax, eax + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Failed + call sys_msg_board_str +end if + ret +;*************************************************************************** +;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 +;* +;* +;*************************************************************************** +Get_Mac_SIS635_900_REV: +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Start + call sys_msg_board_str +end if + mov ebp,[io_addr] + lea edx,[ebp+SIS900_rfcr] + in eax,dx + mov edi,eax ; EDI=rfcrSave + lea edx,[ebp+SIS900_cr] + or eax,SIS900_RELOAD + out dx,eax + xor eax,eax + out dx,eax + ; Disable packet filtering before setting filter + lea edx,[ebp+SIS900_rfcr] + mov eax,edi + and edi,not SIS900_RFEN + out dx,eax + ; Load MAC to filter data register + xor ecx,ecx + mov esi,node_addr +.get_mac_loop: + lea edx,[ebp+SIS900_rfcr] + mov eax,ecx + shl eax,SIS900_RFADDR_shift + out dx,eax + lea edx,[ebp+SIS900_rfdr] + in eax,dx + mov [esi],ax + add esi,2 + inc ecx + cmp ecx,3 + jne .get_mac_loop + ; Enable packet filtering + ;lea edx,[ebp+SIS900_rfcr] + ;mov eax,edi + ;or eax,SIS900_RFEN + ;out dx, eax + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ret +;*************************************************************************** +;* Function: sis900_read_eeprom +;* +;* Description: reads and returns a given location from EEPROM +;* +;* Arguments: eax - location: requested EEPROM location +;* +;* Returns: eax : contents of requested EEPROM location +;* +; Read Serial EEPROM through EEPROM Access Register, Note that location is +; in word (16 bits) unit */ +;done+ +;*************************************************************************** +sis900_read_eeprom: + push esi + push edx + push ecx + push ebx + mov ebp,[io_addr] + mov ebx, eax ;location of Mac byte to read + or ebx, SIS900_EEread ; + lea edx,[ebp+SIS900_mear] ; Eeprom access register + xor eax, eax ; start send + out dx,eax + call SIS900_Eeprom_Delay_1 + mov eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + ;************ Shift the read command (9) bits out. ********* + mov cl, 8 ; +sis900_read_eeprom_Send: + mov eax, 1 + shl eax, cl + and eax, ebx + jz SIS900_Read_Eeprom_8 + mov eax, 9 + jmp SIS900_Read_Eeprom_9 +SIS900_Read_Eeprom_8: + mov eax, 8 +SIS900_Read_Eeprom_9: + out dx, eax + call SIS900_Eeprom_Delay_1 + or eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + cmp cl, 0 + je sis900_read_eeprom_Send_Done + dec cl + jmp sis900_read_eeprom_Send + ;********************* +sis900_read_eeprom_Send_Done: + mov eax, SIS900_EECS ; + out dx, eax + call SIS900_Eeprom_Delay_1 + ;********** Read 16-bits of data in *************** + mov cx, 16 ;16 bits to read +sis900_read_eeprom_Send2: + mov eax, SIS900_EECS + out dx, eax + call SIS900_Eeprom_Delay_1 + or eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + in eax, dx + shl ebx, 1 + and eax, SIS900_EEDO + jz SIS900_Read_Eeprom_0 + or ebx, 1 +SIS900_Read_Eeprom_0: + dec cx + jnz sis900_read_eeprom_Send2 + ;************** Terminate the EEPROM access. ************** + xor eax, eax + out dx, eax + call SIS900_Eeprom_Delay_1 + mov eax, SIS900_EECLK + out dx, eax + mov eax, ebx + and eax, 0x0000ffff ;return only 16 bits + pop ebx + pop ecx + pop edx + pop esi + ret +;*************************************************************************** +; Function +; SIS900_Eeprom_Delay_1 +; Description +; +; +; +; +;*************************************************************************** +SIS900_Eeprom_Delay_1: + push eax + in eax, dx + pop eax + ret + +;*************************************************************************** +; Function +; SIS900_poll +; Description +; polls card to see if there is a packet waiting +; +; Currently only supports one descriptor per packet, if packet is fragmented +; between multiple descriptors you will lose part of the packet +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 +SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 +SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 +end if +SIS900_poll: + ;**************Get Status ************** + xor eax, eax ;get RX_Status + mov [eth_rx_data_len], ax + mov al, [cur_rx] ;find current discriptor + imul eax, 12 ; + mov ecx, [rxd+eax+4] ; get receive status + ;**************Check Status ************** + mov ebx, ecx ;move status + ;Check RX_Status to see if packet is waiting + and ebx, 0x80000000 + jnz SIS900_poll_IS_packet + ret + ;**********There is a packet waiting check it for errors************** +SIS900_poll_IS_packet: + mov ebx, ecx ;move status + and ebx, 0x67C0000 ;see if there are any errors + jnz SIS900_Poll_Error_Status + ;**************Check size of packet************* + and ecx, SIS900_DSIZE ;get packet size minus CRC + cmp cx, SIS900_CRC_SIZE + ;make sure packet contains data + jle SIS900_Poll_Error_Size + ;*******Copy Good Packet to receive buffer****** + sub cx, SIS900_CRC_SIZE ;dont want crc + mov word [eth_rx_data_len], cx ;save size of packet + ;**********Continue copying packet**************** + push ecx + ; first copy dword-wise, divide size by 4 + shr ecx, 2 + mov esi, [rxd+eax+8] ; set source + add esi, OS_BASE ; get linear address + mov edi, Ether_buffer ; set destination + cld ; clear direction + rep movsd ; copy the dwords + pop ecx + and ecx, 3 ; + rep movsb + ;********Debug, tell user we have a good packet************* +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Packet_good + call sys_msg_board_str +end if + jmp SIS900_Poll_Cnt ; + ;*************Error occured let user know through debug window*********** +SIS900_Poll_Error_Status: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Bad_Packet_Status + call sys_msg_board_str +end if + jmp SIS900_Poll_Cnt +SIS900_Poll_Error_Size: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Bad_Packet_Size + call sys_msg_board_str +end if + ;*************Increment to next available descriptor************** +SIS900_Poll_Cnt: + ;Reset status, allow ethernet card access to descriptor + mov ecx, RX_BUFF_SZ + mov [rxd+eax+4], ecx ; + inc [cur_rx] ;get next descriptor + and [cur_rx],3 ;only 4 descriptors 0-3 + ;******Enable Receiver************ + mov ebp, [io_addr] ; Base Address + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_RxENA ;Enable Receive + out dx, eax + ret +;*************************************************************************** +; Function +; SIS900_transmit +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +; only one transmit descriptor is used +; +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 +SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 +end if +str1 db 'Transmitting packet:',13,10,0 +str2 db ' ',0 +SIS900_transmit: + mov ebp, [io_addr] ; Base Address + ;******** Stop the transmitter ******** + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_TxDIS ; Disable Transmitter + out dx, eax + ;*******load Transmit Descriptor Register ******* + lea edx,[ebp+SIS900_txdp] + mov eax, txd - OS_BASE + out dx, eax + ;******* copy packet to descriptor******* + push esi + mov esi, edi ;copy destination addess + mov edi, txb + cld + movsd + movsw + mov esi, node_addr ;copy my mac address + movsd + movsw + mov [edi], bx ;copy packet type + add edi, 2 + pop esi ;restore pointer to source of packet + push ecx ;save packet size + shr ecx, 2 ;divide by 4, size in bytes send in dwords + rep movsd ;copy data to decriptor + pop ecx ;restore packet size + push ecx ;save packet size + and ecx, 3 ;last three bytes if not a multiple of 4 + rep movsb + ;**************set length tag************** + pop ecx ;restore packet size + add ecx, SIS900_ETH_HLEN ;add header to length + and ecx, SIS900_DSIZE ; + ;**************pad to minimum packet size **************not needed + ;cmp ecx, SIS900_ETH_ZLEN + ;jge SIS900_transmit_Size_Ok + ;push ecx + ;mov ebx, SIS900_ETH_ZLEN + ;sub ebx, ecx + ;mov ecx, ebx + ;rep movsb + ;pop ecx +SIS900_transmit_Size_Ok: + mov [txd+4], dword 0x80000000 ;card owns descriptor + or [txd+4], ecx ;set size of packet +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Transmit_Packet + call sys_msg_board_str +end if + ;***************restart the transmitter ******** + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_TxENA ; Enable Transmitter + out dx, eax + ;****make sure packet transmitted successfully**** +; mov esi,10 +; call delay_ms + mov eax, [txd+4] + and eax, 0x6200000 + jz SIS900_transmit_OK + ;**************Tell user there was an error through debug window +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Transmit_Packet_Err + call sys_msg_board_str +end if +SIS900_transmit_OK: + ;******** Disable interrupts by clearing the interrupt mask. ******** + lea edx,[ebp+SIS900_imr] ; Interupt Mask Register + xor eax, eax + out dx,eax + ret + +;*************************************************************************** +;* Function: Create_Mac_String +;* +;* Description: Converts the 48 bit value to a string for display +;* +;* String Format: XX:XX:XX:XX:XX:XX +;* +;* Arguments: node_addr is location of 48 bit MAC ID +;* +;* Returns: Prints string to general debug window +;* +;* +;done +;*************************************************************************** +if defined SIS900_DEBUG + +SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' + db 'A','B','C','D','E','F' +Mac_str_build: times 20 db 0 +Create_Mac_String: + pusha + xor ecx, ecx +Create_Mac_String_loop: + mov al,byte [edx+ecx];[node_addr+ecx] + push eax + shr eax, 4 + and eax, 0x0f + mov bl, byte [SIS900_Char_String+eax] + mov [Mac_str_build+ecx*3], bl + pop eax + and eax, 0x0f + mov bl, byte [SIS900_Char_String+eax] + mov [Mac_str_build+1+ecx*3], bl + cmp ecx, 5 + je Create_Mac_String_done + mov bl, ':' + mov [Mac_str_build+2+ecx*3], bl + inc ecx + jmp Create_Mac_String_loop +Create_Mac_String_done: ;Insert CR and Zero Terminate + mov [Mac_str_build+2+ecx*3],byte 13 + mov [Mac_str_build+3+ecx*3],byte 10 + mov [Mac_str_build+4+ecx*3],byte 0 + mov esi, Mac_str_build + call sys_msg_board_str ;Print String to message board + popa + ret +end if +;*************************************************************************** +;* Set device to be a busmaster in case BIOS neglected to do so. +;* Also adjust PCI latency timer to a reasonable value, 64. +;*************************************************************************** +SIS900_adjust_pci_device: + ;*******Get current setting************************ + mov al, 2 ;read a word + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x04 ;from command Register + call pci_read_reg + ;******see if its already set as bus master******** + mov bx, ax + and bx,5 + cmp bx,5 + je SIS900_adjust_pci_device_Latency + ;******Make card a bus master******* + mov cx, ax ;value to write + mov bh, [pci_dev] + mov al, 2 ;write a word + or cx,5 + mov ah, [pci_bus] + mov bl, 0x04 ;to command register + call pci_write_reg + ;******Check latency setting*********** +SIS900_adjust_pci_device_Latency: + ;*******Get current latency setting************************ + mov al, 1 ;read a byte + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x0D ;from Lantency Timer Register + call pci_read_reg + ;******see if its aat least 64 clocks******** + cmp ax,64 + jge SIS900_adjust_pci_device_Done + ;******Set latency to 32 clocks******* + mov cx, 64 ;value to write + mov bh, [pci_dev] + mov al, 1 ;write a byte + mov ah, [pci_bus] + mov bl, 0x0D ;to Lantency Timer Register + call pci_write_reg + ;******Check latency setting*********** +SIS900_adjust_pci_device_Done: + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/ethernet.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/ethernet.inc new file mode 100644 index 000000000..d113aaecb --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/ethernet.inc @@ -0,0 +1,509 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ETHERNET.INC ;; +;; ;; +;; Ethernet network layer for Menuet OS ;; +;; ;; +;; This file contains the following: ;; +;; PCI bus scanning for valid devices ;; +;; Table of supported ethernet drivers ;; +;; Code to identify and activate a supported driver ;; +;; ARP handler ;; +;; Driver interface to the IP layer ;; +;; Gateway support ;; +;; ;; +;; Individual driver files are included here ;; +;; ;; +;; The PCI bus scanning code was ported from the etherboot ;; +;; 5.0.6 project. The copyright statement for that code is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************** +; Interface +; ethernet_driver called by stack_handler in stack.inc +; eth_probe called by app_stack_handler in stack.inc +; +;******************************************************************** + +ETHER_IP equ 0x0008 ; Reversed from 0800 for intel +ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel +ETHER_RARP equ 0x3580 + +struc ETH_FRAME +{ .DstMAC dp ? ;destination MAC-address [6 bytes] + .SrcMAC dp ? ;source MAC-address [6 bytes] + .Type dw ? ;type of the upper-layer protocol [2 bytes] + .Data db ? ;data [46-1500 bytes] +} + +virtual at Ether_buffer + ETH_FRAME ETH_FRAME +end virtual + + +; Some useful information on data structures + +; Ethernet Packet - ARP Request example +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Dest H/W Address | +; | ( 14 byte header ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Source H/W Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Protocol - ARP 08 06 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | H/W Type 00 01 | Protocol Type 08 00 | +; | ( ARP Request packet ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | HLen 0x06 | PLen 0x04 | OpCode 00 01 | +; | ( 0001 for request, 0002 for reply ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Source Hardware Address ( MAC Address ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Source IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Destination Hardware Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Destination IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +; Include individual drivers source files at this point. +; If you create a new driver, include it below. + +include "drivers/rtl8029.inc" +include "drivers/i8255x.inc" +include "drivers/rtl8139.inc" +include "drivers/3c59x.inc" +include "drivers/sis900.inc" +include "drivers/pcnet32.inc" +include "drivers/rtl8169.inc" +include "drivers/forcedeth.inc" + +; PCICards +; ======== +; PCI vendor and hardware types for hardware supported by the above drivers +; If you add a driver, ensure you update this datastructure, otherwise the +; card will not be probed. +; Each driver is defined by 4 double words. These are +; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction +; The last entry must be kept at all zeros, to indicate the end of the list +; As a PCI driver may support more than one hardware implementation, there may +; be several lines which refer to the same functions. +; The first driver found on the PCI bus will be the one used. + +PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry + +iglobal +PCICards: +dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 + +dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 + +dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok +dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok +dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable + +dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x816710ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 + +dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 + +dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 + +dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 +dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 +dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 + +;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable + +; following cards are untested +dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 +;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable +;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable + +dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller +dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller +dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested + +rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove +endg + +uglobal +;Net-stack's interface's settings + node_addr: db 0,0,0,0,0,0 + gateway_ip: dd 0 + dns_ip: dd 0 + + eth_rx_data_len: dw 0 + eth_status: dd 0 + io_addr: dd 0 + hdrtype: db 0 + vendor_device: dd 0 + pci_data: dd 0 + pci_dev: dd 0 + pci_bus: dd 0 + + ; These will hold pointers to the selected driver functions + drvr_probe: dd 0 + drvr_reset: dd 0 + drvr_poll: dd 0 + drvr_transmit: dd 0 + drvr_cable: dd 0 + +endg + +iglobal + broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff + subnet_mask: dd 0x00ffffff ; 255.255.255.0 +endg + +include "arp.inc" ;arp-protocol functions +include "pci.inc" ;PCI bus access functions + + +;*************************************************************************** +; Function +; eth_tx +; +; Description +; Looks at the NET1OUT_QUEUE for data to send. +; Stores that destination IP in a location used by the tx routine +; Looks up the MAC address in the ARP table; stores that where +; the tx routine can get it +; Get the length of the data. Store that where the tx routine wants it +; Call tx +; Places buffer on empty queue when the tx routine finished +; +;*************************************************************************** +proc eth_tx stdcall uses ebx esi edi +local MACAddress dp ? ;allocate 6 bytes in the stack + + ; Look for a buffer to tx + mov eax, NET1OUT_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit ; Exit if no buffer available + + push eax ;save buffer number + + ; convert buffer pointer eax to the absolute address + imul eax, IPBUFFSIZE + add eax, IPbuffs + + ; Extract the destination IP + ; find the destination IP in the ARP table, get MAC + ; store this MAC in 'MACAddress' + mov ebx, eax ; Save buffer address + mov edx, [ebx + 16] ; get destination address + + ; If the destination address is 255.255.255.255, + ; set the MACAddress to all ones ( broadcast ) + cld + mov esi, broadcast_add + lea edi, [MACAddress] + movsd + movsw + cmp edx, 0xffffffff + je .send ; If it is broadcast, just send + + lea eax, [MACAddress] ;cause this is local variable + stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address. + + cmp eax, ARP_VALID_MAPPING + je .send + + ; No valid entry. Has the request been sent, but timed out? + cmp eax, ARP_RESPONSE_TIMEOUT + je .freebuf + + .wait_response: ;we wait arp-response + ; Re-queue the packet, and exit + pop ebx + mov eax, NET1OUT_QUEUE + call queue ; Get the buffer back + jmp .exit + + .send: ;if ARP_VALID_MAPPING then send the packet + lea edi, [MACAddress] ; Pointer to 48 bit destination address + movzx ecx, word[ebx+2] ; Size of IP packet to send + xchg ch, cl ; because mirror byte-order + mov esi, ebx ; Pointer to packet data + mov bx, ETHER_IP ; Type of packet + push ebp + call dword [drvr_transmit] ; Call the drivers transmit function + pop ebp + + ; OK, we have sent a packet, so increment the count + inc dword [ip_tx_count] + + ; And finally, return the buffer to the free queue + .freebuf: + pop eax + call freeBuff + + .exit: + ret +endp + +;*************************************************************************** +; Function +; ether_IP_handler +; +; Description +; Called when an IP ethernet packet is received on the ethernet +; Header + Data is in Ether_buffer[] +; We just need to get a buffer from the 'free' queue, and +; store the packet in it, then insert the packet number into the +; IPRX queue. +; If no queue entry is available, the packet is silently discarded +; All registers may be destroyed +; +;*************************************************************************** +;uglobal +; ether_IP_handler_cnt dd ? +;endg +ether_IP_handler: + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je eiph00x + + ; convert buffer pointer eax to the absolute address + push eax + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edi, eax + + ; get a pointer to the start of the DATA + mov esi, ETH_FRAME.Data + + ; Now store it all away + mov ecx, IPBUFFSIZE / 4 ; Copy all of the available + ; data across - worse case + cld + rep movsd + +; inc [ether_IP_handler_cnt] +; DEBUGF 1, "K : ether_IP_handler (%u)\n", [ether_IP_handler_cnt] + + ; And finally, place the buffer in the IPRX queue + pop ebx + mov eax, IPIN_QUEUE + call queue + +eiph00x: + ret + +;*************************************************************************** +; Function +; eth_probe +; Description +; Searches for an ethernet card. If found, the card is enabled and +; the ethernet -> IP link established +; +; This function scans the PCI bus looking for a supported device. +; ISA bus is currently not supported. +; +; eax is 0 if no hardware found +;*************************************************************************** +eth_probe: + ; Find a card on the PCI bus, and get it's address + call scan_bus ; Find the ethernet cards PIC address + xor eax, eax + cmp [io_addr], eax + je ep_00x ; Return 0 in eax if no cards found + + call dword [drvr_probe] ; Call the drivers probe function + + mov eax, [io_addr] ; return a non zero value + +ep_00x: + ret + +;*************************************************************************** +; Function +; ethernet_driver +; +; Description +; The ethernet RX and TX handler +; This is a kernel function, called by stack_handler +; +;*************************************************************************** +ethernet_driver: + ; Do nothing if the driver is inactive + cmp [ethernet_active], byte 0 + je eth_exit + + call eth_rx + call eth_tx + +eth_exit: + ret + +;*************************************************************************** +; Function +; eth_rx +; +; Description +; Polls the ethernet card for received data. Extracts if present +; Depending on the Protocol within the packet: +; ARP : Pass to ARP_handler. This may result in an ARP reply +; being tx'ed +; IP : Store in an IP buffer +; +;*************************************************************************** +eth_rx: + xor ax, ax + mov [eth_rx_data_len], ax + call dword [drvr_poll] ; Call the drivers poll function + + mov ax, [eth_rx_data_len] + cmp ax, 0 + je .exit + + + ; Check the protocol. Call appropriate handler + + mov ax, [ETH_FRAME.Type] ; The address of the protocol word + + cmp ax, ETHER_IP + je .is_ip ; It's IP + + cmp ax, ETHER_ARP + je .is_arp ; It is ARP + + DEBUGF 1,"K : eth_rx - dumped (%u)\n", ax + inc [dumped_rx_count] + jmp .exit ; If not IP or ARP, ignore + + .is_ip: +; DEBUGF 1,"K : eth_rx - IP packet\n" + inc dword [ip_rx_count] + call ether_IP_handler + jmp .exit + + .is_arp: +; DEBUGF 1,"K : eth_rx - ARP packet\n" + ; At this point, the packet is still in the Ether_buffer + call arp_handler + + .exit: + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/eth_drv/pci.inc b/kernel/tags/kolibri0.7.7.0/network/eth_drv/pci.inc new file mode 100644 index 000000000..5935480c9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/eth_drv/pci.inc @@ -0,0 +1,351 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;*************************************************************************** +; +; PCI CODE FOLLOWS +; +; the following functions provide access to the PCI interface. +; These functions are used by scan_bus, and also some ethernet drivers +; +;*************************************************************************** + +; PCI Bus defines +PCI_HEADER_TYPE equ 0x0e ;8 bit +PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit +PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_VENDOR_ID equ 0x00 ;16 bit +PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC + +;*************************************************************************** +; Function +; config_cmd +; +; Description +; creates a command dword for use with the PCI bus +; bus # in ebx +; devfn in ecx +; where in edx +; +; command dword returned in eax +; Only eax destroyed +;*************************************************************************** +config_cmd: + push ecx + mov eax, ebx + shl eax, 16 + or eax, 0x80000000 + shl ecx, 8 + or eax, ecx + pop ecx + or eax, edx + and eax, 0xFFFFFFFC + ret + +;*************************************************************************** +; Function +; pcibios_read_config_byte +; +; Description +; reads a byte from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; byte returned in al ( rest of eax zero ) +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_byte: + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + + xor eax, eax + and dx, 0x03 + add dx, 0xCFC +; and dx, 0xFFC + in al, dx + ret + +;*************************************************************************** +; Function +; pcibios_read_config_word +; +; Description +; reads a word from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; word returned in ax ( rest of eax zero ) +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_word: + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + + xor eax, eax + and dx, 0x02 + add dx, 0xCFC +; and dx, 0xFFC + in ax, dx + ret + +;*************************************************************************** +; Function +; pcibios_read_config_dword +; +; Description +; reads a dword from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; dword returned in eax +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_dword: + push edx + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + xor eax, eax + mov dx, 0xCFC + in eax, dx + pop edx + ret + +;*************************************************************************** +; Function +; pcibios_write_config_byte +; +; Description +; write a byte in al to the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; Only eax/edx destroyed +;*************************************************************************** +pcibios_write_config_byte: + push ax + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + pop ax + + and dx, 0x03 + add dx, 0xCFC + out dx, al + ret + +;*************************************************************************** +; Function +; pcibios_write_config_word +; +; Description +; write a word in ax to the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; Only eax/edx destroyed +;*************************************************************************** +pcibios_write_config_word: + push ax + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + pop ax + + and dx, 0x02 + add dx, 0xCFC + out dx, ax + ret + +;*************************************************************************** +; Function +; delay_us +; +; Description +; delays for 30 to 60 us +; +; I would prefer this routine to be able to delay for +; a selectable number of microseconds, but this works for now. +; +; If you know a better way to do 2us delay, pleae tell me! +;*************************************************************************** +delay_us: + push eax + push ecx + + mov ecx,2 + + in al,0x61 + and al,0x10 + mov ah,al + cld + +dcnt1: + in al,0x61 + and al,0x10 + cmp al,ah + jz dcnt1 + + mov ah,al + loop dcnt1 + + pop ecx + pop eax + + ret + +;*************************************************************************** +; Function +; scan_bus +; +; Description +; Scans the PCI bus for a supported device +; If a supported device is found, the drvr_ variables are initialised +; to that drivers functions ( as defined in the PCICards table) +; +; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid +; pci_data holds the PCI vendor + device code +; pci_dev holds PCI bus dev # +; pci_bus holds PCI bus # +; +; io_addr will be zero if no card found +; +;*************************************************************************** +scan_bus: + xor eax, eax + mov [hdrtype], al + mov [pci_data], eax + + xor ebx, ebx ; ebx = bus# 0 .. 255 + +sb_bus_loop: + xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) + +sb_devf_loop: + mov eax, ecx + and eax, 0x07 + + cmp eax, 0 + jne sb_001 + + mov edx, PCI_HEADER_TYPE + call pcibios_read_config_byte + mov [hdrtype], al + jmp sb_002 + +sb_001: + mov al, [hdrtype] + and al, 0x80 + cmp al, 0x80 + jne sb_inc_devf + +sb_002: + mov edx, PCI_VENDOR_ID + call pcibios_read_config_dword + mov [vendor_device], eax + cmp eax, 0xffffffff + je sb_empty + cmp eax, 0 + jne sb_check_vendor + +sb_empty: + mov [hdrtype], byte 0 + jmp sb_inc_devf + +sb_check_vendor: + ; iterate though PCICards until end or match found + mov esi, PCICards + +sb_check: + cmp [esi], dword 0 + je sb_inc_devf ; Quit if at last entry + cmp eax, [esi] + je sb_got_card + add esi, PCICARDS_ENTRY_SIZE + jmp sb_check + +sb_got_card: + ; indicate that we have found the card + mov [pci_data], eax + mov [pci_dev], ecx + mov [pci_bus], ebx + + ; Define the driver functions + push eax + mov eax, [esi+4] + mov [drvr_probe], eax + mov eax, [esi+8] + mov [drvr_reset], eax + mov eax, [esi+12] + mov [drvr_poll], eax + mov eax, [esi+16] + mov [drvr_transmit], eax + mov eax, [esi+20] + mov [drvr_cable], eax + pop eax + + mov edx, PCI_BASE_ADDRESS_0 + +sb_reg_check: + call pcibios_read_config_dword + mov [io_addr], eax + and eax, PCI_BASE_ADDRESS_IO_MASK + cmp eax, 0 + je sb_inc_reg + mov eax, [io_addr] + and eax, PCI_BASE_ADDRESS_SPACE_IO + cmp eax, 0 + je sb_inc_reg + + mov eax, [io_addr] + and eax, PCI_BASE_ADDRESS_IO_MASK + mov [io_addr], eax + +sb_exit1: + ret + +sb_inc_reg: + add edx, 4 + cmp edx, PCI_BASE_ADDRESS_5 + jbe sb_reg_check + +sb_inc_devf: + inc ecx + cmp ecx, 255 + jb sb_devf_loop + inc ebx + cmp ebx, 256 + jb sb_bus_loop + + ; We get here if we didn't find our card + ; set io_addr to 0 as an indication + xor eax, eax + mov [io_addr], eax + +sb_exit2: + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/network/icmp.inc b/kernel/tags/kolibri0.7.7.0/network/icmp.inc new file mode 100644 index 000000000..5c0fc9f2f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/icmp.inc @@ -0,0 +1,193 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ICMP.INC ;; +;; ;; +;; Internet Control Message Protocol ( RFC 792 ) ;; +;; ;; +;; Last revision: 11.11.2006 ;; +;; ;; +;; This file contains the following: ;; +;; icmp_rx - processes ICMP-packets received by the IP layer ;; +;; ;; +;; Changes history: ;; +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; +;; 11.11.2006 - [Johnny_B] and [smb] ;; +;; ;; +;; Current status: ;; +;; This implemetation of ICMP proto supports message of ECHO type. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +struc ICMP_PACKET +{ .Type db ? ;+00 + .Code db ? ;+01 + .Checksum dw ? ;+02 + .Identifier dw ? ;+04 + .SequenceNumber dw ? ;+06 + .Data db ? ;+08 +} + +virtual at 0 + ICMP_PACKET ICMP_PACKET +end virtual + + +; Example: +; ECHO message format +; +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Type | Code | Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Identifier | Sequence Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Data ... +; +-+-+-+-+- +; + +; +; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources +; + +ICMP_ECHOREPLY equ 0 ; echo reply message + +ICMP_UNREACH equ 3 + ICMP_UNREACH_NET equ 0 ; bad net + ICMP_UNREACH_HOST equ 1 ; bad host + ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol + ICMP_UNREACH_PORT equ 3 ; bad port + ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop + ICMP_UNREACH_SRCFAIL equ 5 ; src route failed + ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net + ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host + ICMP_UNREACH_ISOLATED equ 8 ; src host isolated + ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access + ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto + ICMP_UNREACH_TOSNET equ 11 ; bad tos for net + ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host + ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib + ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. + ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff + +ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down + +ICMP_REDIRECT equ 5 ; shorter route, codes: + ICMP_REDIRECT_NET equ 0 ; for network + ICMP_REDIRECT_HOST equ 1 ; for host + ICMP_REDIRECT_TOSNET equ 2 ; for tos and net + ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host + +ICMP_ALTHOSTADDR equ 6 ; alternate host address +ICMP_ECHO equ 8 ; echo service +ICMP_ROUTERADVERT equ 9 ; router advertisement + ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement + ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing + +ICMP_ROUTERSOLICIT equ 10 ; router solicitation +ICMP_TIMXCEED equ 11 ; time exceeded, code: + ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit + ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass + +ICMP_PARAMPROB equ 12 ; ip header bad + ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr + ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent + ICMP_PARAMPROB_LENGTH equ 2 ; bad length + +ICMP_TSTAMP equ 13 ; timestamp request +ICMP_TSTAMPREPLY equ 14 ; timestamp reply +ICMP_IREQ equ 15 ; information request +ICMP_IREQREPLY equ 16 ; information reply +ICMP_MASKREQ equ 17 ; address mask request +ICMP_MASKREPLY equ 18 ; address mask reply +ICMP_TRACEROUTE equ 30 ; traceroute +ICMP_DATACONVERR equ 31 ; data conversion error +ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect +ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you + ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here +ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req +ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply +ICMP_SKIP equ 39 ; SKIP + +ICMP_PHOTURIS equ 40 ; Photuris + ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index + ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed + ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed + + +;*************************************************************************** +; Function +; icmp_rx [by Johnny_B] +; +; Description +; ICMP protocol handler +; This is a kernel function, called by ip_rx +; +; IN: +; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards +; IPPacketBase - IP_PACKET base address +; IPHeaderLength - Header length of IP_PACKET +; +; OUT: +; EAX=not defined +; +; All used registers will be saved +; +;*************************************************************************** +proc icmp_rx stdcall uses ebx esi edi,\ + buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD + + mov esi,[IPPacketBase] ;esi=IP_PACKET base address + mov edi, esi + add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address + + cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not + jz .icmp_echo + + mov eax, [buffer_number] + call freeBuff + jmp .exit + + .icmp_echo: + + ; swap the source and destination addresses + mov ecx, [esi + IP_PACKET.DestinationAddress] + mov ebx, [esi + IP_PACKET.SourceAddress] + mov [esi + IP_PACKET.DestinationAddress], ebx + mov [esi + IP_PACKET.SourceAddress], ecx + + ; recalculate the IP header checksum + mov eax,[IPHeaderLength] + stdcall checksum_jb,esi,eax ;buf_ptr,buf_size + + mov byte[esi + IP_PACKET.HeaderChecksum], ah + mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order? + + mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response + mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc + + ; Calculate the length of the ICMP data ( IP payload) + xor eax, eax + mov ah, byte[esi + IP_PACKET.TotalLength] + mov al, byte[esi + IP_PACKET.TotalLength + 1] + sub ax, word[IPHeaderLength] ;ax=ICMP-packet length + + stdcall checksum_jb,edi,eax ;buf_ptr,buf_size + + mov byte[edi + ICMP_PACKET.Checksum], ah + mov byte[edi + ICMP_PACKET.Checksum + 1], al + + ; Queue packet for transmission + mov ebx, [buffer_number] + mov eax, NET1OUT_QUEUE + call queue + + .exit: + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/network/ip.inc b/kernel/tags/kolibri0.7.7.0/network/ip.inc new file mode 100644 index 000000000..2fda5fd3e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/ip.inc @@ -0,0 +1,244 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; IP.INC ;; +;; ;; +;; IP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Version 0.3 29 August 2002 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; IP underlying protocols numbers +PROTOCOL_ICMP equ 1 +PROTOCOL_TCP equ 6 +PROTOCOL_UDP equ 17 + +struc IP_PACKET +{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits] + .TypeOfService db ? ;+01 + .TotalLength dw ? ;+02 + .Identification dw ? ;+04 + .FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15] + .TimeToLive db ? ;+08 + .Protocol db ? ;+09 + .HeaderChecksum dw ? ;+10 + .SourceAddress dd ? ;+12 + .DestinationAddress dd ? ;+16 + .DataOrOptional dd ? ;+20 +} + +virtual at 0 + IP_PACKET IP_PACKET +end virtual + + +;******************************************************************* +; Interface +; +; ip_rx processes all packets received by the network layer +; It calls the appropriate protocol handler +; +; +; +;******************************************************************* + + +; +; IP Packet after reception - Normal IP packet format +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;0 |Version| IHL |Type of Service| Total Length | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;4 | Identification |Flags| Fragment Offset | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;8 | Time to Live | Protocol | Header Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;12 | Source Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;16 | Destination Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;20 | Data | +; +-+-+-.......... -+ +; +; +; [smb] attention! according to RFC 791 IP packet may have 'options' sections, +; so we can't simply think, that data have offset 20. We must calculate offset from +; IHL field +; +macro GET_IHL reg, header_addr +{ + movzx reg, byte [header_addr] + + ; we need 4-7 bits, so.... + and reg, 0x0000000F + + ; IHL keeps number of octets, so we need to << 2 'reg' + shl reg, 2 +} + + +include "tcp.inc" +include "udp.inc" +include "icmp.inc" + +;*************************************************************************** +; Function +; ip_rx +; +; Description +; This is a kernel function, called by stack_handler +; Processes all IP-packets received by the network layer +; It calls the appropriate protocol handler +; +;*************************************************************************** +proc ip_rx stdcall +local buffer_number dd ? + + ; Look for a buffer to tx + mov eax, IPIN_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit ; Exit if no buffer available + + mov [buffer_number], eax ;save buffer number + + ; convert buffer pointer eax to the absolute address + imul eax, IPBUFFSIZE + add eax, IPbuffs + + mov ebx, eax ; ebx=pointer to IP_PACKET + +; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1 + + ; Validate the IP checksum + mov dx, word[ebx + IP_PACKET.HeaderChecksum] + xchg dh,dl ; Get the checksum in intel format + + mov [ebx + IP_PACKET.HeaderChecksum], 0 ; clear checksum field - need to when + ; recalculating checksum + ; this needs two data pointers and two size #. + ; 2nd pointer can be of length 0 + + GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx + stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size + cmp dx, ax + +; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax + + jnz .dump.1 ;if CHECKSUM isn't valid then dump packet + mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!! + +; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip] + + ; Validate the IP address, if it isn't broadcast + mov eax, [stack_ip] + cmp dword[ebx + IP_PACKET.DestinationAddress], eax + je @f + + ; If the IP address is 255.255.255.255, accept it + ; - it is a broadcast packet, which we need for dhcp + + mov eax, [ebx + IP_PACKET.DestinationAddress] + cmp eax, 0xffffffff + je @f + mov ecx, [stack_ip] + and eax, [subnet_mask] + and ecx, [subnet_mask] + cmp eax, ecx + jne .dump.2 + mov eax, [ebx + IP_PACKET.DestinationAddress] + or eax, [subnet_mask] + cmp eax, 0xffffffff + jne .dump.2 + + @@: + mov al, [ebx + IP_PACKET.VersionAndIHL] + and al, 0x0f ;get IHL(header length) + cmp al, 0x05 ;if IHL!= 5*4(20 bytes) +; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al + jnz .dump.3 ;then dump it + +; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2 + + cmp [ebx + IP_PACKET.TimeToLive], 0 + je .dump.4 ;if TTL==0 then dump it + + mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset] + and ax, 0xFFBF ;get flags +; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax + cmp ax, 0 ;if some flags was set then we dump this packet + jnz .dump.5 ;the flags should be used for fragmented packets + + ; Check the protocol, and call the appropriate handler + ; Each handler will re-use or free the queue buffer as appropriate + + mov al, [ebx + IP_PACKET.Protocol] + + cmp al , PROTOCOL_TCP + jne .not_tcp +; DEBUGF 1,"K : ip_rx - TCP packet\n" + mov eax, dword[buffer_number] + call tcp_rx + jmp .exit + + .not_tcp: + cmp al, PROTOCOL_UDP + jne .not_udp +; DEBUGF 1,"K : ip_rx - UDP packet\n" + mov eax, dword[buffer_number] + call udp_rx + jmp .exit + + .not_udp: + cmp al, PROTOCOL_ICMP + jne .dump.6 ;protocol ain't supported + +; DEBUGF 1,"K : ip_rx - ICMP packet\n" + ;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx + mov eax, dword[buffer_number] + stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength + jmp .exit + + + .dump.1: + DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax + jmp .dump.x + + .dump.2: + DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1 + jmp .dump.x + + .dump.3: + DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al + jmp .dump.x + + .dump.4: + DEBUGF 1, "K : ip_rx - dumped (ttl: %u)\n", [ebx + IP_PACKET.TimeToLive] + jmp .dump.x + + .dump.5: + DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax + jmp .dump.x + + .dump.6: + DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1 + + .dump.x: + inc dword[dumped_rx_count] + mov eax, [buffer_number] + call freeBuff + + .exit: + ret +endp + diff --git a/kernel/tags/kolibri0.7.7.0/network/queue.inc b/kernel/tags/kolibri0.7.7.0/network/queue.inc new file mode 100644 index 000000000..fb5d27ce9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/queue.inc @@ -0,0 +1,229 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; QUEUE.INC ;; +;; ;; +;; Buffer queue management for Menuet OS TCP/IP Stack ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************* +; Interface +; +; queueInit Configures the queues to empty +; dequeue Removes a buffer pointer from a queue +; queue Inserts a buffer pointer into a queue +; freeBuff Adds the buffer pointer to the list of free buffers +; queueSize Returns the number of entries in a queue +; +; The various defines for queue names can be found in stack.inc +; +;******************************************************************* + + +;*************************************************************************** +; Function +; freeBuff +; +; Description +; Adds a buffer number to the beginning of the free list. +; buffer number in eax ( ms word zeroed ) +; all other registers preserved +; This always works, so no error returned +;*************************************************************************** +;uglobal +; freeBuff_cnt dd ? +;endg +freeBuff: +; inc [freeBuff_cnt] +; DEBUGF 1, "K : freeBuff (%u)\n", [freeBuff_cnt] + push ebx + push ecx + mov ebx, queues + EMPTY_QUEUE * 2 + cli ; Ensure that another process does not interfer + mov cx, [ebx] + mov [ebx], ax + mov [queueList + eax * 2], cx + sti + pop ecx + pop ebx + + ret + + +;*************************************************************************** +; Function +; queueSize +; +; Description +; Counts the number of entries in a queue +; queue number in ebx ( ms word zeroed ) +; Queue size returned in eax +; This always works, so no error returned +;*************************************************************************** +queueSize: + xor eax, eax + shl ebx, 1 + add ebx, queues + movzx ecx, word [ebx] + cmp cx, NO_BUFFER + je qs_exit + +qs_001: + inc eax + shl ecx, 1 + add ecx, queueList + movzx ecx, word [ecx] + cmp cx, NO_BUFFER + je qs_exit + jmp qs_001 + +qs_exit: + ret + + +;*************************************************************************** +; Function +; queue +; +; Description +; Adds a buffer number to the *end* of a queue +; This is quite quick because these queues will be short +; queue number in eax ( ms word zeroed ) +; buffer number in ebx ( ms word zeroed ) +; all other registers preserved +; This always works, so no error returned +;*************************************************************************** +;uglobal +; queue_cnt dd ? +;endg +queue: +; inc [queue_cnt] +; DEBUGF 1, "K : queue (%u)\n", [queue_cnt] + push ebx + shl ebx, 1 + add ebx, queueList ; eax now holds address of queue entry + mov [ebx], word NO_BUFFER ; This buffer will be the last + + cli + shl eax, 1 + add eax, queues ; eax now holds address of queue + movzx ebx, word [eax] + + cmp bx, NO_BUFFER + jne qu_001 + + pop ebx + ; The list is empty, so add this to the head + mov [eax], bx + jmp qu_exit + +qu_001: + ; Find the last entry + shl ebx, 1 + add ebx, queueList + mov eax, ebx + movzx ebx, word [ebx] + cmp bx, NO_BUFFER + jne qu_001 + + mov ebx, eax + pop eax + mov [ebx], ax + +qu_exit: + sti + ret + + + +;*************************************************************************** +; Function +; dequeue +; +; Description +; removes a buffer number from the head of a queue +; This is fast, as it unlinks the first entry in the list +; queue number in eax ( ms word zeroed ) +; buffer number returned in eax ( ms word zeroed ) +; all other registers preserved +; +;*************************************************************************** +;uglobal +; dequeue_cnt dd ? +;endg +dequeue: + push ebx + shl eax, 1 + add eax, queues ; eax now holds address of queue + mov ebx, eax + cli + movzx eax, word [eax] + cmp ax, NO_BUFFER + je dq_exit +; inc [dequeue_cnt] +; DEBUGF 1, "K : dequeue (%u)\n", [dequeue_cnt] + push eax + shl eax, 1 + add eax, queueList ; eax now holds address of queue entry + mov ax, [eax] + mov [ebx], ax + pop eax + +dq_exit: + sti + pop ebx + ret + + +;*************************************************************************** +; Function +; queueInit +; +; Description +; Initialises the queues to empty, and creates the free queue +; list. +; +;*************************************************************************** +queueInit: + mov esi, queues + mov ecx, NUMQUEUES + mov ax, NO_BUFFER + +qi001: + mov [esi], ax + inc esi + inc esi + loop qi001 + + mov esi, queues + ( 2 * EMPTY_QUEUE ) + + ; Initialise empty queue list + + xor ax, ax + mov [esi], ax + + mov ecx, NUMQUEUEENTRIES - 1 + mov esi, queueList + +qi002: + inc ax + mov [esi], ax + inc esi + inc esi + loop qi002 + + mov ax, NO_BUFFER + mov [esi], ax + + ret diff --git a/kernel/tags/kolibri0.7.7.0/network/socket.inc b/kernel/tags/kolibri0.7.7.0/network/socket.inc new file mode 100644 index 000000000..37e2b8b53 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/socket.inc @@ -0,0 +1,1107 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; SOCKET.INC ;; +;; ;; +;; Sockets constants, structures and functions ;; +;; ;; +;; This file contains the following: ;; +;; is_localport_unused ;; +;; get_free_socket ;; +;; socket_open ;; +;; socket_open_tcp ;; +;; socket_close ;; +;; socket_close_tcp ;; +;; socket_poll ;; +;; socket_status ;; +;; socket_read ;; +;; socket_write ;; +;; socket_write_tcp ;; +;; ;; +;; ;; +;; Changes history: ;; +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; +;; 11.11.2006 - [Johnny_B] and [smb] ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +; socket data structure +struct SOCKET + .PrevPtr dd ? ; pointer to previous socket in list + .NextPtr dd ? ; pointer to next socket in list + .Number dd ? ; socket number (unique within single process) + .PID dd ? ; application process id + .LocalIP dd ? ; local IP address + .LocalPort dw ? ; local port + .RemoteIP dd ? ; remote IP address + .RemotePort dw ? ; remote port + .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) + .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) + .rxDataCount dd ? ; rx data count + .TCBState dd ? ; TCB state + .TCBTimer dd ? ; TCB timer (seconds) + .ISS dd ? ; initial send sequence + .IRS dd ? ; initial receive sequence + .SND_UNA dd ? ; sequence number of unack'ed sent packets + .SND_NXT dd ? ; bext send sequence number to use + .SND_WND dd ? ; send window + .RCV_NXT dd ? ; next receive sequence number to use + .RCV_WND dd ? ; receive window + .SEG_LEN dd ? ; segment length + .SEG_WND dd ? ; segment window + .wndsizeTimer dd ? ; window size timer + .lock dd ? ; lock mutex + .rxData dd ? ; receive data buffer here +ends + +; TCP opening modes +SOCKET_PASSIVE = 0 +SOCKET_ACTIVE = 1 + +; socket types +SOCK_STREAM = 1 +SOCK_DGRAM = 2 + +; pointer to bitmap of free ports (1=free, 0=used) +uglobal +align 4 +network_free_ports dd ? +endg + +iglobal +align 4 +network_free_hint dd 1024/8 +endg + +;; Allocate memory for socket data and put new socket into the list +; Newly created socket is initialized with calling PID and number and +; put into beginning of list (which is a fastest way). +; +; @return socket structure address in EAX +;; +proc net_socket_alloc stdcall uses ebx ecx edx edi + stdcall kernel_alloc, SOCKETBUFFSIZE + DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax + ; check if we can allocate needed amount of memory + or eax, eax + jz .exit + + ; zero-initialize allocated memory + push eax + mov edi, eax + mov ecx, SOCKETBUFFSIZE / 4 + cld + xor eax, eax + rep stosd + pop eax + + ; add socket to the list by changing pointers + mov ebx, net_sockets + push [ebx + SOCKET.NextPtr] + mov [ebx + SOCKET.NextPtr], eax + mov [eax + SOCKET.PrevPtr], ebx + pop ebx + mov [eax + SOCKET.NextPtr], ebx + or ebx, ebx + jz @f + mov [ebx + SOCKET.PrevPtr], eax + + @@: ; set socket owner PID to the one of calling process + mov ebx, [TASK_BASE] + mov ebx, [ebx + TASKDATA.pid] + mov [eax + SOCKET.PID], ebx + + ; find first free socket number and use it + ;mov edx, ebx + mov ebx, net_sockets + xor ecx, ecx + .next_socket_number: + inc ecx + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .last_socket_number + cmp [ebx + SOCKET.Number], ecx + jne .next_socket + ;cmp [ebx + SOCKET.PID], edx + ;jne .next_socket + mov ebx, net_sockets + jmp .next_socket_number + + .last_socket_number: + mov [eax + SOCKET.Number], ecx + + .exit: + ret +endp + +;; Free socket data memory and pop socket off the list +; +; @param sockAddr is a socket structure address +;; +proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD + mov eax, [sockAddr] + DEBUGF 1, "K : net_socket_free (0x%x)\n", eax + ; check if we got something similar to socket structure address + or eax, eax + jz .error + + ; make sure sockAddr is one of the socket addresses in the list + mov ebx, net_sockets + ;mov ecx, [TASK_BASE] + ;mov ecx, [ecx + TASKDATA.pid] + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .error + cmp ebx, eax + jne .next_socket + ;cmp [ebx + SOCKET.PID], ecx + ;jne .next_socket + + ; okay, we found the correct one + ; mark local port as unused + movzx ebx, [eax + SOCKET.LocalPort] + push eax + mov eax, [network_free_ports] + xchg bl, bh +lock bts [eax], ebx + pop eax + ; remove it from the list first, changing pointers + mov ebx, [eax + SOCKET.NextPtr] + mov eax, [eax + SOCKET.PrevPtr] + mov [eax + SOCKET.NextPtr], ebx + or ebx, ebx + jz @f + mov [ebx + SOCKET.PrevPtr], eax + + @@: ; and finally free the memory structure used + stdcall kernel_free, [sockAddr] + ret + + .error: + DEBUGF 1, "K : failed\n" + ret +endp + +;; Get socket structure address by its number +; Scan through sockets list to find the socket with specified number. +; This proc uses SOCKET.PID indirectly to check if socket is owned by +; calling process. +; +; @param sockNum is a socket number +; @return socket structure address or 0 (not found) in EAX +;; +proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD + mov eax, [sockNum] + ; check if we got something similar to socket number + or eax, eax + jz .error + + ; scan through sockets list + mov ebx, net_sockets + ;mov ecx, [TASK_BASE] + ;mov ecx, [ecx + TASKDATA.pid] + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .error + cmp [ebx + SOCKET.Number], eax + jne .next_socket + ;cmp [ebx + SOCKET.PID], ecx + ;jne .next_socket + + ; okay, we found the correct one + mov eax, ebx + ret + + .error: + xor eax, eax + ret +endp + +;; Get socket number by its structure address +; Scan through sockets list to find the socket with specified address. +; This proc uses SOCKET.PID indirectly to check if socket is owned by +; calling process. +; +; @param sockAddr is a socket structure address +; @return socket number (SOCKET.Number) or 0 (not found) in EAX +;; +proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD + mov eax, [sockAddr] + ; check if we got something similar to socket structure address + or eax, eax + jz .error + + ; scan through sockets list + mov ebx, net_sockets + ;mov ecx, [TASK_BASE] + ;mov ecx, [ecx + TASKDATA.pid] + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .error + cmp ebx, eax + jne .next_socket + ;cmp [ebx + SOCKET.PID], ecx + ;jne .next_socket + + ; okay, we found the correct one + mov eax, [ebx + SOCKET.Number] + ret + + .error: + xor eax, eax + ret +endp + +;; [53.9] Check if local port is used by any socket in the system. +; Scan through sockets list, checking SOCKET.LocalPort. +; Useful when you want a to generate a unique local port number. +; This proc doesn't guarantee that after calling it and trying to use +; the port reported being free in calls to socket_open/socket_open_tcp it'll +; still be free or otherwise it'll still be used if reported being in use. +; +; @param BX is a port number +; @return 1 (port is free) or 0 (port is in use) in EAX +;; +proc is_localport_unused stdcall + movzx ebx, bx + mov eax, [network_free_ports] + bt [eax], ebx + setc al + movzx eax, al + ret +endp + +;====================================== +set_local_port: +;-------------------------------------- +;? Set local port in socket structure. +;-------------------------------------- +;> eax -> struct SOCKET +;> bx = local port, or 0 if the kernel must select it itself +;-------------------------------------- +;< CF set on error / cleared on success +;< [eax+SOCKET.LocalPort] filled on success +;====================================== +; 0. Prepare: save registers, make eax point to ports table, expand port to ebx. + push eax ecx + mov eax, [network_free_ports] + movzx ebx, bx +; 1. Test, whether the kernel should choose port itself. If no, proceed to 5. + test ebx, ebx + jnz .given +; 2. Yes, it should. Set ecx = limit of table, eax = start value + lea ecx, [eax+0x10000/8] + add eax, [network_free_hint] +; 3. First scan loop: from free hint to end of table. +.scan1: +; 3a. For each dword, find bit set to 1 + bsf ebx, [eax] + jz .next1 +; 3b. If such bit has been found, atomically test again and clear it. +lock btr [eax], ebx +; 3c. If the bit was still set (usual case), we have found and reserved one port. +; Proceed to 6. + jc .found +; 3d. Otherwise, someone has reserved it between bsf and btr, so retry search. + jmp .scan1 +.next1: +; 3e. All bits are cleared, so advance to next dword. + add eax, 4 +; 3f. Check limit and continue loop. + cmp eax, ecx + jb .scan1 +; 4. Second scan loop: from port 1024 (start of non-system ports) to free hint. + mov eax, [network_free_ports] + mov ecx, eax + add ecx, [network_free_hint] + add eax, 1024/8 +; 4a. Test whether there is something to scan. + cmp eax, ecx + jae .fail +; 4b. Enter the loop, the process is same as for 3. +.scan2: + bsf ebx, [eax] + jz .next2 +lock btr [eax], ebx + jc .found + jmp .scan2 +.next2: + add eax, 4 + cmp eax, ecx + jb .scan2 +; 4c. None found. Fail. +.fail: + pop ecx eax + stc + ret +; 5. No, the kernel should reserve selected port. +.given: +; 5a. Atomically test old value and clear bit. +lock btr [eax], ebx +; 5b. If the bit was set, reservation is successful. Proceed to 8. + jc .set +; 5c. Otherwise, fail. + jmp .fail +.found: +; 6. We have found the bit set to 1, convert the position to port number. + sub eax, [network_free_ports] + lea ebx, [ebx+eax*8] +; 7. Update free hint. + add eax, 4 + cmp eax, 65536/8 + jb @f + mov eax, 1024/8 +@@: + mov [network_free_hint], eax +.set: +; 8. Restore eax, set SOCKET.LocalPort and return. + pop ecx eax + xchg bl, bh ; Intel -> network byte order + mov [eax + SOCKET.LocalPort], bx + clc + ret + +;; [53.0] Open DGRAM socket (connectionless, unreliable) +; +; @param BX is local port number +; @param CX is remote port number +; @param EDX is remote IP address +; @return socket number or -1 (error) in EAX +;; +proc socket_open stdcall + call net_socket_alloc + or eax, eax + jz .error + + DEBUGF 1, "K : socket_open (0x%x)\n", eax + + push eax + + call set_local_port + jc .error.free + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + + ;pop eax ; Get the socket number back, so we can return it + stdcall net_socket_addr_to_num + ret + + .error.free: + stdcall net_socket_free;, eax + + .error: + DEBUGF 1, "K : socket_open (fail)\n" + or eax, -1 + ret +endp + +;; [53.5] Open STREAM socket (connection-based, sequenced, reliable, two-way) +; +; @param BX is local port number +; @param CX is remote port number +; @param EDX is remote IP address +; @param ESI is open mode (SOCKET_ACTIVE, SOCKET_PASSIVE) +; @return socket number or -1 (error) in EAX +;; +proc socket_open_tcp stdcall +local sockAddr dd ? + + cmp esi, SOCKET_PASSIVE + jne .skip_port_check + + push ebx + mov eax, ebx + xchg al, ah + mov ebx, net_sockets + + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .last_socket + cmp [ebx + SOCKET.TCBState], TCB_LISTEN + jne .next_socket + cmp [ebx + SOCKET.LocalPort], ax + jne .next_socket + + xchg al, ah + DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx + pop ebx + jmp .error + + .last_socket: + pop ebx + + .skip_port_check: + call net_socket_alloc + or eax, eax + jz .error + + DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax + + mov [sockAddr], eax + + ; TODO - check this works! + ;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer. + + call set_local_port + jc .error.free + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx + mov [eax + SOCKET.OrigRemotePort], cx + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + mov [eax + SOCKET.OrigRemoteIP], edx + + mov ebx, TCB_LISTEN + cmp esi, SOCKET_PASSIVE + je @f + mov ebx, TCB_SYN_SENT + @@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB + + cmp ebx, TCB_LISTEN + je .exit + + ; Now, if we are in active mode, then we have to send a SYN to the specified remote port + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit + + push eax + + mov bl, TH_SYN + xor ecx, ecx + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + mov esi, [sockAddr] + + ; increment SND.NXT in socket + add esi, SOCKET.SND_NXT + call inc_inet_esi + + .exit: + ; Get the socket number back, so we can return it + stdcall net_socket_addr_to_num, [sockAddr] + ret + + .error.free: + stdcall net_socket_free, eax + + .error: + DEBUGF 1, "K : socket_open_tcp (fail)\n" + or eax, -1 + ret +endp + +;; [53.1] Close DGRAM socket +; +; @param EBX is socket number +; @return 0 (closed successfully) or -1 (error) in EAX +;; +proc socket_close stdcall + DEBUGF 1, "K : socket_close (0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + stdcall net_socket_free, eax + + xor eax, eax + ret + + .error: + DEBUGF 1, "K : socket_close (fail)\n" + or eax, -1 + ret +endp + +;; [53.8] Close STREAM socket +; Closing TCP sockets takes time, so when you get successful return code +; from this function doesn't always mean that socket is actually closed. +; +; @param EBX is socket number +; @return 0 (closed successfully) or -1 (error) in EAX +;; +proc socket_close_tcp stdcall +local sockAddr dd ? + + DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx + ; first, remove any resend entries + pusha + + mov esi, resendQ + mov ecx, 0 + + .next_resendq: + cmp ecx, NUMRESENDENTRIES + je .last_resendq ; None left + cmp [esi + 4], ebx + je @f ; found one + inc ecx + add esi, 8 + jmp .next_resendq + + @@: mov dword[esi + 4], 0 + inc ecx + add esi, 8 + jmp .next_resendq + + .last_resendq: + popa + + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + mov ebx, eax + mov [sockAddr], eax + + cmp [ebx + SOCKET.TCBState], TCB_LISTEN + je .destroy_tcb + cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT + je .destroy_tcb + cmp [ebx + SOCKET.TCBState], TCB_CLOSED + je .destroy_tcb + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .error + + push eax + + mov bl, TH_FIN+TH_ACK + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov ebx, [sockAddr] + ; increament SND.NXT in socket + lea esi, [ebx + SOCKET.SND_NXT] + call inc_inet_esi + + ; Get the socket state + mov eax, [ebx + SOCKET.TCBState] + cmp eax, TCB_SYN_RECEIVED + je .fin_wait_1 + cmp eax, TCB_ESTABLISHED + je .fin_wait_1 + + ; assume CLOSE WAIT + ; Send a fin, then enter last-ack state + mov [ebx + SOCKET.TCBState], TCB_LAST_ACK + jmp .send + + .fin_wait_1: + ; Send a fin, then enter finwait2 state + mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1 + + .send: + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + jmp .exit + + .destroy_tcb: + + ; Clear the socket variables + stdcall net_socket_free, ebx + + .exit: + xor eax, eax + ret + + .error: + DEBUGF 1, "K : socket_close_tcp (fail)\n" + or eax, -1 + ret +endp + +;; [53.2] Poll socket +; +; @param EBX is socket number +; @return count or bytes in rx buffer or 0 (error) in EAX +;; +proc socket_poll stdcall +; DEBUGF 1, "socket_poll(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + mov eax, [eax + SOCKET.rxDataCount] + ret + + .error: + xor eax, eax + ret +endp + +;; [53.6] Get socket TCB state +; +; @param EBX is socket number +; @return socket TCB state or 0 (error) in EAX +;; +proc socket_status stdcall +;; DEBUGF 1, "socket_status(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + mov eax, [eax + SOCKET.TCBState] + ret + + .error: + xor eax, eax + ret +endp + +;; [53.3] Get one byte from rx buffer +; This function can return 0 in two cases: if there's one byte read and +; non left, and if an error occured. Behavior should be changed and function +; shouldn't be used for now. Consider using [53.11] instead. +; +; @param EBX is socket number +; @return number of bytes left in rx buffer or 0 (error) in EAX +; @return byte read in BL +;; +proc socket_read stdcall +; DEBUGF 1, "socket_read(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + lea ebx, [eax + SOCKET.lock] + call wait_mutex + + mov ebx, eax + mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes + test eax, eax + jz .error_release + + dec eax + mov esi, ebx ; esi is address of socket + mov [ebx + SOCKET.rxDataCount], eax ; store new count + movzx eax, byte[ebx + SOCKET.rxData] ; get the byte + + mov ecx, SOCKETBUFFSIZE - SOCKET.rxData - 1 + lea edi, [esi + SOCKET.rxData] + lea esi, [edi + 1] + cld + push ecx + shr ecx, 2 + rep movsd + pop ecx + and ecx, 3 + rep movsb + + mov [ebx + SOCKET.lock], 0 + mov ebx, eax + + ret + + .error_release: + mov [ebx + SOCKET.lock], 0 + .error: + xor ebx, ebx + ret +endp + +;; [53.11] Get specified number of bytes from rx buffer +; Number of bytes in rx buffer can be less than requested size. In this case, +; only available number of bytes is read. +; This function can return 0 in two cases: if there's no data to read, and if +; an error occured. Behavior should be changed. +; +; @param EBX is socket number +; @param ECX is pointer to application buffer +; @param EDX is application buffer size (number of bytes to read) +; @return number of bytes read or 0 (error) in EAX +;; +proc socket_read_packet stdcall +; DEBUGF 1, "socket_read_packet(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx ; get real socket address + or eax, eax + jz .error + + lea ebx, [eax + SOCKET.lock] + call wait_mutex + + mov ebx, eax + mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes + test eax, eax ; if count of bytes is zero.. + jz .exit ; exit function (eax will be zero) + + test edx, edx ; if buffer size is zero, copy all data + jz .copy_all_bytes + cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data + jge .copy_all_bytes + + sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy) + mov [ebx + SOCKET.rxDataCount], eax ; + push eax + mov eax, edx ; number of bytes we want to copy must be in eax + call .start_copy ; copy to the application + + mov esi, ebx ; now we're going to copy the remaining bytes to the beginning + add esi, SOCKET.rxData ; we dont need to copy the header + mov edi, esi ; edi is where we're going to copy to + add esi, edx ; esi is from where we copy + pop ecx ; count of bytes we have left + push ecx ; push it again so we can re-use it later + shr ecx, 2 ; divide eax by 4 + cld + rep movsd ; copy all full dwords + pop ecx + and ecx, 3 + rep movsb ; copy remaining bytes + + .exit: + mov [ebx + SOCKET.lock], 0 + ret ; at last, exit + + .error: + xor eax, eax + ret + + .copy_all_bytes: + xor esi, esi + mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) + call .start_copy + mov [ebx + SOCKET.lock], 0 + ret + + .start_copy: + mov edi, ecx + mov esi, ebx + add esi, SOCKET.rxData ; we dont need to copy the header + mov ecx, eax ; eax is count of bytes + push ecx + shr ecx, 2 ; divide eax by 4 + cld ; copy all full dwords + rep movsd + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes + retn ; exit, or go back to shift remaining bytes if any +endp + +;; [53.4] Send data through DGRAM socket +; +; @param EBX is socket number +; @param ECX is application data size (number of bytes to send) +; @param EDX is pointer to application data buffer +; @return 0 (sent successfully) or -1 (error) in EAX +;; +proc socket_write stdcall +; DEBUGF 1, "socket_write(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx ; get real socket address + or eax, eax + jz .error + + mov ebx, eax + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .error + + ; Save the queue entry number + push eax + + ; save the pointers to the data buffer & size + push edx + push ecx + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax + + ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr + + ; Fill in the IP header (some data is in the socket descriptor) + mov eax, [ebx + SOCKET.LocalIP] + mov [edx + IP_PACKET.SourceAddress], eax + mov eax, [ebx + SOCKET.RemoteIP] + mov [edx + IP_PACKET.DestinationAddress], eax + + mov [edx + IP_PACKET.VersionAndIHL], 0x45 + mov [edx + IP_PACKET.TypeOfService], 0 + + pop eax ; Get the UDP data length + push eax + + add eax, 20 + 8 ; add IP header and UDP header lengths + xchg al, ah + mov [edx + IP_PACKET.TotalLength], ax + xor eax, eax + mov [edx + IP_PACKET.Identification], ax + mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040 + mov [edx + IP_PACKET.TimeToLive], 0x20 + mov [edx + IP_PACKET.Protocol], PROTOCOL_UDP + + ; Checksum left unfilled + mov [edx + IP_PACKET.HeaderChecksum], ax + + ; Fill in the UDP header (some data is in the socket descriptor) + mov ax, [ebx + SOCKET.LocalPort] + mov [edx + 20 + UDP_PACKET.SourcePort], ax + + mov ax, [ebx + SOCKET.RemotePort] + mov [edx + 20 + UDP_PACKET.DestinationPort], ax + + pop eax + push eax + + add eax, 8 + xchg al, ah + mov [edx + 20 + UDP_PACKET.Length], ax + + ; Checksum left unfilled + xor eax, eax + mov [edx + 20 + UDP_PACKET.Checksum], ax + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + pop eax ; get callers ptr to data to send + + ; Get the address of the callers data + mov edi, [TASK_BASE] + add edi, TASKDATA.mem_start + add eax, [edi] + mov esi, eax + + mov edi, edx + add edi, 28 + cld + rep movsb ; copy the data across + + ; we have edx as IPbuffer ptr. + ; Fill in the UDP checksum + ; First, fill in pseudoheader + mov eax, [edx + IP_PACKET.SourceAddress] + mov [pseudoHeader], eax + mov eax, [edx + IP_PACKET.DestinationAddress] + mov [pseudoHeader + 4], eax + mov word[pseudoHeader + 8], PROTOCOL_UDP shl 8 + 0 ; 0 + protocol + add ebx, 8 + mov eax, ebx + xchg al, ah + mov [pseudoHeader + 10], ax + + mov eax, pseudoHeader + mov [checkAdd1], eax + mov [checkSize1], word 12 + mov eax, edx + add eax, 20 + mov [checkAdd2], eax + mov eax, ebx + mov [checkSize2], ax ; was eax!! mjh 8/7/02 + + call checksum + + ; store it in the UDP checksum ( in the correct order! ) + mov ax, [checkResult] + + ; If the UDP checksum computes to 0, we must make it 0xffff + ; (0 is reserved for 'not used') + test ax, ax + jnz @f + mov ax, 0xffff + + @@: xchg al, ah + mov [edx + 20 + UDP_PACKET.Checksum], ax + + ; Fill in the IP header checksum + GET_IHL ecx,edx ; get IP-Header length + stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size + xchg al, ah + mov [edx + IP_PACKET.HeaderChecksum], ax + + ; Check destination IP address. + ; If it is the local host IP, route it back to IP_RX + + pop ebx + + mov eax, NET1OUT_QUEUE + mov ecx, [edx + SOCKET.RemoteIP] + mov edx, [stack_ip] + cmp edx, ecx + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + call queue + + xor eax, eax + ret + + .error: + or eax, -1 + ret +endp + +;; [53.7] Send data through STREAM socket +; +; @param EBX is socket number +; @param ECX is application data size (number of bytes to send) +; @param EDX is pointer to application data buffer +; @return 0 (sent successfully) or -1 (error) in EAX +;; +proc socket_write_tcp stdcall +local sockAddr dd ? + +; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx + stdcall net_socket_num_to_addr, ebx + or eax, eax + jz .error + + mov ebx, eax + mov [sockAddr], ebx + + ; If the sockets window timer is nonzero, do not queue packet + cmp [ebx + SOCKET.wndsizeTimer], 0 + jne .error + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .error + + push eax + + ; Get the address of the callers data + mov edi, [TASK_BASE] + add edi, TASKDATA.mem_start + add edx, [edi] + mov esi, edx + + pop eax + push eax + + push ecx + mov bl, TH_ACK + stdcall build_tcp_packet, [sockAddr] + pop ecx + + ; Check destination IP address. + ; If it is the local host IP, route it back to IP_RX + + pop ebx + push ecx + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + pop ecx + push ebx ; save ipbuffer number + + call queue + + mov esi, [sockAddr] + + ; increament SND.NXT in socket + ; Amount to increment by is in ecx + add esi, SOCKET.SND_NXT + call add_inet_esi + + pop ebx + + ; Copy the IP buffer to a resend queue + ; If there isn't one, dont worry about it for now + mov esi, resendQ + mov ecx, 0 + + .next_resendq: + cmp ecx, NUMRESENDENTRIES + je .exit ; None found + cmp dword[esi + 4], 0 + je @f ; found one + inc ecx + add esi, 8 + jmp .next_resendq + + @@: push ebx + + ; OK, we have a buffer descriptor ptr in esi. + ; resend entry # in ecx + ; Populate it + ; socket # + ; retries count + ; retry time + ; fill IP buffer associated with this descriptor + + stdcall net_socket_addr_to_num, [sockAddr] + mov [esi + 4], eax + mov byte[esi + 1], TCP_RETRIES + mov word[esi + 2], TCP_TIMEOUT + + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov edi, resendBuffer - IPBUFFSIZE + + @@: add edi, IPBUFFSIZE + loop @b + + ; we have dest buffer location in edi + pop eax + ; convert source buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + mov esi, eax + + ; do copy + mov ecx, IPBUFFSIZE + cld + rep movsb + + .exit: + xor eax, eax + ret + + .error: + or eax, -1 + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/network/stack.inc b/kernel/tags/kolibri0.7.7.0/network/stack.inc new file mode 100644 index 000000000..ab72790bf --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/stack.inc @@ -0,0 +1,1024 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; STACK.INC ;; +;; ;; +;; TCP/IP stack for Menuet OS ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; Version 0.7 ;; +;; Added a timer per socket to allow delays when rx window ;; +;; gets below 1KB ;; +;; ;; +;;10.01.2007 Bugfix for checksum function from Paolo Franchetti ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************* +; Interface +; The interfaces defined in ETHERNET.INC plus: +; stack_init +; stack_handler +; app_stack_handler +; app_socket_handler +; checksum +; +;******************************************************************* + +uglobal +StackCounters: + dumped_rx_count dd 0 + arp_tx_count: dd 0 + arp_rx_count: dd 0 + ip_rx_count: dd 0 + ip_tx_count: dd 0 +endg + +; socket buffers +SOCKETBUFFSIZE equ 4096 ; state + config + buffer. +SOCKETHEADERSIZE equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data + +;NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 + +; IPBUFF status values +BUFF_EMPTY equ 0 +BUFF_RX_FULL equ 1 +BUFF_ALLOCATED equ 2 +BUFF_TX_FULL equ 3 + +NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX + +NUMQUEUES equ 4 + +EMPTY_QUEUE equ 0 +IPIN_QUEUE equ 1 +IPOUT_QUEUE equ 2 +NET1OUT_QUEUE equ 3 + +NO_BUFFER equ 0xFFFF +IPBUFFSIZE equ 1500 ; MTU of an ethernet packet +NUMQUEUEENTRIES equ NUM_IPBUFFERS +NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets + +; These are the 0x40 function codes for application access to the stack +STACK_DRIVER_STATUS equ 52 +SOCKET_INTERFACE equ 53 + + +; 128KB allocated for the stack and network driver buffers and other +; data requirements +;stack_data_start equ 0x700000 +;eth_data_start equ 0x700000 +;stack_data equ 0x704000 +;stack_data_end equ 0x71ffff + +; 32 bit word +stack_config equ stack_data + +; 32 bit word - IP Address in network format +stack_ip equ stack_data + 4 + +; 1 byte. 0 == inactive, 1 = active +ethernet_active equ stack_data + 9 + + +; TODO :: empty memory area + +; Address of selected socket +;sktAddr equ stack_data + 32 +; Parameter to checksum routine - data ptr +checkAdd1 equ stack_data + 36 +; Parameter to checksum routine - 2nd data ptr +checkAdd2 equ stack_data + 40 +; Parameter to checksum routine - data size +checkSize1 equ stack_data + 44 +; Parameter to checksum routine - 2nd data size +checkSize2 equ stack_data + 46 +; result of checksum routine +checkResult equ stack_data + 48 + +; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| +pseudoHeader equ stack_data + 50 + +; receive and transmit IP buffer allocation +;sockets equ stack_data + 62 +Next_free2 equ stack_data + 62;Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) +; 1560 byte buffer for rx / tx ethernet packets +Ether_buffer equ Next_free2 +Next_free3 equ Ether_buffer + 1518 +last_1sTick equ Next_free3 +IPbuffs equ Next_free3 + 1 +queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) +queueList equ queues + (2 * NUMQUEUES) +last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) + +;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) +;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP +; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) + + + +;resendQ equ 0x770000 +;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP ; XTODO: validate size +resendBuffer equ resendQ + ( 8 * NUMRESENDENTRIES ) ; for TCP + + +uglobal +net_sockets rd 2 +endg + +; simple macro for memory set operation +macro _memset_dw adr,value,amount +{ + mov edi, adr + mov ecx, amount + if value = 0 + xor eax, eax + else + mov eax, value + end if + cld + rep stosd +} + + +; Below, the main network layer source code is included +; +include "queue.inc" +include "eth_drv/ethernet.inc" +include "ip.inc" +include "socket.inc" + +;*************************************************************************** +; Function +; stack_init +; +; Description +; Clear all allocated memory to zero. This ensures that +; on startup, the stack is inactive, and consumes no resources +; This is a kernel function, called prior to the OS main loop +; in set_variables +; +;*************************************************************************** + +stack_init: + ; Init two address spaces with default values + _memset_dw stack_data_start, 0, 0x20000/4 + _memset_dw resendQ, 0, NUMRESENDENTRIES * 2 + + mov [net_sockets], 0 + mov [net_sockets + 4], 0 + + ; Queries initialization + call queueInit + + ; The following block sets up the 1s timer + mov al, 0x0 + out 0x70, al + in al, 0x71 + mov [last_1sTick], al +ret + + + +;*************************************************************************** +; Function +; stack_handler +; +; Description +; The kernel loop routine for the stack +; This is a kernel function, called in the main loop +; +;*************************************************************************** +align 4 +stack_handler: + + call ethernet_driver + call ip_rx + + + ; Test for 10ms tick, call tcp timer + mov eax, [timer_ticks] ;[0xfdf0] + cmp eax, [last_1hsTick] + je sh_001 + + mov [last_1hsTick], eax + call tcp_tx_handler + +sh_001: + + ; Test for 1 second event, call 1s timer functions + mov al, 0x0 ;second + out 0x70, al + in al, 0x71 + cmp al, [last_1sTick] + je sh_exit + + mov [last_1sTick], al + + stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0 + call tcp_tcb_handler + +sh_exit: + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Checksum [by Johnny_B] +;; IN: +;; buf_ptr=POINTER to buffer +;; buf_size=SIZE of buffer +;; OUT: +;; AX=16-bit checksum +;; Saves all used registers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +proc checksum_jb stdcall uses ebx esi ecx,\ + buf_ptr:DWORD, buf_size:DWORD + + xor eax, eax + xor ebx, ebx ;accumulator + mov esi, dword[buf_ptr] + mov ecx, dword[buf_size] + shr ecx, 1 ; ecx=ecx/2 + jnc @f ; if CF==0 then size is even number + mov bh, byte[esi + ecx*2] + @@: + cld + + .loop: + lodsw ;eax=word[esi],esi=esi+2 + xchg ah,al ;cause must be a net byte-order + add ebx, eax + loop .loop + + mov eax, ebx + shr eax, 16 + add ax, bx + not ax + + ret +endp + +;*************************************************************************** +; Function +; checksum +; +; Description +; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult +; Dont break anything; Most registers are used by the caller +; This code is derived from the 'C' source, cksum.c, in the book +; Internetworking with TCP/IP Volume II by D.E. Comer +; +;*************************************************************************** + + +checksum: + pusha + mov eax, [checkAdd1] + xor edx, edx ; edx is the accumulative checksum + xor ebx, ebx + mov cx, [checkSize1] + shr cx, 1 + jz cs1_1 + +cs1: + mov bh, [eax] + mov bl, [eax + 1] + + add eax, 2 + add edx, ebx + + loopw cs1 + +cs1_1: + and word [checkSize1], 0x01 + jz cs_test2 + + mov bh, [eax] + xor bl, bl + + add edx, ebx + +cs_test2: + mov cx, [checkSize2] + cmp cx, 0 + jz cs_exit ; Finished if no 2nd buffer + + mov eax, [checkAdd2] + + shr cx, 1 + jz cs2_1 + +cs2: + mov bh, [eax] + mov bl, [eax + 1] + + add eax, 2 + add edx, ebx + + loopw cs2 + +cs2_1: + and word [checkSize2], 0x01 + jz cs_exit + + mov bh, [eax] + xor bl, bl + + add edx, ebx + +cs_exit: + mov ebx, edx + + shr ebx, 16 + and edx, 0xffff + add edx, ebx + mov eax, edx + shr eax, 16 + add edx, eax + not dx + + mov [checkResult], dx + popa + ret + + + + +;*************************************************************************** +; Function +; app_stack_handler +; +; Description +; This is an application service, called by int 0x40, function 52 +; It provides application access to the network interface layer +; +;*************************************************************************** +app_stack_handler: + cmp eax, 0 + jnz not0 + ; Read the configuration word + mov eax, [stack_config] + ret + +not0: + cmp eax, 1 + jnz not1 + ; read the IP address + + mov eax, [stack_ip] + ret + +not1: + cmp eax, 2 + jnz not2 + + ; write the configuration word + mov [stack_config], ebx + + ; + ; 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/tags/kolibri0.7.7.0/network/tcp.inc b/kernel/tags/kolibri0.7.7.0/network/tcp.inc new file mode 100644 index 000000000..ae01e2ba4 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/tcp.inc @@ -0,0 +1,1169 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; TCP.INC ;; +;; ;; +;; TCP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; v0.6 : Added reset handling in the established state ;; +;; Added a timer per socket to allow delays when ;; +;; rx window gets below 1KB ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; TCP TCB states +TCB_LISTEN equ 1 +TCB_SYN_SENT equ 2 +TCB_SYN_RECEIVED equ 3 +TCB_ESTABLISHED equ 4 +TCB_FIN_WAIT_1 equ 5 +TCB_FIN_WAIT_2 equ 6 +TCB_CLOSE_WAIT equ 7 +TCB_CLOSING equ 8 +TCB_LAST_ACK equ 9 +TCB_TIMED_WAIT equ 10 +TCB_CLOSED equ 11 + +TH_FIN = 0x01 +TH_SYN = 0x02 +TH_RST = 0x04 +TH_PUSH = 0x08 +TH_ACK = 0x10 +TH_URG = 0x20 + +TWOMSL equ 10 ; # of secs to wait before closing socket + +TCP_RETRIES equ 5 ; Number of times to resend a packet +TCP_TIMEOUT equ 20 ; resend if not replied to in x hs + +;******************************************************************* +; Interface +; +; tcp_tx_handler Handles the TCP transmit queue +; tcp_rx The protocol handler for received data +; buildTCPPacket fills in the packet headers and data +; tcpStateMachine Main state machine for received TCP packets +; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state +; +;******************************************************************* + + +; TCP Payload ( Data field in IP datagram ) +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;20 | Source Port | Destination Port | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;24 | Sequence Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;28 | Acknowledgment Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;32 | Data | |U|A|P|R|S|F| | +; | Offset| Reserved |R|C|S|S|Y|I| Window | +; | | |G|K|H|T|N|N| | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;36 | Checksum | Urgent Pointer | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;40 | Options | Padding | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | data + + +struc TCP_PACKET +{ .SourcePort dw ? ;+00 + .DestinationPort dw ? ;+02 + .SequenceNumber dd ? ;+04 + .AckNumber dd ? ;+08 + .DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7] + .Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN + .Window dw ? ;+14 + .Checksum dw ? ;+16 + .UrgentPointer dw ? ;+18 + .Options rb 3 ;+20 + .Padding db ? ;+23 + .Data db ? ;+24 +} + +virtual at 0 + TCP_PACKET TCP_PACKET +end virtual + + + +;*************************************************************************** +; Function +; tcp_tcb_handler +; +; Description +; Handles sockets in the timewait state, closing them +; when the TCB timer expires +; +;*************************************************************************** + +proc tcp_tcb_handler stdcall uses ebx + ; scan through all the sockets, decrementing active timers + + mov ebx, net_sockets + + cmp [ebx + SOCKET.NextPtr], 0 + je .exit + ;DEBUGF 1, "K : sockets:\n" + + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .exit + + ;DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState] + + cmp [ebx + SOCKET.TCBTimer], 0 + jne .decrement_tcb + cmp [ebx + SOCKET.wndsizeTimer], 0 + jne .decrement_wnd + jmp .next_socket + + .decrement_tcb: + ; decrement it, delete socket if TCB timer = 0 & socket in timewait state + dec [ebx + SOCKET.TCBTimer] + jnz .next_socket + + cmp [ebx + SOCKET.TCBState], TCB_TIMED_WAIT + jne .next_socket + + push [ebx + SOCKET.PrevPtr] + stdcall net_socket_free, ebx + pop ebx + jmp .next_socket + + .decrement_wnd: + ; TODO - prove it works! + dec [ebx + SOCKET.wndsizeTimer] + jmp .next_socket + + .exit: + ret +endp + + +;*************************************************************************** +; Function +; tcp_tx_handler +; +; Description +; Handles queued TCP data +; This is a kernel function, called by stack_handler +; +;*************************************************************************** + +proc tcp_tx_handler stdcall + ; decrement all resend buffers timers. If they + ; expire, queue them for sending, and restart the timer. + ; If the retries counter reach 0, delete the entry + + mov esi, resendQ + mov ecx, 0 + + .next_resendq: + cmp ecx, NUMRESENDENTRIES + je .exit ; None left + cmp dword[esi + 4], 0 + jne @f ; found one + inc ecx + add esi, 8 + jmp .next_resendq + + @@: ; we have one. decrement it's timer by 1 + dec word[esi + 2] + jz @f + inc ecx + add esi, 8 + jmp .next_resendq ; Timer not zero, so move on + + @@: + xor ebx, ebx + ; restart timer, and decrement retries + ; After the first resend, back of on next, by a factor of 5 + mov [esi + 2], word TCP_TIMEOUT * 5 + dec byte[esi + 1] + jnz @f + + ; retries now 0, so delete from queue + xchg [esi + 4], ebx + + @@: ; resend packet + pushad + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + jne .tth004z + + ; TODO - try again in 10ms. + test ebx, ebx + jnz @f + mov [esi + 4], ebx + + @@: ; Mark it to expire in 10ms - 1 tick + mov byte[esi + 1], 1 + mov word[esi + 2], 1 + jmp .tth005 + + .tth004z: + ; we have a buffer # in ax + push eax ecx + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + ; we have the buffer address in eax + mov edi, eax + pop ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + imul esi, ecx, IPBUFFSIZE + add esi, resendBuffer + + ; we have resend buffer location in esi + mov ecx, IPBUFFSIZE + + ; copy data across + push edi + cld + rep movsb + pop edi + + ; queue packet + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + cmp edx, [edi + IP_PACKET.DestinationAddress] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + pop ebx + call queue + + .tth005: + popad + + inc ecx + add esi, 8 + jmp .next_resendq + + .exit: + ret +endp + + +;*************************************************************************** +; Function +; tcp_rx +; +; Description +; TCP protocol handler +; This is a kernel function, called by ip_rx +; IP buffer address given in edx +; IP buffer number in eax +; Free up (or re-use) IP buffer when finished +; +;*************************************************************************** + +proc tcp_rx stdcall uses ebx + ; The process is as follows. + ; Look for a socket with matching remote IP, remote port, local port + ; if not found, then + ; look for remote IP + local port match ( where sockets remote port = 0) + ; if not found, then + ; look for a socket where local socket port == IP packets remote port + ; where sockets remote port, remote IP = 0 + ; discard if not found + ; Call sockets tcbStateMachine, with pointer to packet. + ; the state machine will not delete the packet, so do that here. + + push eax + + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; IP Packet SA = Remote IP + ; IP Packet TCP Source Port = remote Port + + mov ebx, net_sockets + + .next_socket.1: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .next_socket.1.exit + +; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 + + mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr + cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr + jne .next_socket.1 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP] + + mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr + cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP + jne .next_socket.1 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4 + + mov ax, [edx + 20 + TCP_PACKET.SourcePort] ; get the source port from the TCP hdr + cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port + jne .next_socket.1 ; different - try next socket + + ; We have a complete match - use this socket + jmp .change_state + + .next_socket.1.exit: + + ; If we got here, there was no match + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; IP Packet SA = Remote IP + ; socket remote Port = 0 + + mov ebx, net_sockets + + .next_socket.2: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .next_socket.2.exit + +; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 + + mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr + cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port + jne .next_socket.2 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP] + + mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr + cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP + jne .next_socket.2 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 + + cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 + jne .next_socket.2 ; different - try next socket + + ; We have a complete match - use this socket + jmp .change_state + + .next_socket.2.exit: + + ; If we got here, there was no match + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; socket Remote IP = 0 + ; socket remote Port = 0 + + mov ebx, net_sockets + + .next_socket.3: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .next_socket.3.exit + +; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 + + mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get destination port from the TCP hdr + cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port + jne .next_socket.3 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP] + + cmp [ebx + SOCKET.RemoteIP], 0 ; only match a socket remote IP of 0 + jne .next_socket.3 ; different - try next socket + +; DEBUGF 1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 + + cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 + jne .next_socket.3 ; different - try next socket + + ; We have a complete match - use this socket + jmp .change_state + + .next_socket.3.exit: + + ; If we got here, we need to reject the packet + + DEBUGF 1, "K : tcp_rx - dumped\n" + DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2 + + inc [dumped_rx_count] + jmp .exit + + .change_state: + + ; We have a valid socket/TCB, so call the TCB State Machine for that skt. + ; socket is pointed to by ebx + ; IP packet is pointed to by edx + ; IP buffer number is on stack ( it will be popped at the end) + + stdcall tcpStateMachine, ebx + + .exit: + pop eax + call freeBuff + ret +endp + + +;*************************************************************************** +; Function +; buildTCPPacket +; +; Description +; builds an IP Packet with TCP data fully populated for transmission +; You may destroy any and all registers +; TCP control flags specified in bl +; This TCB is in [sktAddr] +; User data pointed to by esi +; Data length in ecx +; Transmit buffer number in eax +; +;*************************************************************************** + +proc build_tcp_packet stdcall, sockAddr:DWORD + push ecx ; Save data length + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax + + mov [edx + 20 + TCP_PACKET.Flags], bl ; TCP flags + + mov ebx, [sockAddr] + + ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr + + ; Fill in the IP header ( some data is in the socket descriptor) + mov eax, [ebx + SOCKET.LocalIP] + mov [edx + IP_PACKET.SourceAddress], eax + mov eax, [ebx + SOCKET.RemoteIP] + mov [edx + IP_PACKET.DestinationAddress], eax + + mov [edx + IP_PACKET.VersionAndIHL], 0x45 + mov [edx + IP_PACKET.TypeOfService], 0 + + pop eax ; Get the TCP data length + push eax + + add eax, 20 + 20 ; add IP header and TCP header lengths + rol ax, 8 + mov [edx + IP_PACKET.TotalLength], ax + mov [edx + IP_PACKET.Identification], 0 + mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040 + mov [edx + IP_PACKET.TimeToLive], 0x20 + mov [edx + IP_PACKET.Protocol], PROTOCOL_TCP + + ; Checksum left unfilled + mov [edx + IP_PACKET.HeaderChecksum], 0 + + ; Fill in the TCP header (some data is in the socket descriptor) + mov ax, [ebx + SOCKET.LocalPort] + mov [edx + 20 + TCP_PACKET.SourcePort], ax ; Local Port + + mov ax, [ebx + SOCKET.RemotePort] + mov [edx + 20 + TCP_PACKET.DestinationPort], ax ; desitination Port + + ; Checksum left unfilled + mov [edx + 20 + TCP_PACKET.Checksum], 0 + + ; sequence number + mov eax, [ebx + SOCKET.SND_NXT] + mov [edx + 20 + TCP_PACKET.SequenceNumber], eax + + ; ack number + mov eax, [ebx + SOCKET.RCV_NXT] + mov [edx + 20 + TCP_PACKET.AckNumber], eax + + ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) + ; 768 bytes seems better + mov [edx + 20 + TCP_PACKET.Window], 0x0003 + + ; Urgent pointer (0) + mov [edx + 20 + TCP_PACKET.UrgentPointer], 0 + + ; data offset ( 0x50 ) + mov [edx + 20 + TCP_PACKET.DataOffset], 0x50 + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + + cmp ebx, 0 + jz @f + + mov edi, edx + add edi, 40 + cld + rep movsb ; copy the data across + + @@: ; we have edx as IPbuffer ptr. + ; Fill in the TCP checksum + ; First, fill in pseudoheader + mov eax, [edx + IP_PACKET.SourceAddress] + mov [pseudoHeader], eax + mov eax, [edx + IP_PACKET.DestinationAddress] + mov [pseudoHeader + 4], eax + mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0 + add ebx, 20 + mov [pseudoHeader + 10], bh + mov [pseudoHeader + 11], bl + + mov eax, pseudoHeader + mov [checkAdd1], eax + mov word[checkSize1], 12 + mov eax, edx + add eax, 20 + mov [checkAdd2], eax + mov eax, ebx + mov [checkSize2], ax + + call checksum + + ; store it in the TCP checksum ( in the correct order! ) + mov ax, [checkResult] + rol ax, 8 + mov [edx + 20 + TCP_PACKET.Checksum], ax + + ; Fill in the IP header checksum + GET_IHL eax, edx ; get IP-Header length + stdcall checksum_jb, edx, eax ; buf_ptr, buf_size + rol ax, 8 + mov [edx + IP_PACKET.HeaderChecksum], ax + + ret +endp + + +; Increments the 32 bit value pointed to by esi in internet order +proc inc_inet_esi stdcall + push eax + mov eax, [esi] + bswap eax + inc eax + bswap eax + mov [esi], eax + pop eax + ret +endp + + +; Increments the 32 bit value pointed to by esi in internet order +; by the value in ecx +proc add_inet_esi stdcall + push eax + mov eax, [esi] + bswap eax + add eax, ecx + bswap eax + mov [esi], eax + pop eax + ret +endp + + +iglobal + TCBStateHandler dd \ + stateTCB_LISTEN, \ + stateTCB_SYN_SENT, \ + stateTCB_SYN_RECEIVED, \ + stateTCB_ESTABLISHED, \ + stateTCB_FIN_WAIT_1, \ + stateTCB_FIN_WAIT_2, \ + stateTCB_CLOSE_WAIT, \ + stateTCB_CLOSING, \ + stateTCB_LAST_ACK, \ + stateTCB_TIME_WAIT, \ + stateTCB_CLOSED +endg + + +;*************************************************************************** +; Function +; tcpStateMachine +; +; Description +; TCP state machine +; This is a kernel function, called by tcp_rx +; +; IP buffer address given in edx +; Socket/TCB address in ebx +; +; The IP buffer will be released by the caller +;*************************************************************************** + +proc tcpStateMachine stdcall, sockAddr:DWORD + ; as a packet has been received, update the TCB timer + mov [ebx + SOCKET.TCBTimer], TWOMSL + + ; If the received packet has an ACK bit set, + ; remove any packets in the resend queue that this + ; received packet acknowledges + pushad + test [edx + 20 + TCP_PACKET.Flags], TH_ACK + jz .call_handler ; No ACK, so no data yet + + ; get skt number in eax + stdcall net_socket_addr_to_num, ebx + + ; The ack number is in [edx + 28], inet format + ; skt in eax + + mov esi, resendQ + xor ecx, ecx + + .next_resendq: + cmp ecx, NUMRESENDENTRIES + je .call_handler ; None left + cmp [esi + 4], eax + je @f ; found one + inc ecx + add esi, 8 + jmp .next_resendq + + @@: ; Can we delete this buffer? + + ; If yes, goto @@. No, goto .next_resendq + ; Get packet data address + + push ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + imul edi, ecx, IPBUFFSIZE + add edi, resendBuffer + + ; we have dest buffer location in edi. incoming packet in edx. + ; Get this packets sequence number + ; preserve al, ecx, esi, edx + mov ecx, [edi + 20 + TCP_PACKET.SequenceNumber] + bswap ecx + movzx ebx, word[edi + 2] + xchg bl, bh + sub ebx, 40 + add ecx, ebx ; ecx is now seq# of last byte +1, intel format + + ; get recievd ack #, in intel format + mov ebx, [edx + 20 + TCP_PACKET.AckNumber] + bswap ebx + + cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que + ; DANGER! need to handle case that we have just + ; passed the 2**32, and wrapped round! + pop ecx + jae @f ; if rx > old, delete old + + inc ecx + add esi, 8 + jmp .next_resendq + + @@: mov dword[esi + 4], 0 + inc ecx + add esi, 8 + jmp .next_resendq + + .call_handler: + popad + + ; Call handler for given TCB state + + mov eax, [ebx + SOCKET.TCBState] + cmp eax, TCB_LISTEN + jb .exit + cmp eax, TCB_CLOSED + ja .exit + + stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr] + + .exit: + ret +endp + +;*************************************************************************** +; Function +; signal_network_event +; +; Description +; Signals about network event to socket owner +; This is a kernel function, called from TCP handler +; +; Socket/TCB address in ebx +;*************************************************************************** +proc signal_network_event + push ecx esi eax + mov eax, [ebx + SOCKET.PID] + mov ecx, 1 + mov esi, TASK_DATA + TASKDATA.pid + + .next_pid: + cmp [esi], eax + je .found_pid + inc ecx + add esi, 0x20 + cmp ecx, [TASK_COUNT] + jbe .next_pid + + .found_pid: + shl ecx, 8 + or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event + pop eax esi ecx + ret +endp + +proc stateTCB_LISTEN stdcall, sockAddr:DWORD + ; In this case, we are expecting a SYN packet + ; For now, if the packet is a SYN, process it, and send a response + ; If not, ignore it + + ; Look at control flags + test [edx + 20 + TCP_PACKET.Flags], TH_SYN + jz .exit + + ; We have a SYN. update the socket with this IP packets details, + ; And send a response + + mov eax, [edx + IP_PACKET.SourceAddress] + mov [ebx + SOCKET.RemoteIP], eax + mov ax, [edx + 20 + TCP_PACKET.SourcePort] + mov [ebx + SOCKET.RemotePort], ax + mov eax, [edx + 20 + TCP_PACKET.SequenceNumber] + mov [ebx + SOCKET.IRS], eax + mov [ebx + SOCKET.RCV_NXT], eax + lea esi, [ebx + SOCKET.RCV_NXT] + call inc_inet_esi ; RCV.NXT + mov eax, [ebx + SOCKET.ISS] + mov [ebx + SOCKET.SND_NXT], eax + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit + + push ebx + push eax + mov bl, TH_SYN + TH_ACK + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + pop ebx + mov esi, [sockAddr] + mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED + call signal_network_event + + ; increment SND.NXT in socket + add esi, SOCKET.SND_NXT + call inc_inet_esi + + .exit: + ret +endp + + +proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD + ; We are awaiting an ACK to our SYN, with a SYM + ; Look at control flags - expecting an ACK + + mov al, [edx + 20 + TCP_PACKET.Flags] + and al, TH_SYN + TH_ACK + cmp al, TH_SYN + TH_ACK + je .syn_ack + + test al, TH_SYN + jz .exit + + mov [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED + push TH_SYN + TH_ACK + jmp .send + + .syn_ack: + mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED + push TH_ACK + + .send: + call signal_network_event + ; Store the recv.nxt field + mov eax, [edx + 20 + TCP_PACKET.SequenceNumber] + + ; Update our recv.nxt field + mov [ebx + SOCKET.RCV_NXT], eax + lea esi, [ebx + SOCKET.RCV_NXT] + call inc_inet_esi + + ; Send an ACK + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + pop ebx + je .exit + + push eax + + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + .exit: + ret +endp + + +proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD + ; In this case, we are expecting an ACK packet + ; For now, if the packet is an ACK, process it, + ; If not, ignore it + + test [edx + 20 + TCP_PACKET.Flags], TH_RST + jz .check_ack + + push [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP] + pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort] + + mov [ebx + SOCKET.TCBState], TCB_LISTEN + jmp .signal + + .check_ack: + ; Look at control flags - expecting an ACK + test [edx + 20 + TCP_PACKET.Flags], TH_ACK + jz .exit + + mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED + .signal: + call signal_network_event + + .exit: + ret +endp + + +proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD + ; Here we are expecting data, or a request to close + ; OR both... + + ; Ignore all packets with sequnce number other than next expected + + ; recv.nxt is in dword [edx+24], in inet format + ; recv seq is in [sktAddr]+56, in inet format + ; just do a comparision + mov eax, [ebx + SOCKET.RCV_NXT] + cmp eax, [edx + 20 + TCP_PACKET.SequenceNumber] + jne .exit + + ; Did we receive a FIN or RST? + test [edx + 20 + TCP_PACKET.Flags], TH_FIN+TH_RST + jz .check_ack + + ; It was a fin or reset. + + ; Remove resend entries from the queue - I dont want to send any more data + pushad + + ; get skt # + stdcall net_socket_addr_to_num, ebx + + mov esi, resendQ + mov ecx, 0 + + .next_resendq: + cmp ecx, NUMRESENDENTRIES + je .last_resendq ; None left + cmp [esi + 4], eax + je @f ; found one + inc ecx + add esi, 8 + jmp .next_resendq + + @@: mov dword[esi + 4], 0 + inc ecx + add esi, 8 + jmp .next_resendq + + .last_resendq: + popad + + @@: ; Send an ACK to that fin, and enter closewait state + + mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT + test [edx + 20 + TCP_PACKET.Flags], TH_RST + je @f + mov [ebx + SOCKET.TCBState], TCB_CLOSED + @@: + call signal_network_event + lea esi, [ebx + SOCKET.RCV_NXT] + mov eax, [esi] ; save original + call inc_inet_esi + ;; jmp ste_ack - NO, there may be data + + .check_ack: + ; Check that we received an ACK + test [edx + 20 + TCP_PACKET.Flags], TH_ACK + jz .exit + + ; TODO - done, I think! + ; First, look at the incoming window. If this is less than or equal to 1024, + ; Set the socket window timer to 1. This will stop an additional packets being queued. + ; ** I may need to tweak this value, since I do not know how many packets are already queued + mov cx, [edx + 20 + TCP_PACKET.Window] + xchg cl, ch + cmp cx, 1024 + ja @f + + mov [ebx + SOCKET.wndsizeTimer], 1 + + @@: ; OK, here is the deal + + + ; Read the data bytes, store in socket buffer + movzx ecx, [edx + IP_PACKET.TotalLength] + xchg cl, ch + sub ecx, 40 ; Discard 40 bytes of header + ja .data ; Read data, if any + + ; If we had received a fin, we need to ACK it. + cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT + je .ack + jmp .exit + + .data: + push ebx + add ebx, SOCKET.lock + call wait_mutex + pop ebx + + push ecx + push ebx + mov eax, [ebx + SOCKET.rxDataCount] + add eax, ecx + cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE + ja .overflow + + mov [ebx + SOCKET.rxDataCount], eax ; increment the count of bytes in buffer + + ; point to the location to store the data + lea edi, [ebx + eax + SOCKETHEADERSIZE] + sub edi, ecx + + add edx, 40 ; edx now points to the data + mov esi, edx + + cld + rep movsb ; copy the data across + mov [ebx + SOCKET.lock], 0 ; release mutex + + ; flag an event to the application + pop ebx + call signal_network_event + + pop ecx + + ; Update our recv.nxt field + lea esi, [ebx + SOCKET.RCV_NXT] + call add_inet_esi + + .ack: + ; Send an ACK + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit + + push eax + + mov bl, TH_ACK + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + .exit: + ret + .overflow: + ; no place in buffer + ; so simply restore stack and exit + pop eax ecx + mov [ebx + SOCKET.lock], 0 + ret +endp + + +proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD + ; We can either receive an ACK of a fin, or a fin + mov al, [edx + 20 + TCP_PACKET.Flags] + and al, TH_FIN + TH_ACK + + cmp al, TH_ACK + jne @f + + ; It was an ACK + mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2 + jmp .exit + + @@: mov [ebx + SOCKET.TCBState], TCB_CLOSING + cmp al, TH_FIN + je @f + mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT + + @@: lea esi, [ebx + SOCKET.RCV_NXT] + call inc_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit + + push eax + + mov bl, TH_ACK + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + .exit: + ret +endp + + +proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD + test [edx + 20 + TCP_PACKET.Flags], TH_FIN + jz .exit + + ; Change state, as we have a fin + mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT + + lea esi, [ebx + SOCKET.RCV_NXT] + call inc_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit + + push eax + + mov bl, TH_ACK + xor ecx, ecx + xor esi, esi + stdcall build_tcp_packet, [sockAddr] + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [sockAddr] + cmp edx, [ecx + SOCKET.RemoteIP] + jne .not_local + mov eax, IPIN_QUEUE + + .not_local: + ; Send it. + pop ebx + call queue + + .exit: + ret +endp + + +proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD + ; Intentionally left empty + ; socket_close_tcp handles this + ret +endp + + +proc stateTCB_CLOSING stdcall, sockAddr:DWORD + ; We can either receive an ACK of a fin, or a fin + test [edx + 20 + TCP_PACKET.Flags], TH_ACK + jz .exit + + mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT + + .exit: + ret +endp + + +proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD + ; Look at control flags - expecting an ACK + test [edx + 20 + TCP_PACKET.Flags], TH_ACK + jz .exit + + ; delete the socket + stdcall net_socket_free, ebx + + .exit: + ret +endp + + +proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD + ret +endp + + +proc stateTCB_CLOSED stdcall, sockAddr:DWORD + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/network/udp.inc b/kernel/tags/kolibri0.7.7.0/network/udp.inc new file mode 100644 index 000000000..9b99e7225 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/network/udp.inc @@ -0,0 +1,155 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ;; +;; UDP.INC ;; +;; ;; +;; UDP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;******************************************************************* +; Interface +; +; udp_rx Handles received IP packets with the UDP protocol +; +;******************************************************************* + + +; +; UDP Payload ( Data field in IP datagram ) +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Source Port | Destination Port | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Length ( UDP Header + Data ) | Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | UDP Data | +; +-+-+-.......... -+ +; + +struc UDP_PACKET +{ .SourcePort dw ? ;+00 + .DestinationPort dw ? ;+02 + .Length dw ? ;+04 - Length of (UDP Header + Data) + .Checksum dw ? ;+06 + .Data db ? ;+08 +} + +virtual at 0 + UDP_PACKET UDP_PACKET +end virtual + + +;*************************************************************************** +; Function +; udp_rx [by Johnny_B] +; +; Description +; UDP protocol handler +; This is a kernel function, called by ip_rx +; IP buffer address given in edx +; IP buffer number in eax +; Free up (or re-use) IP buffer when finished +; +;*************************************************************************** + +proc udp_rx stdcall + push eax + + ; First validate the header & checksum. Discard buffer if error + + ; Look for a socket where + ; IP Packet UDP Destination Port = local Port + ; IP Packet SA = Remote IP + + mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from + ; the IP packet's UDP header + + mov ebx, net_sockets + + .next_socket: + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .exit ; No match, so exit + cmp [ebx + SOCKET.LocalPort], ax ; ax will hold the 'wrong' value, + ; but the comparision is correct + jne .next_socket ; Return back if no match + + ; For dhcp, we must allow any remote server to respond. + ; I will accept the first incoming response to be the one + ; I bind to, if the socket is opened with a destination IP address of + ; 255.255.255.255 + cmp [ebx + SOCKET.RemoteIP], 0xffffffff + je @f + + mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet + cmp [ebx + SOCKET.RemoteIP], eax + jne .exit ; Quit if the source IP is not valid + + @@: ; OK - we have a valid UDP packet for this socket. + ; First, update the sockets remote port number with the incoming msg + ; - it will have changed + ; from the original ( 69 normally ) to allow further connects + mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port + ; ( was 69, now new ) + mov [ebx + SOCKET.RemotePort], ax + + ; Now, copy data to socket. We have socket address as [eax + sockets]. + ; We have IP packet in edx + + ; get # of bytes in ecx + movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract + xchg cl, ch ; 20 + 8 gives data length + sub ecx, 28 + + mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer + add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer + + ; ecx has count, edx points to data + + add edx, 28 ; edx now points to the data + lea edi, [ebx + eax + SOCKETHEADERSIZE] + mov esi, edx + + cld + rep movsb ; copy the data across + + ; flag an event to the application + mov eax, [ebx + SOCKET.PID] ; get socket owner PID + mov ecx, 1 + mov esi, TASK_DATA + TASKDATA.pid + + .next_pid: + cmp [esi], eax + je .found_pid + inc ecx + add esi, 0x20 + cmp ecx, [TASK_COUNT] + jbe .next_pid + + jmp .exit + + .found_pid: + shl ecx, 8 + or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event + + mov [check_idle_semaphore], 200 + + .exit: + pop eax + call freeBuff ; Discard the packet + ret +endp diff --git a/kernel/tags/kolibri0.7.7.0/proc32.inc b/kernel/tags/kolibri0.7.7.0/proc32.inc new file mode 100644 index 000000000..3f474c02f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/proc32.inc @@ -0,0 +1,271 @@ + +$Revision$ + + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ 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/tags/kolibri0.7.7.0/sec_loader/trunk/boot/PrimaryLoader.txt b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/PrimaryLoader.txt new file mode 100644 index 000000000..510f24309 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/PrimaryLoader.txt @@ -0,0 +1,91 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +Спецификация на первичный загрузчик KordOS. +Загрузчик должен предоставлять следующие сервисы: +1. При загрузке компьютера, получив управление от BIOS'а, загружать + файл loader из папки kord по адресу 1000:0000. + Размер файла loader не превосходит 30000h = 192 Kb. +2. При этом устанавливать следующие регистры: + ax идентифицирует устройство: + al = тип: + 'f' - флопик + 'h' - HDD + 'c' - CD/DVD + 'u' - USB флешка + '?' - неизвестное устройство + ah = номер устройства (среди всех устройств фиксированного типа) + bx = тип файловой системы: + '12' = FAT12 + '16' = FAT16 + '32' = FAT32 + 'nt' = NTFS + 'is' = ISO-9660 + ds:si = far-указатель на callback-сервис +3. Предоставлять callback-сервис для вторичного загрузчика - far-процедуру: + на входе: ax = запрашиваемая функция + на выходе: CF=1, если функция не поддерживается; CF=0 иначе + Загрузчик может разрушать все регистры, включая сегментные, + за исключением ss и sp. +4. Всегда должна поддерживаться callback-функция 1: + назначение: прочитать файл, расположенный на загрузочном устройстве + на входе: ax = 1, ds:di = указатель на информационную структуру: + dw:dw far-указатель на буфер, + первое слово - смещение, второе - сегмент + dw максимальное число 4Kb-блоков для чтения (0x1000 байт) + должно быть ненулевым и строго меньше 0x100 + ASCIIZ имя файла в формате "<папка1>/<папка2>/<файл>" + Если имя файла содержит символы из старшей половины + ASCIIZ-таблицы или не является 8.3-именем (в смысле, одна из компонент + имени файла имеет имя длиннее 8 символов или расширение длиннее 3), + загрузчик может не найти такой файл, даже если он есть + (а может и найти). + на выходе: bx = статус: + 0 = успешно + 1 = файл оказался слишком большим, буфер заполнен целиком + и есть ещё данные файла + 2 = файл не найден + 3 = произошла ошибка чтения + dx:ax = размер файла или FFFF:FFFF, если файл не найден +5. Всегда должна поддерживаться callback-функция 2: + назначение: продолжить чтение файла, частично загруженного функцией 1 + на входе: ax = 2, ds:di = указатель на информационную структуру: + dw:dw far-указатель на буфер, + первое слово - смещение, второе - сегмент + dw максимальное число 4Kb-блоков для чтения (0x1000 байт) + должно быть ненулевым и строго меньше 0x100 + на выходе: bx = статус: + 0 = успешно + 1 = файл оказался слишком большим, буфер заполнен целиком + и есть ещё данные файла + 3 = произошла ошибка чтения + dx:ax = размер файла + Функцию можно вызывать только в случае, когда последний вызов функции + 1 и все последующие вызовы функции 2 вернули bx=1 (иными словами, + только для продолжения загрузки файла, который уже был частично + загружен, но ещё не загружен полностью). +Загрузчик может быть уверен, что данные в областях памяти 0-9000 и + 60000-A0000 не будут модифицированы ядром. diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/build.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/build.bat new file mode 100644 index 000000000..5419e0d68 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/build.bat @@ -0,0 +1,2 @@ +@fasm -m 65535 kordldr.win.asm kordldr.win +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/fat.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/fat.inc new file mode 100644 index 000000000..66130eabd --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/fat.inc @@ -0,0 +1,509 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; in: ss:bp = 0:dat +; in: es:bx = address to load file +; in: ds:si -> ASCIIZ name +; in: cx = limit in sectors +; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found +; out: dx:ax = file size (0xFFFFFFFF if file not found) +load_file_fat: + mov eax, [bp + root_clus - dat] + mov [bp + cur_obj - dat], root_string + push es + push bx + push cx +.parse_dir_loop: +; convert name to FAT name + push [bp + cur_obj - dat] + push ax + mov [bp + cur_obj - dat], si + push ss + pop es +; convert ASCIIZ filename to FAT name + mov di, fat_filename + push di + mov cx, 8+3 + mov al, ' ' + rep stosb + pop di + mov cl, 8 ; 8 symbols per name + mov bl, 1 +.nameloop: + lodsb + test al, al + jz .namedone + cmp al, '/' + jz .namedone + cmp al, '.' + jz .namedot + dec cx + js .badname + cmp al, 'a' + jb @f + cmp al, 'z' + ja @f + sub al, 'a'-'A' +@@: + stosb + jmp .nameloop +.namedot: + inc bx + jp .badname + add di, cx + mov cl, 3 + jmp .nameloop +.badname: + mov si, badname_msg + jmp find_error_si +.namedone: +; scan directory + pop ax ; eax = cluster of directory + ; high word of eax is preserved by operations above + push ds + push si +; read a folder sector-by-sector and scan +; first, try to use the cache + push ss + pop ds + mov bx, -2 + mov cx, [bp + rootcache_size - dat] + cmp [bp + root_clus - dat], eax + jz .lookcache_root + mov di, foldcache_mark + xor bx, bx + mov cx, [bp + cachelimit - dat] +@@: + lea si, [di+bx] + mov edx, dword [foldcache_clus+si-foldcache_mark+bx] + cmp edx, eax + jz .cacheok + test edx, edx + jz .cacheadd ; the cache has place for new entry + inc bx + inc bx + dec cx + js @b +; the folder is not present in the cache, so add it +; the cache is full; find the oldest entry and replace it with the new one + mov bx, -2 + mov dx, [bp + cachelimit - dat] +@@: + inc bx + inc bx + cmp word [di+bx], dx ; marks have values 0 through [cachelimit] + jnz @b +.cacheadd: + or word [di+bx], 0xFFFF ; very big value, it will be changed soon + and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet + lea si, [di+bx] + mov dword [foldcache_clus+si-foldcache_mark+bx], eax +.cacheok: +; update cache marks + mov dx, [di+bx] + mov cx, [foldcache_size+di-foldcache_mark+bx] + mov di, [bp + cachelimit - dat] + add di, di +.cacheupdate: + cmp [foldcache_mark+di], dx + adc [foldcache_mark+di], 0 + dec di + dec di + jns .cacheupdate + and [foldcache_mark+bx], 0 +; done, bx contains (position in cache)*2 +.lookcache_root: +; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder + ;mov dx, bx + ;shl dx, 8 + ;add dx, 0x9200 + lea dx, [bx + 0x92] + xchg dl, dh + mov ds, dx + mov si, fat_filename ; ss:si -> filename in FAT style + call fat_scan_for_filename + jz .lookup_done +; cache miss, read folder data from disk +; we are reading parent directory, it can result in disk read errors; restore [cur_obj] + mov di, sp + mov bx, [bp + cur_obj - dat] + xchg bx, [ss:di+4] + mov [bp + cur_obj - dat], bx + mov bx, cx + add bx, 0xF + shr bx, 4 + shl cx, 5 + mov di, cx ; es:di -> free space in cache entry +; external loop: scan clusters +.folder_next_cluster: +; internal loop: scan sectors in cluster + movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus + push eax +; FAT12/16 root - special handling + test eax, eax + jnz .folder_notroot + mov cx, [ss:0x3211] ; BPB_RootEntCnt + mov dx, cx + add cx, 0xF + rcr cx, 1 + shr cx, 3 + mov eax, [bp + root_start - dat] + jmp .folder_next_sector +.folder_notroot: + mul ecx + add eax, [bp + data_start - dat] +.folder_next_sector: + sub dx, 0x10 +; skip first bx sectors + dec bx + jns .folder_skip_sector + push cx + push es di + push 0x8000 + pop es + xor bx, bx + mov cx, 1 + push es + call read + jc ..found_disk_error +; copy data to the cache... + pop ds + pop di es + cmp di, 0x2000 ; ...if there is free space, of course + jae @f + pusha + mov cx, 0x100 + xor si, si + rep movsw + mov di, es + shr di, 8 + cmp di, 0x90 + jz .update_rootcache_size + add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache + jmp .updated_cachesize +.update_rootcache_size: + mov cl, 0x10 + cmp cx, dx + jb @f + mov cx, dx +@@: + add [bp + rootcache_size - dat], cx +.updated_cachesize: + popa +@@: + push es + mov cl, 0x10 ; ch=0 at this point + cmp cx, dx + jb @f + mov cx, dx +@@: + call fat_scan_for_filename + pop es + pop cx + jz .lookup_done_pop +.folder_skip_sector: + inc eax + loop .folder_next_sector + pop eax ; eax = current cluster + test eax, eax + jz @f + call [bp + get_next_cluster_ptr - dat] + jc .folder_next_cluster +@@: + stc + push eax +.lookup_done_pop: + pop eax +.lookup_done: + pop si +; CF=1 <=> failed + jnc .found + pop ds + pop [bp + cur_obj - dat] + mov si, error_not_found + jmp find_error_si +.found: + mov eax, [di+20-2] + mov edx, [di+28] + mov ax, [di+26] ; get cluster + test byte [di+11], 10h ; directory? + pop ds + pop [bp + cur_obj - dat] ; forget old [cur_obj] + jz .regular_file + cmp byte [si-1], 0 + jnz .parse_dir_loop +..directory_error: + mov si, directory_string + jmp find_error_si +.regular_file: + cmp byte [si-1], 0 + jz @f +..notdir_error: + mov si, notdir_string + jmp find_error_si +@@: +; ok, we have found a regular file and the caller requested it +; parse FAT chunk + push ss + pop es + push ss + pop ds + mov di, 0x4005 + mov byte [di-5], 1 ; non-resident attribute + mov dword [di-4], 1 + stosd + pop cx + push cx +.parsefat: + call [bp + get_next_cluster_ptr - dat] + jnc .done + mov esi, [di-8] + add esi, [di-4] + cmp eax, esi + jz .contc + mov dword [di], 1 + scasd + stosd + jmp @f +.contc: + inc dword [di-8] +@@: + sub cl, [0x320D] + sbb ch, 0 + ja .parsefat +.done: + xor eax, eax + stosd + mov si, 0x4000 +load_file_common_end: + xor ecx, ecx + pop cx + pop bx + pop es + mov [bp + filesize - dat], edx + mov [bp + sectors_read - dat], ecx + add edx, 0x1FF + shr edx, 9 + mov [bp + filesize_sectors - dat], edx + cmp edx, ecx + seta al + mov ah, 0 + push ax + call read_file_chunk +continue_load_common_end: + mov [bp + cur_chunk_ptr - dat], si + pop bx + mov ax, word [bp + filesize - dat] + mov dx, word [bp + filesize+2 - dat] + jnc @f + mov bl, 3 ; read error +@@: + ret + +continue_load_file: +; es:bx -> buffer for output, ecx = cx = number of sectors + mov si, [bp + cur_chunk_ptr - dat] + push ecx + add ecx, [bp + sectors_read - dat] + mov [bp + sectors_read - dat], ecx + cmp [bp + filesize_sectors - dat], ecx + pop ecx + seta al + mov ah, 0 + push ax + push continue_load_common_end + push ss + pop ds + cmp [bp + cur_chunk_resident - dat], ah + jnz .nonresident +.resident: + mov ax, word [bp + num_sectors - dat] + jmp read_file_chunk.resident.continue +.nonresident: + mov eax, [bp + cur_cluster - dat] + mov edx, [bp + num_sectors - dat] + add eax, [bp + cur_delta - dat] + jmp read_file_chunk.nonresident.continue + +fat_scan_for_filename: +; in: ss:si -> 11-bytes FAT name +; in: ds:0 -> part of directory data +; in: cx = number of entries +; out: if found: CF=0, ZF=1, es:di -> directory entry +; out: if not found, but continue required: CF=1 and ZF=0 +; out: if not found and zero item reached: CF=1 and ZF=1 + push ds + pop es + xor di, di + push cx + jcxz .noent +.loop: + cmp byte [di], 0 + jz .notfound + test byte [di+11], 8 ; volume label? + jnz .cont ; ignore volume labels + pusha + mov cx, 11 + repz cmps byte [ss:si], byte [es:di] + popa + jz .done +.cont: + add di, 0x20 + loop .loop +.noent: + inc cx ; clear ZF flag +.notfound: + stc +.done: + pop cx + ret + +fat12_get_next_cluster: +; in: ax = cluster (high word of eax is zero) +; out: if there is next cluster: CF=1, ax = next cluster +; out: if there is no next cluster: CF=0 + push si + push ds + push 0x6000 + pop ds + mov si, ax + shr si, 1 + add si, ax + test al, 1 + lodsw + jz @f + shr ax, 4 +@@: + and ax, 0xFFF + cmp ax, 0xFF7 + pop ds si + ret + +fat16_get_next_cluster: +; in: ax = cluster (high word of eax is zero) +; out: if there is next cluster: CF=1, ax = next cluster +; out: if there is no next cluster: CF=0 +; each sector contains 200h bytes = 100h FAT entries +; so ah = # of sector, al = offset in sector + push si + mov si, ax + shr si, 8 +; calculate segment for this sector of FAT table +; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) +; segment = 6000 + 20*si, offset = 0 + push es + push si + shl si, 5 + add si, 0x6000 + mov es, si + pop si + cmp byte [ss:0x3400+si], 0 ; sector already loaded? + jnz .noread +; load corresponding sector, try all FATs if disk read error detected + pusha + movzx di, byte [ss:0x3210] ; BPB_NumFATs + xor bx, bx + mov ax, [ss:0x320E] ; BPB_RsvdSecCnt + xor dx, dx + add ax, si + adc dx, bx +@@: + push es + push dx ax + pop eax + mov cx, 1 ; read 1 sector + call read + pop es + jnc @f + add ax, [ss:0x3216] ; BPB_FATSz16 + adc dx, bx + dec di + jnz @b +..found_disk_error: + mov si, disk_error_msg + jmp find_error_si +@@: + popa +.noread: + mov si, ax + and si, 0xFF + add si, si + mov ax, [es:si] + pop es + cmp ax, 0xFFF7 + pop si + ret + +fat32_get_next_cluster: +; in: eax = cluster +; out: if there is next cluster: CF=1, eax = next cluster +; out: if there is no next cluster: CF=0 + push di + push ax + shr eax, 7 +; eax = FAT sector number; look in cache + push si + mov si, cache1head + call cache_lookup + pop si + jnc .noread +; read FAT, try all FATs if disk read error detected + push es + pushad + movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt + add eax, edx + movzx si, byte [ss:0x3210] ; BPB_NumFATs +@@: + lea cx, [di - 0x3400 + (0x6000 shr (9-3))] + shl cx, 9-3 + mov es, cx + xor bx, bx + mov cx, 1 + call read + jnc @f + add eax, [ss:0x3224] ; BPB_FATSz32 + dec si + jnz @b + jmp ..found_disk_error +@@: + popad + pop es +.noread: +; get requested item + lea ax, [di - 0x3400 + (0x6000 shr (9-3))] + pop di + and di, 0x7F + shl di, 2 + shl ax, 9-3 + push ds + mov ds, ax + and byte [di+3], 0x0F + mov eax, [di] + pop ds + pop di + ;and eax, 0x0FFFFFFF + cmp eax, 0x0FFFFFF7 + ret diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.asm new file mode 100644 index 000000000..5080bf080 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.asm @@ -0,0 +1,921 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond +; It is used when main bootloader is Windows loader. + +; this code is loaded: +; NT/2k/XP: by ntldr to 0D00:0000 +; 9x: by io.sys from config.sys to xxxx:0100 +; Vista: by bootmgr to 0000:7C00 + format binary + use16 + +; in any case, we relocate this code to 0000:0600 + org 0x600 +; entry point for 9x and Vista booting + call @f + db 'NTFS' +@@: + pop si + sub si, 3 + cmp si, 100h + jnz boot_vista + mov si, load_question + 100h - 600h + call out_string +; mov si, answer + 100h - 0600h ; already is +xxy: mov ah, 0 + int 16h + or al, 20h + mov [si], al + cmp al, 'y' + jz xxz + cmp al, 'n' + jnz xxy +; continue load Windows +; call out_string +; ret +out_string: + push bx +@@: + lodsb + test al, al + jz @f + mov ah, 0Eh + mov bx, 7 + int 10h + jmp @b +@@: + pop bx + ret +xxz: +; boot KordOS + call out_string +; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers, +; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached + xor di, di + mov ds, di + mov word [di+4], new01handler + 100h - 600h + mov [di+6], cs + pushf + pop ax + or ah, 1 + push ax + popf +; we cannot issue INT 19h directly, because INT command clears TF +; int 19h ; don't issue it directly, because INT command clears TF +; so instead we use direct call +; pushf ; there will be no IRET + call far [di + 19h*4] +xxt: + xor di, di + mov ds, di + cmp word [di + 8*4+2], 0F000h + jz @f + les bx, [di + 8*4] + mov eax, [es:bx+1] + mov [di + 8*4], eax +@@: + mov si, 100h +boot_vista: +; relocate cs:si -> 0000:0600 + push cs + pop ds + xor ax, ax + mov es, ax + mov di, 0x600 + mov cx, 2000h/2 + rep movsw + jmp 0:real_entry + +load_question db 'Load KordOS? [y/n]: ',0 +answer db ? + db 13,10,0 + +new01handler: +; [sp]=ip, [sp+2]=cs, [sp+4]=flags + push bp + mov bp, sp + push ds + lds bp, [bp+2] + cmp word [ds:bp], 19cdh + jz xxt + pop ds + pop bp + iret + +; read from hard disk +; in: eax = absolute sector +; cx = number of sectors +; es:bx -> buffer +; out: CF=1 if error +read: + pushad + add eax, [bp + partition_start - dat] + cmp [bp + use_lba - dat], 0 + jz .chs +; LBA read + push ds +.lbado: + push ax + push cx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F +@@: +; create disk address packet on the stack +; dq starting LBA + push 0 + push 0 + push eax +; dd buffer + push es + push bx +; dw number of blocks to transfer (no more than 0x7F) + push cx +; dw packet size in bytes + push 10h +; issue BIOS call + push ss + pop ds + mov si, sp + mov dl, [bp + boot_drive - dat] + mov ah, 42h + int 13h + jc .disk_error_lba + add sp, 10h ; restore stack +; increase current sector & buffer; decrease number of sectors + movzx esi, cx + mov ax, es + shl cx, 5 + add ax, cx + mov es, ax + pop cx + pop ax + add eax, esi + sub cx, si + jnz .lbado + pop ds + popad + ret +.disk_error_lba: + add sp, 14h + pop ds + popad + stc + ret + +.chs: + pusha + pop edi ; loword(edi) = di, hiword(edi) = si + push bx + +; eax / (SectorsPerTrack) -> eax, remainder bx + movzx esi, [bp + sectors - dat] + xor edx, edx + div esi + mov bx, dx ; bx = sector-1 + +; eax -> dx:ax + push eax + pop ax + pop dx +; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx + div [bp + heads - dat] + +; number of sectors: read no more than to end of track + sub si, bx + cmp cx, si + jbe @f + mov cx, si +@@: + + inc bx +; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector +; convert to int13 format + movzx edi, cx + mov dh, dl + mov dl, [bp + boot_drive - dat] + shl ah, 6 + mov ch, al + mov al, cl + mov cl, bl + or cl, ah + pop bx + mov si, 3 + mov ah, 2 +@@: + push ax + int 13h + jnc @f + xor ax, ax + int 13h ; reset drive + pop ax + dec si + jnz @b + add sp, 12 + popad + stc + ret +@@: + pop ax + mov ax, es + mov cx, di + shl cx, 5 + add ax, cx + mov es, ax + push edi + popa + add eax, edi + sub cx, di + jnz .chs + popad + ret + +disk_error2 db 'Fatal: cannot read partitions info: ' +disk_error_msg db 'disk read error',0 +disk_params_msg db 'Fatal: cannot get drive parameters',0 +start_msg db 2,' KordOS bootloader',13,10,0 +part_msg db 'looking at partition ' +part_char db '0' ; will be incremented before writing message + db ' ... ',0 +errfs_msg db 'unknown filesystem',13,10,0 +fatxx_msg db 'FATxx' +newline db 13,10,0 +ntfs_msg db 'NTFS',13,10,0 +error_msg db 'Error' +colon db ': ',0 +root_string db '\',0 +nomem_msg db 'No memory',0 +filesys_string db '(filesystem)',0 +directory_string db 'is a directory',0 +notdir_string db 'not a directory',0 + +; entry point for NT/2k/XP booting +; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256 + repeat 600h + 256h - $ + db 1 ; any data can be here; 1 in ASCII is a nice face :) + end repeat +; cs=es=0D00, ds=07C0, ss=0 +; esi=edi=ebp=0, esp=7C00 + xor si, si + jmp boot_vista + +real_entry: +; ax = 0 + mov ds, ax + mov es, ax +; our stack is 4 Kb: memory range 2000-3000 + mov ss, ax + mov sp, 3000h + mov bp, dat + sti ; just for case +; say hi to user + mov si, start_msg + call out_string +; we are booting from hard disk identified by [boot_drive] + mov dl, [bp + boot_drive - dat] +; is LBA supported? + mov [bp + use_lba - dat], 0 + mov ah, 41h + mov bx, 55AAh + int 13h + jc .no_lba + cmp bx, 0AA55h + jnz .no_lba + test cl, 1 + jz .no_lba + inc [bp + use_lba - dat] + jmp disk_params_ok +.no_lba: +; get drive geometry + mov ah, 8 + mov dl, [bp + boot_drive - dat] + int 13h + jnc @f + mov si, disk_params_msg + call out_string + jmp $ +@@: + movzx ax, dh + inc ax + mov [bp + heads - dat], ax + and cx, 3Fh + mov [bp + sectors - dat], cx +disk_params_ok: +; determine size of cache for folders + int 12h ; ax = size of available base memory in Kb + sub ax, 94000h / 1024 + jc nomem + shr ax, 3 + mov [bp + cachelimit - dat], ax ; size of cache - 1 +; scan all partitions +new_partition_ex: + xor eax, eax ; read first sector of current disk area + mov [bp + extended_part_cur - dat], eax ; no extended partition yet + mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition + push es + mov cx, 1 + mov bx, 3000h + call read + pop es + jnc new_partition + mov si, disk_error2 + call out_string + jmp $ +new_partition: + mov bx, [bp + cur_partition_ofs - dat] + mov al, [bx+4] ; partition type + test al, al + jz next_partition + cmp al, 5 + jz @f + cmp al, 0xF + jnz not_extended +@@: +; extended partition + mov eax, [bx+8] ; partition start + add eax, [bp + extended_part_start - dat] + mov [bp + extended_part_cur - dat], eax +next_partition: + add [bp + cur_partition_ofs - dat], 10h + cmp [bp + cur_partition_ofs - dat], 31FEh + jb new_partition + mov eax, [bp + extended_part_cur - dat] + test eax, eax + jz partitions_done + cmp [bp + extended_part_start - dat], 0 + jnz @f + mov [bp + extended_part_start - dat], eax +@@: + mov [bp + extended_parent - dat], eax + mov [bp + partition_start - dat], eax + jmp new_partition_ex +partitions_done: + mov si, total_kaput + call out_string + jmp $ +not_extended: + mov eax, [bx+8] + add eax, [bp + extended_parent - dat] + mov [bp + partition_start - dat], eax +; try to load from current partition +; inform user + mov si, part_msg + inc [si + part_char - part_msg] + call out_string +; read bootsector + xor eax, eax + mov [bp + cur_obj - dat], filesys_string + push es + mov cx, 1 + mov bx, 3200h + call read + pop es + mov si, disk_error_msg + jc find_error_si + movzx si, byte [bx+13] + mov word [bp + sect_per_clust - dat], si + test si, si + jz unknown_fs + lea ax, [si-1] + test si, ax + jnz unknown_fs +; determine file system +; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h) + cmp word [bx+11], 0x200 + jnz unknown_fs +; is it NTFS? + cmp dword [bx+3], 'NTFS' + jnz not_ntfs + cmp byte [bx+16], bl + jz ntfs +not_ntfs: +; is it FAT? FAT12/FAT16/FAT32? +; get count of sectors to dword in cx:si + mov si, [bx+19] + xor cx, cx + test si, si + jnz @f + mov si, [bx+32] + mov cx, [bx+34] +@@: + xor eax, eax +; subtract size of system area + sub si, [bx+14] ; BPB_ResvdSecCnt + sbb cx, ax + mov ax, [bx+17] ; BPB_RootEntCnt + add ax, 0xF + rcr ax, 1 + shr ax, 3 + sub si, ax + sbb cx, 0 + push cx + push si + mov ax, word [bx+22] + test ax, ax + jnz @f + mov eax, [bx+36] +@@: + movzx ecx, byte [bx+16] + imul ecx, eax + pop eax + sub eax, ecx +; now eax = count of sectors in the data region + xor edx, edx + div [bp + sect_per_clust - dat] +; now eax = count of clusters in the data region + mov si, fatxx_msg + cmp eax, 0xFFF5 + jae test_fat32 +; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38 + cmp byte [bx+38], 0x29 + jnz not_fat + cmp ax, 0xFF5 + jae fat16 +fat12: + mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster + mov di, cx ; BPB_NumFATs + mov ax, '12' + push ax ; save for secondary loader + mov word [si+3], ax + call out_string + movzx ecx, word [bx+22] ; BPB_FATSz16 +; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes) +.fatloop: +; if first copy is not readable, try to switch to other copies + push 0x6000 + pop es + xor bx, bx + movzx eax, word [0x320E] ; BPB_RsvdSecCnt + push cx + cmp cx, 12 + jb @f + mov cx, 12 +@@: + call read + pop cx + jnc fat1x_common + add eax, ecx ; switch to next copy of FAT + dec di + jnz .fatloop + mov si, disk_error_msg + jmp find_error_si +fat16: + mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster + mov ax, '16' + push ax ; save for secondary loader + mov word [si+3], ax + call out_string +; FAT16: init FAT cache - no sectors loaded + mov di, 0x3400 + xor ax, ax + mov cx, 0x100/2 + rep stosw +fat1x_common: + mov bx, 0x3200 + movzx eax, word [bx+22] ; BPB_FATSz16 + xor esi, esi ; no root cluster + jmp fat_common +test_fat32: +; FAT32 bootsector has it at the offset +66 + cmp byte [bx+66], 0x29 + jnz not_fat + mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster + mov ax, '32' + push ax ; save for secondary loader + mov word [si+3], ax + call out_string +; FAT32 - init cache for FAT table: no sectors loaded + lea si, [bp + cache1head - dat] + mov [si], si ; no sectors in cache: + mov [si+2], si ; 'prev' & 'next' links point to self + mov [bp + cache1end - dat], 3400h ; first free item = 3400h + mov [bp + cache1limit - dat], 3C00h + mov eax, [bx+36] ; BPB_FATSz32 + mov esi, [bx+44] ; BPB_RootClus + jmp fat_common +not_fat: +unknown_fs: + mov si, errfs_msg + call out_string + jmp next_partition +fat_common: + push ss + pop es + movzx edx, byte [bx+16] ; BPB_NumFATs + mul edx + mov [bp + root_start - dat], eax ; this is for FAT1x +; eax = total size of all FAT tables, in sectors + movzx ecx, word [bx+17] ; BPB_RootEntCnt + add ecx, 0xF + shr ecx, 4 + add eax, ecx + mov cx, word [bx+14] ; BPB_RsvdSecCnt + add [bp + root_start - dat], ecx ; this is for FAT1x + add eax, ecx +; cluster 2 begins from sector eax + movzx ebx, byte [bx+13] ; BPB_SecPerClus + sub eax, ebx + sub eax, ebx + mov [bp + data_start - dat], eax +; no clusters in folders cache + mov di, foldcache_clus - 2 + xor ax, ax + mov cx, 7*8/2 + 1 + rep stosw + mov [bp + root_clus - dat], esi +; load secondary loader + mov [bp + load_file_ptr - dat], load_file_fat +load_secondary: + push 0x1000 + pop es + xor bx, bx + mov si, kernel_name + mov cx, 0x30000 / 0x200 + call [bp + load_file_ptr - dat] +; say error if needed + mov si, error_too_big + dec bx + js @f + jz find_error_si + mov si, disk_error_msg + jmp find_error_si +@@: +; fill loader information and jump to secondary loader + mov al, 'h' ; boot device: hard drive + mov ah, [bp + boot_drive - dat] + sub ah, 80h ; boot device: identifier + pop bx ; restore file system ID ('12'/'16'/'32'/'nt') + mov si, callback + jmp 1000h:0000h + +nomem: + mov si, nomem_msg + call out_string + jmp $ + +ntfs: + push 'nt' ; save for secondary loader + mov si, ntfs_msg + call out_string + xor eax, eax + mov [bp + data_start - dat], eax + mov ecx, [bx+40h] ; frs_size + cmp cl, al + jg .1 + neg cl + inc ax + shl eax, cl + jmp .2 +.1: + mov eax, ecx + shl eax, 9 +.2: + mov [bp + frs_size - dat], ax +; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different +; (at least with standard tools) +; we allow extra size, but no more than 0x1000 bytes = 4 Kb + mov si, invalid_volume_msg + cmp eax, 0x1000 + ja find_error_si +; must be multiple of sector size + test ax, 0x1FF + jnz find_error_si + shr ax, 9 + xchg cx, ax +; initialize cache - no data loaded + lea si, [bp + cache1head - dat] + mov [si], si + mov [si+2], si + mov word [si+4], 3400h ; first free item = 3400h + mov word [si+6], 3400h + 8*8 ; 8 items in this cache +; read first MFT record - description of MFT itself + mov [bp + cur_obj - dat], mft_string + mov eax, [bx+30h] ; mft_cluster + mul [bp + sect_per_clust - dat] + push 0x8000 + pop es + xor bx, bx + push es + call read + pop ds + call restore_usa +; scan for unnamed $DATA attribute + mov [bp + freeattr - dat], 4000h + mov ax, 80h + call load_attr + push ss + pop ds + mov si, nodata_string + jc find_error_si +; load secondary loader + mov [bp + load_file_ptr - dat], load_file_ntfs + jmp load_secondary + +find_error_si: + push si +find_error_sp: + cmp [bp + in_callback - dat], 0 + jnz error_in_callback + push ss + pop ds + push ss + pop es + mov si, error_msg + call out_string + mov si, [bp + cur_obj - dat] +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jz @f + mov ah, 0Eh + mov bx, 7 + int 10h + jmp @b +@@: + mov si, colon + call out_string + pop si + call out_string + mov si, newline + call out_string + mov sp, 0x3000 + jmp next_partition +error_in_callback: +; return status: file not found, except for read errors + mov bx, 2 + cmp si, disk_error_msg + jnz @f + inc bx +@@: + mov ax, 0xFFFF + mov dx, ax + mov sp, 3000h - 6 + ret + +callback: +; in: ax = function number; only functions 1 and 2 are defined for now +; save caller's stack + mov dx, ss + mov cx, sp +; set our stack (required because we need ss=0) + xor si, si + mov ss, si + mov sp, 3000h + mov bp, dat + mov [bp + in_callback - dat], 1 + push dx + push cx +; set ds:si -> ASCIIZ name + lea si, [di+6] +; set cx = limit in sectors; 4Kb = 8 sectors + movzx ecx, word [di+4] + shl cx, 3 +; set es:bx = pointer to buffer + les bx, [di] +; call our function + stc ; unsupported function + dec ax + jz callback_readfile + dec ax + jnz callback_ret + call continue_load_file + jmp callback_ret_succ +callback_readfile: +; function 1: read file +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error +; out: dx:ax = file size (0xFFFFFFFF if file was not found) + call [bp + load_file_ptr - dat] +callback_ret_succ: + clc +callback_ret: +; restore caller's stack + pop cx + pop ss + mov sp, cx +; return to caller + retf + +read_file_chunk.resident: +; auxiliary label for read_file_chunk procedure + mov di, bx + lodsw +read_file_chunk.resident.continue: + mov dx, ax + add dx, 0x1FF + shr dx, 9 + cmp dx, cx + jbe @f + mov ax, cx + shl ax, 9 +@@: + xchg ax, cx + rep movsb + xchg ax, cx + clc ; no disk error if no disk requests + mov word [bp + num_sectors - dat], ax + ret + +read_file_chunk: +; in: ds:si -> file chunk +; in: es:bx -> buffer for output +; in: ecx = maximum number of sectors to read (high word must be 0) +; out: CF=1 <=> disk read error + lodsb + mov [bp + cur_chunk_resident - dat], al + test al, al + jz .resident +; normal case: load (non-resident) attribute from disk +.read_block: + lodsd + xchg eax, edx + test edx, edx + jz .ret + lodsd +; eax = start cluster, edx = number of clusters, cx = limit in sectors + imul eax, [bp + sect_per_clust - dat] + add eax, [bp + data_start - dat] + mov [bp + cur_cluster - dat], eax + imul edx, [bp + sect_per_clust - dat] + mov [bp + num_sectors - dat], edx + and [bp + cur_delta - dat], 0 +.nonresident.continue: + cmp edx, ecx + jb @f + mov edx, ecx +@@: + test dx, dx + jz .read_block + add [bp + cur_delta - dat], edx + sub [bp + num_sectors - dat], edx + sub ecx, edx + push cx + mov cx, dx + call read + pop cx + jc .ret + test cx, cx + jnz .read_block +.ret: + ret + +cache_lookup: +; in: eax = value to look, si = pointer to cache structure +; out: di->cache entry; CF=1 <=> the value was not found + push ds bx + push ss + pop ds + mov di, [si+2] +.look: + cmp di, si + jz .not_in_cache + cmp eax, [di+4] + jz .in_cache + mov di, [di+2] + jmp .look +.not_in_cache: +; cache miss +; cache is full? + mov di, [si+4] + cmp di, [si+6] + jnz .cache_not_full +; yes, delete the oldest entry + mov di, [si] + mov bx, [di] + mov [si], bx + push word [di+2] + pop word [bx+2] + jmp .cache_append +.cache_not_full: +; no, allocate new item + add word [si+4], 8 +.cache_append: + mov [di+4], eax + stc + jmp @f +.in_cache: +; delete this sector from the list + push si + mov si, [di] + mov bx, [di+2] + mov [si+2], bx + mov [bx], si + pop si +@@: +; add new sector to the end of list + mov bx, di + xchg bx, [si+2] + push word [bx] + pop word [di] + mov [bx], di + mov [di+2], bx + pop bx ds + ret + +include 'fat.inc' +include 'ntfs.inc' + +total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0 +error_too_big db 'file is too big',0 +nodata_string db '$DATA ' +error_not_found db 'not found',0 +noindex_string db '$INDEX_ROOT not found',0 +badname_msg db 'bad name for FAT',0 +invalid_volume_msg db 'invalid volume',0 +mft_string db '$MFT',0 +fragmented_string db 'too fragmented file',0 +invalid_read_request_string db 'cannot read attribute',0 + +kernel_name db 'kord/loader',0 + +align 4 +dat: + +extended_part_start dd 0 ; start sector for main extended partition +extended_part_cur dd ? ; start sector for current extended child +extended_parent dd 0 ; start sector for current extended parent +partition_start dd 0 ; start sector for current logical disk +cur_partition_ofs dw ? ; offset in MBR data for current partition +sect_per_clust dd 0 +; change this variable if you want to boot from other physical drive +boot_drive db 80h +in_callback db 0 + +; uninitialized data +use_lba db ? +cur_chunk_resident db ? +align 2 +heads dw ? +sectors dw ? +cache1head rw 2 +cache1end dw ? +cache1limit dw ? +data_start dd ? +cachelimit dw ? +load_file_ptr dw ? +cur_obj dw ? +missing_slash dw ? +root_clus dd ? +root_start dd ? +get_next_cluster_ptr dw ? +frs_size dw ? +freeattr dw ? +index_root dw ? +index_alloc dw ? +cur_index_seg dw ? +cur_index_cache dw ? +filesize dd ? +filesize_sectors dd ? +cur_cluster dd ? +cur_delta dd ? +num_sectors dd ? +sectors_read dd ? +cur_chunk_ptr dw ? + +rootcache_size dw ? ; must be immediately before foldcache_clus +if $-dat >= 0x80 +warning: unoptimal data displacement! +end if +foldcache_clus rd 7 +foldcache_mark rw 7 +foldcache_size rw 7 +fat_filename rb 11 + +if $ > 2000h +error: file is too big +end if + +; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long +repeat 0x2600 - $ + db 2 ; any data can be here; 2 is another nice face in ASCII :) +end repeat diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.txt b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.txt new file mode 100644 index 000000000..703c5a447 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/kordldr.win.txt @@ -0,0 +1,391 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + Нет повести печальнее на свете, + Чем повесть о заклинившем Reset'е... + +Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает +Windows, для носителей с размером сектора 512 байт. + +===================================================================== + +Требования для работы: +1) Все используемые файлы должны быть читабельны. +2) Минимальный процессор - 80386. +3) В системе должно быть как минимум 592K свободной базовой памяти. +4) Пути к используемым файлам не должны содержать символических ссылок NTFS + (жёсткие ссылки допускаются). +5) Используемые файлы не должны быть сжатыми или разреженными файлами + (актуально для NTFS, для FAT выполнено автоматически). + +===================================================================== + +Документация в тему (ссылки проверялись на валидность 08.08.2008): + официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf + русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip + спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys + и file://C:/ntldr либо file://C:/bootmgr + неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 + официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf + то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf + описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html + официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf + официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx + официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx + формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx + +===================================================================== + +Схема используемой памяти: + 600-2000 код загрузчика (и данные) + 2000-3000 стек + 3000-3200 сектор MBR + 3200-3400 бутсектор логического диска + 3400-3C00 информация о кэше для таблиц FAT16/FAT32: + для FAT16 - массив на 0x100 байт, каждый байт равен + 0 или 1 в зависимости от того, загружен ли + соответствующий сектор таблицы FAT16; + для FAT32 - 100h входов по 8 байт: 4 байта + (две ссылки - вперёд и назад) для организации L2-списка + всех прочитанных секторов в порядке возрастания + последнего времени использования + 4 байта для номера + сектора; при переполнении кэша выкидывается элемент из + головы списка, то есть тот, к которому дольше всех + не было обращений + 3400-3440 информация о кэше для файловых записей NTFS в + таком же формате, как и кэш для FAT32, но на 8 входов + 3480-34C0 заголовки для кэшей записей индекса NTFS + 3500-3D00 информация о кэшах записей индекса NTFS: с каждой + файловой записью связан свой кэш для + соответствующего индекса + 4000-8000 место для информации об атрибутах для NTFS + 60000-80000 таблица FAT12 / место под таблицу FAT16 / + кэш для таблицы FAT32 / кэш для структур NTFS + 80000-90000 текущий рассматриваемый кластер + 90000-92000 FAT: кэш для корневой папки + 92000-... FAT: кэш для некорневых папок (каждой папке отводится + 2000h байт = 100h входов, одновременно в кэше + может находиться не более 7 папок; + точный размер определяется размером доступной + физической памяти - как правило, непосредственно + перед A0000 размещается EBDA, Extended BIOS Data Area) + +===================================================================== + +Основной процесс загрузки. +0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется + размещением команды install=c:\kordldr.win в первой строке config.sys; + при этом основной загрузчик системы загружает kordldr.win как обычный + com-файл, в какой-то сегмент по смещению 100h и передаёт управление + в начало кода (xxxx:0100). +0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется + добавлением строки наподобие c:\kordldr.win="KordOS" в секцию + [operating systems] файла boot.ini; если загружаемый файл имеет размер + не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' + (в случае kordldr.win так и есть), то основной загрузчик каждой из + этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт + управление на адрес 0D00:0256. +0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями + с базой данных основного загрузчика через bcdedit и подробно описана в + инструкции к kordldr.win; основной загрузчик загружает целиком + kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. +1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная + им программа окажется в свою очередь загрузчиком, и в этом случае + kordldr.win оказывается в условиях, когда основной загрузчик уже + установил какое-то окружение, в частности, перехватил некоторые + прерывания. Поэтому перед остальными действиями загрузчик должен + восстановить систему в начальное состояние. (При загрузке под + NT-линейкой такой проблемы не возникает, поскольку там основной + загрузчик ничего в системе не трогает.) Поэтому перед собственно + инициализацией KordOS при работе из-под DOS/9x производятся + дополнительные действия. Первым делом kordldr проверяет, какой из + случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт + управление не на начало кода): определяет значение ip (команда call + помещает в стек адрес следующей после call инструкции, команда pop si + выталкивает его в регистр si), и если оно равно 100h, то kordldr + загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения + у пользователя (поскольку в этой схеме kordldr загружается всегда, + он должен оставить возможность продолжить загрузку DOS/9x). Если + пользователь хочет продолжить обычную загрузку, kordldr завершается. + Иначе используется тот факт, что при выдаче прерывания перезагрузки + int 19h система предварительно снимает все свои перехваты BIOSовских + прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что + kordldr устанавливает свой обработчик трассировочного прерывания, + устанавливает флаг трассировки и передаёт управление DOSовскому + обработчику. Обработчик трассировочного прерывания ничего не делает + до тех пор, пока следующей инструкцией не оказывается int 19h, а + в этот момент отбирает управление и продолжает загрузку KordOS. + При этом BIOSовские обработчики восстановлены за исключением, + быть может, прерывания таймера int 8, которое, возможно, восстановлено + до команды jmp far на оригинальный обработчик. В последнем случае его + нужно восстановить явно. +2. Загрузчик перемещает свой код на адрес 0000:0600. +3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, + настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы + все данные можно было адресовать через [bp+N] с однобайтовым N + (в дальнейшем они так и будут адресоваться для освобождения ds и + экономии на размере кода). Разрешает прерывания на случай, если + они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся + с весёлой рожицы (символ с ASCII-кодом 2). +4. Определяет характеристики жёсткого диска, указанного в качестве + загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), + если LBA не поддерживается, то определяет геометрию - число дорожек + и число секторов на дорожке (функция 8 прерывания 13h), эти параметры + нужны функции чтения с диска. +5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. + Цель цикла - для каждого логического диска попытаться загрузиться с + него (действия по загрузке с конкретного логического диска начинаются + с метки not_extended), при ошибке загрузки управление передаётся + назад этому циклу (метка next_partition), и поиск подходящего раздела + продолжается. На выходе заполняется одна переменная partition_start, + имеющая смысл начала текущего рассматриваемого логического диска, + но по ходу дела из-за приколов таблиц разделов используются ещё четыре + переменных. cur_partition_ofs - фактически счётчик цикла, формально + указатель на текущий вход в текущей загрузочной записи. Сама + загрузочная запись считывается в память начиная с адреса 3000h. + Три оставшихся нужны для правильной работы с расширенными разделами. + В каждой загрузочной записи помещается не более 4 записей о разделах. + Поэтому главной загрузочной записи, размещающейся в первом физическом + секторе диска, может не хватить, и обычно создаётся так называемый + расширенный раздел с расширенными загрузочными записями, формат + которых почти идентичен главной. Расширенный раздел может быть только + один, но в нём может быть много логических дисков и расширенных + загрузочных записей. Расширенные загрузочные записи организованы + в односвязный список, в каждой такой записи первый вход указывает + на соответствующий логический диск, а второй - на следующую расширенную + загрузочную запись. + При этом в главной загрузочной записи все адреса разделов являются + абсолютными номерами секторов. В расширенных же записях адреса разделов + относительны, причём с разными базами: адрес логического диска + указывается относительно расширенной записи, а адрес следующей + расширенной записи указывается относительно начала расширенного + раздела. Такой разнобой выглядит несколько странно, но имеет место + быть. Три оставшихся переменных содержат: extended_part_start - + начало расширенного раздела; extended_parent - текущая рассматриваемая + расширенная загрузочная запись; extended_part_cur - следующая + загрузочная запись для рассмотрения. + Цикл выглядит так: просматриваются все разделы, указанные в текущей + (главной или расширенной) загрузочной записи; для нормальных разделов + (они же логические диски) происходит переход на not_extended, где + устанавливается partition_start и начинается собственно загрузка + (последующие шаги); при встрече с разделом, тип которого указывает + на расширенность (5 или 0xF), код запоминает начало этого раздела + (в главной загрузочной записи такой тип означает расширенный раздел, + в расширенной - только указатель на следующую расширенную запись, + в обоих случаях он может встретиться только один раз в данной записи); + когда код доходит до конца списка, все нормальные разделы, описываемые + в этой записи, уже просмотрены, так что код с чистой совестью переходит + к следующей расширенной записи. Если он её не встретил, значит, уже + все логические разделы были подвергнуты попыткам загрузиться, и все + безрезультатно, так что выводится ругательство и работа останавливается + (jmp $). + Может возникнуть вопрос, зачем нужна такая сложная схема и почему + нельзя узнать нужный логический диск заранее или хотя бы ограничиться + первым попавшимся логическим диском, не крутя цикл. Так вот, вариант + с предварительным определением нужного раздела в данном случае не + используется, поскольку повлёк бы за собой нетривиальные лишние + действия по установке (в текущем виде установку можно провести вручную, + и она сводится к указанию системному загрузчику на существование + kordldr); кстати, в альтернативной версии загрузки после + Windows-загрузчика, когда установка осуществляется не вручную, а + специальной программой под Windows, используется модифицированная + версия, в которой как раз начальный физический сектор нужного раздела + прописывается установщиком. Сам kordldr не может установить, с какого + раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан + быть файлом на диске C:\). Вариант с первым попавшимся логическим + диском был реализован в первой версии загрузчика, но по ходу дела + обнаружилось, что таки нужно крутить цикл: во-вторых, может быть + приятным, что сама система может стоять вовсе не на системном C:\, а и + на других дисках; во-первых, диск C: может и не быть первым логическим + разделом - Vista любит создавать скрытый первичный раздел перед + системным, и тогда диск C: становится вторым логическим. +6. Извещает пользователя о том, что происходит попытка загрузки с очередного + логического диска. +7. Читает первый сектор логического диска и определяет файловую систему. + И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе + и должно совпадать с характеристикой физического носителя, то есть + 200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число + секторов в кластере и должно быть степенью двойки. + Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со + смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано + быть ненулевым). + Критерий FAT: загрузчик вычисляет число кластеров, определяет + предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению + +38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). + После определения типа файловой системы извещает пользователя об + определённом типе. Если файловая система не распознана, выдаёт + соответствующее сообщение и переходит к следующему логическому диску. +8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - + константу '12'; устанавливает указатель на функцию получения следующего + в цепочке FAT кластера на FAT12-обработчик; считывает в память всю + таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке + чтения пытается использовать другие копии FAT. +8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - + константу '16'; устанавливает указатель на функцию получения следующего + в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию + о кэше секторов FAT (массив байт с возможными значениями 0 и 1, + означающими, был ли уже загружен соответствующий сектор - всего в + таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не + загружен, все байты нулевые. +8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - + константу '32'; устанавливает указатель на функцию получения следующего + в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию + о кэше секторов FAT (формат информации описан выше, в распределении + используемой загрузчиком памяти) - ни один сектор ещё не загружен. +8г. Общее для FAT-томов: определяет значения служебных переменных + root_start (первый сектор корневого каталога в FAT12/16, игнорируется + при обработке FAT32-томов), data_start (начало данных с поправкой, + вводимой для того, чтобы кластер N начинался с сектора + N*sectors_per_cluster+data_start), root_clus (первый кластер корневого + каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию + загрузки файла на FAT-обработчик. +8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - + константу 'nt'; определяет значение служебной переменной frs_size + (размер в байтах файловой записи, File Record Segment), для полной + корректности проверяет, что это значение (равное 0x400 байт на всех + реальных NTFS-томах - единственный способ изменить его заключается + в пересоздании всех системных структур вручную) не превосходит 0x1000 + и кратно размеру сектора 0x200 байт; инициализирует кэш файловых + записей - ничего ещё не загружено; считывает первый кластер $MFT + и загружает информацию о расположении на диске всей таблицы $MFT + (атрибут 0x80, $Data); устанавливает указатель на функцию загрузки + файла на NTFS-обработчик. +9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного + загрузчика. При обнаружении ошибки переходит на обработчик ошибок с + соответствующим сообщением. +10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), + ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), + может быть изменён путём модификации константы в исходнике или + специальным установщиком), bx=идентификатор файловой системы (берётся + из стека, куда ранее был засунут на шаге 8), ds:si=указатель на + callback-функцию. +11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. + +Функция обратного вызова для вторичного загрузчика: + предоставляет возможность чтения файла. +Вход и выход описаны в спецификации на загрузчик. +Чтение файла: +1. Сохраняет стек вызывающего кода и устанавливает свой стек: + ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным + кодом должна указывать на 0:dat. +2. Разбирает переданные параметры и вызывает процедуру загрузки файла. +3. Восстанавливает стек вызывающего кода и возвращает управление. + +Вспомогательные процедуры. +Процедура чтения секторов (read): +на входе должно быть установлено: + ss:bp = 0:dat + es:bx = указатель на начало буфера, куда будут прочитаны данные + eax = стартовый сектор (относительно начала логического диска) + cx = число секторов (должно быть больше нуля) +на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, + флаг CF установлен, если возникла ошибка чтения +1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на + устройстве, прибавляя номер первого сектора логического диска, + найденный при переборе дисков. +2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации + CHS-версия: все читаемые секторы были на одной дорожке. + LBA-версия: число читаемых секторов не превосходило 7Fh (требование + спецификации EDD BIOS). +CHS-версия: +3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как + единица плюс остаток от деления абсолютного номера на число секторов + на дорожке; дорожка рассчитывается как остаток от деления частного, + полученного на предыдущем шаге, на число дорожек, а цилиндр - как + частное от этого же деления. Если число секторов для чтения больше, + чем число секторов до конца дорожки, уменьшает число секторов для + чтения. +4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, + dh=головка, (младшие 6 бит cl)=сектор, + (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска + и повторяет попытку чтения, всего делается не более трёх попыток + (несколько попыток нужно в случае дискеты для гарантии того, что + мотор раскрутился). Если все три раза происходит ошибка чтения, + переходит на код обработки ошибок с сообщением "Read error". +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. +LBA-версия: +3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей + итерации) до 7Fh. +4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами + push, причём в обратном порядке: стек - структура LIFO, и данные в + стеке хранятся в обратном порядке по отношению к тому, как их туда + клали). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки + ошибок с сообщением "Read error". Очищает стек от пакета, + сформированного на предыдущем шаге. +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. + +Процедура обработки ошибок (find_error_si и find_error_sp): +на входе: указатель на сообщение об ошибке в si либо на верхушке стека +0. Если вызывается find_error_si, она помещает переданный указатель в стек. +1. Если ошибка произошла в процессе работы callback-функции, то + (метка error_in_callback) обработчик просто возвращает управление + вызвавшему коду, рапортуя о ненайденном файле. +2. Если же ошибка произошла до передачи управления вторичному загрузчику, + обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" + и (восстановив стек) переходит к следующему логическому диску. + +Процедура чтения файла/атрибута по известному размещению на диске + (read_file_chunk): +на входе должно быть установлено: + ds:si = указатель на информацию о размещении + es:bx = указатель на начало буфера, куда будут прочитаны данные + ecx = лимит числа секторов для чтения, старшее слово должно быть 0 +на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, + флаг CF установлен, если возникла ошибка чтения +1. Определяет, является ли атрибут резидентным (возможно только в NTFS + и означает, что данные файла/атрибута уже были целиком прочитаны при + обработке информации о файле) или нерезидентным (означает, что данные + хранятся где-то на диске, и имеется информация о том, где именно). +2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует + данные по месту назначения (с учётом указанного лимита). +3. Для нерезидентных атрибутов информация состоит из пар <размер очередного + фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура + читает фрагменты, пока файл не закончится или пока не будет достигнут + указанный лимит. + +Процедура просмотра кэша (cache_lookup): +на входе должно быть установлено: + eax = искомое значение + ss:si = указатель на структуру-заголовок кэша +на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение + было только что добавлено, и сброшен, если оно уже было в кэше. +1. Просматривает кэш в поисках указанного значения. Если значение найдено + (при этом флаг CF оказывается сброшенным), переходит к шагу 4. +2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в + голове двусвязного списка), иначе добавляет к кэшу ещё один вход. +3. Устанавливает в полученном входе указанное значение. Устанавливает флаг + CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. +4. Удаляет вход из списка. +5. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/ntfs.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/ntfs.inc new file mode 100644 index 000000000..f92f13caa --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/after_win/ntfs.inc @@ -0,0 +1,587 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +restore_usa: +; Update Sequence Array restore +; in: ds:bx -> USA-protected structure + push bx + lea di, [bx+1feh] + mov cx, [bx+6] + add bx, [bx+4] + dec cx +@@: + mov ax, [bx+2] + mov [di], ax + inc bx + inc bx + add di, 200h + loop @b + pop bx + ret + +find_attr: +; in: ds:di->file record, ax=attribute +; out: ds:di->attribute or di=0 if not found + add di, [di+14h] +.1: +; attributes' codes are formally dwords, but all of them fit in word + cmp word [di], -1 + jz .notfound + cmp word [di], ax + jnz .continue +; for $DATA attribute, scan only unnamed + cmp ax, 80h + jnz .found + cmp byte [di+9], 0 + jz .found +.continue: + add di, [di+4] + jmp .1 +.notfound: + xor di, di +.found: + ret + +process_mcb_nonres: +; in: ds:si->attribute, es:di->buffer +; out: es:di->buffer end + pushad + pop di + add si, [si+20h] + xor ebx, ebx +.loop: + lodsb + test al, al + jz .done + push invalid_read_request_string + movzx cx, al + shr cx, 4 + jz find_error_sp + xchg ax, dx + and dx, 0Fh + jz find_error_sp + add si, cx + add si, dx + pop ax + push si + dec si + movsx eax, byte [si] + dec cx + jz .l1e +.l1: + dec si + shl eax, 8 + mov al, [si] + loop .l1 +.l1e: + xchg ebp, eax + dec si + movsx eax, byte [si] + mov cx, dx + dec cx + jz .l2e +.l2: + dec si + shl eax, 8 + mov al, byte [si] + loop .l2 +.l2e: + pop si + add ebx, ebp +; eax=length, ebx=disk block + stosd + mov eax, ebx + stosd + cmp di, 0x8000 - 12 + jbe .loop +..attr_overflow: + mov si, fragmented_string + jmp find_error_si +.done: + xor ax, ax + stosw + stosw + push di + popad + ret + +load_attr: +; in: ax=attribute, ds:bx->base record +; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated, +; edx=size of attribute in bytes +; out: if not found: CF=1 + mov di, [bp + freeattr - dat] + push ss + pop es + mov byte [es:di], 1 + inc di + cmp di, 0x8000 - 12 + ja ..attr_overflow + or edx, -1 ; file size is not known yet +; scan for attribute + push di + mov di, bx + add di, [di+14h] +@@: + call find_attr.1 + test di, di + jz .notfound1 + cmp byte [di+8], 0 + jnz .nonresident + mov si, di + pop di + push ds + jmp .resident +.aux_resident: + mov ax, ds + mov si, di + pop di ds bx ds edx + push ss + pop es + push ds + mov ds, ax +; resident attribute +.resident: + dec di + mov al, 0 + stosb + mov ax, [si+10h] + stosw + push di + add di, ax + cmp di, 0x8000 - 12 + pop di + ja ..attr_overflow + movzx edx, ax ; length of attribute + xchg ax, cx + add si, [si+14h] + rep movsb + mov [bp + freeattr - dat], di + pop ds + ret +.nonresident: +; nonresident attribute + cmp dword [di+10h], 0 + jnz @b +; read start of data + mov si, di + mov edx, [di+30h] ; size of attribute + pop di + call process_mcb_nonres + sub di, 4 + push di +.notfound1: + pop di + push edx +; $ATTRIBUTE_LIST is always in base file record + cmp ax, 20h + jz .nofragmented +; try to load $ATTRIBUTE_LIST = 20h + push ax + mov ax, 20h + push [bp + freeattr - dat] + mov [bp + freeattr - dat], di + push di + call load_attr + pop di + pop [bp + freeattr - dat] + pop ax + jc .nofragmented + push ds bx + pusha + mov si, di + push ss + pop ds + push 0x8100 + pop es + xor ecx, ecx + mov cl, 0x78 + xor bx, bx + push es + call read_file_chunk + pop ds + jc ..found_disk_error + test cx, cx + jz ..attr_overflow + popa + push ss + pop es + xor bx, bx +.1: + cmp [bx], ax + jnz .continue1 +; only unnamed $DATA attributes! + cmp ax, 80h + jnz @f + cmp byte [bx+6], 0 + jnz .continue1 +@@: + cmp dword [bx+10h], 0 + jz .continue1 + cmp dword [bx+8], 0 + jnz @f + dec di + cmp di, [bp + freeattr - dat] + lea di, [di+1] + jnz .continue1 +@@: + push ds di + push ax + mov eax, [bx+10h] + mov ecx, [bx+8] + call read_file_record + pop ax + mov di, [14h] +.2: + call find_attr.1 + cmp byte [di+8], 0 + jz .aux_resident + cmp dword [di+10h], ecx + jnz .2 + mov si, di + mov di, sp + cmp dword [ss:di+8], -1 + jnz @f + push dword [si+30h] ; size of attribute + pop dword [ss:di+8] +@@: + pop di + call process_mcb_nonres + sub di, 4 + pop ds +.continue1: + add bx, [bx+4] + cmp bx, dx + jb .1 + pop bx ds +.nofragmented: + pop edx + dec di + cmp di, [bp + freeattr - dat] + jnz @f + stc + ret +@@: + inc di + xor ax, ax + stosw + stosw + mov [bp + freeattr - dat], di + ret + +read_file_record: +; in: eax = index of record +; out: ds:0 -> record +; find place in cache + push di + push si + mov si, cache1head + call cache_lookup + pop si + pushf + sub di, 3400h + shl di, 10-3 + add di, 0x6000 + mov ds, di + popf + pop di + jnc .noread +; read file record to ds:0 + pushad + push ds + push es + movzx ecx, [bp + frs_size - dat] + shr cx, 9 + mul ecx + push ds + pop es + push ss + pop ds + mov si, 0x4000 + xor bx, bx + push [bp + cur_obj - dat] + mov [bp + cur_obj - dat], mft_string + push es + call read_attr +; initialize cache for $INDEX_ALLOCATION for this record + pop si + push si + sub si, 0x6000 + mov ax, si + shr si, 10-3 + shr ax, 2 + add si, 3480h + add ax, 3500h + mov [si], si + mov [si+2], si + mov [si+4], ax + pop ds + call restore_usa + pop [bp + cur_obj - dat] + pop es + pop ds + popad +.noread: + ret + +read_attr: +; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute + push invalid_read_request_string + cmp byte [si], 0 + jnz .nonresident + cmp eax, 10000h shr 9 + jae find_error_sp + shl ax, 9 + shl cx, 9 + cmp ax, [si+2] + jae find_error_sp + cmp cx, [si+2] + ja find_error_sp + add si, 3 + add si, ax + mov di, bx + rep movsb + pop ax + ret +.nonresident: + inc si +.loop: + mov edx, dword [si] + add si, 8 + test edx, edx + jz find_error_sp + imul edx, [bp + sect_per_clust - dat] + sub eax, edx + jnc .loop + add eax, edx + sub edx, eax + push cx + cmp ecx, edx + jb @f + mov cx, dx +@@: + push bx + mov ebx, [si-4] + imul ebx, [bp + sect_per_clust - dat] + add eax, ebx + pop bx + call read + jc ..found_disk_error + mov dx, cx + pop cx + xor eax, eax + sub cx, dx + jnz .loop + pop ax + ret + +load_file_ntfs: +; in: ss:bp = 0:dat +; in: es:bx = address to load file +; in: ds:si -> ASCIIZ name +; in: cx = limit in sectors +; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found +; out: dx:ax = file size (0xFFFFFFFF if file not found) + push es bx cx + mov eax, 5 ; root cluster + mov [bp + cur_obj - dat], root_string +.parse_dir_loop: + push ds si + call read_file_record +; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP + mov ax, [bp + freeattr - dat] + mov [bp + index_root - dat], ax + mov ax, 90h ; $INDEX_ROOT + xor bx, bx + call load_attr + mov si, noindex_string + jc find_error_si + mov ax, [bp + freeattr - dat] + mov [bp + index_alloc - dat], ax + mov ax, 0A0h ; $INDEX_ALLOCATION + call load_attr + jnc @f + mov [bp + index_alloc - dat], bx +@@: + push ds +; search for entry + mov si, [bp + index_root - dat] + push ss + pop ds + push 0x8100 + pop es + xor ecx, ecx + mov cl, 0x78 + xor bx, bx + push es + call read_file_chunk + pop ds + jc ..found_disk_error + test cx, cx + jz ..attr_overflow + mov si, invalid_read_request_string + cmp word [bx+10], 0 + jnz find_error_si +; calculate number of items in cache + mov di, [bx+8] ; subnode_size + mov ax, 0x4000 + sub ax, word [bp + frs_size - dat] + cwd + div di + test ax, ax + jz find_error_si + mov si, invalid_volume_msg + test di, 0x1FF + jnz find_error_si + pop cx + mov [bp + cur_index_seg - dat], cx + shl ax, 3 + sub cx, 6000h + mov si, cx + shr cx, 2 + shr si, 10-3 + add cx, ax + add si, 3480h + mov [bp + cur_index_cache - dat], si + add cx, 3500h + mov [ss:si+6], cx + mov dx, di + add bx, 10h +.scan_record: + add bx, [bx] +.scan: + test byte [bx+0Ch], 2 + jnz .look_child + movzx cx, byte [bx+50h] ; namelen + lea di, [bx+52h] ; name + push ds + pop es + pop si ds + push ds si + xor ax, ax +.1: + lodsb + cmp al, '/' + jnz @f + mov al, 0 +@@: + cmp al, 'A' + jb .nocapital + cmp al, 'Z' + ja .nocapital + or al, 20h +.nocapital: + cmp al, 'a' + jb .notletter + cmp al, 'z' + ja .notletter + or byte [es:di], 20h +.notletter: + scasw + loopz .1 + jb .look_child + ja @f + cmp byte [si], 0 + jz .file_found + cmp byte [si], '/' + jz .file_found +@@: + push es + pop ds + add bx, [bx+8] + jmp .scan +.look_child: + push es + pop ds + test byte [bx+0Ch], 1 + jz .not_found + mov si, [bp + index_alloc - dat] + test si, si + jz .not_found + add bx, [bx+8] + mov eax, [bx-8] + mov es, [bp + cur_index_seg - dat] + push si + mov si, [bp + cur_index_cache - dat] + call cache_lookup + pop si + pushf + mov bx, di + mov bh, 0 + shr bx, 3 + imul bx, dx + add bx, [bp + frs_size - dat] + popf + jnc .noread + push es + push dx + push ss + pop ds + movzx ecx, dx + shr cx, 9 + mul [bp + sect_per_clust - dat] + call read_attr + pop dx + pop es + push es + pop ds + call restore_usa +.noread: + push es + pop ds + add bx, 18h + jmp .scan_record +.not_found: + pop [bp + cur_obj - dat] + mov si, error_not_found + jmp find_error_si +.file_found: + pop [bp + cur_obj - dat] + pop cx + mov ax, [bp + index_root - dat] + mov [bp + freeattr - dat], ax + mov eax, [es:bx] + test byte [es:bx+48h+3], 10h + jz .regular_file + cmp byte [si], 0 + jz ..directory_error + inc si + jmp .parse_dir_loop +.regular_file: + cmp byte [si], 0 + jnz ..notdir_error +; read entry + call read_file_record + xor bx, bx + mov ax, 80h + call load_attr + mov si, nodata_string + jc find_error_si + mov si, [bp + index_root - dat] + mov [bp + freeattr - dat], si + push ss + pop ds + jmp load_file_common_end diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/build.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/build.bat new file mode 100644 index 000000000..24948f9fe --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/build.bat @@ -0,0 +1,20 @@ +echo off +cls +echo ** bulding after win loader ** +@fasm -m 65535 after_win/kordldr.win.asm after_win/kordldr.win +echo ============================== +echo ** building first loader for cd/dvd ** +@fasm -m 65535 cdfs/bootsect.asm cdfs/bootsect.bin +echo ============================== +echo ** building first loader for fat12/fat16 ** +@fasm -m 65535 fat1x/bootsect.asm fat1x/bootsect.bin +@fasm -m 65535 fat1x/kordldr.f1x.asm fat1x/kordldr.f1x +echo ============================== +echo ** building firs loader for fat32 ** +@fasm -m 65535 fat32/bootsect.asm fat32/bootsect.bin +@fasm -m 65535 fat32/kordldr.f1x.asm fat32/kordldr.f1x +echo ============================== +echo ** make a image of fdd ** +@fasm -m 65535 floppy.asc kord.img + +@pause diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.asm new file mode 100644 index 000000000..4d03989b3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.asm @@ -0,0 +1,1024 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + jmp far 0:real_start +; special text +org $+0x7C00 +real_start: +; initialize + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov es, ax + cld + sti + mov [bootdrive], dl +; check LBA support + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cl, 1 + jz err_ +; get file system information +; scan for Primary Volume Descriptor + db 66h + push 10h-1 + pop eax +pvd_scan_loop: + mov cx, 1 + inc eax + mov bx, 0x1000 + call read_sectors + jnc @f +fatal_read_err: + mov si, aReadError +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ +@@: + push ds + pop es + cmp word [bx+1], 'CD' + jnz pvd_scan_loop + cmp word [bx+3], '00' + jnz pvd_scan_loop + cmp byte [bx+5], '1' + jnz pvd_scan_loop +; we have found ISO9660 descriptor, look for type + cmp byte [bx], 1 ; Primary Volume Descriptor? + jz pvd_found + cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? + jnz pvd_scan_loop +; Volume Descriptor Set Terminator reached, no PVD found - fatal error + mov si, no_pvd + jmp err_ +pvd_found: + add bx, 80h + mov ax, [bx] + mov [lb_size], ax +; calculate number of logical blocks in one sector + mov ax, 800h + cwd + div word [bx] + mov [lb_per_sec], ax +; get location of root directory + mov di, root_location + movzx eax, byte [bx+1Dh] + add eax, [bx+1Eh] + stosd +; get memory size + int 12h + mov si, nomem_str + cmp ax, 71000h / 400h + jb err_ + shr ax, 1 + sub ax, 60000h / 800h + mov [size_rest], ax + mov [free_ptr], 60000h / 800h +; load path table +; if size > 62K => it's very strange, avoid using it +; if size > (size of cache)/2 => avoid using it too + mov ecx, [bx+4] + cmp ecx, 0x10000 - 0x800 + ja nopathtable + shr ax, 1 + cmp ax, 0x20 + jae @f + shl ax, 11 + cmp cx, ax + ja nopathtable +@@: +; size is ok, try to load it + mov [pathtable_size], cx + mov eax, [bx+12] + xor edx, edx + div dword [lb_per_sec] + imul dx, [bx] + mov [pathtable_start], dx + add cx, dx + call cx_to_sectors + xor bx, bx + push 6000h + pop es + call read_sectors + jc nopathtable +; path table has been loaded + inc [use_path_table] + sub [size_rest], cx + add [free_ptr], cx +nopathtable: +; init cache + mov ax, [size_rest] + mov [cache_size], ax + mov ax, [free_ptr] + mov [cache_start], ax +; load secondary loader + mov di, secondary_loader_info + call load_file + test bx, bx + jnz noloader +; set registers for secondary loader + mov ah, [bootdrive] + mov al, 'c' + mov bx, 'is' + mov si, callback + jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 + +noloader: + mov si, aKernelNotFound + jmp err_ + +read_sectors: +; es:bx = pointer to data +; eax = first sector +; cx = number of sectors + pushad + push ds +do_read_sectors: + push ax + push cx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F +@@: +; create disk address packet on the stack +; dq starting LBA + db 66h + push 0 + push eax +; dd buffer + push es + push bx +; dw number of blocks to transfer (no more than 0x7F) + push cx +; dw packet size in bytes + push 10h +; issue BIOS call + push ss + pop ds + mov si, sp + mov dl, [cs:bootdrive] + mov ah, 42h + int 13h + jc diskreaderr +; restore stack + add sp, 10h +; increase current sector & buffer; decrease number of sectors + movzx esi, cx + mov ax, es + shl cx, 7 + add ax, cx + mov es, ax + pop cx + pop ax + add eax, esi + sub cx, si + jnz do_read_sectors + pop ds + popad + ret +diskreaderr: + add sp, 10h + 2*2 + pop ds + popad + stc +out_string.ret: + ret + +out_string: +; in: ds:si -> ASCIIZ string + lodsb + test al, al + jz .ret + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string + +aNoLBA db 'The drive does not support LBA!',0 +aReadError db 'Read error',0 +no_pvd db 'Primary Volume Descriptor not found!',0 +nomem_str db 'No memory',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 + +load_file: +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found +; out: dx:ax = file size (0xFFFFFFFF if file not found) +; parse path to the file + lea si, [di+6] + mov eax, [cs:root_location] + cmp [cs:use_path_table], 0 + jz parse_dir +; scan for path in path table + push di + push 6000h + pop es + mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table + mov dx, 1 ; dx = number of current entry in path table, start from 1 + mov cx, [cs:pathtable_size] +pathtable_newparent: + mov bx, dx ; bx = number of current parent in path table: root = 1 +scan_path_table_e: + call is_last_component + jnc path_table_scanned +scan_path_table_i: + cmp word [es:di+6], bx + jb .next + ja path_table_notfound + call test_filename1 + jc .next +@@: + lodsb + cmp al, '/' + jnz @b + jmp pathtable_newparent +.next: +; go to next entry + inc dx + movzx ax, byte [es:di] + add ax, 8+1 + and al, not 1 + add di, ax + sub cx, ax + ja scan_path_table_i +path_table_notfound: + pop di + mov ax, -1 + mov dx, ax + mov bx, 2 ; file not found + ret +path_table_scanned: + movzx eax, byte [es:di+1] + add eax, [es:di+2] + pop di +parse_dir: +; eax = logical block, ds:di -> information structure, ds:si -> file name +; was the folder already read? + push di ds + push cs + pop ds + mov [cur_desc_end], 2000h + mov bx, cachelist +.scan1: + mov bx, [bx+2] + cmp bx, cachelist + jz .notfound + cmp [bx+4], eax + jnz .scan1 +.found: +; yes; delete this item from the list (the following code will append this item to the tail) + mov di, [bx] + push word [bx+2] + pop word [di+2] + mov di, [bx+2] + push word [bx] + pop word [di] + mov di, bx + jmp .scan +.notfound: +; no; load first sector of the folder to get its size + push eax + push si + mov si, 1 + call load_phys_sector_for_lb_force + mov bx, si + pop si + pop eax + jnc @f +; read error - return +.readerr: + pop ds +.readerr2: + pop di + mov ax, -1 + mov dx, ax + mov bx, 3 + ret +@@: +; first item of the folder describes the folder itself +; do not cache too big folders: size < 64K and size <= (total cache size)/2 + cmp word [bx+12], 0 + jnz .nocache + mov cx, [cache_size] ; cx = cache size in sectors + shr cx, 1 ; cx = (cache size)/2 + cmp cx, 0x20 + jae @f + shl cx, 11 + cmp [bx+10], cx + ja .nocache +@@: +; we want to cache this folder; get space for it + mov cx, [bx+10] + call cx_to_sectors + jnz .yescache +.nocache: + push dword [bx+10] + pop dword [cur_nocache_len] + call lb_to_sector + push ds + pop es + pop ds +.nocache_loop: + push eax + mov dx, 1800h + call scan_for_filename_in_sector + mov cx, dx + pop eax + jnc .j_scandone + sub cx, bx + sub word [es:cur_nocache_len], cx + sbb word [es:cur_nocache_len+2], 0 + jb .j_scandone + ja @f + cmp word [es:cur_nocache_len], 0 + jz .j_scandone +@@: + mov cx, 1 + inc eax + push es + mov bx, 1000h + call read_sectors + pop es + jc .readerr2 + jmp .nocache_loop +.j_scandone: + jmp .scandone +.yescache: + push bx + mov bx, [cachelist.head] +.freeloop: + cmp cx, [size_rest] + jbe .sizeok +@@: +; if we are here: there is not enough free space, so we must delete old folders' data +; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). +; one loop iteration: delete data of one folder + pusha + mov dx, [bx+10] + mov es, dx ; es = segment of folder data to be deleted + xor di, di + mov ax, [bx+8] + add ax, 0x7FF + rcr ax, 1 + shr ax, 10 + push ax + shl ax, 11-4 ; get number of paragraphs in folder data to be deleted + mov cx, [cache_size] + add cx, [cache_start] + push ds + push ax + add ax, dx + mov ds, ax + pop ax + shl cx, 11-4 + sub cx, dx ; cx = number of paragraphs to be moved + push si + xor si, si +; move cx paragraphs from ds:si to es:di to get free space in the end of cache +@@: + sub cx, 1000h + jbe @f + push cx + mov cx, 8000h + rep movsw + mov cx, ds + add cx, 1000h + mov ds, cx + mov cx, es + add cx, 1000h + mov es, cx + pop cx + jmp @b +@@: + add cx, 1000h + shl cx, 3 + rep movsw + pop si + pop ds +; correct positions in cache for existing items + mov cx, 80h + mov di, 8400h +.correct: + cmp [di+10], dx + jbe @f + sub [di+10], ax +@@: + add di, 12 + loop .correct +; some additional space is free now + pop ax + add [size_rest], ax + sub [free_ptr], ax +; add cache item to the list of free items + mov dx, [bx] + mov ax, [free_cache_item] + mov [bx], ax + mov [free_cache_item], bx + mov bx, dx +; current iteration done + popa + jmp .freeloop +.sizeok: + mov [cachelist.head], bx + mov word [bx+2], cachelist +; allocate new item in cache + mov di, [free_cache_item] + test di, di + jz .nofree + push word [di] + pop [free_cache_item] + jmp @f +.nofree: + mov di, [last_cache_item] + add [last_cache_item], 12 +@@: + pop bx + push si di +; mov [di+4], eax ; start of folder + scasd + stosd + push ax + mov ax, [free_ptr] + shl ax, 11-4 + mov [di+10-8], ax + mov es, ax + pop ax + add [free_ptr], cx + sub [size_rest], cx +; read folder data +; first sector is already in memory, 0000:bx + pusha + mov cx, [bx+10] + mov [di+8-8], cx ; folder size in bytes + mov si, bx + xor di, di + mov cx, 0x1800 + sub cx, si + rep movsb + pop ax + push di + popa +; read rest of folder + mov esi, dword [lb_per_sec] + add eax, esi + dec si + not si + and ax, si + mov si, word [bx+10] + mov bx, di + pop di + sub si, bx + jbe @f + mov [cur_limit], esi + call read_many_bytes + pop si + jnc .scan + jmp .readerr +@@: + pop si +.scan: +; now we have required cache item; append it to the end of list + mov bx, [cachelist.tail] + mov [cachelist.tail], di + mov [di+2], bx + mov word [di], cachelist + mov [bx], di +; scan for given filename + mov es, [di+10] + mov dx, [di+8] + pop ds + xor bx, bx + call scan_for_filename_in_sector +.scandone: + push cs + pop es + mov bx, 2000h + cmp bx, [es:cur_desc_end] + jnz filefound +j_notfound: + jmp path_table_notfound +filefound: +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b +@@: + mov cl, [es:bx+8] + test al, al + jz @f +; parse next component of file name + test cl, 2 ; directory? + jz j_notfound + mov eax, [es:bx] + pop di + jmp parse_dir +@@: + test cl, 2 ; directory? + jnz j_notfound ; do not allow read directories as regular files +; ok, now load the file + pop di + les bx, [di] + call normalize + movzx esi, word [di+4] ; esi = limit in 4K blocks + shl esi, 12 ; esi = limit in bytes + push cs + pop ds + mov [cur_limit], esi + mov di, 2000h +loadloop: + and [cur_start], 0 +.loadnew: + mov esi, [cur_limit] + mov eax, [cur_start] + add esi, eax + mov [overflow], 1 + sub esi, [di+4] + jb @f + xor esi, esi + dec [overflow] +@@: + add esi, [di+4] ; esi = number of bytes to read + mov [cur_start], esi + sub esi, eax + jz .loadcontinue + xor edx, edx + div dword [lb_size] ; eax = number of logical blocks to skip, + mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block + cmp byte [di+10], 0 + jnz .interleaved + add eax, [di] +; read esi bytes from logical block eax to buffer es:bx + call read_many_bytes.with_first + jc .readerr3 +.loadcontinue: + mov [cur_chunk], di + add di, 11 + cmp di, [cur_desc_end] + jae @f + cmp [cur_limit], 0 + jnz loadloop +@@: + mov bx, [overflow] +.calclen: +; calculate length of file + xor ax, ax + xor dx, dx + mov di, 2000h +@@: + add ax, [di+4] + adc dx, [di+6] + add di, 11 + cmp di, [cur_desc_end] + jb @b + ret +.interleaved: + mov [cur_unit_limit], esi + push esi +; skip first blocks + movzx ecx, byte [di+9] ; Unit Size + movzx esi, byte [di+10] ; Interleave Gap + add si, cx + mov edx, [di] +@@: + sub eax, ecx + jb @f + add edx, esi + jmp @b +@@: + add ecx, eax ; ecx = number of logical blocks to skip + lea eax, [ecx+edx] ; eax = first logical block + pop esi +.interleaved_loop: +; get number of bytes in current file unit + push eax + movzx eax, byte [di+9] + sub ax, cx + imul eax, dword [lb_size] + cmp eax, esi + ja .i2 +.i1: + xchg esi, eax +.i2: + pop eax + sub [cur_unit_limit], esi + push eax +; read esi bytes from logical block eax to buffer es:bx + call read_many_bytes.with_first + pop eax + jnc @f +.readerr3: + mov bx, 3 + jmp .calclen +@@: + mov esi, [cur_unit_limit] + test esi, esi + jz .loadcontinue + movzx ecx, byte [di+9] ; add Unit Size + add cl, byte [di+10] ; add Interleave Gap + adc ch, 0 + add eax, ecx + xor cx, cx + mov [first_byte], cx + jmp .interleaved_loop + +cx_to_sectors: + add cx, 7FFh + rcr cx, 1 + shr cx, 10 + ret + +is_last_component: +; in: ds:si -> name +; out: CF set <=> current component is not last (=> folder) + push si +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + stc +@@: + pop si + ret + +test_filename1: +; in: ds:si -> filename, es:di -> path table item +; out: CF set <=> no match + pusha + mov cl, [es:di] + add di, 8 + jmp test_filename2.start +test_filename2: +; in: ds:si -> filename, es:bx -> directory item +; out: CF set <=> no match + pusha + mov cl, [es:bx+32] + lea di, [bx+33] +.start: + mov ch, 0 +@@: + lodsb + test al, al + jz .test1 + cmp al, '/' + jz .test1 + call toupper + mov ah, al + mov al, [es:di] + call toupper + inc di + cmp al, ah + loopz @b + jnz .next1 +; if we have reached this point: current name is done + lodsb + test al, al + jz .ret + cmp al, '/' + jz .ret +; if we have reached this point: current name is done, but input name continues +; so they do not match + jmp .next1 +.test1: +; if we have reached this point: input name is done, but current name continues +; "filename.ext;version" in ISO-9660 represents file "filename.ext" +; "filename." and "filename.;version" are also possible for "filename" + cmp byte [es:di], '.' + jnz @f + inc di + dec cx + jz .ret +@@: + cmp byte [es:di], ';' + jnz .next1 + jmp .ret +.next1: + stc +.ret: + popa + ret + +toupper: +; in: al=symbol +; out: al=symbol in uppercase + cmp al, 'a' + jb .ret + cmp al, 'z' + ja .ret + sub al, 'a'-'A' +.ret: + ret + +scan_for_filename_in_sector: +; in: ds:si->filename, es:bx->folder data, dx=limit +; out: CF=0 if found + push bx +.loope: + push bx +.loop: + cmp bx, dx + jae .notfound + cmp byte [es:bx], 0 + jz .loopd + test byte [es:bx+25], 4 ; ignore files with Associated bit + jnz .next + call test_filename2 + jc .next + push ds es di + push es + pop ds + push cs + pop es + mov di, [es:cur_desc_end] + movzx eax, byte [bx+1] + add eax, [bx+2] + stosd ; first logical block + mov eax, [bx+10] + stosd ; length + mov al, [bx+25] + stosb ; flags + mov ax, [bx+26] + stosw ; File Unit size, Interleave Gap size + mov [es:cur_desc_end], di + cmp di, 3000h + pop di es ds + jae .done + test byte [es:bx+25], 80h + jz .done +.next: + add bl, [es:bx] + adc bh, 0 + jmp .loop +.loopd: + mov ax, bx + pop bx +@@: + add bx, [cs:lb_size] + jz .done2 + cmp bx, ax + jb @b + jmp .loope +.notfound: + stc +.done: + pop bx +.done2: + pop bx + ret + +lb_to_sector: + xor edx, edx + div dword [lb_per_sec] + ret + +load_phys_sector_for_lb_force: +; in: eax = logical block, ds=0 +; in: si=0 - accept 0 logical blocks, otherwise force read at least 1 +; out: 0000:1000 = physical sector data; si -> logical block +; out: eax = next physical sector +; out: CF=1 if read error +; destroys cx +; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector + call lb_to_sector + or si, dx + jnz @f + mov si, 1800h + jmp .done +@@: + mov si, 1000h + imul dx, [lb_size] + add si, dx + mov cx, 1 + push es bx + push ds + pop es + mov bx, 1000h + call read_sectors + pop bx es + inc eax +.done: + ret + +normalize: +; in: es:bx = far pointer +; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) + push ax bx + mov ax, es + shr bx, 4 + add ax, bx + mov es, ax + pop bx ax + and bx, 0x0F + ret + +read_many_bytes: + and [first_byte], 0 +read_many_bytes.with_first: +; read esi bytes from logical block dx:ax to buffer es:bx +; out: CF=1 <=> disk error + push di +; load first physical sector + push bx si + mov si, [first_byte] + call load_phys_sector_for_lb_force + jnc @f + pop si bx +.ret: + pop di + ret +@@: + add si, [first_byte] + mov ecx, 1800h + sub cx, si + mov ebx, esi + pop bx + sub ebx, ecx + jnc @f + add cx, bx + xor ebx, ebx +@@: + pop di + sub [cur_limit], ecx + rep movsb + mov esi, ebx + mov bx, di + call normalize +; load other physical sectors +; read esi bytes from physical sector eax to buffer es:bx + test esi, esi + jz .ret + push esi + add esi, 0x7FF + and si, not 0x7FF + cmp esi, [cur_limit] + jbe .okplace +.noplace: + sub esi, 800h +.okplace: + shr esi, 11 ; si = number of sectors + mov cx, si + jz @f + call read_sectors +@@: + pop esi + jc .ret + movzx ecx, cx + add eax, ecx + shl ecx, 11 + sub [cur_limit], ecx + sub esi, ecx + jc .big + jz .nopost + push bx es + push ds + pop es + mov bx, 1000h + mov cx, 1 + call read_sectors + pop es di + jc .ret2 + mov cx, si + mov si, 1000h + sub word [cur_limit], cx + sbb word [cur_limit+2], 0 + rep movsb + mov bx, di + call normalize +.nopost: + clc +.ret2: + pop di + ret +.big: + mov ax, es + sub ax, 80h + mov es, ax + add bx, 800h + add bx, si + call normalize + sub [cur_limit], esi + jmp .nopost + +; Callback function for secondary loader +callback: +; in: ax = function number; only function 1 is defined for now + dec ax + jz callback_readfile + dec ax + jz callback_continueread + stc ; unsupported function + retf + +callback_readfile: +; function 1: read file +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error +; out: dx:ax = file size (0xFFFFFFFF if file was not found) + call load_file + clc ; function is supported + retf + +callback_continueread: +; function 2: continue to read file +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error +; out: dx:ax = file size + les bx, [di] + call normalize + movzx esi, word [di+4] ; si = limit in 4K blocks + shl esi, 12 ; bp:si = limit in bytes + push cs + pop ds + mov [cur_limit], esi + mov di, [cur_chunk] + call loadloop.loadnew + clc ; function is supported + retf + +secondary_loader_info: + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + +align 2 +cachelist: +.head dw cachelist +.tail dw cachelist +free_cache_item dw 0 +last_cache_item dw 0x8400 + +use_path_table db 0 +bootdrive db ? +align 2 +lb_size dw ? ; Logical Block size in bytes + dw 0 ; to allow access dword [lb_size] +lb_per_sec dw ? ; Logical Blocks per physical sector + dw 0 ; to allow access dword [lb_per_sec] +free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) +size_rest dw ? ; free space in cache (in blocks) +cache_size dw ? +cache_start dw ? +pathtable_size dw ? +pathtable_start dw ? +root_location dd ? +cur_desc_end dw ? +cur_nocache_len dd ? +cur_limit dd ? +cur_unit_limit dd ? +overflow dw ? +cur_chunk dw ? +first_byte dw ? +cur_start dd ? + +;times 83FEh-$ db 0 + db 43h +; just to make file 2048 bytes long :) + db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' + + dw 0xAA55 ; this is not required for CD, but to be consistent... diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.txt b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.txt new file mode 100644 index 000000000..969c52bba --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/bootsect.txt @@ -0,0 +1,418 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? + +Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. +(ISO-9660 и её расширения - стандарт для CD; DVD может использовать +либо ISO-9660, либо UDF.) + +===================================================================== + +Требования для работы: +1) Сам бутсектор и все используемые файлы должны быть читабельны. +2) Минимальный процессор - 80386. +3) В системе должно быть как минимум 452K свободной базовой памяти. + +===================================================================== + +Документация в тему (ссылки проверялись на валидность 14.09.2008): + стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf + стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf + официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf + то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf + описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html + официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf + +===================================================================== + +Схема используемой памяти: + 1000-1800 временный буфер для чтения одиночных секторов + ...-7C00 стек + 7C00-8400 код бутсектора + 8400-8A00 информация о кэше для папок: массив входов следующего + формата: + dw следующий элемент в L2-списке закэшированных папок, + упорядоченном по времени использования + (голова списка - самый старый); + dw предыдущий элемент в том же списке; + dd первый сектор папки; + dw размер папки в байтах; + dw сегмент кэша + 60000-... содержимое Path Table, если она используется + + кэш для папок; + точный размер определяется размером доступной + физической памяти - как правило, непосредственно + перед A0000 размещается EBDA, Extended BIOS Data Area + +===================================================================== + +Основной процесс загрузки. +Точка входа (start): получает управление от BIOS при загрузке, при этом + dl содержит идентификатор диска, с которого идёт загрузка +1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip + равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает + дальний прыжок на самого себя с целью получить cs=0 (в некоторых + местах используется адресация переменных загрузчика через cs, поскольку + и ds, и es могут быть заняты под другие сегменты). +2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) + и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления + и разрешённые прерывания. Сохраняет идентификатор загрузочного диска + в специальную переменную. +3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять + LBA-функции. +4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту + ISO9660 со смещения 10h начинается цепочка описателей тома, + завершающаяся специальным описателем (Volume Descriptor Set + Terminator). Код по очереди считывает все сектора, пока не наткнётся + либо на искомый описатель, либо на терминатор. Во втором случае + выдаётся соответствующее сообщение, и загрузка прекращается. +Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD + располагается в последней сессии. И спецификация ElTorito загрузочного + CD оперирует также с последней сессией. Однако на практике оказывается, + что: во-первых, реальные BIOSы не понимают мультисессионных CD и + всегда используют первую сессию; во-вторых, BIOSовский int 13h просто + не позволяет получить информацию о последней сессии. В связи с этим + загрузчик также использует первую сессию. (В-третьих, в одной из BIOS + обнаружилась заготовка, которая в случае запроса сектора 10h, в котором + во всех нормальных случаях и располагается PVD, перенаправляет его + на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с + последней сессии, то благодаря заготовке загрузчик без всяких + модификаций также читал бы последнюю сессию.) +5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во + внутренние переменные: размер логического блока (согласно спецификации, + должен быть степенью двойки от 512 до размера логического сектора, + равного 2048 для CD и DVD); положение на диске корневой папки; + вычисляет число блоков в секторе (из предыдущего примечания следует, + что оно всегда целое и само является степенью двойки). +6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет + размер пространства, которое может использовать загрузчик (от + адреса 6000:0000 до конца доступной памяти). +7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит + базовую информацию обо всех папках на диске. Если таблица слишком + велика (больше 62K или больше половины доступной памяти), то она + игнорируется. Если таблица путей недоступна, то запрос типа + dir1/dir2/dir3/file приведёт к последовательному разбору корневой + папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать + саму таблицу путей (где записано положение папки dir1/dir2/dir3) + и папку dir3. Если таблица загружена, то соответственно уменьшается + объём оставшейся доступной памяти и увеличивается указатель на + свободную область. +8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 + доступная память отводится под этот кэш). +9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке + печатает соответствующее сообщение и прекращает загрузку с CD. +10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует + тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' + идентифицирует файловую систему ISO-9660; ds:si указывает на + callback-функцию, которую может вызывать вторичный загрузчик. +11. Передаёт управление вторичному загрузчику, совершая дальний прыжок + на адрес, куда kord/loader был загружен. + +Функция обратного вызова для вторичного загрузчика (callback): + предоставляет возможность чтения файла. +Вход и выход описаны в спецификации на загрузчик. +Перенаправляет запрос соответствующей локальной процедуре (load_file при + первом запросе на загрузку файла, loadloop.loadnew при последующих + запросах на продолжение загрузки файла). + +Вспомогательные процедуры. +Код обработки ошибок (err): +1. Выводит строку с сообщением об ошибке. +2. Выводит строку "Press any key...". +3. Ждёт нажатия any key. +4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. +5. Для подстраховки зацикливается. + +Процедура чтения секторов (read_sectors): +на входе должно быть установлено: + es:bx = указатель на начало буфера, куда будут прочитаны данные + eax = стартовый сектор + cx = число секторов +на выходе: + es:bx указывает на конец буфера, в который были прочитаны данные + если произошла ошибка чтения, флаг CF установлен +1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации + число читаемых секторов не превосходило 7Fh (требование спецификации + EDD BIOS). +2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей + итерации) до 7Fh. +3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами + push, причём в обратном порядке: стек - структура LIFO, и данные в + стеке хранятся в обратном порядке по отношению к тому, как их туда + клали). +4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, + устанавливает CF=1 и выходит из процедуры. + Очищает стек от пакета, сформированного на предыдущем шаге. +5. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 2. + +Процедура вывода на экран ASCIIZ-строки (out_string): +на входе: ds:si -> строка +В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. + +Процедура загрузки файла (load_file): +на входе: + ds:di = указатель на информационную структуру, описанную в спецификации + на загрузчик, а также в комментариях к коду +на выходе: + bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, + 2=файл не найден, 3=ошибка чтения + dx:ax = размер файла, 0xFFFFFFFF, если файл не найден +1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, + иначе переходит сразу к шагу 4, установив eax = начальный блок + корневой папки. +2. Устанавливает es:di на начало таблицы путей. Ограничение на размер + гарантирует, что вся таблица помещается в сегменте 6000h. + Инициализирует dx (в котором будет хранится номер текущего входа в + таблице, считая с 1), cx (размер оставшегося участка таблицы), + bx (номер входа, соответствующего родительской папке для текущего + рассматриваемого участка пути). +3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы + таблицы путей упорядочены (подробно о порядке написано в спецификации), + так что если родительский элемент для очередного входа больше нужного, + то нужного входа в таблице нет совсем, и в этом случае происходит + выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, + соответствующий очередной папке в запрошенном пути, то на рассмотрение + выносится следующая компонента пути. Если эта компонента последняя, + то осталось найти файл в папке, и код переходит к пункту 4, + установив eax = начальный блок этой папки. Если же нет, то эта + компонента должна задавать имя папки, и код возвращается к пункту 3, + скорректировав указатель на имя ds:si и номер родительского входа bx. +4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax + и указатель на имя файла относительно этой папки в ds:si. Если + папку искали по таблице путей, то имя файла уже не содержит подпапок; + если же нет, то подпапки вполне возможны. +5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый + из которых задаётся отдельным входом в папке. Информация обо всех + таких кусках при просмотре папки запоминается в области, начинающейся + с адреса 0000:2000. Переменная cur_desc_end содержит указатель на + конец этой области, он же указатель, куда будет помещена информация + при обнаружении следующего входа. (Папки, согласно спецификации, + должны задаваться одним куском.) +6. Код сначала ищет запрошенную папку в кэше папок. +7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, + отсортированного по давности последнего обращения и код переходит к + п.15. (Следующим действием станет добавление папки в конец списка.) +8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать + с диска. Сначала загружается первый сектор (физический сектор, + содержащий первый логический блок). При ошибке ввода/вывода + происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. + Первый элемент папки содержит информацию о самой этой папке, конкретно + загрузчик интересуется её размером. +9. Если размер папки слишком большой (больше или равен 64K либо больше половины + общего размера кэша), то кэшироваться она не будет. В этом случае код + считывает папку посекторно во временный буфер (0000:1000) и посекторно + сканирует на наличие запрошенного имени, пока не найдёт такого имени + или пока не кончатся данные. (Цикл начинается со сканирования, + поскольку первая часть данных уже прочитана.) В конце код переходит + к п.17. +10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно + обеспечить достаточное количество свободного места. Для этого может + понадобиться выкинуть какое-то количество старых данных (цикл + parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, + свободное пространство окажется разорванным на несколько фрагментов. + Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает + все следующие за ней данные назад по памяти и соответственно + корректирует информацию о местонахождении данных в информации о кэше. + При этом новое пространство всегда добавляется в конец доступной + памяти. Цикл выкидывания продолжается, пока не освободится место, + достаточное для хранения папки. Из-за ограничений на размер кэшируемых + папок в конце концов место найдётся. +11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы + организуются в единый список свободных элементов; если он непуст, + то очередной элемент берётся из этого списка; если же пуст, то + берётся совсем новый элемент из области памяти, предназначенной для + элементов кэша. +12. В новом элементе заполняются поля начального блока, сегмента с данными, + размера в байтах. +13. Уже прочитанные данные первого физического сектора пересылаются на + законное место в кэше. +14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся + данные с диска. При ошибке чтения, как и раньше, происходит выход из + процедуры с bx=3, ax=dx=0xFFFF. +15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов + кэша. +16. Загрузчик ищет запрошенное имя в загруженных данных папки. + (Из-за ограничений на размер кэшируемой папки все данные располагаются + в одном сегменте.) +17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено + никаких кусков файла, то cur_desc_end такой же, каким был вначале. + В этом случае процедура рапортует о ненайденном файле и выходит. +18. (filefound) Пропускает текущую компоненту имени. Если она была не последней + (то есть подпапкой, в которой нужно производить дальнейший поиск), + то код проверяет, что найденный вход - действительно подпапка, + устанавливает новый стартовый блок и возвращается к п.4. + Если же последней, то код проверяет, что найденный вход - регулярный + файл и начинает загрузку файла. +19. Нормализует указатель, по которому требуется прочитать файл. Под + нормализацией понимается преобразование типа + 1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, + но гарантирует отсутствие переполнений: в приведённом примере попытка + переслать 400h байт по rep movsb приведёт к тому, что последние 8 + байт запишутся не в нужное место, а на 64K раньше. Далее нормализация + будет производиться после каждой пересылки. В cur_limit помещает + предельный размер для чтения в байтах. +20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты + (пункты 21-27). +21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое + нужно пропустить с начала фрагмента. +22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего + шага, либо напрямую из callback-процедуры при запросе на продолжение + чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - + при продолжении чтения, прервавшегося из-за конца буфера посередине + фрагмента, там будет записано соответствующее значение. +23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента + и максимальной длины остатка. Если второе строго меньше, то + запоминает, что файл слишком большой и прочитан только частично. + Определяет новое значение числа прочитанных байт во фрагменте + для возможных будущих вызовов [cur_start]. +24. Переводит пропускаемое число байт в число логических блоков и байт + в первом блоке, последнее число записывает в переменную [first_byte], + откуда её позднее достанет read_many_bytes.with_first. +25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код + определяет начальный блок фрагмента и вызывает вспомогательную функцию + чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) + и выходит из цикла к п.28. +26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала + код пропускает нужное количество непрерывных частей, а потом + в цикле загружает непрерывные части с помощью той же функции, + в промежутках между частями увеличивая номер начального блока. + Пока не кончится фрагмент или пока не наберётся запрошенное число байт. + При ошибке чтения делает то же самое, что и в предыдущем случае. +27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер + ещё не достигнут, переходит к следующему фрагменту и п.20. В противном + случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли + переполнение в п.23. +28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех + фрагментов. + +Процедура проверки, является ли текущая компонента имени файла последней + (is_last_component): +на входе: ds:si = указатель на имя +на выходе: флаг CF установлен, если есть последующие компоненты +В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, + то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF + и выходит. + +Процедуры проверки на совпадение текущей компоненты имени файла с именем +текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): +на входе: ds:si = указатель на имя, es:di = указатель на элемент + таблицы путей для test_filename1, папки для test_filename2 +на выходе: CF установлен, если имена не совпадают +В цикле проверяет совпадение приведённых к верхнему регистру очередных символов + имён файла и элемента. Условия выхода из цикла: закончилось имя файла + в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение + возможно только в ситуации типа имени "filename.ext" и элемента + "filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми + именами в папке отсортированы по убыванию версий); + несовпадение символов - означает, что имена не совпадают; + закончилось имя элемента - нужно проверить, закончилось ли при этом имя + файла, и в зависимости от этого принимать решение о совпадении. + +Процедура приведения символа в верхний регистр (toupper): +на входе: ASCII-символ +на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к + нему неприменимо) +Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', + остальные символы не трогает. + +Процедура поиска файла в данных папки (scan_for_filename_in_sector): +на входе: + ds:si = указатель на имя файла + es:bx = указатель на начало данных папки + es:dx = указатель на конец данных папки +на выходе: + CF сброшен, если найден финальный фрагмент файла + (и дальше сканировать папку не нужно) + в область для информации о фрагментах файла записывается найденное +В цикле просматривает все входы папки, пропуская те, у которых установлен + бит Associated (это специальные входы, дополняющие основные). Если + имя очередного входа совпадает с именем файла, то запоминает новый + фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), + то код выходит с CF=0. Если достигнут конец данных, то код выходит + с CF=1. Если очередной вход нулевой (первый байт настоящего входа + содержит длину и не может быть нулём), то процедура переходит к + рассмотрению следующего логического блока. При этом потенциально + возможно переполнение при добавлении размера блока; поскольку такой + сценарий означает, что процедура вызвана для кэшированной папки + с размером почти 64K и началом данных bx=0 (это свойство вызывающего + кода), а размер блока - степень двойки, то после переполнения всегда + bx=0, так что это можно обнаружить по взведённому ZF после сложения; + в этом случае также происходит выход (а после переполнения CF=1). + +Процедура перевода логического блока в номер сектора: +на входе: eax = логический блок +на выходе: eax = физический сектор, dx = номер логического блока в секторе +Осуществляет обычное деление 32-битного числа на 32-битное (число логических + блоков в секторе, хранящееся во внутренней переменной). + +Процедура загрузки физического сектора, содержащего указанный логический блок + (load_phys_sector_for_lb_force): +на входе: eax = логический блок; + si - индикатор, задающий, следует ли читать данные в случае, + если логический блок начинается с начала физического: + si = 0 - не нужно, si ненулевой - нужно +на выходе: + физический сектор загружен по адресу 0000:1000 + si указывает на данные логического блока + CF установлен при ошибке чтения +Преобразует предыдущей процедурой номер логического блока в номер физического + сектора и номер логического блока внутри сектора; если последняя + величина нулевая и никаких действий в этом случае не запрошено (si=0), + то ничего и не делает; иначе устанавливает si в соответствии с ней + и читает сектор. + +Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков + (read_many_bytes и read_many_bytes.with_first): +на входе: + eax = логический блок + esi = число байт для чтения + es:bx = указатель на начало буфера, куда будут прочитаны данные + cur_limit = размер буфера (не меньше esi) +на выходе: + es:bx указывает на конец буфера, в который были прочитаны данные + если произошла ошибка чтения, флаг CF установлен + cur_limit соответствующим образом уменьшен +Отличие двух процедур: вторая дополнительно принимает во внимание переменную + [first_byte], начиная чтение первого блока со смещения [first_byte]; + соответственно, первая читает блок с начала, обнуляя [first_byte] + при входе. +1. Отдельно считывает первый физический сектор во временную область 0000:1000, + если первый логический блок начинается не с начала сектора. При + ошибке чтения выходит из процедуры. +2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, + в буфер. Нормализует указатель на буфер. +3. Если все необходимые данные уже прочитаны, выходит из процедуры. +4. Дальнейшие данные находятся в нескольких физических секторах, при этом, + возможно, последний сектор считывать нужно не целиком. +5. Если в буфере есть место для считывания всех секторов, то сразу читаются + все сектора, после чего указатель на буфер нужным образом уменьшается. +6. Если же нет, то считываются все сектора, кроме последнего, после чего + последний сектор считывается отдельно во временную область, и уже + оттуда нужная часть данных копируется в буфер. diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/build.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/build.bat new file mode 100644 index 000000000..93b242702 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/cdfs/build.bat @@ -0,0 +1,2 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.asm new file mode 100644 index 000000000..772829f06 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.asm @@ -0,0 +1,392 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +use_lba = 0 + org 0x7C00 + jmp start + nop +; FAT parameters, BPB +; note: they can be changed at install, replaced with real values +; these settings are for most typical 1.44M floppies + db 'KOLIBRI ' ; BS_OEMName, ignored + dw 200h ; BPB_BytsPerSec +BPB_SecsPerClus db 1 +BPB_RsvdSecCnt dw 1 +BPB_NumFATs db 2 +BPB_RootEntCnt dw 0xE0 + dw 2880 ; BPB_TotSec16 + db 0xF0 ; BPB_Media +BPB_FATSz16 dw 9 +BPB_SecPerTrk dw 18 +BPB_NumHeads dw 2 +BPB_HiddSec dd 0 + dd 0 ; BPB_TotSec32 +BS_DrvNum db 0 + db 0 ; BS_Reserved1 + db ')' ; BS_BootSig + dd 12344321h ; BS_VolID +filename: + db 'KORD.OS ' ; BS_VolLab + db 'FAT12 ' ; BS_FilSysType +; Used memory map: +; 8000:0000 - current directory +; 9000:0000 - root directory data [cached] +start: + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov bp, sp + cld + sti + mov [bp+BS_DrvNum-0x7C00], dl +if use_lba + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cx, 1 + jz err_ +else + mov ah, 8 + int 13h + jc @f ; on error, assume that BPB geometry is valid + mov al, dh + mov ah, 0 + inc ax + mov [bp+BPB_NumHeads-0x7C00], ax + and cx, 3Fh + mov [bp+BPB_SecPerTrk-0x7C00], cx +@@: +end if +; get FAT parameters + xor bx, bx + mov al, [bp+BPB_NumFATs-0x7C00] + mov ah, 0 + mul [bp+BPB_FATSz16-0x7C00] + add ax, [bp+BPB_RsvdSecCnt-0x7C00] + adc dx, bx + push dx + push ax ; root directory start = dword [bp-4] + mov cx, [bp+BPB_RootEntCnt-0x7C00] + add cx, 0xF + rcr cx, 1 + shr cx, 3 ; cx = size of root directory in sectors + add ax, cx + adc dx, bx + push dx + push ax ; data start = dword [bp-8] +; load start of root directory (no more than 0x2000 bytes = 0x10 sectors) + cmp cx, 0x10 + jb @f + mov cx, 0x10 +@@: + mov ax, [bp-4] + mov dx, [bp-2] + push 0x9000 + pop es + call read_sectors + add word [bp-4], cx ; dword [bp-4] = start of non-cached root data + adc word [bp-2], bx +; load kordldr.f12 + mov si, main_loader + call lookup_in_root_dir + jc noloader + test byte [es:di+11], 10h ; directory? + jz kordldr_ok +noloader: + mov si, aLoaderNotFound +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ +kordldr_ok: + mov ax, [es:di+26] ; get file cluster + mov bx, 0x7E00 + xor cx, cx + mov es, cx + sub ax, 2 + jc noloader + push bx ; save return address: bx = 7E00 + mov cl, [bp+BPB_SecsPerClus-0x7C00] + mul cx +; fall through - 'ret' in read_sectors will return to 7E00 + +read_sectors2: +; same as read_sectors, but dx:ax is relative to start of data + add ax, [bp-8] + adc dx, [bp-6] +read_sectors: +; ss:bp = 0:7C00 +; es:bx = pointer to data +; dx:ax = first sector +; cx = number of sectors + pusha + add ax, word [bp+BPB_HiddSec-0x7C00] + adc dx, word [bp+BPB_HiddSec+2-0x7C00] +if use_lba + push ds +do_read_sectors: + push ax + push cx + push dx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F +@@: +; create disk address packet on the stack +; dq starting LBA + push 0 + push 0 + push dx + push ax +; dd buffer + push es + push bx +; dw number of blocks to transfer (no more than 0x7F) + push cx +; dw packet size in bytes + push 10h +; issue BIOS call + push ss + pop ds + mov si, sp + mov dl, [bp+BS_DrvNum-0x7C00] + mov ah, 42h + int 13h + mov si, aReadError + jc err_ +; restore stack + add sp, 10h +; increase current sector & buffer; decrease number of sectors + mov si, cx + mov ax, es + shl cx, 5 + add ax, cx + mov es, ax + pop dx + pop cx + pop ax + add ax, si + adc dx, 0 + sub cx, si + jnz do_read_sectors + pop ds + popa + ret +else +do_read_sectors: + pusha + pop di + push bx + +; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx + mov si, ax + xchg ax, dx + xor dx, dx + div [bp+BPB_SecPerTrk-0x7C00] + push ax + mov ax, si + div [bp+BPB_SecPerTrk-0x7C00] + mov bx, dx ; bx=sector-1 + pop dx + +; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx + div [bp+BPB_NumHeads-0x7C00] + +; number of sectors: read no more than to end of track + push bx + sub bx, [bp+BPB_SecPerTrk-0x7C00] + neg bx + cmp cx, bx + jbe @f + mov cx, bx +@@: + pop bx + + inc bx +; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format + mov di, cx + mov dh, dl + mov dl, [bp+BS_DrvNum-0x7C00] + shl ah, 6 + mov ch, al + mov al, cl + mov cl, bl + or cl, ah + pop bx + mov si, 3 + mov ah, 2 +@@: + push ax + int 13h + jnc @f + xor ax, ax + int 13h ; reset drive + pop ax + dec si + jnz @b + mov si, aReadError + jmp err_ +@@: + pop ax + mov ax, es + mov cx, di + shl cx, 5 + add ax, cx + mov es, ax + push di + popa + add ax, di + adc dx, 0 + sub cx, di + jnz do_read_sectors + popa + ret +end if + +scan_for_filename: +; in: ds:si -> 11-bytes FAT name +; in: es:0 -> part of directory data +; in: cx = number of entries +; out: if found: CF=0, ZF=1, es:di -> directory entry +; out: if not found, but continue required: CF=1 and ZF=0 +; out: if not found and zero item reached: CF=1 and ZF=1 + xor di, di + push cx +sloop: + cmp byte [es:di], 0 + jz snotfound + test byte [es:di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmpsb + popa + jz sdone +scont: + add di, 0x20 + loop sloop + inc cx ; clear ZF flag +snotfound: + stc +sdone: + pop cx +lrdret: + ret + +lookup_in_root_dir: +; ss:bp = 0:7C00 +; in: ds:si -> 11-bytes FAT name +; out: if found: CF=0, es:di -> directory entry +; out: if not found: CF=1 + mov cx, [bp+BPB_RootEntCnt-0x7C00] + push cx +; first, look in root directory cache + push 0x9000 + pop es + test ch, ch + jz @f + mov cx, 0x100 +@@: + mov ax, [bp-4] + mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory +lrdloop: + call scan_for_filename + pop bx + jz lrdret + sub bx, cx + mov cx, bx + stc + jz lrdret +; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries + push cx + cmp ch, 0x8 + jb @f + mov cx, 0x800 +@@: + push 0x8000 + pop es + push cx + push es + xor bx, bx + add cx, 0xF + shr cx, 4 + call read_sectors + pop es + add ax, cx + adc dx, bx + pop cx + jmp lrdloop + +out_string: +; in: ds:si -> ASCIIZ string + lodsb + test al, al + jz lrdret + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string + +aReadError db 'Read error',0 +if use_lba +aNoLBA db 'The drive does not support LBA!',0 +end if +aLoaderNotFound db 'Loader not found',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 +main_loader db 'KORDLDR F1X' + +if use_lba + db 0 ; make bootsector 512 bytes in length +end if + +; bootsector signature + dw 0xAA55 + +; display offsets of all procedures used by kordldr.f12.asm +macro show [procedure] +{ + bits = 16 + display `procedure,' = ' + repeat bits/4 + d = '0' + procedure shr (bits - %*4) and 0Fh + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 +} + +show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.txt b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.txt new file mode 100644 index 000000000..26a9621e1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/bootsect.txt @@ -0,0 +1,360 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + Встречаются вирус и FAT. + - Привет, ты кто? + - Я? Вирус. + - A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... + +Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. + +===================================================================== + +Есть две версии в зависимости от того, поддерживает ли носитель LBA, +выбор осуществляется установкой константы use_lba в первой строке исходника. +Требования для работы: +1) Сам бутсектор, первая копия FAT и все используемые файлы +должны быть читабельны. +2) Минимальный процессор - 80186. +3) В системе должно быть как минимум 592K свободной базовой памяти. + +===================================================================== + +Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): + официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf + русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip + официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf + то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf + описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html + официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf + +===================================================================== + +Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер +занимает 12 бит в таблице FAT, так что общий размер не превосходит +0x17EE = 6126 байт. Вся таблица помещается в памяти. +Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый +кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит +0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в +этом случае несколько нецелесообразно считывать всю таблицу, поскольку +на практике нужна только небольшая её часть. Поэтому место в памяти +резервируется, но данные считываются только в момент, когда к ним +действительно идёт обращение. + +Схема используемой памяти: + ...-7C00 стек + 7C00-7E00 код бутсектора + 7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) + 8200-8300 список загруженных секторов таблицы FAT16 + (1 = соответствующий сектор загружен) + 60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 + 80000-90000 текущий кластер текущей рассматриваемой папки + 90000-92000 кэш для корневой папки + 92000-... кэш для некорневых папок (каждой папке отводится + 2000h байт = 100h входов, одновременно в кэше + может находиться не более 7 папок; + точный размер определяется размером доступной + физической памяти - как правило, непосредственно + перед A0000 размещается EBDA, Extended BIOS Data Area) + +===================================================================== + +Основной процесс загрузки. +Точка входа (start): получает управление от BIOS при загрузке, при этом + dl содержит идентификатор диска, с которого идёт загрузка +1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед + кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало + бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - + это освобождает ds и экономит на размере кода). +2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h + прерывания 13h. Если нет, переходит на код обработки ошибок с + сообщением об отсутствии LBA. +CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и + записывает полученные данные поверх BPB. Если вызов завершился ошибкой, + предполагает уже существующие данные корректными. +3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки + и начальный сектор данных. Кладёт их в стек; впоследствии они + всегда будут лежать в стеке и адресоваться через bp. +4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых + секторов - минимум из размера корневой папки, указанного в BPB, и 16 + (размер кэша для корневой папки - 2000h байт = 16 секторов). +5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если + он оказывается папкой, или если файл имеет нулевую длину - + переходит на код обработки ошибок с сообщением о + ненайденном загрузчике. + Замечание: на этом этапе загрузки искать можно только в корневой + папке и только имена, заданные в формате файловой системе FAT + (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны + быть заглавными, при необходимости имя и расширение дополняются + пробелами, разделяющей точки нет, завершающего нуля нет). +6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт + ему управление. При этом в регистрах dx:ax оказывается абсолютный + номер первого сектора kordldr.f1x, а в cx - число считанных секторов + (равное размеру кластера). + +Вспомогательные процедуры бутсектора. +Код обработки ошибок (err): +1. Выводит строку с сообщением об ошибке. +2. Выводит строку "Press any key...". +3. Ждёт нажатия any key. +4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. +5. Для подстраховки зацикливается. + +Процедура чтения секторов (read_sectors и read_sectors2): +на входе должно быть установлено: + ss:bp = 0:7C00 + es:bx = указатель на начало буфера, куда будут прочитаны данные + dx:ax = стартовый сектор (относительно начала логического диска + для read_sectors, относительно начала данных для read_sectors2) + cx = число секторов (должно быть больше нуля) +на выходе: es:bx указывает на конец буфера, в который были прочитаны данные +0. Если вызывается read_sectors2, она переводит указанный ей номер сектора + в номер относительно начала логического диска, прибавляя номер сектора + начала данных, хранящийся в стеке как [bp-8]. +1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на + устройстве, прибавляя значение соответствующего поля из BPB. +2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации + CHS-версия: все читаемые секторы были на одной дорожке. + LBA-версия: число читаемых секторов не превосходило 7Fh (требование + спецификации EDD BIOS). +CHS-версия: +3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как + единица плюс остаток от деления абсолютного номера на число секторов + на дорожке; дорожка рассчитывается как остаток от деления частного, + полученного на предыдущем шаге, на число дорожек, а цилиндр - как + частное от этого же деления. Если число секторов для чтения больше, + чем число секторов до конца дорожки, уменьшает число секторов для + чтения. +4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, + dh=головка, (младшие 6 бит cl)=сектор, + (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска + и повторяет попытку чтения, всего делается не более трёх попыток + (несколько попыток нужно в случае дискеты для гарантии того, что + мотор раскрутился). Если все три раза происходит ошибка чтения, + переходит на код обработки ошибок с сообщением "Read error". +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. +LBA-версия: +3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей + итерации) до 7Fh. +4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами + push, причём в обратном порядке: стек - структура LIFO, и данные в + стеке хранятся в обратном порядке по отношению к тому, как их туда + клали). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки + ошибок с сообщением "Read error". Очищает стек от пакета, + сформированного на предыдущем шаге. +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. + +Процедура поиска элемента по имени в уже прочитанных данных папки + (scan_for_filename): +на входе должно быть установлено: + ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, + 3 на расширение, все буквы заглавные, если имя/расширение + короче, оно дополняется до максимума пробелами) + es = сегмент данных папки + cx = число элементов в прочитанных данных +на выходе: ZF определяет, нужно ли продолжать разбор данных папки + (ZF=1, если либо найден запрошенный элемент, либо достигнут + конец папки); CF определяет, удалось ли найти элемент с искомым именем + (CF=1, если не удалось); если удалось, то es:di указывает на него. +scan_for_filename считает, что данные папки размещаются начиная с es:0. +Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки +проверяет имена. + +Процедура поиска элемента в корневой папке (lookup_in_root_dir): +на входе должно быть установлено: + ss:bp = 0:7C00 + ds:si = указатель на имя файла в формате FAT (см. выше) +на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то + CF сброшен и es:di указывает на элемент папки +Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле + сканирует элементы; если по результатам сканирования обнаруживает, + что нужно читать папку дальше, то считывает не более 0x10000 = 64K + байт (ограничение введено по двум причинам: во-первых, чтобы заведомо + не вылезти за пределы используемой памяти, во-вторых, сканирование + предполагает, что все обрабатываемые элементы располагаются в одном + сегменте) и продолжает цикл. +Сканирование прекращается в трёх случаях: обнаружен искомый элемент; + кончились элементы в папке (судя по числу элементов, указанному в BPB); + очередной элемент папки сигнализирует о конце (первый байт нулевой). + +Процедура вывода на экран ASCIIZ-строки (out_string): +на входе: ds:si -> строка +В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. + +===================================================================== + +Работа вспомогательного загрузчика kordldr.f1x: +1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. + В зависимости от этого устанавливает смещения используемых процедур + бутсектора. Критерий проверки: scan_for_filename должна начинаться + с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может + с равным успехом ассемблироваться и как 33 FF, но fasm генерирует + именно такую форму). +2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска + адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с + ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента + место должно быть, отсюда ограничение в 592 Kb (94000h байт). + Замечание: этот размер не может превосходить 0A0000h байт и + на практике оказывается немного (на 1-2 килобайта) меньшим из-за + наличия дополнительной области данных BIOS "вверху" базовой памяти. +3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной + спецификации от Microsoft (версия 1.03 спецификации датирована, + к слову, 06 декабря 2000 года), разрядность FAT определяется + исключительно числом кластеров: максимальное число кластеров на + FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 + может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, + а число 0xFF7 не может быть корректным номером кластера. + Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается + по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает + явно неверно, считая, что 0xFF6 (или меньше) кластеров означает + FAT12-том, в результате получается, что последний кластер + (в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe + [встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик + [бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы + лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили + в соответствии со спецификацией. Linux при определении FAT12/FAT16 + честно следует спецификации. + Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT + Microsoft если и будет исправлять ошибки, то согласно собственному + описанию. +4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. + Если размер, указанный в BPB, превосходит 12 секторов, + это означает, что заявленный размер слишком большой (это не считается + ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 + заведомо влезает в такой объём данных). +Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор + FAT не загружен (они будут подгружаться позднее, когда понадобятся + и только те, которые понадобятся). +5. Если кластер равен сектору, то бутсектор загрузил только часть файла + kordldr.f1x, и загрузчик подгружает вторую свою часть, используя + значения регистров на входе в kordldr.f1x. +6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не + найден, или оказался папкой, или оказался слишком большим, то переходит + на код обработки ошибок из бутсектора с сообщением + "Fatal error: cannot load the secondary loader". + Замечание: на этом этапе имя файла уже можно указывать вместе с путём + и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов + по-прежнему нет. +7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. + Это нужно, чтобы последующие обращения к коду бутсектора в случае + ошибок чтения не выводил соответствующее сообщение с последующей + перезагрузкой, а рапортовал об ошибке чтения, которую мог бы + как-нибудь обработать вторичный загрузчик. +8. Если загрузочный диск имеет идентификатор меньше 0x80, + то устанавливает al='f' ("floppy"), ah=идентификатор диска, + иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). + Устанавливает bx='12', если тип файловой системы - FAT12, и + bx='16' в случае FAT16. Устанавливает si=смещение функции обратного + вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. +9. Передаёт управление по адресу 1000:0000. + +Функция обратного вызова для вторичного загрузчика: + предоставляет возможность чтения файла. +Вход и выход описаны в спецификации на загрузчик. +1. Сохраняет стек вызывающего кода и устанавливает свой стек: + ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным + кодом должна указывать на 0:7C00, а -8 берётся от того, что + инициализирующий код бутсектора уже поместил в стек 2 двойных слова, + и они должны сохраняться в неизменности. +2. Разбирает переданные параметры, выясняет, какое действие запрошено, + и вызывает нужную вспомогательную процедуру. +3. Восстанавливает стек вызывающего кода и возвращает управление. + +Вспомогательные процедуры kordldr.f1x. +Процедура получения следующего кластера в FAT (get_next_cluster): +1. Вспоминает разрядность FAT, вычисленную ранее. +Для FAT12: +2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана + вся таблица FAT. +3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте + слова, задающего следующий кластер. Загружает слово по этому адресу. +4. Если кластер имеет нечётный номер, то соответствующий ему элемент + располагается в старших 12 битах слова, и слово нужно сдвинуть вправо + на 4 бита; в противном случае - в младших 12 битах, и делать ничего не + надо. +5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: + номера нормальных кластеров меньше, и флаг CF устанавливается; + специальные значения EOF и BadClus сбрасывают флаг CF. +Для FAT16: +2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных + в таблице FAT. +3. Если сектор ещё не загружен, то загружает его. +4. Вычисляет смещение данных для конкретного кластера относительно начала + сектора. +5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. +6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг + CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. + +Процедура загрузки файла (load_file): +1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. +2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты + разделяются символом '/') в FAT-формат 8+3. Если это невозможно + (больше 8 символов в имени, больше 3 символов в расширении или + больше одной точки), возвращается с ошибкой. +3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой + папки используется процедура из бутсектора. Для остальных папок: + a) Проверяет, есть ли такая папка в кэше некорневых папок. + (Идентификация папок осуществляется по номеру начального кластера.) + Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, + выкидывает папку, к которой дольше всего не было обращений. (Для + каждого элемента кэша хранится метка от 0 до (размер кэша)-1, + определяющая его номер при сортировке по давности последнего обращения. + При обращении к какому-то элементу его метка становится нулевой, + а те метки, которые меньше старого значения, увеличиваются на единицу.) + б) Просматривает в поисках запрошенного имени все элементы из кэша, + используя процедуру из бутсектора. Если обнаруживает искомый элемент, + переходит к шагу 4. Если обнаруживает конец папки, возвращается из + процедуры с ошибкой. + в) В цикле считывает папку посекторно. При этом пропускает начальные + секторы, которые уже находятся в кэше и уже были просмотрены. Каждый + прочитанный сектор копирует в кэш, если там ещё остаётся место, + и просматривает в нём все элементы. Работает, пока не случится одно из + трёх событий: найден искомый элемент; кончились кластеры (судя по + цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце + (первый байт нулевой). В двух последних случаях возвращается с ошибкой. +4. Проверяет тип найденного элемента (файл/папка): последний элемент в + запрошенном имени должен быть файлом, все промежуточные - папками. + Если текущий компонент имени - промежуточный, продвигает текущую + рассматриваемую папку и возвращается к пункту 2. +5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный + при вызове буфер последовательными вызовами функции бутсектора; + при этом если несколько кластеров файла расположены на диске + последовательно, то их чтение объединяется в одну операцию. + Следит за тем, чтобы не превысить указанный при вызове процедуры + лимит числа секторов для чтения. + +Процедура продолжения загрузки файла (continue_load_file): встроена + внутрь шага 5 load_file; загружает в регистры нужные значения (ранее + сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/build.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/build.bat new file mode 100644 index 000000000..17c30cac1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/build.bat @@ -0,0 +1,3 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@fasm -m 65535 kordldr.f1x.asm kordldr.f1x +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm new file mode 100644 index 000000000..6f2348ae6 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm @@ -0,0 +1,667 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + org 0x7E00 +; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here +; ss:bp = 0:7C00 +virtual at bp + rb 3 ; BS_jmpBoot + rb 8 ; BS_OEMName, ignored + dw ? ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? +BPB_TotSec16 dw ? + db ? ; BPB_Media +BPB_FATSz16 dw ? +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? +BPB_TotSec32 dd ? +BS_DrvNum db ? +fat_type db ? ; this is BS_Reserved1, + ; we use it to save FS type: 0=FAT12, 1=FAT16 + db ? ; BS_BootSig +num_sectors dd ? ; BS_VolID +; rb 11 ; BS_VolLab +; rb 3 ; BS_FilSysType, first 3 bytes +read_sectors dw ? +read_sectors2 dw ? +lookup_in_root_dir dw ? +scan_for_filename dw ? +err_ dw ? +noloader dw ? +cachelimit dw ? +filesize: ; will be used to save file size + rb 5 ; BS_FilSysType, last 5 bytes +; following variables are located in the place of starting code; +; starting code is no more used at this point +sect_per_clus dw ? +cur_cluster dw ? +next_cluster dw ? +flags dw ? +cur_delta dd ? +end virtual + +; procedures from boot sector +; LBA version +lba_read_sectors = 7CE2h +lba_read_sectors2 = 7CDCh +lba_lookup_in_root_dir = 7D4Fh +lba_scan_for_filename = 7D2Dh +lba_err = 7CB5h +lba_noloader = 7CB2h +; CHS version +chs_read_sectors = 7CDEh +chs_read_sectors2 = 7CD8h +chs_lookup_in_root_dir = 7D70h +chs_scan_for_filename = 7D4Eh +chs_err = 7CB1h +chs_noloader = 7CAEh + + push ax cx ; save our position on disk + push ss + pop es +; determine version of bootsector (LBA vs CHS) +; mov [read_sectors], chs_read_sectors +; mov [read_sectors2], chs_read_sectors2 +; mov [lookup_in_root_dir], chs_lookup_in_root_dir +; mov [scan_for_filename], chs_scan_for_filename +; mov [err], chs_err +; mov [noloader], chs_noloader + lea di, [read_sectors] + mov si, chs_proc_addresses + mov cx, 6*2 + cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' + jz @f + add si, cx +; mov [read_sectors], lba_read_sectors +; mov [read_sectors2], lba_read_sectors2 +; mov [lookup_in_root_dir], lba_lookup_in_root_dir +; mov [scan_for_filename], lba_scan_for_filename +; mov [err], lba_err +; mov [noloader], lba_noloader +@@: + rep movsb + mov cl, [BPB_SecsPerClus] + mov [sect_per_clus], cx + xor bx, bx +; determine size of cache for folders + int 12h ; ax = size of available base memory in Kb + sub ax, 94000h / 1024 + jae @f +nomem: + mov si, nomem_str + jmp [err_] +@@: + shr ax, 3 + mov [cachelimit], ax ; size of cache - 1 +; get type of file system - FAT12 or FAT16? +; calculate number of clusters + mov ax, [BPB_TotSec16] + xor dx, dx + test ax, ax + jnz @f + mov ax, word [BPB_TotSec32] + mov dx, word [BPB_TotSec32+2] +@@: + sub ax, [bp-8] ; dword [bp-8] = first data sector + sbb dx, [bp-6] + jb j_noloader + div [sect_per_clus] +; ax = number of clusters +; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes + mov [fat_type], ch + cmp ax, 0xFF5 + jb init_fat12 + inc [fat_type] +init_fat16: +; no sectors loaded + mov di, 0x8200 + xor ax, ax + mov cx, 0x100/2 + rep stosw + jmp init_fat_done +init_fat12: +; read FAT + push 0x6000 + pop es + mov ax, [BPB_RsvdSecCnt] + mov cx, [BPB_FATSz16] + cmp cx, 12 + jb @f + mov cx, 12 +@@: + xor dx, dx + call [read_sectors] +init_fat_done: +; if cluster = sector, we need to read second part of our file +; (bootsector loads only first cluster of kordldr.f1x) + pop cx ax ; restore our position on disk + cmp cx, 1 + ja kordldr_full + sub ax, [bp-8] + inc ax + inc ax ; ax = first cluster of kordldr.f12 + call get_next_cluster + jc @f +j_noloader: + jmp [noloader] +@@: + dec ax + dec ax + push 0x800 + pop es + call [read_sectors2] +kordldr_full: +; ...continue loading... + mov di, secondary_loader_info + call load_file + test bx, bx + mov bx, [err_] + jz @f + mov si, aKernelNotFound + jmp bx +@@: +; for subsequent calls to callback function, hook error handler +; mov byte [bx], 0xE9 ; 'jmp' opcode +; mov ax, hooked_err - 3 +; sub ax, bx +; mov word [bx+1], ax +; push hooked_err / ret + mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) + mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) +; set registers for secondary loader + mov ah, [BS_DrvNum] + mov al, 'f' + test ah, ah + jns @f + sub ah, 80h + mov al, 'h' +@@: + mov bx, '12' + cmp [fat_type], 0 + jz @f + mov bh, '6' +@@: + mov si, callback ; ds:si = far pointer to callback procedure + jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 + +nomem_str db 'No memory',0 + +chs_proc_addresses: + dw chs_read_sectors + dw chs_read_sectors2 + dw chs_lookup_in_root_dir + dw chs_scan_for_filename + dw chs_err + dw chs_noloader +lba_proc_addresses: + dw lba_read_sectors + dw lba_read_sectors2 + dw lba_lookup_in_root_dir + dw lba_scan_for_filename + dw lba_err + dw lba_noloader + +get_next_cluster: +; in: ax = cluster +; out: if there is next cluster: CF=1, ax = next cluster +; out: if there is no next cluster: CF=0 + push si + cmp [fat_type], 0 + jnz gnc16 +; for FAT12 + push ds + push 0x6000 + pop ds + mov si, ax + shr si, 1 + add si, ax + test al, 1 + lodsw + jz @f + shr ax, 4 +@@: + and ax, 0xFFF + cmp ax, 0xFF7 + pop ds si + ret +; for FAT16 +gnc16: +; each sector contains 200h bytes = 100h FAT entries +; so ah = # of sector, al = offset in sector + mov si, ax + mov ah, 0 + shr si, 8 +; calculate segment for this sector of FAT table +; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) +; segment = 6000 + 20*si, offset = 0 + push es + push si + shl si, 5 + add si, 0x6000 + mov es, si + pop si + cmp byte [ss:0x8200+si], ah ; sector already loaded? + jnz @f +; load corresponding sector + pusha + push es + xor bx, bx + mov ax, [BPB_RsvdSecCnt] + xor dx, dx + add ax, si + adc dx, bx + mov cx, 1 ; read 1 sector + call [read_sectors] + pop es + popa +@@: + mov si, ax + add si, si +; mov ax, [es:si] + lods word [es:si] + pop es + cmp ax, 0xFFF7 + pop si + ret + +if $ > 0x8000 +error 'get_next_cluster must fit in first sector of kordldr.f1x!' +end if + +load_file: +; in: ss:bp = 0:7C00 +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found +; out: dx:ax = file size (0xFFFFFFFF if file not found) + xor ax, ax ; start from root directory + mov dx, -1 + mov word [filesize], dx + mov word [filesize+2], dx ; initialize file size with invalid value + lea si, [di+6] +parse_dir_loop: +; convert name to FAT name + push di + push ax + push ss + pop es +; convert ASCIIZ filename to FAT name + mov di, filename + push di + mov cx, 8+3 + mov al, ' ' + rep stosb + pop di + mov cl, 8 ; 8 symbols per name + mov bl, 1 +nameloop: + lodsb + test al, al + jz namedone + cmp al, '/' + jz namedone + cmp al, '.' + jz namedot + dec cx + js badname + cmp al, 'a' + jb @f + cmp al, 'z' + ja @f + sub al, 'a'-'A' +@@: + stosb + jmp nameloop +namedot: + inc bx + jp badname + add di, cx + mov cl, 3 + jmp nameloop +badname: ; do not make direct js/jp to notfound_pop: + ; this generates long forms of conditional jumps and results in longer code + jmp notfound_pop +namedone: +; scan directory + pop ax ; ax = cluster of directory or 0 for root + push ds + push si + push es + pop ds + mov si, filename ; ds:si -> filename in FAT style + test ax, ax + jnz lookup_in_notroot_dir +; for root directory, use the subroutine from bootsector + call [lookup_in_root_dir] + jmp lookup_done +lookup_in_notroot_dir: +; for other directories, read a folder sector-by-sector and scan +; first, try to use the cache + push ds + push cs + pop ds + mov bx, [cachelimit] + add bx, bx + mov di, foldcache_mark +@@: + mov dx, [foldcache_clus+di-foldcache_mark+bx] + cmp dx, ax + jz cacheok + test dx, dx + jz cacheadd ; the cache has place for new entry + dec bx + dec bx + jns @b +; the folder is not present in the cache, so add it +; the cache is full; find the oldest entry and replace it with the new one + mov dx, [cachelimit] +@@: + inc bx + inc bx + cmp word [di+bx], dx ; marks have values 0 through [cachelimit] + jnz @b +cacheadd: + or word [di+bx], 0xFFFF ; very big value, it will be changed soon + mov [foldcache_clus+di-foldcache_mark+bx], ax + and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet +cacheok: +; update cache marks + mov dx, [di+bx] + mov cx, [foldcache_size+di-foldcache_mark+bx] + mov di, [cachelimit] + add di, di +cacheupdate: + cmp [foldcache_mark+di], dx + adc [foldcache_mark+di], 0 + dec di + dec di + jns cacheupdate + and [foldcache_mark+bx], 0 +; done, bx contains (position in cache)*2 + pop ds +; mov dx, bx +; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 +; add dx, 0x9200 + lea dx, [bx+0x92] + xchg dl, dh + mov es, dx + jcxz not_in_cache + call [scan_for_filename] + jz lookup_done +not_in_cache: +; cache miss, read folder data from disk + mov bx, cx + shr bx, 4 + shl cx, 5 + mov di, cx ; es:di -> free space in cache entry +; external loop: scan clusters +folder_next_cluster: +; internal loop: scan sectors in cluster + mov cx, [sect_per_clus] + push ax + dec ax + dec ax + mul cx + add ax, [bp-8] + adc dx, [bp-6] ; dx:ax = absolute sector +folder_next_sector: +; skip first bx sectors + dec bx + jns folder_skip_sector + push cx + push es di + push 0x8000 + pop es + xor bx, bx + mov cx, 1 + push es + call [read_sectors] +; copy data to the cache... + pop ds + pop di es + cmp di, 0x2000 ; ...if there is free space, of course + jae @f + push si di + mov cx, 0x100 + xor si, si + rep movsw + mov di, es + shr di, 8 + add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache + pop di si +@@: + push es + push 0x8000 + pop es + push cs + pop ds + mov cx, 0x10 + call [scan_for_filename] + pop es + pop cx + jz lookup_done_pop +folder_skip_sector: + inc ax + jnz @f + inc dx +@@: + loop folder_next_sector + pop ax ; ax = current cluster + call get_next_cluster + jc folder_next_cluster + stc + push ax +lookup_done_pop: + pop ax +lookup_done: + pop si + pop ds +; CF=1 <=> failed + jnc found +notfound: + pop di + mov bx, 2 ; file not found + mov ax, 0xFFFF + mov dx, ax ; invalid file size + ret +notfound_pop: + pop ax + jmp notfound +found: + mov ax, [es:di+26] ; get cluster + test byte [es:di+11], 10h ; directory? + jz regular_file + cmp byte [si-1], 0 + jz notfound ; don't read directories as a regular files +; ok, we have found a directory and the caller requested a file into it + pop di + jmp parse_dir_loop ; restart with new cluster in ax +regular_file: + cmp byte [si-1], 0 + jnz notfound ; file does not contain another files +; ok, we have found a regular file and the caller requested it +; save file size + mov dx, [es:di+28] + mov [filesize], dx + mov dx, [es:di+30] + mov [filesize+2], dx + pop di + mov si, [di+4] + shl si, 3 + push si ; [ds:di+4] = limit in 4K blocks + les bx, [di] ; es:bx -> buffer +clusloop: +; ax = first cluster, top of stack contains limit in sectors + mov si, ax ; remember current cluster + xor cx, cx ; cx will contain number of consecutive clusters + mov word [cur_delta], cx + mov word [cur_delta+2], cx + mov di, ax +clusfind: + inc di + inc cx + call get_next_cluster + jnc clusread + cmp ax, di + jz clusfind + stc +clusread: + pop di ; limit in sectors + push ax ; save next cluster + pushf ; save flags +; read cx clusters, starting from si +; calculate number of sectors + xchg ax, cx + mul [sect_per_clus] +; dx:ax = number of sectors; compare with limit + mov word [num_sectors], ax + mov word [num_sectors+2], dx + jmp @f +continue_load_file: + les bx, [di] ; es:bx -> buffer + mov di, [di+4] ; ds:di = limit in 4K blocks + shl di, 3 ; now di = limit in sectors + mov ax, word [num_sectors] + mov dx, word [num_sectors+2] + mov si, [cur_cluster] + push [next_cluster] + push [flags] + or ax, dx + jz nextclus +@@: + test dx, dx + jnz clusdecrease + push dx ; limit was not exceeded + cmp ax, di + jbe @f + pop ax +clusdecrease: + push 1 ; limit was exceeded + mov ax, di +@@: + sub di, ax ; calculate new limit + sub word [num_sectors], ax + sbb word [num_sectors+2], 0 +; calculate starting sector + xchg ax, cx + lea ax, [si-2] + mul [sect_per_clus] + add ax, word [cur_delta] + adc dx, word [cur_delta+2] + add word [cur_delta], cx + adc word [cur_delta+2], 0 +; read + call [read_sectors2] + pop dx +; next cluster? +nextclus: + popf + pop ax + mov [cur_cluster], si + mov [next_cluster], ax + pushf + pop [flags] + jnc @f ; no next cluster => return + mov dl, 1 ; dh=0 in any case + test di, di + jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded + push di + jmp clusloop ; all is ok, continue +hooked_err: + mov sp, 7C00h-12-2 ; restore stack + mov dx, 3 ; return: read error +@@: + mov bx, dx + mov ax, [filesize] + mov dx, [filesize+2] + ret + +; Callback function for secondary loader +callback: +; in: ax = function number; only functions 1 and 2 are defined for now +; save caller's stack + mov dx, ss + mov cx, sp +; set our stack (required because we need ss=0) + xor si, si + mov ss, si + mov sp, 7C00h-8 + mov bp, 7C00h + push dx + push cx +; call our function + stc ; unsupported function + dec ax + jz callback_readfile + dec ax + jnz callback_ret +; function 2: continue loading file +; can be called only after function 1 returned value bx=1 (only part of file was loaded) +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error +; out: dx:ax = file size + call continue_load_file + jmp callback_ret_succ +callback_readfile: +; function 1: read file +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error +; out: dx:ax = file size (0xFFFFFFFF if file was not found) + call load_file +callback_ret_succ: + clc ; function is supported +callback_ret: +; restore caller's stack + pop cx + pop ss + mov sp, cx +; return to caller + retf + +secondary_loader_info: + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + +foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache +foldcache_mark rw 7 +foldcache_size rw 7 +filename rb 11 +if $ > 0x8200 +error: table overwritten +end if diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.asm new file mode 100644 index 000000000..3dbee8865 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.asm @@ -0,0 +1,358 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +use_lba = 0 + org 0x7C00 + jmp start + nop +; FAT parameters, BPB +; they must be changed at install, replaced with real values + rb 8 ; BS_OEMName, ignored + dw 200h ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? + dw ? ; BPB_TotSec16 + db ? ; BPB_Media + dw ? ; BPB_FATSz16 = 0 for FAT32 +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? + dd ? ; BPB_TotSec32 +BPB_FATSz32 dd ? +BPB_ExtFlags dw ? + dw ? ; BPB_FSVer +BPB_RootClus dd ? + dw ? ; BPB_FSInfo +BPB_BkBootSec dw ? + rb 12 ; BPB_Reserved +BS_DrvNum db ? + db ? ; BS_Reserved1 + db ? ; BS_BootSig + dd ? ; BS_VolID + rb 11 ; BS_VolLab + rb 8 ; + +curseg dw 0x8000 + +start: + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov bp, sp + cld + sti + push dx ; byte [bp-2] = boot drive +if use_lba + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cl, 1 + jz err_ +else + mov ah, 8 + int 13h + jc @f + movzx ax, dh + inc ax + mov [bp+BPB_NumHeads-0x7C00], ax + and cx, 3Fh + mov [bp+BPB_SecPerTrk-0x7C00], cx +@@: +end if +; get FAT parameters + xor bx, bx + movzx eax, [bp+BPB_NumFATs-0x7C00] + mul [bp+BPB_FATSz32-0x7C00] + movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] + push ecx ; FAT start = dword [bp-6] + add eax, ecx + push eax ; data start = dword [bp-10] + ;push dword -1 ; dword [bp-14] = current sector for FAT cache + db 66h + push -1 ; dword [bp-14] = current sector for FAT cache + mov eax, [bp+BPB_RootClus-0x7C00] + mov si, main_loader + call lookup_in_dir + jnc kordldr_ok +noloader: + mov si, aLoaderNotFound +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ +kordldr_ok: + mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) + mov ax, [es:di+26] ; loword(eax) = loword(cluster) + mov es, bx ; es = 0 + mov bx, 0x7E00 + push bx ; save return address: bx = 7E00 +; fall through - 'ret' in read_cluster will return to 7E00 + +read_cluster: +; ss:bp = 0:7C00 +; es:bx = pointer to data +; eax = cluster + sub eax, 2 + movzx ecx, [bp+BPB_SecsPerClus-0x7C00] + mul ecx + +read_sectors2: +; same as read_sectors32, but eax is relative to start of data + add eax, [bp-10] +read_sectors32: +; ss:bp = 0:7C00 +; es:bx = pointer to data +; eax = first sector +; cx = number of sectors +; some high words of 32-bit registers are destroyed! + pusha + add eax, [bp+BPB_HiddSec-0x7C00] +if use_lba + push ds +do_read_sectors: + push ax + push cx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F +@@: +; create disk address packet on the stack +; dq starting LBA + push 0 + push 0 + push eax +; dd buffer + push es + push bx +; dw number of blocks to transfer (no more than 0x7F) + push cx +; dw packet size in bytes + push 10h +; issue BIOS call + push ss + pop ds + mov si, sp + mov dl, [bp-2] + mov ah, 42h + int 13h + mov si, aReadError + jc err_ +; restore stack + add sp, 10h +; increase current sector & buffer; decrease number of sectors + movzx esi, cx + mov ax, es + shl cx, 5 + add ax, cx + mov es, ax + pop cx + pop ax + add eax, esi + sub cx, si + jnz do_read_sectors + pop ds + popa + ret +else +do_read_sectors: + pusha + pop edi ; loword(edi) = di, hiword(edi) = si + push bx + +; eax / (SectorsPerTrack) -> eax, remainder bx + movzx esi, [bp+BPB_SecPerTrk-0x7C00] + xor edx, edx + div esi + mov bx, dx ; bx=sector-1 + +; eax -> dx:ax + push eax + pop ax + pop dx +; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx + div [bp+BPB_NumHeads-0x7C00] + +; number of sectors: read no more than to end of track + sub si, bx + cmp cx, si + jbe @f + mov cx, si +@@: + + inc bx +; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format + movzx edi, cx + mov dh, dl + mov dl, [bp-2] + shl ah, 6 + mov ch, al + mov al, cl + mov cl, bl + or cl, ah + pop bx + mov si, 3 + mov ah, 2 +@@: + push ax + int 13h + jnc @f + xor ax, ax + int 13h ; reset drive + pop ax + dec si + jnz @b + mov si, aReadError + jmp err_ +@@: + pop ax + mov ax, es + mov cx, di + shl cx, 5 + add ax, cx + mov es, ax + push edi + popa + add eax, edi + sub cx, di + jnz do_read_sectors + popa + ret +end if + +lookup_in_dir: +; in: ds:si -> 11-bytes FAT name +; in: eax = cluster +; in: bx = 0 +; out: if found: CF=0, es:di -> directory entry +; out: if not found: CF=1 +; push 0x8000 +; pop es +; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000 + mov es, [bp-7C00h + curseg] + push es + push eax + call read_cluster + mov ax, es + cmp ah, 82h + jb @f + mov ax, 8200h +@@: + mov [bp-7C00h + curseg], ax + pop eax + pop es +; scan for filename + shl cx, 4 + xor di, di +sloop: + cmp byte [es:di], bl + jz snotfound + test byte [es:di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmpsb + popa + jz sdone +scont: + add di, 0x20 + loop sloop +; next cluster + push 0x6000 + pop es + push es ax + shr eax, 7 + cmp eax, [bp-14] + mov [bp-14], eax + jz @f + add eax, [bp-6] + mov cx, 1 + call read_sectors32 +@@: + pop di es + and di, 0x7F + shl di, 2 + and byte [es:di+3], 0x0F + mov eax, [es:di] + ;and eax, 0x0FFFFFFF + cmp eax, 0x0FFFFFF7 + jb lookup_in_dir +snotfound: + stc +sdone: + ret + +out_string: +; in: ds:si -> ASCIIZ string + lodsb + test al, al + jz sdone + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string + +aReadError db 'Read error',0 +if use_lba +aNoLBA db 'The drive does not support LBA!',0 +end if +aLoaderNotFound db 'Loader not found',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 +main_loader db 'KORDLDR F32' + + db 56h +; just to make file 512 bytes long :) + db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' + +; bootsector signature + dw 0xAA55 + +; display offsets of all procedures used by kordldr.f12.asm +macro show [procedure] +{ + bits = 16 + display `procedure,' = ' + repeat bits/4 + d = '0' + procedure shr (bits - %*4) and 0Fh + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 +} + +show read_sectors32, read_sectors2, err_, noloader diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.txt b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.txt new file mode 100644 index 000000000..858b52a8b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/bootsect.txt @@ -0,0 +1,333 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + Читай между строк - там никогда не бывает опечаток. + +Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. + +===================================================================== + +Есть две версии в зависимости от того, поддерживает ли носитель LBA, +выбор осуществляется установкой константы use_lba в первой строке исходника. +Требования для работы: +1) Сам бутсектор, первая копия FAT и все используемые файлы +должны быть читабельны. (Если дело происходит на носителе с разбиением на +разделы и загрузочный код в MBR достаточно умный, то читабельности резервной +копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности +самого бутсектора). +2) Минимальный процессор - 80386. +3) В системе должно быть как минимум 584K свободной базовой памяти. + +===================================================================== + +Документация в тему (ссылки проверялись на валидность 15.05.2008): + официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf + русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip + официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf + то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf + описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html + официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf + +===================================================================== + +Схема используемой памяти: + ...-7C00 стек + 7C00-7E00 код бутсектора + 7E00-8200 вспомогательный файл загрузчика (kordldr.f32) + 8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 + байт: 4 байта (две ссылки - вперёд и назад) для + организации L2-списка всех прочитанных секторов в + порядке возрастания последнего времени использования + + 4 байта для номера сектора; при переполнении кэша + выкидывается элемент из головы списка, то есть тот, + к которому дольше всех не было обращений + 60000-80000 кэш для таблицы FAT (100h секторов) + 80000-90000 текущий кластер текущей рассматриваемой папки + 90000-... кэш для содержимого папок (каждой папке отводится + 2000h байт = 100h входов, одновременно в кэше + может находиться не более 8 папок; + точный размер определяется размером доступной + физической памяти - как правило, непосредственно + перед A0000 размещается EBDA, Extended BIOS Data Area) + +===================================================================== + +Основной процесс загрузки. +Точка входа (start): получает управление от BIOS при загрузке, при этом + dl содержит идентификатор диска, с которого идёт загрузка +1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед + кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало + бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - + это освобождает ds и экономит на размере кода). Сохраняет в стеке + идентификатор загрузочного диска для последующего обращения + через byte [bp-2]. +2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h + прерывания 13h. Если нет, переходит на код обработки ошибок с + сообщением об отсутствии LBA. +CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и + записывает полученные данные поверх BPB. Если вызов завершился ошибкой, + предполагает уже существующие данные корректными. +3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего + обращения через dword [bp-10]. В процессе вычисления узнаёт начало + первой FAT, сохраняет и его в стек для последующего обращения через + dword [bp-6]. +4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 + для последующего обращения через dword [bp-14] - инициализация + переменной, содержащей текущий сектор, находящийся в кэше FAT + (-1 не является валидным значением для номера сектора FAT). +5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на + код обработки ошибок с сообщением о ненайденном загрузчике. + Замечание: на этом этапе загрузки искать можно только в корневой + папке и только имена, заданные в формате файловой системе FAT + (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны + быть заглавными, при необходимости имя и расширение дополняются + пробелами, разделяющей точки нет, завершающего нуля нет). +6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт + ему управление. При этом в регистре eax оказывается абсолютный + номер первого сектора kordldr.f32, а в cx - число считанных секторов + (равное размеру кластера). + +Вспомогательные процедуры бутсектора. +Код обработки ошибок (err): +1. Выводит строку с сообщением об ошибке. +2. Выводит строку "Press any key...". +3. Ждёт нажатия any key. +4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. +5. Для подстраховки зацикливается. + +Процедура чтения кластера (read_cluster): +на входе должно быть установлено: + ss:bp = 0:7C00 + es:bx = указатель на начало буфера, куда будут прочитаны данные + eax = номер кластера +на выходе: ecx = число прочитанных секторов (размер кластера), + es:bx указывает на конец буфера, в который были прочитаны данные, + eax и старшие слова других 32-битных регистров разрушаются +Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора +и переходит к следующей процедуре. + +Процедура чтения секторов (read_sectors32 и read_sectors2): +на входе должно быть установлено: + ss:bp = 0:7C00 + es:bx = указатель на начало буфера, куда будут прочитаны данные + eax = стартовый сектор (относительно начала логического диска + для read_sectors32, относительно начала данных + для read_sectors2) + cx = число секторов (должно быть больше нуля) +на выходе: es:bx указывает на конец буфера, в который были прочитаны данные + старшие слова 32-битных регистров могут разрушиться +0. Если вызывается read_sectors2, она переводит указанный ей номер сектора + в номер относительно начала логического диска, прибавляя номер сектора + начала данных, хранящийся в стеке как [bp-10]. +1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на + устройстве, прибавляя значение соответствующего поля из BPB. +2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации + CHS-версия: все читаемые секторы были на одной дорожке. + LBA-версия: число читаемых секторов не превосходило 7Fh (требование + спецификации EDD BIOS). +CHS-версия: +3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как + единица плюс остаток от деления абсолютного номера на число секторов + на дорожке; дорожка рассчитывается как остаток от деления частного, + полученного на предыдущем шаге, на число дорожек, а цилиндр - как + частное от этого же деления. Если число секторов для чтения больше, + чем число секторов до конца дорожки, уменьшает число секторов для + чтения. +4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, + dh=головка, (младшие 6 бит cl)=сектор, + (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска + и повторяет попытку чтения, всего делается не более трёх попыток + (несколько попыток нужно в случае дискеты для гарантии того, что + мотор раскрутился). Если все три раза происходит ошибка чтения, + переходит на код обработки ошибок с сообщением "Read error". +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. +LBA-версия: +3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей + итерации) до 7Fh. +4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами + push, причём в обратном порядке: стек - структура LIFO, и данные в + стеке хранятся в обратном порядке по отношению к тому, как их туда + клали). +5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки + ошибок с сообщением "Read error". Очищает стек от пакета, + сформированного на предыдущем шаге. +6. В соответствии с числом прочитанных на текущей итерации секторов + корректирует текущий сектор, число оставшихся секторов и указатель на + буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает + работу, иначе возвращается на шаг 3. + +Процедура поиска элемента в папке (lookup_in_dir): +на входе должно быть установлено: + ss:bp = 0:7C00 + ds:si = указатель на имя файла в формате FAT (см. выше) + eax = начальный кластер папки + bx = 0 +на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то + CF сброшен и es:di указывает на элемент папки +В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных +данных. Для чтения кластера использует уже описанную процедуру read_clusters, +для продвижения по цепочке кластеров - описанную далее процедуру +get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса +8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, +если чтение прервётся раньше) не перекрываются последующими чтениями +(это будет использовано позднее, в системе кэширования из kordldr.f32). +Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; +кончились элементы в папке (первый байт очередного элемента нулевой); +кончились данные папки в соответствии с цепочкой кластеров из FAT. + +Процедура вывода на экран ASCIIZ-строки (out_string): +на входе: ds:si -> строка +В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. + +===================================================================== + +Работа вспомогательного загрузчика kordldr.f32: +1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. + В зависимости от этого устанавливает смещения используемых процедур + бутсектора. Критерий проверки: в CHS-версии по адресу err находится + байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу + находится байт 0x14, а адрес процедуры err другой. +2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска + адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с + ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента + место должно быть, отсюда ограничение в 592 Kb (94000h байт). + Замечание: этот размер не может превосходить 0A0000h байт и + на практике оказывается немного (на 1-2 килобайта) меньшим из-за + наличия дополнительной области данных BIOS "вверху" базовой памяти. +3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть + данных корневой папки; копирует загруженные данные в кэш и запоминает, + что в кэше есть корневая папка. +4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только + том случае, когда ему приходится загружать данные корневой папки, + не поместившиеся в один кластер. В этом случае в памяти присутствует + один сектор FAT (если было несколько обращений - последний из + использованных). +5. Если кластер равен сектору, то бутсектор загрузил только часть файла + kordldr.f32, и загрузчик подгружает вторую свою часть, используя + значения регистров на входе в kordldr.f32. +6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не + найден, или оказался папкой, или оказался слишком большим, то переходит + на код обработки ошибок из бутсектора с сообщением + "Fatal error: cannot load the secondary loader". + Замечание: на этом этапе имя файла уже можно указывать вместе с путём + и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов + по-прежнему нет. +7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. + Это нужно, чтобы последующие обращения к коду бутсектора в случае + ошибок чтения не выводил соответствующее сообщение с последующей + перезагрузкой, а рапортовал об ошибке чтения, которую могло бы + как-нибудь обработать ядро. +8. Если загрузочный диск имеет идентификатор меньше 0x80, + то устанавливает al='f' ("floppy"), ah=идентификатор диска, + иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). + (Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но + уверены ли Вы, что нет загрузочных устройств, подобных дискетам, + но большего размера, и для которых BIOS-идентификатор меньше 0x80?) + Устанавливает bx='32' (тип файловой системы - FAT32). + Устанавливает si=смещение функции обратного вызова. Поскольку в этот + момент ds=0, то ds:si образуют полный адрес. +9. Передаёт управление по адресу 1000:0000. + +Функция обратного вызова для вторичного загрузчика: + предоставляет возможность чтения файла. +Вход и выход описаны в спецификации на загрузчик. +1. Сохраняет стек вызывающего кода и устанавливает свой стек: + ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным + кодом должна указывать на 0:7C00, а -10 берётся от того, что + инициализирующий код бутсектора уже поместил в стек 10 байт параметров, + и они должны сохраняться в неизменности. (Значение [ebp-14], + "текущий сектор, находящийся в кэше FAT", не используется после + инициализации кэширования в kordldr.f32.) +2. Разбирает переданные параметры и вызывает нужную из вспомогательных + процедур (загрузки файла либо продолжения загрузки файла). +3. Восстанавливает стек вызывающего кода и возвращает управление. + +Вспомогательные процедуры kordldr.f32. +Процедура получения следующего кластера в FAT (get_next_cluster): +1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. + (В секторе 0x200 байт, каждый вход занимает 4 байта.) +2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. +3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, + выделяет очередной элемент в конце кэша. Если заполнен, удаляет + самый старый элемент (тот, к которому дольше всего не было обращений); + для того, чтобы отслеживать порядок элементов по времени последнего + обращения, все (выделенные) элементы кэша связаны в двусвязный список, + в котором первым элементом является самый старый, а ссылки вперёд + указывают на следующий по времени последнего обращения. +4. Читает соответствующий сектор FAT с диска. +5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, + где он находится, и добавляется в конец. (В случае со свежедобавленными + в кэш элементами удаления не делается, поскольку их в списке ещё нет.) +6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. +7. Сравнивает прочитанное значение с пределом: если оно строго меньше + 0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; + в противном случае цепочка закончилась. + +Процедура загрузки файла (load_file): +1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. +2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты + разделяются символом '/') в FAT-формат 8+3. Если это невозможно + (больше 8 символов в имени, больше 3 символов в расширении или + больше одной точки), возвращается с ошибкой. +3. Ищет элемент с таким именем в текущей рассматриваемой папке. + а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок + осуществляется по номеру начального кластера.) Если такой папки ещё + нет, добавляет её в кэш; если тот переполняется, выкидывает папку, + к которой дольше всего не было обращений. (Для каждого элемента кэша + хранится метка от 0 до (размер кэша)-1, определяющая его номер при + сортировке по давности последнего обращения. При обращении к какому-то + элементу его метка становится нулевой, а те метки, которые меньше + старого значения, увеличиваются на единицу.) + б) Просматривает в поисках запрошенного имени все элементы из кэша, + используя процедуру из бутсектора. Если обнаруживает искомый элемент, + переходит к шагу 4. Если обнаруживает конец папки, возвращается из + процедуры с ошибкой. + в) В цикле считывает папку посекторно. При этом пропускает начальные + секторы, которые уже находятся в кэше и уже были просмотрены. Каждый + прочитанный сектор копирует в кэш, если там ещё остаётся место, + и просматривает в нём все элементы. Работает, пока не случится одно из + трёх событий: найден искомый элемент; кончились кластеры (судя по + цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце + (первый байт нулевой). В двух последних случаях возвращается с ошибкой. +4. Проверяет тип найденного элемента (файл/папка): последний элемент в + запрошенном имени должен быть файлом, все промежуточные - папками. + Если текущий компонент имени - промежуточный, продвигает текущую + рассматриваемую папку и возвращается к пункту 2. +5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный + при вызове буфер последовательными вызовами функции бутсектора; + при этом если несколько кластеров файла расположены на диске + последовательно, то их чтение объединяется в одну операцию. + Следит за тем, чтобы не превысить указанный при вызове процедуры + лимит числа секторов для чтения. + +Процедура продолжения загрузки файла (continue_load_file): встроена + внутрь шага 5 load_file; загружает в регистры нужные значения (ранее + сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/build.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/build.bat new file mode 100644 index 000000000..267c29375 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/build.bat @@ -0,0 +1,3 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@fasm -m 65535 kordldr.f32.asm kordldr.f32 +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/kordldr.f32.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/kordldr.f32.asm new file mode 100644 index 000000000..9913b442b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/fat32/kordldr.f32.asm @@ -0,0 +1,672 @@ +; Copyright (c) 2008-2009, diamond +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + org 0x7E00 +; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here +; ss:bp = 0:7C00 +; ds = 0 +virtual at bp + rb 3 ; BS_jmpBoot + rb 8 ; BS_OEMName, ignored + dw ? ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? + dw ? ; BPB_TotSec16 + db ? ; BPB_Media + dw ? ; BPB_FATSz16 = 0 for FAT32 +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? + dd ? ; BPB_TotSec32 +BPB_FATSz32 dd ? +BPB_ExtFlags dw ? + dw ? ; BPB_FSVer +BPB_RootClus dd ? +filesize: + dw ? ; BPB_FSInfo + dw ? ; BPB_BkBootSec + rb 12 ; BPB_Reserved +BS_DrvNum db ? + db ? ; BS_Reserved1 + db ? ; BS_BootSig + dd ? ; BS_VolID +; rb 11 ; BS_VolLab +; rb 5 ; BS_FilSysType, first 5 bytes +read_sectors32 dw ? +read_sectors2 dw ? +err_ dw ? +noloader dw ? +cachelimit dw ? +fatcachehead rw 2 +fatcacheend dw ? + rb 3 ; BS_FilSysType, last 3 bytes +curseg dw ? +num_sectors dd ? +cur_cluster dd ? +next_cluster dd ? +flags dw ? +cur_delta dd ? +end virtual + +; procedures from boot sector +; LBA version +lba_read_sectors2 = 7CD6h +lba_err = 7CAAh +lba_noloader = 7CA7h ; = lba_err - 3 +; CHS version +chs_read_sectors2 = 7CD2h +chs_err = 7CA6h +chs_noloader = 7CA3h ; = chs_err - 3 + + push eax cx ; save our position on disk +; determine version of bootsector (LBA vs CHS) + mov [read_sectors2], chs_read_sectors2 + mov bx, chs_err + mov [err_], bx +; mov [noloader], chs_noloader + cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version + jz @f + add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 + add [err_], lba_err - chs_err +; mov [noloader], lba_noloader +@@: + xor bx, bx +; determine size of cache for folders + int 12h ; ax = size of available base memory in Kb + sub ax, 92000h / 1024 + jae @f +nomem: + mov si, nomem_str + jmp [err_] +@@: + shr ax, 3 + mov [cachelimit], ax ; size of cache - 1 + mov es, bx +; no folders in cache yet + mov di, foldcache_clus + mov cx, 8*4/2 + 1 + xor ax, ax + rep stosw +; bootsector code caches one FAT sector, [bp-14], in 6000:0000 +; initialize our (more advanced) FAT caching from this + mov di, 8400h + mov cx, di + lea si, [fatcachehead] + mov [si], si ; no sectors in cache: + mov [si+2], si ; 'prev' & 'next' links point to self + mov [fatcacheend], di ; first free item = 8400h + stosw ; 'next cached sector' link + stosw ; 'prev cached sector' link + mov eax, [bp-14] + stosd ; first sector number in cache + test eax, eax + js @f + mov [si], cx ; 'first cached sector' link = 8400h + mov [si+2], cx ; 'next cached sector' link = 8400h + mov [fatcacheend], di ; first free item = 8406h +@@: +; if cluster = sector, we need to read second part of our file +; (bootsector loads only first cluster of kordldr.f32) + pop cx eax ; restore our position on disk + cmp cx, 1 + ja kordldr_full + sub eax, [bp-10] + inc eax + inc eax ; eax = first cluster of kordldr.f32 + call get_next_cluster + jc @f +; jmp [noloader] + mov ax, [err_] + sub ax, 3 + jmp ax +@@: + dec eax + dec eax + push 0x800 + pop es + call [read_sectors2] +kordldr_full: +; bootsector code has read some data of root directory to 8000:0000 +; initialize our folder caching from this + mov eax, [BPB_RootClus] + mov [foldcache_clus], eax + mov cx, [curseg] + mov ax, 8000h + sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) + shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) + mov [foldcache_size], cx + shl cx, 4 + push ds + mov ds, ax + push 0x9000 + pop es + xor si, si + xor di, di + rep movsw + pop ds +; ...continue loading... + mov di, secondary_loader_info + call load_file + test bx, bx + mov bx, [err_] + jz @f + mov si, aKernelNotFound + jmp bx +@@: +; for subsequent calls to callback function, hook error handler +; push hooked_err / ret + mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) +; set registers for secondary loader + mov ah, [bp-2] ; drive id + mov al, 'f' + btr ax, 15 + jnc @f + mov al, 'h' +@@: + mov bx, '32' + mov si, callback + jmp far [si+secondary_loader_info-callback] + +nomem_str db 'No memory',0 + +cluster2sector: + sub eax, 2 +clustersz2sectorsz: + movzx ecx, [BPB_SecsPerClus] + mul ecx + ret + +get_next_cluster: +; in: eax = cluster +; out: if there is next cluster: CF=1, eax = next cluster +; out: if there is no next cluster: CF=0 + push di bx + push ds + push ss + pop ds + push ax + shr eax, 7 +; eax = FAT sector number; look in cache + mov di, 8400h +.cache_lookup: + cmp di, [fatcacheend] + jae .not_in_cache + scasd + scasd + jnz .cache_lookup +.in_cache: + sub di, 8 +; delete this sector from the list + push si + mov si, [di] + mov bx, [di+2] + mov [si+2], bx + mov [bx], si + pop si + jmp @f +.not_in_cache: +; cache miss +; cache is full? + mov di, [fatcacheend] + cmp di, 8C00h + jnz .cache_not_full +; yes, delete the oldest entry + mov di, [fatcachehead] + mov bx, [di] + mov [fatcachehead], bx + push word [di+2] + pop word [bx+2] + jmp .cache_append +.cache_not_full: +; no, allocate new sector + add [fatcacheend], 8 +.cache_append: +; read FAT + mov [di+4], eax + push es + pushad + lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM + shl cx, 9-3 + mov es, cx + xor bx, bx + mov cx, 1 + add eax, [bp-6] ; FAT start + sub eax, [bp-10] + call [read_sectors2] + popad + pop es +@@: +; add new sector to the end of list + mov bx, di + xchg bx, [fatcachehead+2] + push word [bx] + pop word [di] + mov [bx], di + mov [di+2], bx +; get requested item + lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] + pop di + and di, 0x7F + shl di, 2 + shl ax, 9-3 + mov ds, ax + and byte [di+3], 0x0F + mov eax, [di] + pop ds + pop bx di + ;and eax, 0x0FFFFFFF + cmp eax, 0x0FFFFFF7 + ret + +if $ > 0x8000 +error 'get_next_cluster must fit in first sector of kordldr.f32!' +end if + +load_file: +; in: ss:bp = 0:7C00 +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found +; out: dx:ax = file size (0xFFFFFFFF if file not found) + mov eax, [BPB_RootClus] ; start from root directory + or dword [filesize], -1 ; initialize file size with invalid value + lea si, [di+6] +parse_dir_loop: +; convert name to FAT name + push di + push ax + push ss + pop es +; convert ASCIIZ filename to FAT name +filename equ bp + mov di, filename + push di + mov cx, 8+3 + mov al, ' ' + rep stosb + pop di + mov cl, 8 ; 8 symbols per name + mov bl, 1 +nameloop: + lodsb + test al, al + jz namedone + cmp al, '/' + jz namedone + cmp al, '.' + jz namedot + dec cx + js badname + cmp al, 'a' + jb @f + cmp al, 'z' + ja @f + sub al, 'a'-'A' +@@: + stosb + jmp nameloop +namedot: + inc bx + jp badname + add di, cx + mov cl, 3 + jmp nameloop +badname: ; do not make direct js/jp to notfound_pop: + ; this generates long forms of conditional jumps and results in longer code + jmp notfound_pop +namedone: +; scan directory + pop ax ; eax = cluster of directory + ; high word of eax is preserved by operations above + push ds + push si +; read a folder sector-by-sector and scan +; first, try to use the cache + push ss + pop ds + mov di, foldcache_mark + xor bx, bx + mov cx, [cachelimit] +@@: + lea si, [di+bx] + mov edx, dword [foldcache_clus+si-foldcache_mark+bx] + cmp edx, eax + jz cacheok + test edx, edx + jz cacheadd ; the cache has place for new entry + inc bx + inc bx + dec cx + jns @b +; the folder is not present in the cache, so add it +; the cache is full; find the oldest entry and replace it with the new one + mov bx, -2 + mov dx, [cachelimit] +@@: + inc bx + inc bx + cmp word [di+bx], dx ; marks have values 0 through [cachelimit] + jnz @b + lea si, [di+bx] +cacheadd: + or word [di+bx], 0xFFFF ; very big value, it will be changed soon + and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet + mov dword [foldcache_clus+si-foldcache_mark+bx], eax +cacheok: +; update cache marks + mov dx, [di+bx] + mov cx, [foldcache_size+di-foldcache_mark+bx] + mov di, [cachelimit] + add di, di +cacheupdate: + cmp [foldcache_mark+di], dx + adc [foldcache_mark+di], 0 + dec di + dec di + jns cacheupdate + and [foldcache_mark+bx], 0 +; done, bx contains (position in cache)*2 + ;mov dx, bx + ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 + ;add dx, 0x9000 + lea dx, [bx + 0x90] + xchg dl, dh + mov ds, dx + mov si, filename ; ss:si -> filename in FAT style + call scan_for_filename + jz lookup_done +; cache miss, read folder data from disk + mov bx, cx + shr bx, 4 + shl cx, 5 + mov di, cx ; es:di -> free space in cache entry +; external loop: scan clusters +folder_next_cluster: +; internal loop: scan sectors in cluster + push eax + call cluster2sector +folder_next_sector: +; skip first bx sectors + dec bx + jns folder_skip_sector + push cx + push es di + push 0x8000 + pop es + xor bx, bx + mov cx, 1 + push es + push eax + call [read_sectors2] + pop eax +; copy data to the cache... + pop ds + pop di es + cmp di, 0x2000 ; ...if there is free space, of course + jae @f + pusha + mov cx, 0x100 + xor si, si + rep movsw + mov di, es + shr di, 8 + add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache + popa +@@: + push es + mov cl, 0x10 ; ch=0 at this point + call scan_for_filename + pop es + pop cx + jz lookup_done_pop +folder_skip_sector: + inc eax + loop folder_next_sector + pop eax ; eax = current cluster + call get_next_cluster + jc folder_next_cluster + stc + push eax +lookup_done_pop: + pop eax +lookup_done: + pop si +; CF=1 <=> failed + jnc found + pop ds +notfound: + pop di +notfound2: + mov bx, 2 ; file not found + mov ax, 0xFFFF + mov dx, ax ; invalid file size + ret +notfound_pop: + pop ax + jmp notfound +found: + mov eax, [di+20-2] + mov edx, [di+28] + mov ax, [di+26] ; get cluster + test byte [di+11], 10h ; directory? + pop ds + pop di + jz regular_file + cmp byte [si-1], 0 + jz notfound2 ; don't read directories as regular files +; ok, we have found a directory and the caller requested a file into it + jmp parse_dir_loop ; restart with new cluster in ax +regular_file: + cmp byte [si-1], 0 + jnz notfound2 ; file does not contain another files +; ok, we have found a regular file and the caller requested it +; save file size + mov [filesize], edx + mov si, [di+4] ; [ds:di+4] = limit in 4K blocks + shl si, 3 + push si + les bx, [di] ; es:bx -> buffer +clusloop: +; eax = first cluster, top of stack contains limit in sectors + mov esi, eax ; remember current cluster + xor ecx, ecx ; ecx will contain number of consecutive clusters + mov [cur_delta], ecx + mov edi, eax +clusfind: + inc edi + inc ecx + call get_next_cluster + jnc clusread + cmp eax, edi + jz clusfind + stc +clusread: + pop di ; limit in sectors + movzx edi, di + push eax ; save next cluster + pushf ; save flags +; read cx clusters, starting from si +; calculate number of sectors + xchg eax, ecx + call clustersz2sectorsz + mov [num_sectors], eax + jmp @f +continue_load_file: + les bx, [di] ; es:bx -> buffer + movzx edi, word [di+4] ; di = limit in 4K blocks + shl di, 3 ; now di = limit in sectors + mov eax, [num_sectors] + mov esi, [cur_cluster] + push [next_cluster] + push [flags] + test eax, eax + jz nextclus +@@: +; eax = number of sectors; compare with limit + cmp eax, edi + seta dl + push dx ; limit was exceeded? + jbe @f + mov eax, edi +@@: + sub di, ax ; calculate new limit + sub [num_sectors], eax + mov [cur_cluster], esi +; calculate starting sector + push ax + xchg eax, esi + call cluster2sector + pop cx + add eax, [cur_delta] + add [cur_delta], ecx +; read + call [read_sectors2] + pop dx +; next cluster? +nextclus: + popf + pop eax + mov [next_cluster], eax + pushf + pop [flags] + jnc @f ; no next cluster => return + mov dl, 1 ; dh=0 in any case + test di, di + jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded + push di + jmp clusloop ; all is ok, continue +hooked_err: + mov sp, 7C00h-14-2 ; restore stack + mov dx, 3 ; return: read error +@@: + mov bx, dx + mov ax, [filesize] + mov dx, [filesize+2] + ret + +scan_for_filename: +; in: ss:si -> 11-bytes FAT name +; in: ds:0 -> part of directory data +; in: cx = number of entries +; in: bh = 0 +; out: if found: CF=0, ZF=1, es:di -> directory entry +; out: if not found, but continue required: CF=1 and ZF=0 +; out: if not found and zero item reached: CF=1 and ZF=1 + push ds + pop es + xor di, di + push cx + jcxz snoent +sloop: + cmp byte [di], bh + jz snotfound + test byte [di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmps byte [ss:si], byte [es:di] + popa + jz sdone +scont: + add di, 0x20 + loop sloop +snoent: + inc cx ; clear ZF flag +snotfound: + stc +sdone: + pop cx +lrdret: + ret + +; Callback function for secondary loader +callback: +; in: ax = function number; only functions 1 and 2 are defined for now +; save caller's stack + mov dx, ss + mov cx, sp +; set our stack (required because we need ss=0) + xor si, si + mov ss, si + mov sp, 7C00h-10 + mov bp, 7C00h + push dx + push cx +; call our function + stc ; unsupported function + dec ax + jz callback_readfile + dec ax + jnz callback_ret +; function 2: continue loading file +; can be called only after function 1 returned value bx=1 (only part of file was loaded) +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error +; out: dx:ax = file size + call continue_load_file + jmp callback_ret_succ +callback_readfile: +; function 1: read file +; in: ds:di -> information structure +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name +; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error +; out: dx:ax = file size (0xFFFFFFFF if file was not found) + call load_file +callback_ret_succ: + clc ; function is supported +callback_ret: +; restore caller's stack + pop cx + pop ss + mov sp, cx +; return to caller + retf + +secondary_loader_info: + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + +;if $ > 0x8200 +;error 'total size of kordldr.f32 must not exceed 1024 bytes!' +;end if + +;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache +;foldcache_mark dw 0 +; rw 7 +;foldcache_size rw 8 +foldcache_clus rd 8 +foldcache_mark rw 8 +foldcache_size rw 8 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/floppy.asc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/floppy.asc new file mode 100644 index 000000000..7d2ba1bfd --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/floppy.asc @@ -0,0 +1,49 @@ +include "mkfloppy.inc" +;// insert boot sect +file "fat1x/bootsect.bin", 512 + +; fat1 +db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0 +; fat2 +db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0 + +; root +dent kordldr, "KORDLDR F1X", FA_ARC +dent kord, "KORD ",FA_DIR +dent kolibri, "KOLIBRI ",FA_DIR +; ... + +rb 33*512-$ +;/////////////////////////// +defdir kord +{ +dent loader, "LOADER ", FA_ARC +dent ini,"STARTOS INI", FA_ARC +} + +defdir kolibri +{ +dent kolibri_ldm, "KOLIBRI LDM", FA_ARC +} + + +; data +stof kordldr, "fat1x/kordldr.f1x" +stod kord,root + +stof loader, "../loader" +stof ini,"../startos.ini" + +store dword ini_base/512+1 at ini_base+1F8h +store word (ini_size+511)/512-1 at ini_base+1FCh +store word 220h at ini_base+1FEh + +stod kolibri,root +stof kolibri_ldm, "../kolibri_ldm/bin/kolibri.ldm" +store dword kolibri_ldm_base/512+1 at kolibri_ldm_base+1F8h +store word (kolibri_ldm_size+511)/512-1 at kolibri_ldm_base+1FCh +store word 220h at kolibri_ldm_base+1FEh + + +; ... +rb 2*80*18*512-$ \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/mkfloppy.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/mkfloppy.inc new file mode 100644 index 000000000..1f21abab4 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot/mkfloppy.inc @@ -0,0 +1,90 @@ +; --------------------------------------------------------------------------- +; mkfloppy.inc +; --------------------------------------------------------------------------- +; Created by Phantom-84 +; --------------------------------------------------------------------------- + +FA_RO equ 01h +FA_HID equ 02h +FA_SYS equ 04h +FA_VOL equ 08h +FA_DIR equ 10h +FA_ARC equ 20h + +DSTAMP equ 28C1h +TSTAMP equ 6000h + +root_size=0 + +macro reset id +{ +local count, cur, disp, val, var +times 511-($+511) mod 512 db 0 +if id#_size>0 +count=(id#_size+511)/512 +cur=id#_base/512-(33-2) +repeat count +if %=count +val=0FFFh +else +val=cur+1 +end if +if cur and 1 +val=val shl 4 +end if +disp=(cur*3)/2 +load var word from 512+disp +var=var or val +store word var at 512+disp +store word var at 10*512+disp +cur=cur+1 +end repeat +end if +} + +macro dent id, name, attr +{ +@@ db name +times @b+11-$ db 32 +db attr +dw 0, TSTAMP, DSTAMP, DSTAMP, 0, TSTAMP, DSTAMP +if id#_size=0 +dw 0 +else +dw id#_base/512-(33-2) +end if +if (attr) and FA_DIR +dd 0 +else +dd id#_size +end if +} + +macro orgdir id, parentid +{ +id#_base: +dent id, ".", FA_DIR +dent parentid, "..", FA_DIR +} + +macro findir id +{ +id#_size=$-id#_base +reset id +} + +macro stod id, parentid +{ +orgdir id, parentid +id +findir id +} + +macro stof id, name +{ +id#_base: file name +id#_size=$-id#_base +reset id +} + +defdir fix macro \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot_st.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot_st.inc new file mode 100644 index 000000000..3abf541a0 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/boot_st.inc @@ -0,0 +1,68 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + + +version db 'Secondary Loader v 0.010',0 +version_end: + +select_section db 'Select section:' +select_section_end: +section_description db 'Section description:' +section_description_end: +soft_mes db 'Soft (c) 2008-2009' +soft_mes_end: + +badprocessor db '>Fatal - CPU 586+ required.',0 +error_ini_f1 db '>Error: cannot load ini file, buffer is full',0 +error_ini_f2 db '>Error: ini file not found',0 +error_ini_f3 db '>Error: cannot read ini file',0 +error_ini_nf db '>Error: unrecognized error when loading ini file',0 +not_found_sec_loader db '>Not found section [loader]',0 +not_found_def_sect db '>Not found value default in section [loader]',0 +default_eq_loader db '>Error in section [loader] parametr default=loader',0 +found_equal_default db '>Found equal parametr default will be use first value',0 +found_equal_timeout db '>Found equal parametr timeout will be use first value',0 +set_default_timeout_val db '>Section timeout has incorrect value, will be use default value',0 +error_ini_common db ">I will use predefined settings and try to boot. Let's hope for the best..." + db 13,10,"Press any key to continue...",0 +load_ini db '>Ini file loaded successfully',0 +parse_ini_end db '>End parsing ini file',0 +point_to_default_sec_not_found db '>Point to default section is not found in ini file',0 +incorect_section_define db ">Incorect section define not found ']'",0 +default_section_name db '"Section unname"' + +start_msg db "Press any key to change default section, press [Enter] to continue booting" +start_msg_e: +time_msg db "or wait 4 seconds before default continuation" +time_msg_e: +time_str db "seconds before default continuation" +time_str_e: diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/build_ru.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/build_ru.bat new file mode 100644 index 000000000..e326deed7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/build_ru.bat @@ -0,0 +1,4 @@ +@fasm -m 65535 loader.asm loader +@echo off +REM @fasm -m 65535 loader.asm loader > loader.lst +REM @pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/debug_msg.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/debug_msg.inc new file mode 100644 index 000000000..42a5c2804 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/debug_msg.inc @@ -0,0 +1,77 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;Тут определены все сообщения, которые нужны в процессе отладки, и совсем не нужны в рабочей копии программы. +If DEBUG +cseg_msg db ' - Adress of code segment',0 +stack_msg db 'Set stack & segments is have completed',0 +show_string db 'Have loaded size:' +show_decode db ' ',0 +show_db1 db ' -Message debug1',0 +show_db2 db ' -Message debug2',0 + + +lm_l_found db '[loader] is found',0 +lm_lf_timeout db 'timeout is found',0 +lm_lf_default db 'name default is found and end parsing section',0 +lm_lf_section db 'found section [',0 +lm_lf_default_f db 'found default parametr',0 +lm_l_end db 'section [loader] is end',0 +show_all_sect db 'SHOW ALL Sections',0 +no_show_only_w db 'Not show sections - only work on default sect',0 +_not_found db '[ not found',0 +_found_1 db '[] found',0 +_found_2 db '[ found',0 +say_hello db 'Hello $)',0 +ramdiskFS_st db 'Start use_RamdiskFS macros',0 +free_memory_msg db ' -Kb availability system free memory',0 +RamdiskSize_msg db ' -Kb equal RamdiskSize',0 +RamdiskSector_msg db ' -byts RamdiskSector',0 +RamdiskCluster_msg db ' -RamdiskCluster',0 +RamdiskFile_msg db ' -size RamdiskFile',0 +fat_create_msg db ' -first create fat table, point to next block',0 +BPB_msg db ' -in byte, why we get data from move BPB struct',0 +firstDataSect_msg db ' -first data sector, offset to data in sectors',0 +size_root_dir_msg db ' -size root dir in sectrors',0 +DataClasters_msg db ' -size data in Clasters',0 +first_entry_in_fat db ' -data segment in FIRST entry FAT',0 +check_root_fat_ db ' : --------------',0 +check_name_fat_msg_y db 'Name is present that is BAD',0 +check_name_fat_msg_n db 'Name is not present that is GOOD',0 +name_of_seg_get_64 db ' -name of seg where we get 64 Kb of data',0 +convertion_file_name_msg_y db '->Destination name of file is GOOD',0 +convertion_file_name_msg_n db '->Destination name of file is BAD',0 +alarm_msg db '%%%%%%%% WARNING: MISS THE FILE %%%%%%%%%%%',0 +start_making_FAT12_msg db '>>>>>> Begin make a RAMDISK and FS after 1 Mb <<<<<<<',0 +make_fat12_RFS_msg db '-Make FAT12 Ram FS',0 +get_type_FS_msg db '-End make RamDisk',0 +seg_where_get_data db ' - Segment where we get data for move up file',0 +return_code_af_move db ' -return code after 0x87 int 0x15, move block',0 +return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc',0 + + + +end if diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ETFONT.FNT b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/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_IRI800*600 and 800*600->640*480) [1-yes,2-no]:",0 + + +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 + +bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-use preloaded ram-image from kernel restart;" + db 13,10,186," " + db "4-create blank image]: ",0 +probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, " + db "2-probe bios (Vesa 3.0)]: ",0 +prnotfnd db "Fatal - Videomode not found.",0 +not386 db "Fatal - CPU 386+ required.",0 +btns db "Fatal - Can't determine color depth.",0 +fatalsel db "Fatal - Graphics mode not supported by hardware.",0 +pres_key db "Press any key to choose a new videomode.",0 +badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loading diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Press [abc] to change settings, press [Enter] to continue booting",13,10,0 +time_msg db " or wait " +time_str db " 5 seconds" + db " before automatical continuation",13,10,0 +current_cfg_msg db "Current settings:",13,10,0 +curvideo_msg db " [a] Videomode: ",0 + +mode0 db "320x200, EGA/CGA 256 colors",13,10,0 +mode9 db "640x480, VGA 16 colors",13,10,0 + +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " on",13,10,0 +off_msg db " off",13,10,0 +;readonly_msg db " only for reading",13,10,0 +vrrm_msg db " [c] Use VRR:",0 +preboot_device_msg db " [d] Floppy image: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "real floppy",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "use already loaded image",13,10,0 +pdm4 db "create blank image",13,10,0 +loading_msg db "Loading KolibriOS...",0 +save_quest db "Remember current settings? [y/n]: ",0 +loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 + +_st db 186,' ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї',13,10,0 +_r1 db 186,' і 320x200 EGA/CGA 256 colors і і',13,10,0 +_r2 db 186,' і 640x480 VGA 16 colors і і',13,10,0 +_rs db 186,' і ????x????@?? SVGA VESA і і',13,10,0 +_bt db 186,' АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ',13,10,0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootet.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootet.inc new file mode 100644 index 000000000..c29b2b64d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootet.inc @@ -0,0 +1,119 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; kolibri_ldm.asm the module for Secondary Loader ;; +;; ;; +;; KolibriOS 16-bit loader module, ;; +;; based on bootcode for KolibriOS ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + + +d80x25_bottom: + db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Ekraan: EGA/CGA",13,10,0 +vervesa db "Vesa versioon: Vesa x.x",13,10,0 +vervesa_off=20 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 vдrvi: [9] 320x200, " + db "VGA 16 vдrvi: [0] 640x480",13,10 + db 186," Vali reziim: ",0 +bt24 db "Bitti pikseli kohta: 24",13,10,0 +bt32 db "Bitti pikseli kohta: 32",13,10,0 +vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" + db " ainult:",13,10 + db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 +;askmouse db " Hiir:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Vali port [1-3]: ",0 +;no_com1 db 13,10,186, " No COM1 mouse",0 +;no_com2 db 13,10,186, " No COM2 mouse",0 +;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0 +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 +;gr_direct db 186," Use direct LFB writing? " +; db "[1-yes/2-no] ? ",0 +;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Paigalda mдluketas [1-diskett; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-kasuta eellaaditud mдluketast kerneli restardist;" + db 13,10,186," " + db "4-loo tьhi pilt]: ",0 +probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, " + db "2-leia biosist (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 +;modena db "Fataalne - VBE 0x112+ on vajalik.",0 +not386 db "Fataalne - CPU 386+ on vajalik.",0 +btns db "Fataalne - Ei suuda vдrvisьgavust mддratleda.",0 +fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 +badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 +memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaхnnestus.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loen disketti: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jдtkamiseks",13,10,0 +time_msg db " vхi oota " +time_str db " 5 sekundit" + db " automaatseks jдtkamiseks",13,10,0 +current_cfg_msg db "Praegused seaded:",13,10,0 +curvideo_msg db " [a] Videoreziim: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4,mode1,mode2,mode3 +modevesa20 db " koos LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 vдrvi",0 +mode10 db "640x480, VGA 16 vдrvi",0 +probeno_msg db " (standard reziim)",0 +probeok_msg db " (kontrolli ebastandardseid reziime)",0 +;dma_msg db " [b] Kasuta DMA'd HDD juurdepддsuks:",0 +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " sees",13,10,0 +off_msg db " vдljas",13,10,0 +;readonly_msg db " ainult lugemiseks",13,10,0 +vrrm_msg db " [c] Kasuta VRR:",0 +preboot_device_msg db " [d] Disketi kujutis: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "reaalne diskett",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "kasuta juba laaditud kujutist",13,10,0 +pdm4 db "loo tьhi pilt",13,10,0 +loading_msg db "Laadin KolibriOS...",0 +save_quest db "Jдta meelde praegused seaded? [y/n]: ",0 +loader_block_error db "Alglaaduri andmed vigased, ei saa jдtkata. Peatatud.",0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootge.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootge.inc new file mode 100644 index 000000000..11b157a64 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootge.inc @@ -0,0 +1,118 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + + +d80x25_bottom: +; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' +; db 'NO WARRANTY ',186 +; db 186,' See file COPYING for details ' +; db ' ',186 + + db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' + db ' Garantie vertrieben ',186 + db 186,' Details stehen in der Datei COPYING ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Anzeige: EGA/CGA ",13,10,0 +vervesa db "Vesa-Version: Vesa ",13,10,0 +vervesa_off=22 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 Farben: [9] 320x200, " + db "VGA 16 Farben: [0] 640x480",13,10 + db 186," Waehle Modus: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",13,10,0 +vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 +;askmouse db " Maus angeschlossen an:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Waehle Port [1-3]: ",0 +;no_com1 db 13,10,186, " Keine COM1 Maus",0 +;no_com2 db 13,10,186, " Keine COM2 Maus",0 +;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0 +ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 +;gr_direct db 186," Benutze direct LFB? " +; db "[1-ja/2-nein] ? ",0 +;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-benutze ein bereits geladenes Kernel image;" + db 13,10,186," " + db "4-create blank image]: ",0 +probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, " + db "2-BIOS Test (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fatal - Videomodus nicht gefunden.",0 +;modena db "Fatal - VBE 0x112+ required.",0 +not386 db "Fatal - CPU 386+ benoetigt.",0 +btns db "Fatal - konnte Farbtiefe nicht erkennen.",0 +fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0 +badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Lade Diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0 +time_msg db " oder warte " +time_str db " 5 Sekunden" + db " bis zum automatischen Start",13,10,0 +current_cfg_msg db "Aktuelle Einstellungen:",13,10,0 +curvideo_msg db " [a] Videomodus: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4,mode1,mode2,mode3 +modevesa20 db " mit LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 colors",0 +mode10 db "640x480, VGA 16 colors",0 +probeno_msg db " (Standard Modus)",0 +probeok_msg db " (teste nicht-standard Modi)",0 +;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0 +usebd_msg db " [b] Add disks visible by BIOS:",0 +on_msg db " an",13,10,0 +off_msg db " aus",13,10,0 +;readonly_msg db " fur Lesen",13,10,0 +vrrm_msg db " [c] Nutze VRR:",0 +preboot_device_msg db " [d] Diskettenimage: ",0 +preboot_device_msgs dw 0,pdm1,pdm2,pdm3 +pdm1 db "Echte Diskette",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "Nutze bereits geladenes Image",13,10,0 +pdm4 db "create blank image",13,10,0 +loading_msg db "Lade KolibriOS...",0 +save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 +loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 + +remark1 db "Default values were selected to match most of configurations, but not all.",0 +remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0 +remark3 db "If the system does not boot, try to disable the item [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootru.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootru.inc new file mode 100644 index 000000000..c6630991e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootru.inc @@ -0,0 +1,87 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;================================================================= +; +; BOOT DATA +; +;================================================================= + + +d80x25_bottom: + db 186,' Kolibri OS ®б­®ў ­  ­  Menuet OS Ё ­Ґ ЇаҐ¤®бв ў«пҐв ' + db '­ЁЄ ЄЁе Ј аa­вЁ©. ',186 + db 186,' Џ®¤а®Ў­ҐҐ ᬮваЁвҐ ў д ©«Ґ COPYING.TXT ' + db ' ',186 + line_full_bottom +msg_apm db " APM x.x ", 0 +novesa db "‚Ё¤Ґ®Є ав : EGA/CGA",13,10,0 +s_vesa db "‚ҐабЁп VESA: " + .ver db "?.?",13,10,0 + +gr_mode db "‚лЎҐаЁвҐ ўЁ¤Ґ®аҐ¦Ё¬: ",13,10,0 +vrrmprint db "€бЇ®«м§®ў вм VRR? (з бв®в  Є ¤а®ў ўлиҐ 60 ѓж" + db " в®«мЄ® ¤«п ЇҐаҐе®¤®ў:",13,10 + db 186," 1024*768>800*600 Ё 800*600>640*480) [1-¤ , 2-­Ґв]: ",0 +;ask_dma db "€бЇ®«м§®ў вм DMA ¤«п ¤®бвгЇ  Є HDD? [1-¤ , 2-в®«мЄ® з⥭ЁҐ, 3-­Ґв]: ",0 +ask_bd db "„®Ў ўЁвм ¤ЁбЄЁ, ўЁ¤Ё¬лҐ зҐаҐ§ BIOS ў ०Ё¬Ґ V86? [1-¤ , 2-­Ґв]: ",0 +bdev db "‡ Јаг§Ёвм ®Ўа § Ё§ [1-¤ЁбЄҐв ; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §;" + db 13,10,186," " + db "4-б®§¤ вм зЁбвл© ®Ўа §]: ",0 +prnotfnd db "ЋиЁЎЄ  - ‚Ё¤Ґ®аҐ¦Ё¬ ­Ґ ­ ©¤Ґ­.",0 +not386 db "ЋиЁЎЄ  - ’ॡгҐвбп Їа®жҐбб®а 386+.",0 +fatalsel db "ЋиЁЎЄ  - ‚лЎа ­­л© ўЁ¤Ґ®аҐ¦Ё¬ ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп.",0 +pres_key db "Ќ ¦Ё¬ЁвҐ «оЎго Є« ўЁиг, ¤«п ЇҐаҐе®¤  ў ўлЎ®а ०Ё¬®ў.",0 +badsect db 13,10,186," ЋиЁЎЄ  - „ЁбЄҐв  Ї®ўаҐ¦¤Ґ­ . Џ®Їа®Ўг©вҐ ¤агЈго.",0 +memmovefailed db 13,10,186," ЋиЁЎЄ  - Int 0x15 move failed.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "‡ Јаг§Є  ¤ЁбЄҐвл: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 +start_msg db "Ќ ¦¬ЁвҐ [abc] ¤«п Ё§¬Ґ­Ґ­Ёп ­ бв஥Є, [Enter] ¤«п Їа®¤®«¦Ґ­Ёп § Јаг§ЄЁ",13,10,0 +time_msg db " Ё«Ё Ї®¤®¦¤ЁвҐ " +time_str db " 5 ᥪ㭤 " + db " ¤®  ўв®¬ вЁзҐбЄ®Ј® Їа®¤®«¦Ґ­Ёп",13,10,0 +current_cfg_msg db "’ҐЄгйЁҐ ­ бва®©ЄЁ:",13,10,0 +curvideo_msg db " [a] ‚Ё¤Ґ®аҐ¦Ё¬: ",0 + + +mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0 +mode9 db "640x480, VGA 16 梥⮢",13,10,0 + +usebd_msg db " [b] „®Ў ўЁвм ¤ЁбЄЁ, ўЁ¤Ё¬лҐ зҐаҐ§ BIOS:",0 +on_msg db " ўЄ«",13,10,0 +off_msg db " ўлЄ«",13,10,0 +readonly_msg db " в®«мЄ® з⥭ЁҐ",13,10,0 +vrrm_msg db " [c] €бЇ®«м§®ў ­ЁҐ VRR:",0 +;preboot_device_msg db " [d] ЋЎа § ¤ЁбЄҐвл: ",0 +;preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4 +;pdm1 db "­ бв®пй п ¤ЁбЄҐв ",13,10,0 +;pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +;pdm3 db "ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §",13,10,0 +;pdm4 db "б®§¤ вм зЁбвл© ®Ўа §",13,10,0 +loading_msg db "€¤св § Јаг§Є  KolibriOS...",0 +save_quest db "‡ Ї®¬­Ёвм ⥪гйЁҐ ­ бва®©ЄЁ? [y/n]: ",0 +loader_block_error db "ЋиЁЎЄ  ў ¤ ­­ле ­ з «м­®Ј® § Јаг§зЁЄ , Їа®¤®«¦Ґ­ЁҐ ­Ґў®§¬®¦­®.",0 + + +_st db 186,' ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї ',13,10,0 +_r1 db 186,' і 320x200 EGA/CGA 256 梥⮢ і і ',13,10,0 +_r2 db 186,' і 640x480 VGA 16 梥⮢ і і ',13,10,0 +_rs db 186,' і ????x????@?? SVGA VESA і і ',13,10,0 +_bt db 186,' АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ ',13,10,0 + + +remark1 db "‡­ зҐ­Ёп Ї® 㬮«з ­Ёо ўлЎа ­л ¤«п 㤮Ўбвў  Ў®«миЁ­бвў , ­® ­Ґ ўбҐе.",0 +remark2 db "…б«Ё г ‚ б LCD-¬®­Ёв®а, ®вЄ«озЁвҐ VRR ў Їг­ЄвҐ [c] - ®­ ‚ ¬ ­Ґ ­г¦Ґ­.",0 +remark3 db "…б«Ё г ‚ б ­Ґ Јаг§Ёвбп бЁб⥬ , Ї®Їа®Ўг©вҐ ®вЄ«озЁвм Їг­Єв [b].",0 +remarks dw remark1, remark2, remark3 +num_remarks = 3 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootstr.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootstr.inc new file mode 100644 index 000000000..c2f2df132 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootstr.inc @@ -0,0 +1,55 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +; boot data: common strings (for all languages) +macro line_full_top { + db 201 + times 78 db 205 + db 187 +} +macro line_full_bottom { + db 200 + times 78 db 205 + db 188 +} +macro line_half { + db 186,' ' + times 76 db 0xc4 + db ' ',186 +} +macro line_space { + db 186 + times 78 db 32 + db 186 +} +d80x25_top: + line_full_top +cur_line_pos = 75 +; store byte ' ' at d80x25_top+cur_line_pos+1 +; store byte ' ' at d80x25_top+cur_line_pos +; store dword ' SVN' at d80x25_top+cur_line_pos-4 + +space_msg: line_space +;verstr: +; line_space +; version string +; db 186,32 +; repeat 78 +; load a byte from version+%-1 +; if a = 13 +; break +; end if +; db a +; end repeat +; repeat 78 - ($-verstr) +; db ' ' +; end repeat +; db 32,186 +; line_half + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootvesa.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootvesa.inc new file mode 100644 index 000000000..b6ee2bb0e --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/bootvesa.inc @@ -0,0 +1,754 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +struc VBE_VGAInfo { + .VESASignature dd ? ; char + .VESAVersion dw ? ; short + .OemStringPtr dd ? ; char * + .Capabilities dd ? ; ulong + .VideoModePtr dd ? ; ulong + .TotalMemory dw ? ; short + ; VBE 2.0+ + .OemSoftwareRev db ? ; short + .OemVendorNamePtr dw ? ; char * + .OemProductNamePtr dw ? ; char * + .OemProductRevPtr dw ? ; char * + .reserved rb 222 ; char + .OemData rb 256 ; char +} + +struc VBE_ModeInfo { + .ModeAttributes dw ? ; short + .WinAAttributes db ? ; char + .WinBAttributes db ? ; char + .WinGranularity dw ? ; short + .WinSize dw ? ; short + .WinASegment dw ? ; ushort + .WinBSegment dw ? ; ushort + .WinFuncPtr dd ? ; void * + .BytesPerScanLine dw ? ; short + .XRes dw ? ; short + .YRes dw ? ; short + .XCharSize db ? ; char + .YCharSize db ? ; char + .NumberOfPlanes db ? ; char + .BitsPerPixel db ? ; char + .NumberOfBanks db ? ; char + .MemoryModel db ? ; char + .BankSize db ? ; char + .NumberOfImagePages db ? ; char + .res1 db ? ; char + .RedMaskSize db ? ; char + .RedFieldPosition db ? ; char + .GreenMaskSize db ? ; char + .GreenFieldPosition db ? ; char + .BlueMaskSize db ? ; char + .BlueFieldPosition db ? ; char + .RsvedMaskSize db ? ; char + .RsvedFieldPosition db ? ; char + .DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE + ; VBE 2.0+ + .PhysBasePtr dd ? ; ulong + .OffScreenMemOffset dd ? ; ulong + .OffScreenMemSize dw ? ; short + ; VBE 3.0+ + .LinbytesPerScanLine dw ? ; short + .BankNumberOfImagePages db ? ; char + .LinNumberOfImagePages db ? ; char + .LinRedMaskSize db ? ; char + .LinRedFieldPosition db ? ; char + .LingreenMaskSize db ? ; char + .LinGreenFieldPosition db ? ; char + .LinBlueMaskSize db ? ; char + .LinBlueFieldPosition db ? ; char + .LinRsvdMaskSize db ? ; char + .LinRsvdFieldPosition db ? ; char + .MaxPixelClock dd ? ; ulong + .res2 rb 190 ; char +} + +virtual at $A000 + vi VBE_VGAInfo + mi VBE_ModeInfo +modes_table: +end virtual +cursor_pos dw 0 ;временное хранение курсора. +home_cursor dw 0 ;current shows rows a table +end_cursor dw 0 ;end of position current shows rows a table +scroll_start dw 0 ;start position of scroll bar +scroll_end dw 0 ;end position of scroll bar +long_v_table equ 9 ;long of visible video table +size_of_step equ 10 +scroll_area_size equ (long_v_table-2) +int2str: + dec bl + jz @f + xor edx,edx + div ecx + push edx + call int2str + pop eax + @@: or al,0x30 + mov [ds:di],al + inc di + ret + +int2strnz: + cmp eax,ecx + jb @f + xor edx,edx + div ecx + push edx + call int2strnz + pop eax + @@: or al,0x30 + mov [es:di],al + inc di + ret + +;------------------------------------------------------- +;Write message about incorrect v_mode and write message about jmp on swith v_mode +v_mode_error: + _setcursor 19,2 + mov si, fatalsel + call printplain + _setcursor 20,2 + mov si,pres_key + call printplain + xor eax,eax + int 16h + jmp cfgmanager.d +;------------------------------------------------------- +; + + + +;------------------------------------------------------- +print_vesa_info: + _setcursor 5,2 + + mov [es:vi.VESASignature],'VBE2' + mov ax,0x4F00 + mov di,vi ;0xa000 + int 0x10 + or ah,ah + jz @f + mov [es:vi.VESASignature],'VESA' + mov ax,$4F00 + mov di,vi + int 0x10 + or ah,ah + jnz .exit + @@: + cmp [es:vi.VESASignature],'VESA' + jne .exit + cmp [es:vi.VESAVersion],0x0100 + jb .exit + jmp .vesaok2 + + .exit: + mov si,novesa + call printplain + ret + + .vesaok2: + mov ax,[es:vi.VESAVersion] + add ax,'00' + + mov [s_vesa.ver], ah + mov [s_vesa.ver+2], al + mov si,s_vesa + call printplain + + _setcursor 4,2 + mov si,word[es:vi.OemStringPtr] + mov di,si + + push ds + mov ds,word[es:vi.OemStringPtr+2] + call printplain + pop ds + + ret +;----------------------------------------------------------------------------- + +calc_vmodes_table: + pushad + +; push 0 +; pop es + + lfs si, [es:vi.VideoModePtr] + + mov bx,modes_table +;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢ + mov word [es:bx],640 + mov word [es:bx+2],480 + mov word [es:bx+6],0x13 + + mov word [es:bx+10],640 + mov word [es:bx+12],480 + mov word [es:bx+16],0x12 + add bx,20 + .next_mode: + mov cx,word [fs:si] ; mode number + cmp cx,-1 + je .modes_ok.2 + + mov ax,0x4F01 + mov di,mi + int 0x10 + + or ah,ah + jnz .modes_ok.2;vesa_info.exit + + test [es:mi.ModeAttributes],00000001b ;videomode support ? + jz @f + test [es:mi.ModeAttributes],00010000b ;picture ? + jz @f + test [es:mi.ModeAttributes],10000000b ;LFB ? + jz @f + + cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp + jb @f + +; cmp [es:mi.BitsPerPixel],16 +; jne .l0 +; cmp [es:mi.GreenMaskSize],5 +; jne .l0 +; mov [es:mi.BitsPerPixel],15 + + +.l0: + cmp [es:mi.XRes],640 + jb @f + cmp [es:mi.YRes],480 + jb @f +; cmp [es:mi.BitsPerPixel],8 +; jb @f + + mov ax,[es:mi.XRes] + mov [es:bx+0],ax ; +0[2] : resolution X + mov ax,[es:mi.YRes] + mov [es:bx+2],ax ; +2[2] : resolution Y + mov ax,[es:mi.ModeAttributes] + mov [es:bx+4],ax ; +4[2] : attributes + + cmp [s_vesa.ver],'2' + jb .lp1 + + or cx,0x4000 ; use LFB +.lp1: mov [es:bx+6],cx ; +6 : mode number + movzx ax,byte [es:mi.BitsPerPixel] + mov word [es:bx+8],ax ; +8 : bits per pixel + add bx,size_of_step ; size of record + + @@: + add si,2 + jmp .next_mode + + .modes_ok.2: + + mov word[es:bx],-1 ;end video table + mov word[end_cursor],bx ;save end cursor position +;;;;;;;;;;;;;;;;;; +;Sort array +; mov si,modes_table +;.new_mode: +; mov ax,word [es:si] +; cmp ax,-1 +; je .exxit +; add ax,word [es:si+2] +; add ax,word [es:si+8] +; mov bp,si +;.again: +; add bp,12 +; mov bx,word [es:bp] +; cmp bx,-1 +; je .exit +; add bx,word [es:bp+2] +; add bx,word [es:bp+8] +; +; cmp ax,bx +; ja .loops +; jmp .again +;.loops: +; push dword [es:si] +; push dword [es:si+4] +; push dword [es:si+8] +; push dword [es:bp] +; push dword [es:bp+4] +; push dword [es:bp+8] +; +; pop dword [es:si+8] +; pop dword [es:si+4] +; pop dword [es:si] +; pop dword [es:bp+8] +; pop dword [es:bp+4] +; pop dword [es:bp] +; jmp .new_mode +; +;.exit: add si,12 +; jmp .new_mode +;.exxit: + popad + ret + +;----------------------------------------------------------------------------- + +draw_current_vmode: + push 0 + pop es + + mov si,word [cursor_pos] + + cmp word [es:si+6],0x12 + je .no_vesa_0x12 + + cmp word [es:si+6],0x13 + je .no_vesa_0x13 + + mov di,loader_block_error + movzx eax,word[es:si+0] + mov ecx,10 + call int2strnz + mov byte[es:di],'x' + inc di + movzx eax,word[es:si+2] + call int2strnz + mov byte[es:di],'x' + inc di + movzx eax,word[es:si+8] + call int2strnz + mov dword[es:di],0x00000d0a + mov si,loader_block_error + push ds + push es + pop ds + call printplain + pop ds + ret +.no_vesa_0x13: + mov si,mode0 + jmp .print +.no_vesa_0x12: + mov si,mode9 +.print: + call printplain + ret +;----------------------------------------------------------------------------- +check_first_parm: + mov si,word [preboot_graph] + test si,si + jnz .no_zero ;if no zero +.zerro: +; mov ax,modes_table +; mov word [cursor_pos],ax +; mov word [home_cursor],ax +; mov word [preboot_graph],ax +;SET default video of mode first probe will fined a move of work 1024x768@32 + + mov ax,1024 + mov bx,768 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + mov ax,800 + mov bx,600 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + mov ax,640 + mov bx,480 + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + + mov si,modes_table + jmp .ok_found_mode + + + +.no_zero: + mov bp,word [number_vm] + cmp bp,word [es:si+6] + jz .ok_found_mode + mov ax,word [x_save] + mov bx,word [y_save] + mov si,modes_table + call .loops + test ax,ax + jz .ok_found_mode + + mov si,modes_table +; cmp ax,modes_table +; jb .zerro ;check on correct if bellow +; cmp ax,word [end_cursor] +; ja .zerro ;check on correct if anymore + +.ok_found_mode: + mov word [home_cursor],si +; mov word [cursor_pos],si + mov word [preboot_graph],si + mov ax,si + + mov ecx,long_v_table + +.loop: add ax,size_of_step + cmp ax,word [end_cursor] + jae .next_step + loop .loop +.next_step: + sub ax,size_of_step*long_v_table + cmp ax,modes_table + jae @f + mov ax,modes_table +@@: + + mov word [home_cursor],ax + mov si,[preboot_graph] + mov word [cursor_pos],si + + push word [es:si] + pop word [x_save] + push word [es:si+2] + pop word [y_save] + push word [es:si+6] + pop word [number_vm] + + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;; +.loops: + cmp ax,word [es:si] + jne .next + cmp bx,word [es:si+2] + jne .next + cmp word [es:si+8],32 + je .ok + cmp word [es:si+8],24 + je .ok +.next: add si,size_of_step + cmp word [es:si],-1 + je .exit + jmp .loops +.ok: xor ax,ax + ret +.exit: or ax,-1 + ret + + +;----------------------------------------------------------------------------- + +;default_vmode: + +;----------------------------------------------------------------------------- +draw_vmodes_table: + _setcursor 9, 2 + mov si,gr_mode + call printplain + + mov si,_st + call printplain + + push word [cursor_pos] + pop ax + push word [home_cursor] + pop si + mov cx,si + + cmp ax,si + je .ok + jb .low + + + add cx,size_of_step*long_v_table + + cmp ax,cx + jb .ok + + sub cx,size_of_step*long_v_table + add cx,size_of_step + cmp cx,word[end_cursor] + jae .ok + add si,size_of_step + push si + pop word [home_cursor] + jmp .ok + + +.low: sub cx,size_of_step + cmp cx,modes_table + jb .ok + push cx + push cx + pop word [home_cursor] + pop si + + +.ok: +; calculate scroll position + push si + mov ax, [end_cursor] + sub ax, modes_table + mov bx, size_of_step + cwd + div bx + mov si, ax ; si = size of list + mov ax, [home_cursor] + sub ax, modes_table + cwd + div bx + mov di, ax + mov ax, scroll_area_size*long_v_table + cwd + div si + test ax, ax + jnz @f + inc ax +@@: + cmp al, scroll_area_size + jb @f + mov al, scroll_area_size +@@: + mov cx, ax +; cx = scroll height +; calculate scroll pos + xor bx, bx ; initialize scroll pos + sub al, scroll_area_size+1 + neg al + sub si, long_v_table-1 + jbe @f + mul di + div si + mov bx, ax +@@: + inc bx + imul ax, bx, size_of_step + add ax, [home_cursor] + mov [scroll_start], ax + imul cx, size_of_step + add ax, cx + mov [scroll_end], ax + pop si + mov bp,long_v_table ;show rows +.@@_next_bit: +;clear cursor + mov ax,' ' + mov word[ds:_r1+21],ax + mov word[ds:_r1+50],ax + + mov word[ds:_r2+21],ax + mov word[ds:_r2+45],ax + + mov word[ds:_rs+21],ax + mov word[ds:_rs+46],ax +; draw string + cmp word [es:si+6],0x12 + je .show_0x12 + cmp word [es:si+6],0x13 + je .show_0x13 + + movzx eax,word[es:si] + cmp ax,-1 + je .@@_end + mov di,_rs+23 + mov ecx,10 + mov bl,4 + call int2str + movzx eax,word[es:si+2] + inc di + mov bl,4 + call int2str + + movzx eax,word[es:si+8] + inc di + mov bl,2 + call int2str + + cmp si, word [cursor_pos] + jne .next +;draw cursor + mov word[ds:_rs+21],'>>' + mov word[ds:_rs+46],'<<' + + + +.next: + push si + mov si,_rs +.@@_sh: +; add to the string pseudographics for scrollbar + pop bx + push bx + mov byte [si+53], ' ' + cmp bx, [scroll_start] + jb @f + cmp bx, [scroll_end] + jae @f + mov byte [si+53], 0xDB ; filled bar +@@: + push bx + add bx, size_of_step + cmp bx, [end_cursor] + jnz @f + mov byte [si+53], 31 ; 'down arrow' symbol +@@: + sub bx, [home_cursor] + cmp bx, size_of_step*long_v_table + jnz @f + mov byte [si+53], 31 ; 'down arrow' symbol +@@: + pop bx + cmp bx, [home_cursor] + jnz @f + mov byte [si+53], 30 ; 'up arrow' symbol +@@: + call printplain + pop si + add si,size_of_step + + dec bp + jnz .@@_next_bit + +.@@_end: + mov si,_bt + call printplain + ret +.show_0x13: + push si + + cmp si, word [cursor_pos] + jne @f + mov word[ds:_r1+21],'>>' + mov word[ds:_r1+50],'<<' +@@: + mov si,_r1 + jmp .@@_sh +.show_0x12: + push si + cmp si, word [cursor_pos] + jne @f + + mov word[ds:_r2+21],'>>' + mov word[ds:_r2+45],'<<' +@@: + mov si,_r2 + jmp .@@_sh + +;----------------------------------------------------------------------------- +;Clear arrea of current video page (0xb800) +clear_vmodes_table: + pusha + ; draw frames + push es + push 0xb800 + pop es + mov di,1444 + xor ax,ax + mov ah, 1*16+15 + mov cx,70 + mov bp,12 +.loop_start: + rep stosw + mov cx,70 + add di,20 + dec bp + jns .loop_start + pop es + popa + ret + +;----------------------------------------------------------------------------- + +set_vmode: + push 0 ;0;x1000 + pop es + + mov si,word [preboot_graph] ;[preboot_graph] + mov cx,word [es:si+6] ; number of mode + + + mov ax,word [es:si+0] ; resolution X + mov bx,word [es:si+2] ; resolution Y + + + mov word [es:0x900A],ax ; resolution X + mov word [es:0x900C],bx ; resolution Y + mov word [es:0x9008],cx ; number of mode + + cmp cx,0x12 + je .mode0x12_0x13 + cmp cx,0x13 + je .mode0x12_0x13 + + + cmp byte [s_vesa.ver],'2' + jb .vesa12 + +; VESA 2 and Vesa 3 + + mov ax,0x4f01 + and cx,0xfff + mov di,mi;0xa000 + int 0x10 + ; LFB + mov eax,[es:mi.PhysBasePtr];di+0x28] + mov [es:0x9018],eax + ; ---- vbe voodoo + BytesPerLine equ 0x10 + mov ax, [es:di+BytesPerLine] + mov [es:0x9001], ax + ; BPP + cmp [es:mi.BitsPerPixel],16 + jne .l0 + cmp [es:mi.GreenMaskSize],5 + jne .l0 + mov [es:mi.BitsPerPixel],15 +.l0: + mov al, byte [es:di+0x19] + mov [es:0x9000], al + jmp .exit + +.mode0x12_0x13: + mov byte [es:0x9000], 32 + or dword [es:0x9018], 0xFFFFFFFF; 0x800000 + + +; VESA 1.2 PM BANK SWITCH ADDRESS + +.vesa12: + + + mov ax,0x4f0A + xor bx,bx + int 0x10 + xor eax,eax + xor ebx,ebx + mov ax,es + shl eax,4 + mov bx,di + add eax,ebx + movzx ebx,word[es:di] + add eax,ebx + push 0x0000 + pop es + mov [es:0x9014],eax + .exit: + ret + + +; mov dword[es:0x9018],0x000A0000 +; ret + +;============================================================================= +;============================================================================= +;============================================================================= + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/build_ru.bat b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/build_ru.bat new file mode 100644 index 000000000..055418c1c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/build_ru.bat @@ -0,0 +1,89 @@ +@echo off + +set languages=en ru ge et +call :Check_Lang %1 +for %%a in (ru) do if %%a==%target% +call :Target_%target% + +if ERRORLEVEL 0 goto Exit_OK + +echo There was an error executing script. +echo For any help, please send a report. +pause +goto :eof + + + + +:Check_Lang + set res=%1 + :Check_Lang_loop + for %%a in (%languages%) do if %%a==%res% set lang=%res% + if defined lang call :make_all goto :eof + + echo Language '%res%' is incorrect + echo Enter valid language [ %languages% ]: + + set /P res="> + goto Check_Lang_loop +goto :eof + + +:make_all + echo *** building module Kolibri.ldm for Secondary Loader with language '%lang%' ... + + if not exist bin mkdir bin + echo lang fix %lang% > lang.inc + fasm -m 65536 kolibri_ldm.asm bin\kolibri.ldm + if not %errorlevel%==0 goto :Error_FasmFailed + erase lang.inc +goto Exit_OK + + +:Target_all + call :Target_kernel + call :Target_drivers + call :Target_skins +goto :eof + + +:Target_drivers + echo *** building drivers ... + + if not exist bin\drivers mkdir bin\drivers + cd drivers + for %%a in (%drivers%) do ( + fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj + if not %errorlevel%==0 goto :Error_FasmFailed + ) + cd .. + move bin\drivers\vmode.obj bin\drivers\vmode.mdr +goto :eof + + +:Target_skins + echo *** building skins ... + + if not exist bin\skins mkdir bin\skins + cd skin + fasm -m 65536 default.asm ..\bin\skins\default.skn + if not %errorlevel%==0 goto :Error_FasmFailed + cd .. +goto :eof + +:Target_clean + echo *** cleaning ... + rmdir /S /Q bin +goto :Exit_OK + + +:Error_FasmFailed +echo error: fasm execution failed +erase lang.inc +pause +exit 1 + +:Exit_OK +echo all operations has been done +pause +exit 0 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/et.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/et.inc new file mode 100644 index 000000000..f294d2f7b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/et.inc @@ -0,0 +1,14 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; Full ASCII code font +; only х and д added +; Kaitz +ET_FNT: + fontfile file "ETFONT.FNT" + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm new file mode 100644 index 000000000..79e76690b --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm @@ -0,0 +1,808 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Last modify Alexey Teplov 2008. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; kolibri_ldm.asm the module for Secondary Loader ;; +;; ;; +;; KolibriOS 16-bit loader module, ;; +;; based on bootcode for KolibriOS ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +include "lang.inc" + +macro _setcursor row,column +{ + mov dx, row*256 + column + call setcursor +} +long_v_table equ 9 ;long of visible video table +size_of_step equ 10 +d80x25_bottom_num equ 3 +d80x25_top_num equ 4 +;It's a module for Secondary Loader to load kolibri OS +; +start_of_code: + cld +; \begin{diamond}[02.12.2005] +; if bootloader sets ax = 'KL', then ds:si points to loader block +; cmp ax, 'KL' +; jnz @f +; mov word [cs:cfgmanager.loader_block], si +; mov word [cs:cfgmanager.loader_block+2], ds +;@@: +; \end{diamond}[02.12.2005] + +; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk +; (see comment to bx_from_load) +; cmp cx, 'HA' +; jnz no_hd_load +; cmp dx,'RD' +; jnz no_hd_load +; mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007] +;no_hd_load: + +; set up stack + push cs + pop ss + xor ax,ax + mov sp,ax +; mov ax, 3000h +; mov ss, ax +; mov sp, 0EC00h +; set up segment registers + push cs + pop ds + push cs + pop es + +; set videomode + mov ax, 3 + int 0x10 + +;if lang eq ru + ; Load & set russian VGA font (RU.INC) + mov bp, RU_FNT1 ; RU_FNT1 - First part + mov bx, 1000h ; 768 bytes + mov cx, 30h ; 48 symbols + mov dx, 80h ; 128 - position of first symbol + mov ax, 1100h + int 10h + + mov bp, RU_FNT2 ; RU_FNT2 -Second part + mov bx, 1000h ; 512 bytes + mov cx, 20h ; 32 symbols + mov dx, 0E0h ; 224 - position of first symbol + mov ax, 1100h + int 10h + ; End set VGA russian font +;else if lang eq et +; mov bp, ET_FNT ; ET_FNT1 +; mov bx, 1000h ; +; mov cx, 255 ; 256 symbols +; xor dx, dx ; 0 - position of first symbol +; mov ax, 1100h +; int 10h +;end if + +; draw frames + push 0xb800 + pop es + xor di, di + mov ah, 1*16+15 + +; draw top + mov si, d80x25_top + mov cx, d80x25_top_num * 80 +@@: + lodsb + stosw + loop @b +; draw spaces + mov si, space_msg + mov dx, 25 - d80x25_top_num - d80x25_bottom_num +dfl1: + push si + mov cx, 80 +@@: + lodsb + stosw + loop @b + pop si + dec dx + jnz dfl1 +; draw bottom + mov si, d80x25_bottom + mov cx, d80x25_bottom_num * 80 +@@: + lodsb + stosw + loop @b + + mov byte [space_msg+80], 0 ; now space_msg is null terminated + + _setcursor d80x25_top_num,0 + + +; TEST FOR 386+ + + mov bx, 0x4000 + pushf + pop ax + mov dx, ax + xor ax, bx + push ax + popf + pushf + pop ax + and ax, bx + and dx, bx + cmp ax, dx + jnz cpugood + mov si, not386 +sayerr: + call print + jmp $ + cpugood: + + push 0 + popf + sti + +; set up esp + movzx esp, sp + + push 0 + pop es + and word [es:0x9031], 0 +; \begin{Mario79} +; find HDD IDE DMA PCI device +; check for PCI BIOS + mov ax, 0xB101 + int 0x1A + jc .nopci + cmp edx, 'PCI ' + jnz .nopci +; find PCI class code +; class 1 = mass storage +; subclass 1 = IDE controller +; a) class 1, subclass 1, programming interface 0x80 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x80 + xor si, si ; device index = 0 + int 0x1A + jnc .found +; b) class 1, subclass 1, programming interface 0x8A + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x8A + xor si, si ; device index = 0 + int 0x1A + jnc .found +; c) class 1, subclass 1, programming interface 0x85 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x85 + xor si, si + int 0x1A + jc .nopci +.found: +; get memory base + mov ax, 0xB10A + mov di, 0x20 ; memory base is config register at 0x20 + int 0x1A + jc .nopci + and cx, 0xFFF0 ; clear address decode type + mov [es:0x9031], cx +.nopci: +; \end{Mario79} + + mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование + out 0x60, al + xor cx, cx +wait_loop: ; variant 2 +; reading state of port of 8042 controller + in al, 64h + and al, 00000010b ; ready flag +; wait until 8042 controller is ready + loopnz wait_loop + +;;;/diamond today 5.02.2008 +; set keyboard typematic rate & delay + mov al, 0xf3 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b + mov al, 0 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; --------------- APM --------------------- + and word [es:0x9044], 0 ; ver = 0.0 (APM not found) + mov ax, 0x5300 + xor bx, bx + int 0x15 + jc apm_end ; APM not found + test cx, 2 + jz apm_end ; APM 32-bit protected-mode interface not supported + mov [es:0x9044], ax ; Save APM Version + mov [es:0x9046], cx ; Save APM flags + + ; Write APM ver ---- + and ax, 0xf0f + add ax, '00' + mov si, msg_apm + mov [si + 5], ah + mov [si + 7], al + _setcursor 0, 3 + call printplain + ; ------------------ + + mov ax, 0x5304 ; Disconnect interface + xor bx, bx + int 0x15 + mov ax, 0x5303 ; Connect 32 bit mode interface + xor bx, bx + int 0x15 + + mov [es:0x9040], ebx + mov [es:0x9050], ax + mov [es:0x9052], cx + mov [es:0x9054], dx + +apm_end: + _setcursor d80x25_top_num, 0 + +;CHECK current of code + cmp [cfgmanager.loader_block], -1 + jz noloaderblock + les bx, [cfgmanager.loader_block] + cmp byte [es:bx], 1 + mov si, loader_block_error + jnz sayerr + push 0 + pop es + +noloaderblock: +; DISPLAY VESA INFORMATION + call print_vesa_info + call calc_vmodes_table + call check_first_parm ;check and enable cursor_pos + + +; \begin{diamond}[30.11.2005] +cfgmanager: +; settings: +; a) preboot_graph = graphical mode +; preboot_gprobe = probe this mode? +; b) preboot_dma = use DMA access? +; c) preboot_vrrm = use VRR? + +; determine default settings + mov [.bSettingsChanged], 0 + +;.preboot_gr_end: + mov di, preboot_device +; if image in memory is present and [preboot_device] is uninitialized, +; set it to use this preloaded image + cmp byte [di], 0 + jnz .preboot_device_inited + cmp [.loader_block], -1 + jz @f + les bx, [.loader_block] + test byte [es:bx+1], 1 + jz @f + mov byte [di], 3 + jmp .preboot_device_inited +@@: +; otherwise, set [preboot_device] to 1 (default value - boot from floppy) + mov byte [di], 1 +.preboot_device_inited: +; following 6 lines set variables to 1 if its current value is 0 + cmp byte [di+preboot_dma-preboot_device], 1 + adc byte [di+preboot_dma-preboot_device], 0 + cmp byte [di+preboot_biosdisk-preboot_device], 1 + adc byte [di+preboot_biosdisk-preboot_device], 0 + cmp byte [di+preboot_vrrm-preboot_device], 1 + adc byte [di+preboot_vrrm-preboot_device], 0 +; notify user + _setcursor 5,2 + + mov si, linef + call printplain + mov si, start_msg + call print + mov si, time_msg + call print +; get start time + call .gettime + mov [.starttime], eax + mov word [.timer], .newtimer + mov word [.timer+2], cs +.printcfg: + _setcursor 9,0 + mov si, current_cfg_msg + call print + mov si, curvideo_msg + call print + + call draw_current_vmode + + mov si, usebd_msg + cmp [preboot_biosdisk], 1 + call .say_on_off + mov si, vrrm_msg + cmp [preboot_vrrm], 1 + call .say_on_off +; mov si, preboot_device_msg +; call print +; mov al, [preboot_device] +; and eax, 7 +; mov si, [preboot_device_msgs+eax*2] +; call printplain +.show_remarks: +; show remarks in gray color + mov di, ((21-num_remarks)*80 + 2)*2 + push 0xB800 + pop es + mov cx, num_remarks + mov si, remarks +.write_remarks: + lodsw + push si + xchg ax, si + mov ah, 1*16+7 ; background: blue (1), foreground: gray (7) + push di +.write_remark: + lodsb + test al, al + jz @f + stosw + jmp .write_remark +@@: + pop di + pop si + add di, 80*2 + loop .write_remarks +.wait: + _setcursor 25,0 ; out of screen +; set timer interrupt handler + cli + push 0 + pop es + push dword [es:8*4] + pop dword [.oldtimer] + push dword [.timer] + pop dword [es:8*4] +; mov eax, [es:8*4] +; mov [.oldtimer], eax +; mov eax, [.timer] +; mov [es:8*4], eax + sti +; wait for keypressed + xor ax,ax + int 16h + push ax +; restore timer interrupt +; push 0 +; pop es + mov eax, [.oldtimer] + mov [es:8*4], eax + mov [.timer], eax + _setcursor 7,0 + mov si, space_msg + call printplain +; clear remarks and restore normal attributes + push es + mov di, ((21-num_remarks)*80 + 2)*2 + push 0xB800 + pop es + mov cx, num_remarks + mov ax, ' ' + (1*16 + 15)*100h +@@: + push cx + mov cx, 76 + rep stosw + pop cx + add di, 4*2 + loop @b + pop es + pop ax +; switch on key + cmp al, 13 + jz .continue + or al, 20h + cmp al, 'a' + jz .change_a + cmp al, 'b' + jz .change_b + cmp al, 'c' + jnz .show_remarks + + _setcursor 15,0 + mov si, vrrmprint + call print + mov bx, '12' + call getkey + mov [preboot_vrrm], al + _setcursor 12,0 +.d: + mov [.bSettingsChanged], 1 + call clear_vmodes_table ;clear vmodes_table + jmp .printcfg +.change_a: +.loops: + call draw_vmodes_table + _setcursor 25,0 ; out of screen + xor ax,ax + int 0x16 +; call clear_table_cursor ;clear current position of cursor + + mov si,word [cursor_pos] + + cmp ah,0x48;x,0x48E0 ; up + jne .down + cmp si,modes_table + jbe .loops + sub word [cursor_pos],size_of_step + jmp .loops + +.down: cmp ah,0x50;x,0x50E0 ; down + jne .pgup + cmp word[es:si+10],-1 + je .loops + add word [cursor_pos],size_of_step + jmp .loops + +.pgup: cmp ah,0x49 ; page up + jne .pgdn + sub si, size_of_step*long_v_table + cmp si, modes_table + jae @f + mov si, modes_table +@@: + mov word [cursor_pos], si + mov si, word [home_cursor] + sub si, size_of_step*long_v_table + cmp si, modes_table + jae @f + mov si, modes_table +@@: + mov word [home_cursor], si + jmp .loops + +.pgdn: cmp ah,0x51 ; page down + jne .enter + mov ax, [end_cursor] + add si, size_of_step*long_v_table + cmp si, ax + jb @f + mov si, ax + sub si, size_of_step +@@: + mov word [cursor_pos], si + mov si, word [home_cursor] + sub ax, size_of_step*long_v_table + add si, size_of_step*long_v_table + cmp si, ax + jb @f + mov si, ax +@@: + mov word [home_cursor], si + jmp .loops + +.enter: cmp al,0x0D;x,0x1C0D ; enter + jne .loops + push word [cursor_pos] + pop bp + push word [es:bp] + pop word [x_save] + push word [es:bp+2] + pop word [y_save] + push word [es:bp+6] + pop word [number_vm] + mov word [preboot_graph],bp ;save choose + + jmp .d + +.change_b: + _setcursor 15,0 +; mov si, ask_dma +; call print +; mov bx, '13' +; call getkey +; mov [preboot_dma], al + mov si, ask_bd + call print + mov bx, '12' + call getkey + mov [preboot_biosdisk], al + _setcursor 11,0 + jmp .d +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.say_on_off: + pushf + call print + mov si, on_msg + popf + jz @f + mov si, off_msg +@@: jmp printplain +; novesa and vervesa strings are not used at the moment of executing this code +virtual at novesa +.oldtimer dd ? +.starttime dd ? +.bSettingsChanged db ? +.timer dd ? +end virtual +.loader_block dd -1 +.gettime: + mov ah, 0 + int 1Ah + xchg ax, cx + shl eax, 10h + xchg ax, dx + ret +.newtimer: + push ds + push cs + pop ds + pushf + call [.oldtimer] + pushad + call .gettime + sub eax, [.starttime] + sub ax, 18*5 + jae .timergo + neg ax + add ax, 18-1 + mov bx, 18 + xor dx, dx + div bx +if lang eq ru +; Ї®¤®¦¤ЁвҐ 5 ᥪ㭤, 4/3/2 ᥪ㭤л, 1 ᥪ㭤г + cmp al, 5 + mov cl, ' ' + jae @f + cmp al, 1 + mov cl, 'г' + jz @f + mov cl, 'л' +@@: mov [time_str+9], cl +else if lang eq et + cmp al, 1 + ja @f + mov [time_str+9], ' ' + mov [time_str+10],' ' +@@: +else +; wait 5/4/3/2 seconds, 1 second + cmp al, 1 + mov cl, 's' + ja @f + mov cl, ' ' +@@: mov [time_str+9], cl +end if + add al, '0' + mov [time_str+1], al + mov si, time_msg + _setcursor 7,0 + call print + _setcursor 25,0 + popad + pop ds + iret +.timergo: + push 0 + pop es + mov eax, [.oldtimer] + mov [es:8*4], eax + mov sp, 0EC00h +.continue: + sti + _setcursor 6,0 + mov si, space_msg + call printplain + call printplain + _setcursor 6,0 + mov si, loading_msg + call print + _setcursor 15,0 + cmp [.bSettingsChanged], 0 + jz .load + cmp [.loader_block], -1 + jz .load + les bx, [.loader_block] + mov eax, [es:bx+3] + push ds + pop es + test eax, eax + jz .load + push eax + mov si, save_quest + call print +.waityn: + mov ah, 0 + int 16h + or al, 20h + cmp al, 'n' + jz .loadc + cmp al, 'y' + jnz .waityn + call putchar + mov byte [space_msg+80], 186 + pop eax + push cs + push .cont + push eax + retf +.loadc: + pop eax +.cont: + push cs + pop ds + mov si, space_msg + mov byte [si+80], 0 + _setcursor 15,0 + call printplain + _setcursor 15,0 +.load: +; \end{diamond}[02.12.2005] + +; ASK GRAPHICS MODE + + call set_vmode + +; GRAPHICS ACCELERATION +; force yes + mov [es:0x901C], byte 1 + +; DMA ACCESS TO HD + + mov al, [preboot_dma] + mov [es:0x901F], al + +; VRR_M USE + + mov al,[preboot_vrrm] + mov [es:0x9030], al + mov [es:0x901E], byte 1 + +; BOOT DEVICE + + mov al, [preboot_device] + dec al + mov [boot_dev], al + + + + + + +;;;;;;;;;;; set videomode + xor ax, ax + mov es, ax + + mov ax, [es:0x9008] ; vga & 320x200 + mov bx, ax + cmp ax, 0x13 + je setgr + cmp ax, 0x12 + je setgr + mov ax, 0x4f02 ; Vesa +setgr: + int 0x10 + test ah, ah + mov si, fatalsel + jnz v_mode_error +; set mode 0x12 graphics registers: + cmp bx, 0x12 + jne gmok2 + + mov al, 0x05 + mov dx, 0x03ce + push dx + out dx, al ; select GDC mode register + mov al, 0x02 + inc dx + out dx, al ; set write mode 2 + + mov al, 0x02 + mov dx, 0x03c4 + out dx, al ; select VGA sequencer map mask register + mov al, 0x0f + inc dx + out dx, al ; set mask for all planes 0-3 + + mov al, 0x08 + pop dx + out dx, al ; select GDC bit mask register + ; for writes to 0x03cf +gmok2: + push ds + pop es + + jmp $ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;data +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +include "lang.inc" +include "bootstr.inc" ; language-independent boot messages +;if lang eq en +;include "booteng.inc" ; english system boot messages +;else if lang eq ru +include "bootru.inc" ; russian system boot messages +include "ru.inc" ; Russian font +;else if lang eq et +;include "bootet.inc" ; estonian system boot messages +;include "et.inc" ; Estonian font +;else +;include "bootge.inc" ; german system boot messages +;end if + +include 'macros.inc' +include 'bootvesa.inc' + +include "preboot.inc" + + +setcursor: +; in: dl=column, dh=row + mov ah, 2 + mov bh, 0 + int 10h + ret + +putchar: +; in: al=character + mov ah, 0Eh + mov bh, 0 + int 10h + ret + +print: +; in: si->string + mov al, 186 + call putchar + mov al, ' ' + call putchar + +printplain: +; in: si->string + pusha + lodsb +@@: + call putchar + lodsb + cmp al, 0 + jnz @b + popa + ret + +getkey: +; get number in range [bl,bh] (bl,bh in ['0'..'9']) +; in: bx=range +; out: ax=digit (1..9, 10 for 0) + mov ah, 0 + int 16h + cmp al, bl + jb getkey + cmp al, bh + ja getkey + push ax + call putchar + pop ax + and ax, 0Fh + jnz @f + mov al, 10 +@@: + ret diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/macros.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/macros.inc new file mode 100644 index 000000000..01c180f3a --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/macros.inc @@ -0,0 +1,86 @@ + + +; structure definition helper +macro struct name, [arg] + { + common + name@struct equ name + struc name arg { + } + +macro struct_helper name + { + match xname,name + \{ + virtual at 0 + xname xname + sizeof.#xname = $ - xname + name equ sizeof.#xname + end virtual + \} + } + +ends fix } struct_helper name@struct + +;// mike.dld, 2006-29-01 [ + +; macros definition +macro diff16 title,l1,l2 +{ + local s,d + s = l2-l1 + display title,': 0x' + repeat 16 + d = 48 + s shr ((16-%) shl 2) and $0F + if d > 57 + d = d + 65-57-1 + end if + display d + end repeat + display 13,10 +} +macro diff10 title,l1,l2 + { + local s,d,z,m + s = l2-l1 + z = 0 + m = 1000000000 + display title,': ' + repeat 10 + d = '0' + s / m + s = s - (s/m)*m + m = m / 10 + if d <> '0' + z = 1 + end if + if z <> 0 + display d + end if + end repeat + display 13,10 + } + +; \begin{diamond}[29.09.2006] +; may be useful for kernel debugging +; example 1: +; dbgstr 'Hello, World!' +; example 2: +; dbgstr 'Hello, World!', save_flags +macro dbgstr string*, f +{ +local a +iglobal_nested +a db 'K : ',string,13,10,0 +endg_nested +if ~ f eq + pushfd +end if + push esi + mov esi, a + call sys_msg_board_str + pop esi +if ~ f eq + popfd +end if +} +; \end{diamond}[29.09.2006] diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/preboot.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/preboot.inc new file mode 100644 index 000000000..b3fdb3831 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/preboot.inc @@ -0,0 +1,36 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +display_modechg db 0 ; display mode change for text, yes/no (0 or 2) + ; + ; !! Important note !! + ; + ; Must be set to 2, to avoid two screenmode + ; changes within a very short period of time. + +display_atboot db 0 ; show boot screen messages ( 2-no ) + +preboot_graph dw 0 ; graph mode +x_save dw 0 ; x +y_save dw 0 ; y +number_vm dw 0 ; +;pixel_save dw 0 ; per to pixel +preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes) +preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no) +preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never) +preboot_device db 0 ; boot device + ; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk) + ;!!!! 0 - autodetect !!!! +preboot_blogesc = 0 ; start immediately after bootlog +preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no) + +; if $>0x200 +;ERROR: prebooting parameters must fit in first sector!!! +; end if +;hdsysimage db 'KOLIBRI IMG' ; load from +;image_save db 'KOLIBRI IMG' ; save to diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/rdload.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/rdload.inc new file mode 100644 index 000000000..af70d34e3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/rdload.inc @@ -0,0 +1,123 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; READ RAMDISK IMAGE FROM HD + + cmp [boot_dev+OS_BASE+0x10000],1 + jne no_sys_on_hd + + test [DRIVE_DATA+1],byte 0x40 + jz position_2 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + mov [fat32part],0 + position_1_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+2] + cmp [fat32part],eax + jle position_1_1 + position_2: + test [DRIVE_DATA+1],byte 0x10 + jz position_3 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + mov [fat32part],0 + position_2_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+3] + cmp eax,[fat32part] + jle position_2_1 + position_3: + test [DRIVE_DATA+1],byte 0x4 + jz position_4 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + mov [fat32part],0 + position_3_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+4] + cmp eax,[fat32part] + jle position_3_1 + position_4: + test [DRIVE_DATA+1],byte 0x1 + jz no_sys_on_hd + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 + mov [fat32part],0 + position_4_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [DRIVE_DATA+5] + cmp eax,[fat32part] + jle position_4_1 + jmp yes_sys_on_hd + + search_and_read_image: + call set_FAT32_variables + mov edx, bootpath + call read_image + test eax, eax + jz image_present + mov edx, bootpath2 + call read_image + test eax, eax + jz image_present + ret + image_present: + mov [image_retrieved],1 + ret + +read_image: + mov eax, hdsysimage+OS_BASE+0x10000 + mov ebx, 1474560/512 + mov ecx, RAMDISK + mov esi, 0 + mov edi, 12 + call file_read + ret + +image_retrieved db 0 +counter_of_partitions db 0 +no_sys_on_hd: + ; test_to_format_ram_disk (need if not using ram disk) + cmp [boot_dev+OS_BASE+0x10000],3 + jne not_format_ram_disk + ; format_ram_disk + mov edi, RAMDISK + mov ecx, 0x1080 + xor eax,eax +@@: + stosd + loop @b + + mov ecx, 0x58F7F + mov eax,0xF6F6F6F6 +@@: + stosd + loop @b + + mov [RAMDISK+0x200],dword 0xFFFFF0 ; fat table + mov [RAMDISK+0x4200],dword 0xFFFFF0 + +not_format_ram_disk: +yes_sys_on_hd: diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ru.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ru.inc new file mode 100644 index 000000000..606c698e3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/ru.inc @@ -0,0 +1,100 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; Generated by RUFNT.EXE +; By BadBugsKiller (C) +; Modifyed by BadBugsKiller 12.01.2004 17:45 +; Шрифт уменьшен в размере и теперь состоит из 2-ух частей, +; содержащих только символы русского алфавита. +; символы в кодировке ASCII (ДОС'овская), кодовая страница 866. +RU_FNT1: + db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + +RU_FNT2: + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/shutdown.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/shutdown.inc new file mode 100644 index 000000000..07ba5355f --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/kolibri_ldm/shutdown.inc @@ -0,0 +1,207 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Shutdown for Menuet ;; +;; ;; +;; Distributed under General Public License ;; +;; See file COPYING for details. ;; +;; Copyright 2003 Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +align 4 +pr_mode_exit: + +; setup stack + mov ax, 0x3000 + mov ss, ax + mov esp, 0x0EC00 +; setup ds + push cs + pop ds + + lidt [old_ints_h] +;remap IRQs + mov al,0x11 + out 0x20,al + call rdelay + out 0xA0,al + call rdelay + + mov al,0x08 + out 0x21,al + call rdelay + mov al,0x70 + out 0xA1,al + call rdelay + + mov al,0x04 + out 0x21,al + call rdelay + mov al,0x02 + out 0xA1,al + call rdelay + + mov al,0x01 + out 0x21,al + call rdelay + out 0xA1,al + call rdelay + + mov al,0xB8 + out 0x21,al + call rdelay + mov al,0xBD + out 0xA1,al + sti + +temp_3456: + xor ax,ax + mov es,ax + mov al,byte [es:0x9030] + cmp al,1 + jl nbw + cmp al,4 + jle nbw32 + +nbw: + in al,0x60 + cmp al,6 + jae nbw + mov bl,al +nbw2: + in al,0x60 + cmp al,bl + je nbw2 + cmp al,240 ;ax,240 + jne nbw31 + mov al,bl + dec ax + jmp nbw32 +nbw31: + add bl,128 + cmp al,bl + jne nbw + sub al,129 + +nbw32: + + dec ax + dec ax ; 2 = power off + jnz no_apm_off + call APM_PowerOff + jmp $ +no_apm_off: + + dec ax ; 3 = reboot + jnz restart_kernel ; 4 = restart kernel + push 0x40 + pop ds + mov word[0x0072],0x1234 + jmp 0xF000:0xFFF0 + + +rdelay: + ret + +APM_PowerOff: + mov ax, 5304h + xor bx, bx + int 15h +;!!!!!!!!!!!!!!!!!!!!!!!! + mov ax,0x5300 + xor bx,bx + int 0x15 + push ax + + mov ax,0x5301 + xor bx,bx + int 0x15 + + mov ax,0x5308 + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x530E + xor bx,bx + pop cx + int 0x15 + + mov ax,0x530D + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x530F + mov bx,1 + mov cx,bx + int 0x15 + + mov ax,0x5307 + mov bx,1 + mov cx,3 + int 0x15 +;!!!!!!!!!!!!!!!!!!!!!!!! + ret + +restart_kernel: + + mov ax,0x0003 ; set text mode for screen + int 0x10 + jmp 0x4000:0000 + +restart_kernel_4000: + cli + + push ds + pop es + mov cx, 0x8000 + push cx + push 0x7000 + pop ds + xor si, si + xor di, di + rep movsw + pop cx + mov ds, cx + push 0x2000 + pop es + rep movsw + push 0x9000 + pop ds + push 0x3000 + pop es + mov cx, 0xE000/2 + rep movsw + + wbinvd ; write and invalidate cache + + mov al, 00110100b + out 43h, al + jcxz $+2 + mov al, 0xFF + out 40h, al + jcxz $+2 + out 40h, al + jcxz $+2 + sti + +; (hint by Black_mirror) +; We must read data from keyboard port, +; because there may be situation when previous keyboard interrupt is lost +; (due to return to real mode and IRQ reprogramming) +; and next interrupt will not be generated (as keyboard waits for handling) + in al, 0x60 + +; bootloader interface + push 0x1000 + pop ds + mov si, kernel_restart_bootblock + mov ax, 'KL' + jmp 0x1000:0000 + + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/listing.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/listing.inc new file mode 100644 index 000000000..4ef5f8eeb --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/listing.inc @@ -0,0 +1,635 @@ +; Listing generator +; LocoDelAssembly 2007.06.01 + +INSTRUCTIONS equ bt in ja jb jc je jg jl jo jp js jz or \ + aaa aad aam aas adc add and bsf bsr btc btr bts cbw cdq clc \ + cld cli cmc cmp cqo cwd daa das dec div fld fst hlt inc ins \ + int jae jbe jge jle jmp jna jnb jnc jne jng jnl jno jnp jns \ + jnz jpe jpo lar lds lea les lfs lgs lsl lss ltr mov mul neg \ + nop not out pop por rcl rcr ret rol ror rsm sal sar sbb shl \ + shr stc std sti str sub ud2 xor \ + arpl call cdqe clgi clts cmps cwde emms fabs fadd fbld fchs \ + fcom fcos fdiv feni fild fist fld1 fldz fmul fnop fsin fstp \ + fsub ftst fxam fxch idiv imul insb insd insw int1 int3 into \ + invd iret jcxz jnae jnbe jnge jnle lahf lgdt lidt lldt lmsw \ + lods loop movd movq movs orpd orps outs pand popa popd popf \ + popq popw push pxor retd retf retn retq retw sahf salc scas \ + seta setb setc sete setg setl seto setp sets setz sgdt shld \ + shrd sidt sldt smsw stgi stos test verr verw wait xadd xchg \ + xlat \ + addpd addps addsd addss andpd andps bound bswap cmova cmovb \ + cmovc cmove cmovg cmovl cmovo cmovp cmovs cmovz cmppd cmpps \ + cmpsb cmpsd cmpsq cmpss cmpsw cpuid divpd divps divsd divss \ + enter f2xm1 faddp fbstp fclex fcomi fcomp fdisi fdivp fdivr \ + femms ffree fiadd ficom fidiv fimul finit fistp fisub fldcw \ + fldpi fmulp fneni fprem fptan fsave fsqrt fstcw fstsw fsubp \ + fsubr fucom fwait fyl2x icebp iretd iretq iretw jecxz jrcxz \ + lddqu leave lodsb lodsd lodsq lodsw loopd loope loopq loopw \ + loopz maxpd maxps maxsd maxss minpd minps minsd minss movsb \ + movsd movsq movss movsw movsx movzx mulpd mulps mulsd mulss \ + mwait outsb outsd outsw pabsb pabsd pabsw paddb paddd paddq \ + paddw pandn pause pavgb pavgw pf2id pf2iw pfacc pfadd pfmax \ + pfmin pfmul pfrcp pfsub pi2fd pi2fw popad popaw popfd popfq \ + popfw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb \ + psubd psubq psubw pusha pushd pushf pushq pushw rcpps rcpss \ + rdmsr rdpmc rdtsc retfd retfq retfw retnd retnq retnw scasb \ + scasd scasq scasw setae setbe setge setle setna setnb setnc \ + setne setng setnl setno setnp setns setnz setpe setpo stosb \ + stosd stosq stosw subpd subps subsd subss vmrun vmxon wrmsr \ + xlatb xorpd xorps \ + andnpd andnps cmovae cmovbe cmovge cmovle cmovna cmovnb cmovnc\ + cmovne cmovng cmovnl cmovno cmovnp cmovns cmovnz cmovpe cmovpo\ + comisd comiss fcmovb fcmove fcmovu fcomip fcompp fdivrp ffreep\ + ficomp fidivr fisttp fisubr fldenv fldl2e fldl2t fldlg2 fldln2\ + fnclex fndisi fninit fnsave fnstcw fnstsw fpatan fprem1 frstor\ + frstpm fscale fsetpm fstenv fsubrp fucomi fucomp fxsave haddpd\ + haddps hsubpd hsubps invlpg lfence looped loopeq loopew loopne\ + loopnz loopzd loopzq loopzw mfence movapd movaps movdqa movdqu\ + movhpd movhps movlpd movlps movnti movntq movsxd movupd movups\ + paddsb paddsw pextrw pfnacc pfsubr phaddd phaddw phsubd phsubw\ + pinsrw pmaxsw pmaxub pminsw pminub pmulhw pmullw psadbw pshufb\ + pshufd pshufw psignb psignd psignw pslldq psrldq psubsb psubsw\ + pswapd pushad pushaw pushfd pushfq pushfw rdmsrq rdtscp setalc\ + setnae setnbe setnge setnle sfence shufpd shufps skinit sqrtpd\ + sqrtps sqrtsd sqrtss swapgs sysret vmcall vmload vmread vmsave\ + vmxoff wbinvd wrmsrq \ + clflush cmovnae cmovnbe cmovnge cmovnle cmpeqpd cmpeqps \ + cmpeqsd cmpeqss cmplepd cmpleps cmplesd cmpless cmpltpd \ + cmpltps cmpltsd cmpltss cmpxchg fcmovbe fcmovnb fcmovne \ + fcmovnu fdecstp fincstp fnstenv frndint fsincos fucomip \ + fucompp fxrstor fxtract fyl2xp1 invlpga ldmxcsr loopned \ + loopneq loopnew loopnzd loopnzq loopnzw monitor movddup \ + movdq2q movhlps movlhps movntdq movntpd movntps movq2dq \ + paddusb paddusw palignr pavgusb pcmpeqb pcmpeqd pcmpeqw \ + pcmpgtb pcmpgtd pcmpgtw pfcmpeq pfcmpge pfcmpgt pfpnacc \ + pfrsqrt phaddsw phsubsw pmaddwd pmulhrw pmulhuw pmuludq \ + pshufhw pshuflw psubusb psubusw rsqrtps rsqrtss stmxcsr \ + syscall sysexit sysretq ucomisd ucomiss vmclear vmmcall \ + vmptrld vmptrst vmwrite \ + addsubpd addsubps cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd\ + cmpnleps cmpnlesd cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss\ + cmpordpd cmpordps cmpordsd cmpordss cvtdq2pd cvtdq2ps cvtpd2dq\ + cvtpd2pi cvtpd2ps cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi\ + cvtsd2si cvtsd2ss cvtsi2sd cvtsi2ss cvtss2sd cvtss2si fcmovnbe\ + maskmovq movmskpd movmskps movshdup movsldup packssdw packsswb\ + packuswb pfrcpit1 pfrcpit2 pfrsqit1 pmovmskb pmulhrsw prefetch\ + sysenter sysexitq unpckhpd unpckhps unpcklpd unpcklps vmlaunch\ + vmresume \ + cmpxchg8b cvttpd2dq cvttpd2pi cvttps2dq cvttps2pi cvttsd2si \ + cvttss2si pmaddubsw prefetchw punpckhbw punpckhdq punpckhwd \ + punpcklbw punpckldq punpcklwd \ + cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg16b \ + loadall286 loadall386 maskmovdqu prefetcht0 prefetcht1 \ + prefetcht2 punpckhqdq punpcklqdq prefetchnta + +PREFIXES equ rep lock repe repz repne repnz + +DATA_DEFINITORS equ db dw du dd dp df dq dt file +DATA_RESERVERS equ rb rw rd rp rf rq rt + +CRLF equ 13, 10 ; Remove 13 for Linux +MAX_BYTES equ 13 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +macro use16 +{ +use16 + _USE = 16 +} + +macro use32 +{ +use32 + _USE = 32 +} + +macro use64 +{ +use64 + _USE = 64 +} + +macro detect_mode +{ +local aux + + _USE = 32 + + virtual at 0 + xchg eax, eax + load aux byte from 0 + + if aux = $66 + _USE = 16 + else if aux = $87 + _USE = 64 + end if + end virtual +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYING MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +macro display_address address* +{ +local aux, digit + + aux = address + + repeat _USE / 4 + digit = aux shr (_USE - 4 * %) and $F + + display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F + end repeat + + display ': ' +} + +macro display_bytes pointer +{ +local aux, size, digit + + size = $ - pointer + + if size > MAX_BYTES + size = MAX_BYTES + end if + + repeat size + load aux byte from pointer+%-1 + + digit = aux shr 4 + display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F + + digit = aux and $F + display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F + + + display ' ' + end repeat + + repeat MAX_BYTES - size + display ' ' + end repeat +} + +; The macro below in some situations doesn't adds a space to separate things unfortunatelly, so for readability ensurance +; another one will be used instead... +;macro display_args [args] +;{ +;common +; aux = 1 +; +;forward +; if ~args eq +; if aux +; display ' ' +; else +; display ', ' +; end if +; +; aux = 0 +; +; match =ON, _RESOLVE_EQUATES +; \{ +; match args, args +; \\{ +; irps arg, args +; \\\{ +; display \\\`arg +; \\\} +; \\} +; \} +; match =OFF, _RESOLVE_EQUATES +; \{ +; irps arg, args +; \\{ +; display \\`arg +; \\} +; +; \} +; end if +;} + +; This one separates everything with one space. A very ugly listing but at least you will not see things +; like "push ebxesiedi" nor "ret word0" + +macro display_args [args] +{ +common + aux = 1 + +forward + if ~args eq + if ~aux + display ',' + end if + + aux = 0 + + match =ON, _RESOLVE_EQUATES + \{ + match args, args + \\{ + if ~args eqtype "" + irps arg, args + \\\{ + display ' ', \\\`arg + \\\} + else + display " '", args, "'" + end if + \\} + \} + match =OFF, _RESOLVE_EQUATES + \{ + if ~args eqtype "" + irps arg, args + \\{ + display ' ', \\`arg + \\} + else + display " '", args, "'" + end if + \} + end if +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;; INSTRUCTIONS & PREFIXES MACROSES ;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +macro prefix mnemonic +{ +local aux + + macro mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + mnemonic + + match =1, _LISTING + \\{ + display_bytes aux + + display \`mnemonic + display CRLF + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + + def_prefix mnemonic + args + purge mnemonic + \} +} + +macro def_prefix mnemonic +{ + macro def_prefix mnemonic + \{ + prefix mnemonic + \} + def_prefix mnemonic +} + +macro instruction mnemonic +{ +local aux + + macro mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + mnemonic args + + match =1, _LISTING + \\{ + display_bytes aux + + display \`mnemonic + + virtual at 0 + db \`mnemonic + repeat 11 - $ + display ' ' + end repeat + end virtual + + display_args args + display CRLF + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + \} +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +macro data_define mnemonic +{ +local aux + macro mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + mnemonic args + + match =1, _LISTING + \\{ + display_bytes aux + + display \`mnemonic + + display_args args + display CRLF + + aux = aux + MAX_BYTES + + repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES + display_address aux + display_bytes aux + display CRLF + + aux = aux + MAX_BYTES + end repeat + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + \} + + struc mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + . mnemonic args + + match =1, _LISTING + \\{ + display_bytes aux + + display \`., ' ', \`mnemonic + + display_args args + display CRLF + + aux = aux + MAX_BYTES + + repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES + display_address aux + display_bytes aux + display CRLF + + aux = aux + MAX_BYTES + end repeat + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + \} +} + +macro data_reserve mnemonic +{ +local aux + macro mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + mnemonic args + + match =1, _LISTING + \\{ + times MAX_BYTES display ' ' + + display \`mnemonic + + display_args args + display CRLF + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + \} + + struc mnemonic [args] + \{ + \common + match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} + match =equ, args\\{_LISTING equ 0\\} + match =equ any, args\\{_LISTING equ 0\\} + + match =1, _LISTING + \\{ + display_address $ + aux = $ + \\} + + . mnemonic args + + match =1, _LISTING + \\{ + times MAX_BYTES display ' ' + + display \`., ' ', \`mnemonic + + display_args args + display CRLF + \\} + + match =1, _ON_VIRTUAL\\{restore _LISTING\\} + match =equ, args\\{restore _LISTING\\} + match =equ any, args\\{restore _LISTING\\} + \} +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; LISTING CONTROL MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +macro virtual [args] +{ +common + _ON_VIRTUAL equ 1 + + virtual args +} + +macro end [args] +{ +common + match =virtual, args\{restore _ON_VIRTUAL\} + + end args +} + +macro enable_listing +{ + detect_mode + + match =0, _MACROSES_INSTALLED + \{ + match instructions, INSTRUCTIONS + \\{ + irps ins, instructions + \\\{ + instruction ins + \\\} + \\} + + match prefixes, PREFIXES + \\{ + irps prefix, prefixes + \\\{ + def_prefix prefix + \\\} + \\} + + match data_definitors, DATA_DEFINITORS + \\{ + irps def, data_definitors + \\\{ + data_define def + \\\} + \\} + + match data_reservers, DATA_RESERVERS + \\{ + irps def, data_reservers + \\\{ + data_reserve def + \\\} + \\} + \} + + _MACROSES_INSTALLED equ 1 + _LISTING equ 1 +} + +macro disable_listing +{ + _LISTING equ 0 +} + +macro enable [feature*] +{ +forward + UNKNOWN equ 1 + + match =resolve_equates, feature + \{ + restore _RESOLVE_EQUATES + _RESOLVE_EQUATES equ ON + UNKNOWN equ 0 + \} + + match =listing, feature + \{ + enable_listing + UNKNOWN equ 0 + \} + + match =1, UNKNOWN + \{ + display 'ERROR: Unknown "',`feature, '" feature', 13, 10 + err + \} + + restore UNKNOWN + restore UNKNOWN +} + +macro disable [feature*] +{ + UNKNOWN equ 1 + + match =resolve_equates, feature + \{ + restore _RESOLVE_EQUATES + _RESOLVE_EQUATES equ OFF + UNKNOWN equ 0 + \} + + match =listing, feature + \{ + disable_listing + UNKNOWN equ 0 + \} + + match =1, UNKNOWN + \{ + display 'ERROR: Unknown "',`feature, '" feature', 13, 10 + err + \} + + restore UNKNOWN + restore UNKNOWN +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +_MACROSES_INSTALLED equ 0 +_ON_VIRTUAL equ 0 + +disable resolve_equates diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.asm b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.asm new file mode 100644 index 000000000..3ea008ab7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.asm @@ -0,0 +1,317 @@ +; Copyright (c) 2008-2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;start of the project 13.02.2008 year. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Secondary Loader copyright Alexey Teplov nickname +;if you need log preproc +;///////////// +;include 'listing.inc' +;enable listing +;//////////// +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;start of code: ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use16 + org 0x0 + jmp start +include 'sl_equ.inc' ; в файле размещены все equ предопределения +include 'boot_st.inc' +include 'debug_msg.inc' ;here is message from debug +include 'parse_dat.inc' +include 'sl_proc.inc' +include 'parse.inc' +include 'parse_loader.inc' +include 'parse_any.inc' +include 'parse_def_sect.inc' +include 'parse_err.inc' + +file_data dw 0x0,ini_data_ ;формат: смещение: сегмент т.к. используется les +size_data dw 16 ;16 блоков по 4 кб т.е предел до 64 кб +name_ini_f db 'kord/startos.ini',0 + +;//////////// +loader_callback dd ? +load_drive dw ? +load_ft dw ? +;Start code + +start: +; Save far pointer to callback procedure, ds:si is point + mov word [cs:loader_callback], si + mov word [cs:loader_callback+2], ds +; Save type of drive + mov word [cs:load_drive],ax +; Save type of FT + mov word [cs:load_ft],bx +; set up stack + mov ax, cs + mov ss, ax + xor sp, sp +; set up segment registers + mov ds,ax + mov es,ax +; just to be sure: force DF=0, IF=1 + cld + sti + +; set videomode + mov ax,3 + int 0x10 + + mov si,version + call printplain + mov al,'#' + mov cx,80 +;input cx=size al=char будет вывден символ сколько раз указано в cx +@@: + call putchar + loop @b + + if DEBUG + pushad + mov ax,cs + shl eax,4 ; в десятичной системе адрес сегмента + mov cx,0xa + mov di,cseg_msg + call decode +;*************** + mov si,cseg_msg + call printplain + popad + end if + + + if DEBUG + mov si,stack_msg + call printplain + end if + +; Require 586 or higher processor (cpuid and rdtsc,rdmsr/wrmsr commands) +; install int 6 (#UD) handler + xor bx, bx + mov ds, bx + push word [bx+6*4+2] + push word [bx+6*4] + mov word [bx+6*4], ud16 + mov word [bx+6*4+2], cs +; issue CPUID command + xor eax, eax ; N.B.: will cause #UD before 386 + cpuid ; N.B.: will cause #UD before later 486s + test eax, eax + jz cpubad +; get processor features + xor eax, eax + inc ax + cpuid + test dl, 10h ; CPUID[1].edx[4] - TSC support + jz cpubad + test dl, 20h ; CPUID[1].edx[5] - MSR support + jnz cpugood + +ud16: ; #UD handler, called if processor did not recognize some commands +cpubad: +; restore int 6 (#UD) handler + pop word [6*4] + pop word [6*4+2] +; say error + push cs + pop ds + mov si, badprocessor +sayerr: + call printplain + jmp $ + +cpugood: +; restore int 6 (#UD) handler + pop dword [6*4] + push cs + pop ds + +; set up esp + movzx esp, sp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; init memory +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + + +; Load startos.ini + mov cx,loop_read_startos_file ;кол-во попыток чтения файла конфигурации startos.ini +align 4 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Load startos.ini ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +load_startos_file: + + xor ax,ax + mov di,file_data + inc ax ;function 1 - read file + push cx + call far dword [loader_callback] + pop cx + push cs + push cs + pop ds + pop es + + test bx,bx + jz check_conf_file + dec cx + jnz load_startos_file + +;SET DEFAULT Not use ini file +error_ini: + mov si, error_ini_f1 ;Error: cannot load ini file, buffer is full + dec bx + jz err_show_ini + mov si, error_ini_f2 ;Error: ini file not found + dec bx + jz err_show_ini + mov si, error_ini_f3 ;Error: cannot read ini file + dec bx + jz err_show_ini + + mov si, error_ini_nf ;Error: unrecognized error when loading ini file +err_show_ini: + call printplain + mov si, error_ini_common + call printplain +; wait for keypress + xor ax,ax + int 16h + +ini_loaded: + + jmp $ + +align 4 +check_conf_file: +;Check config file in current dir + push ax ;save size file + if DEBUG + mov cx,0x0a + mov di,show_decode + call decode +;Show size + mov si,show_string + call printplain + end if + + +;Show message + mov si,load_ini + call printplain + + pop cx ;restore size file +use_parse ;parsing startos.ini +; + jmp ini_loaded + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;DATA +;;;;;;;;;;;;;;;;;;;;;;;;;;; +; table for move to extended memory (int 15h, ah=87h) +align 4 +table_15_87: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + + db 0xff,0xff + db 0x0,0x10 + db 0x00,0x93,0x0,0x0 + + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + +fat12_buffer: +.BS_jmpBoot db 0x90,0x90,0x90 ;3 байта NOP инструкция - ничего не делать +.BS_OEMName db 'K SyS 64' ;8 байт +.BPB_BytsPerSec dw 512 ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта +.BPB_SecPerClus db 0x1 ;кол-во секторов в кластере +.BPB_RsvdSecCnt dw 0x1 ;для FAt12/16 только 1, для FAT32 обычно 32 +.BPB_NumFATs db 0x1 ;кол-во фат таблиц, на тот случай если будет сброс на дискету образа рам диска +.BPB_RootEntCnt dw 512 ;для мак совместимости с fat16 +.BPB_TotSec16 dw 0x0 ;кл-во секторов +.BPB_Media db 0xF0 +.BPB_FATSz16 dw 0x0 +.BPB_SecPerTrk dw 0x0 ;содержит геометрию диска для RAMFS на как бы без разницы, пока пустое поле, позже внести реальные значения. +.BPB_NumHeads dw 0x0 +.BPB_HiddSec dd 0x0 ;кол-во скрытых секторов +.BPB_TotSec32 dd 0x0 +.BS_DrvNum db 'R' ;от слова RAM +.BS_Reserved1 db 0x0 +.BS_BootSig db 0x29 +.BS_VolID db 'RFKS' +.BS_VolLab db 'RAM DISK FS' ;11 символов +.BS_FilSysType db 'FAT12 ' ;8 символов +;62 байта структура fat12. +db (512-($-fat12_buffer))dup(0x90) + + + +;структура для дирректории fat +struc FAT_32_entry ;Byte Directory Entry Structure +{ +.DIR_Name rb 11 +.DIR_Attr db ? +.DIR_NTRes db ? +.DIR_CrtTimeTenth db ? +.DIR_CrtTime dw ? +.DIR_CrtDate dw ? +.DIR_LstAccDate dw ? +.DIR_FstClusHI dw ? +.DIR_WrtTime dw ? +.DIR_WrtDate dw ? +.DIR_FstClusLO dw ? +.DIR_FileSize dd ? + + +} +;Тут будут распологатсья данные, которые затруднительно распологать в стековой области.... +;;; +;timer +shot_name_fat rb 11 ;временный буфер для fat12, в нем храняться имена файлов приведенные к правилам FAT /* вдальнейшем перенести в стэк + +if DEBUG + rb 1 ;нужен для отладки и вывода имени файла после преобразования +dest_name_fat db 24 dup('_');12 +db 0x0 +end if + +value_timeout rw 1 ;value to timeout +old_timer rd 1 ;старое значение вектора таймера +start_timer rd 1 ;значение таймера +timer_ rd 1 ;новое значение вектора таймера т.е. SL +start_stack rw 1 ;save stack +save_bp_from_timer rw 1 ;save bp from timer + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.lst b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.lst new file mode 100644 index 000000000..3984e145d --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/loader.lst @@ -0,0 +1,2147 @@ +flat assembler version 1.68 (65535 kilobytes memory) +0000: E9 E1 0A jmp start +0003: 53 65 63 6F 6E 64 61 72 79 20 4C 6F 61 version db 'Secondary Loader v 0.009', 0 +0010: 64 65 72 20 76 20 30 2E 30 30 39 00 +001C: 53 65 6C 65 63 74 20 73 65 63 74 69 6F select_section db 'Select section:' +0029: 6E 3A +002B: 53 65 63 74 69 6F 6E 20 64 65 73 63 72 section_description db 'Section description:' +0038: 69 70 74 69 6F 6E 3A +003F: 53 6F 66 74 20 28 63 29 20 32 30 30 38 soft_mes db 'Soft (c) 2008' +004C: 3E 46 61 74 61 6C 20 2D 20 43 50 55 20 badprocessor db '>Fatal - CPU 586+ required.', 0 +0059: 35 38 36 2B 20 72 65 71 75 69 72 65 64 +0066: 2E 00 +0068: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f1 db '>Error: cannot load ini file, buffer is full', 0 +0075: 74 20 6C 6F 61 64 20 69 6E 69 20 66 69 +0082: 6C 65 2C 20 62 75 66 66 65 72 20 69 73 +008F: 20 66 75 6C 6C 00 +0095: 3E 45 72 72 6F 72 3A 20 69 6E 69 20 66 error_ini_f2 db '>Error: ini file not found', 0 +00A2: 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64 +00AF: 00 +00B0: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f3 db '>Error: cannot read ini file', 0 +00BD: 74 20 72 65 61 64 20 69 6E 69 20 66 69 +00CA: 6C 65 00 +00CD: 3E 45 72 72 6F 72 3A 20 75 6E 72 65 63 error_ini_nf db '>Error: unrecognized error when loading ini file', 0 +00DA: 6F 67 6E 69 7A 65 64 20 65 72 72 6F 72 +00E7: 20 77 68 65 6E 20 6C 6F 61 64 69 6E 67 +00F4: 20 69 6E 69 20 66 69 6C 65 00 +00FE: 3E 4E 6F 74 20 66 6F 75 6E 64 20 73 65 not_found_sec_loader db '>Not found section [loader]', 0 +010B: 63 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 +0118: 5D 00 +011A: 3E 4E 6F 74 20 66 6F 75 6E 64 20 76 61 not_found_def_sect db '>Not found value default in section [loader]', 0 +0127: 6C 75 65 20 64 65 66 61 75 6C 74 20 69 +0134: 6E 20 73 65 63 74 69 6F 6E 20 5B 6C 6F +0141: 61 64 65 72 5D 00 +0147: 3E 45 72 72 6F 72 20 69 6E 20 73 65 63 default_eq_loader db '>Error in section [loader] parametr default=loader', 0 +0154: 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 5D +0161: 20 70 61 72 61 6D 65 74 72 20 64 65 66 +016E: 61 75 6C 74 3D 6C 6F 61 64 65 72 00 +017A: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_default db '>Found equal parametr default will be use first value', 0 +0187: 70 61 72 61 6D 65 74 72 20 64 65 66 61 +0194: 75 6C 74 20 77 69 6C 6C 20 62 65 20 75 +01A1: 73 65 20 66 69 72 73 74 20 76 61 6C 75 +01AE: 65 00 +01B0: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_timeout db '>Found equal parametr timeout will be use first value', 0 +01BD: 70 61 72 61 6D 65 74 72 20 74 69 6D 65 +01CA: 6F 75 74 20 77 69 6C 6C 20 62 65 20 75 +01D7: 73 65 20 66 69 72 73 74 20 76 61 6C 75 +01E4: 65 00 +01E6: 3E 53 65 63 74 69 6F 6E 20 74 69 6D 65 set_default_timeout_val db '>Section timeout has incorrect value, will be use default value', 0 +01F3: 6F 75 74 20 68 61 73 20 69 6E 63 6F 72 +0200: 72 65 63 74 20 76 61 6C 75 65 2C 20 77 +020D: 69 6C 6C 20 62 65 20 75 73 65 20 64 65 +021A: 66 61 75 6C 74 20 76 61 6C 75 65 00 +0226: 3E 49 20 77 69 6C 6C 20 75 73 65 20 70 error_ini_common db '>I will use predefined settings and try to boot. Let's hope for the best...' +0233: 72 65 64 65 66 69 6E 65 64 20 73 65 74 +0240: 74 69 6E 67 73 20 61 6E 64 20 74 72 79 +024D: 20 74 6F 20 62 6F 6F 74 2E 20 4C 65 74 +025A: 27 73 20 68 6F 70 65 20 66 6F 72 20 74 +0267: 68 65 20 62 65 73 74 2E 2E 2E +0271: 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B db 13, 10, 'Press any key to continue...', 0 +027E: 65 79 20 74 6F 20 63 6F 6E 74 69 6E 75 +028B: 65 2E 2E 2E 00 +0290: 3E 49 6E 69 20 66 69 6C 65 20 6C 6F 61 load_ini db '>Ini file loaded successfully', 0 +029D: 64 65 64 20 73 75 63 63 65 73 73 66 75 +02AA: 6C 6C 79 00 +02AE: 3E 45 6E 64 20 70 61 72 73 69 6E 67 20 parse_ini_end db '>End parsing ini file', 0 +02BB: 69 6E 69 20 66 69 6C 65 00 +02C4: 3E 50 6F 69 6E 74 20 74 6F 20 64 65 66 point_to_default_sec_not_found db '>Point to default section is not found in ini file', 0 +02D1: 61 75 6C 74 20 73 65 63 74 69 6F 6E 20 +02DE: 69 73 20 6E 6F 74 20 66 6F 75 6E 64 20 +02EB: 69 6E 20 69 6E 69 20 66 69 6C 65 00 +02F7: 3E 49 6E 63 6F 72 65 63 74 20 73 65 63 incorect_section_define db '>Incorect section define not found ']'', 0 +0304: 74 69 6F 6E 20 64 65 66 69 6E 65 20 6E +0311: 6F 74 20 66 6F 75 6E 64 20 27 5D 27 00 +031E: 22 53 65 63 74 69 6F 6E 20 75 6E 6E 61 default_section_name db '"Section unname"' +032B: 6D 65 22 +032E: 50 72 65 73 73 20 61 6E 79 20 6B 65 79 start_msg db 'Press any key to change default section, press [Enter] to continue booting' +033B: 20 74 6F 20 63 68 61 6E 67 65 20 64 65 +0348: 66 61 75 6C 74 20 73 65 63 74 69 6F 6E +0355: 2C 20 70 72 65 73 73 20 5B 45 6E 74 65 +0362: 72 5D 20 74 6F 20 63 6F 6E 74 69 6E 75 +036F: 65 20 62 6F 6F 74 69 6E 67 +0378: 6F 72 20 77 61 69 74 20 34 20 73 65 63 time_msg db 'or wait 4 seconds before default continuation' +0385: 6F 6E 64 73 20 62 65 66 6F 72 65 20 64 +0392: 65 66 61 75 6C 74 20 63 6F 6E 74 69 6E +039F: 75 61 74 69 6F 6E +03A5: 73 65 63 6F 6E 64 73 20 62 65 66 6F 72 time_str db 'seconds before default continuation' +03B2: 65 20 64 65 66 61 75 6C 74 20 63 6F 6E +03BF: 74 69 6E 75 61 74 69 6F 6E +03C8: 53 65 74 20 73 74 61 63 6B 20 26 20 73 stack_msg db 'Set stack & segments is have completed', 0 +03D5: 65 67 6D 65 6E 74 73 20 69 73 20 68 61 +03E2: 76 65 20 63 6F 6D 70 6C 65 74 65 64 00 +03EF: 48 61 76 65 20 6C 6F 61 64 65 64 20 73 show_string db 'Have loaded size:' +03FC: 69 7A 65 3A +0400: 20 20 20 20 20 20 00 show_decode db ' ', 0 +0407: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db1 db ' -Message debug1', 0 +0414: 67 65 20 64 65 62 75 67 31 00 +041E: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db2 db ' -Message debug2', 0 +042B: 67 65 20 64 65 62 75 67 32 00 +0435: 5B 6C 6F 61 64 65 72 5D 20 69 73 20 66 lm_l_found db '[loader] is found', 0 +0442: 6F 75 6E 64 00 +0447: 74 69 6D 65 6F 75 74 20 69 73 20 66 6F lm_lf_timeout db 'timeout is found', 0 +0454: 75 6E 64 00 +0458: 6E 61 6D 65 20 64 65 66 61 75 6C 74 20 lm_lf_default db 'name default is found and end parsing section', 0 +0465: 69 73 20 66 6F 75 6E 64 20 61 6E 64 20 +0472: 65 6E 64 20 70 61 72 73 69 6E 67 20 73 +047F: 65 63 74 69 6F 6E 00 +0486: 66 6F 75 6E 64 20 73 65 63 74 69 6F 6E lm_lf_section db 'found section [', 0 +0493: 20 5B 00 +0496: 66 6F 75 6E 64 20 64 65 66 61 75 6C 74 lm_lf_default_f db 'found default parametr', 0 +04A3: 20 70 61 72 61 6D 65 74 72 00 +04AD: 73 65 63 74 69 6F 6E 20 5B 6C 6F 61 64 lm_l_end db 'section [loader] is end', 0 +04BA: 65 72 5D 20 69 73 20 65 6E 64 00 +04C5: 53 48 4F 57 20 41 4C 4C 20 53 65 63 74 show_all_sect db 'SHOW ALL Sections', 0 +04D2: 69 6F 6E 73 00 +04D7: 4E 6F 74 20 73 68 6F 77 20 73 65 63 74 no_show_only_w db 'Not show sections - only work on default sect', 0 +04E4: 69 6F 6E 73 20 2D 20 6F 6E 6C 79 20 77 +04F1: 6F 72 6B 20 6F 6E 20 64 65 66 61 75 6C +04FE: 74 20 73 65 63 74 00 +0505: 5B 20 6E 6F 74 20 66 6F 75 6E 64 00 _not_found db '[ not found', 0 +0511: 5B 5D 20 66 6F 75 6E 64 00 _found_1 db '[] found', 0 +051A: 5B 20 66 6F 75 6E 64 00 _found_2 db '[ found', 0 +0522: 48 65 6C 6C 6F 20 24 29 00 say_hello db 'Hello $)', 0 +052B: 53 74 61 72 74 20 75 73 65 5F 52 61 6D ramdiskFS_st db 'Start use_RamdiskFS macros', 0 +0538: 64 69 73 6B 46 53 20 6D 61 63 72 6F 73 +0545: 00 +0546: 20 20 20 20 20 20 20 2D 4B 62 20 61 76 free_memory_msg db ' -Kb availability system free memory', 0 +0553: 61 69 6C 61 62 69 6C 69 74 79 20 73 79 +0560: 73 74 65 6D 20 66 72 65 65 20 6D 65 6D +056D: 6F 72 79 00 +0571: 20 20 20 20 20 20 20 2D 4B 62 20 65 71 RamdiskSize_msg db ' -Kb equal RamdiskSize', 0 +057E: 75 61 6C 20 52 61 6D 64 69 73 6B 53 69 +058B: 7A 65 00 +058E: 20 20 20 20 20 20 20 20 2D 62 79 74 73 RamdiskSector_msg db ' -byts RamdiskSector', 0 +059B: 20 52 61 6D 64 69 73 6B 53 65 63 74 6F +05A8: 72 00 +05AA: 20 20 20 20 20 20 20 2D 52 61 6D 64 69 RamdiskCluster_msg db ' -RamdiskCluster', 0 +05B7: 73 6B 43 6C 75 73 74 65 72 00 +05C1: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 RamdiskFile_msg db ' -size RamdiskFile', 0 +05CE: 52 61 6D 64 69 73 6B 46 69 6C 65 00 +05DA: 20 20 20 20 20 20 20 2D 66 69 72 73 74 fat_create_msg db ' -first create fat table, point to next block', 0 +05E7: 20 63 72 65 61 74 65 20 66 61 74 20 74 +05F4: 61 62 6C 65 2C 20 70 6F 69 6E 74 20 74 +0601: 6F 20 6E 65 78 74 20 62 6C 6F 63 6B 00 +060E: 20 20 20 20 20 20 20 2D 69 6E 20 62 79 BPB_msg db ' -in byte, why we get data from move BPB struct', 0 +061B: 74 65 2C 20 77 68 79 20 77 65 20 67 65 +0628: 74 20 64 61 74 61 20 66 72 6F 6D 20 6D +0635: 6F 76 65 20 42 50 42 20 73 74 72 75 63 +0642: 74 00 +0644: 20 20 20 20 20 20 20 2D 66 69 72 73 74 firstDataSect_msg db ' -first data sector, offset to data in sectors', 0 +0651: 20 64 61 74 61 20 73 65 63 74 6F 72 2C +065E: 20 6F 66 66 73 65 74 20 74 6F 20 64 61 +066B: 74 61 20 69 6E 20 73 65 63 74 6F 72 73 +0678: 00 +0679: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 size_root_dir_msg db ' -size root dir in sectrors', 0 +0686: 72 6F 6F 74 20 64 69 72 20 69 6E 20 73 +0693: 65 63 74 72 6F 72 73 00 +069B: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 DataClasters_msg db ' -size data in Clasters', 0 +06A8: 64 61 74 61 20 69 6E 20 43 6C 61 73 74 +06B5: 65 72 73 00 +06B9: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 check_name_fat_msg db ' -if -1 name is present, else 0 then not present name', 0 +06C6: 20 6E 61 6D 65 20 69 73 20 70 72 65 73 +06D3: 65 6E 74 2C 20 65 6C 73 65 20 30 20 74 +06E0: 68 65 6E 20 6E 6F 74 20 70 72 65 73 65 +06ED: 6E 74 20 6E 61 6D 65 00 +06F5: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 convertion_file_name_msg db ' -if -1, then destination name is bad', 0 +0702: 2C 20 74 68 65 6E 20 64 65 73 74 69 6E +070F: 61 74 69 6F 6E 20 6E 61 6D 65 20 69 73 +071C: 20 62 61 64 00 +0721: 2D 4D 61 6B 65 20 46 41 54 31 32 20 52 make_fat12_RFS_msg db '-Make FAT12 Ram FS', 0 +072E: 61 6D 20 46 53 00 +0734: 2D 45 6E 64 20 6D 61 6B 65 20 52 61 6D get_type_FS_msg db '-End make RamDisk', 0 +0741: 44 69 73 6B 00 +0746: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_move db ' -return code after 0x87 int 0x15, move block', 0 +0753: 6F 64 65 20 61 66 74 65 72 20 30 78 38 +0760: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D +076D: 6F 76 65 20 62 6C 6F 63 6B 00 +0777: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc', 0 +0784: 6F 64 65 20 61 66 74 65 72 20 30 78 38 +0791: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D +079E: 6F 76 65 20 66 61 74 20 73 74 72 75 63 +07AB: 00 +07AC: 5B 6C 6F 61 64 65 72 5D parse_loader db '[loader]' +07B4: 74 69 6D 65 6F 75 74 parse_l_timeout db 'timeout' +07BB: 64 65 66 61 75 6C 74 parse_l_default db 'default' +07C2: 61 6D 65 parse_name db 'ame' +07C5: 64 65 73 63 72 69 70 74 parse_descript db 'descript' +07CD: 4C 6F 61 64 65 72 4D 6F 64 75 6C 65 parse_LoaderModule db 'LoaderModule' +07D9: 52 61 6D 64 69 73 6B 53 69 7A 65 parse_RamdiskSize db 'RamdiskSize' +07E4: 52 61 6D 64 69 73 6B 46 53 parse_RamdiskFS db 'RamdiskFS' +07ED: 52 61 6D 64 69 73 6B 53 65 63 74 6F 72 parse_RamdiskSector db 'RamdiskSector' +07FA: 52 61 6D 64 69 73 6B 43 6C 75 73 74 65 parse_RamdiskCluster db 'RamdiskCluster' +0807: 72 +0808: 46 41 54 parse_RFS_FAT db 'FAT' +080B: 4B 52 46 53 parse_RFS_KRFS db 'KRFS' +080F: 4C 6F 61 64 65 72 49 6D 61 67 65 parse_Loader_Image db 'LoaderImage' +081A: 52 61 6D 64 69 73 6B 46 69 6C 65 parse_RamdiskFile db 'RamdiskFile' +0825: 66 39 C8 cmp eax, ecx +0828: 72 0D jb @f +082A: 66 31 D2 xor edx, edx +082D: 66 F7 F1 div ecx +0830: 66 52 push edx +0832: E8 F0 FF call decode +0835: 66 58 pop eax +0837: 0C 30 or al, 0x30 +0839: 88 05 mov [ ds : di ], al +083B: 47 inc di +083C: C3 ret +083D: B4 0E mov ah, 0Eh +083F: B7 00 mov bh, 0 +0841: CD 10 int 10h +0843: C3 ret +0844: 60 pusha +0845: AC lodsb +0846: E8 F4 FF call putchar +0849: AC lodsb +084A: 3C 00 cmp al, 0 +084C: 75 F8 jnz @b +084E: B0 0D mov al, 13 +0850: E8 EA FF call putchar +0853: B0 0A mov al, 10 +0855: E8 E5 FF call putchar +0858: 61 popa +0859: C3 ret +085A: B4 00 mov ah, 0 +085C: CD 16 int 16h +085E: 38 D8 cmp al, bl +0860: 72 F8 jb getkey +0862: 38 F8 cmp al, bh +0864: 77 F4 ja getkey +0866: 50 push ax +0867: E8 D3 FF call putchar +086A: 58 pop ax +086B: 83 E0 0F and ax, 0Fh +086E: 75 02 jnz @f +0870: B0 0A mov al, 10 +0872: C3 ret +0873: 26 8A 05 mov al, byte [ es : di ] +0876: 47 inc di +0877: 49 dec cx +0878: E3 20 jcxz .exit +087A: 3C 0A cmp al, 0xa +087C: 74 0A jz ._entry +087E: 3C 3B cmp al, ';' +0880: 75 F1 jnz .start +0882: B0 0A mov al, 0xa +0884: F2 repnz +0885: AE scasb +0886: E3 12 jcxz .exit +0888: 26 8A 05 mov al, byte [ es : di ] +088B: 3C 20 cmp al, ' ' +088D: 75 07 jnz .not_space +088F: F3 repe +0890: AE scasb +0891: 4F dec di +0892: 41 inc cx +0893: 26 8A 05 mov al, byte [ es : di ] +0896: 3C 3B cmp al, ';' +0898: 74 E8 jz .first_com +089A: C3 ret +089B: 56 push si +089C: 68 00 20 push ini_data_ +089F: 07 pop es +08A0: B0 5D mov al, ']' +08A2: F2 repnz +08A3: AE scasb +08A4: 85 C9 test cx, cx +08A6: 0F 84 0F 02 jz error.incorect_section_def +08AA: B0 6E mov al, 'n' +08AC: F2 repnz +08AD: AE scasb +08AE: E3 69 jcxz .not_name_sec_fb +08B0: BE C2 07 mov si, parse_name +08B3: 51 push cx +08B4: 57 push di +08B5: B9 03 00 mov cx, parse_name_e - parse_name +08B8: F3 repe +08B9: A6 cmpsb +08BA: 5F pop di +08BB: 59 pop cx +08BC: 74 02 jz .yaaa_find_value +08BE: EB EC jmp .find_val_name_fb +08C0: 83 E9 03 sub cx, parse_name_e - parse_name +08C3: 83 C7 03 add di, parse_name_e - parse_name +08C6: B8 20 3D mov ax, 0x3d20 +08C9: F3 repe +08CA: AE scasb +08CB: 85 C9 test cx, cx +08CD: 74 4A jz .not_name_sec_fb +08CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +08D3: 75 D5 jnz .find_val_name_fb1 +08D5: F3 repe +08D6: AE scasb +08D7: 41 inc cx +08D8: 4F dec di +08D9: 06 push es +08DA: 1F pop ds +08DB: 68 00 B8 push 0xb800 +08DE: 07 pop es +08DF: 31 C0 xor ax, ax +08E1: B8 20 07 mov ax, 0x0720 +08E4: B9 27 00 mov cx, 39 +08E7: 89 FE mov si, di +08E9: 89 D7 mov di, dx +08EB: 83 EF 02 sub di, 2 +08EE: F3 rep +08EF: AB stosw +08F0: 89 D7 mov di, dx +08F2: B4 0F mov ah, color_sym_white +08F4: B9 24 00 mov cx, 36 +08F7: AC lodsb +08F8: 83 EF 02 sub di, 2 +08FB: 3C 22 cmp al, '"' +08FD: 74 04 jz @f +08FF: 3C 27 cmp al, ''' +0901: 75 12 jnz .end_sh_name_sec +0903: AC lodsb +0904: AB stosw +0905: AC lodsb +0906: 3C 22 cmp al, '"' +0908: 74 0B jz .end_sh_name_sec +090A: 3C 27 cmp al, ''' +090C: 74 07 jz .end_sh_name_sec +090E: E2 F4 loop @b +0910: B0 7D mov al, '}' +0912: B4 0E mov ah, color_sym_yellow +0914: AB stosw +0915: 0E push cs +0916: 1F pop ds +0917: 5E pop si +0918: C3 ret +0919: 0E push cs +091A: 1F pop ds +091B: BF 1E 03 mov di, default_section_name +091E: EB BB jmp .def_sect_name +0920: 8B 7E F4 mov di, point_default +0923: 68 00 20 push ini_data_ +0926: 07 pop es +0927: 89 F9 mov cx, di +0929: 89 CB mov bx, cx +092B: FD std +092C: B0 0A mov al, 0xa +092E: F2 repnz +092F: AE scasb +0930: E3 25 jcxz .go_ +0932: 89 7E C6 mov find_sec_di, di +0935: 89 F9 mov cx, di +0937: 29 CB sub bx, cx +0939: 89 D9 mov cx, bx +093B: FC cld +093C: E8 34 FF call get_firs_sym +093F: E3 0D jcxz ._not_section +0941: 3B 7E F6 cmp di, point_loader +0944: 74 08 jz ._not_section +0946: 3C 5B cmp al, '[' +0948: 75 04 jnz ._not_section +094A: 89 7E F4 mov point_default, di +094D: C3 ret +094E: 8B 7E C6 mov di, find_sec_di +0951: 89 F9 mov cx, di +0953: 89 CB mov bx, cx +0955: EB D4 jmp .find_start_section +0957: FC cld +0958: 89 D9 mov cx, bx +095A: 26 8A 05 mov al, byte [ es : di ] +095D: 68 6A 09 push word .f_go +0960: 3C 20 cmp al, ' ' +0962: 74 03 jz @f +0964: E9 2F FF jmp get_firs_sym.not_space +0967: E9 21 FF jmp get_firs_sym.first_sp +096A: E3 E1 jcxz .exit_scan_sect +096C: 3B 7E F6 cmp di, point_loader +096F: 74 DC jz .exit_scan_sect +0971: 3C 5B cmp al, '[' +0973: 75 D8 jnz .exit_scan_sect +0975: 89 7E F4 mov point_default, di +0978: C3 ret +0979: 8B 7E F4 mov di, point_default +097C: 68 00 20 push ini_data_ +097F: 07 pop es +0980: 8B 4E FE mov cx, save_cx +0983: 29 F9 sub cx, di +0985: EB 17 jmp .let_s_go +0987: 68 00 20 push ini_data_ +098A: 07 pop es +098B: 8B 4E FE mov cx, save_cx +098E: 26 8A 05 mov al, byte [ es : di ] +0991: 68 A1 09 push word .let_s_go_ret +0994: 3C 20 cmp al, ' ' +0996: 74 03 jz @f +0998: E9 FB FE jmp get_firs_sym.not_space +099B: E9 ED FE jmp get_firs_sym.first_sp +099E: E8 D2 FE call get_firs_sym +09A1: E3 0C jcxz .exit_scan_sect +09A3: 3C 5B cmp al, '[' +09A5: 75 F7 jnz .let_s_go +09A7: 3B 7E F6 cmp di, point_loader +09AA: 74 F2 jz .let_s_go +09AC: 89 7E F4 mov point_default, di +09AF: C3 ret +09B0: 8D 76 F2 lea si, point_to_hframe +09B3: BF 22 03 mov di, 962 - 160 +09B6: 8B 56 F4 mov dx, point_default +09B9: B9 12 00 mov cx, 18 +09BC: 8B 1C mov bx, [ si ] +09BE: 81 C7 A0 00 add di, 160 +09C2: 39 D3 cmp bx, dx +09C4: 74 05 jz .clean_cursor_ +09C6: 83 EE 02 sub si, 2 +09C9: E2 F1 loop .clean_show_cur +09CB: 68 00 B8 push 0xb800 +09CE: 07 pop es +09CF: 50 push ax +09D0: 89 76 CA mov point_to_point_def, si +09D3: 31 C0 xor ax, ax +09D5: B8 20 07 mov ax, 0x0720 +09D8: AB stosw +09D9: 83 C7 44 add di, 68 +09DC: AB stosw +09DD: 58 pop ax +09DE: C3 ret +09DF: B4 00 mov ah, 0 +09E1: CD 1A int 1Ah +09E3: 91 xchg ax, cx +09E4: 66 C1 E0 10 shl eax, 10h +09E8: 92 xchg ax, dx +09E9: C3 ret +09EA: 1E push ds +09EB: 0E push cs +09EC: 1F pop ds +09ED: 9C pushf +09EE: FF 1E D4 1A call far dword [ old_timer ] +09F2: 66 60 pushad +09F4: E8 E8 FF call gettime +09F7: 66 2B 06 D8 1A sub eax, dword [ start_timer ] +09FC: 8B 1E D2 1A mov bx, word [ value_timeout ] +0A00: 6B DB 12 imul bx, 18 +0A03: 29 C3 sub bx, ax +0A05: 76 1F jbe .timergo +0A07: 06 push es +0A08: 68 00 B8 push 0xb800 +0A0B: 07 pop es +0A0C: 89 D8 mov ax, bx +0A0E: BB 12 00 mov bx, 18 +0A11: 31 D2 xor dx, dx +0A13: F7 F3 div bx +0A15: BB 0A 00 mov bx, 10 +0A18: BF 96 0E mov di, 3734 +0A1B: E8 24 00 call .decode +0A1E: 31 C0 xor ax, ax +0A20: AB stosw +0A21: 07 pop es +0A22: 66 61 popad +0A24: 1F pop ds +0A25: CF iret +0A26: 6A 00 push 0 +0A28: 07 pop es +0A29: 66 A1 D4 1A mov eax, dword [ old_timer ] +0A2D: 26 66 A3 20 00 mov [ es : 8 * 4 ], eax +0A32: 66 A3 DC 1A mov dword [ timer_ ], eax +0A36: 8B 26 E0 1A mov sp, word [ start_stack ] +0A3A: 8B 2E E2 1A mov bp, word [ save_bp_from_timer ] +0A3E: FB sti +0A3F: E9 D8 06 jmp parse_start.parse_run_only +0A42: 39 D8 cmp ax, bx +0A44: 72 09 jb @f +0A46: 31 D2 xor dx, dx +0A48: F7 F3 div bx +0A4A: 52 push dx +0A4B: E8 F4 FF call .decode +0A4E: 58 pop ax +0A4F: 0C 30 or al, 0x30 +0A51: 50 push ax +0A52: B4 09 mov ah, 9 +0A54: AB stosw +0A55: 58 pop ax +0A56: C3 ret +0A57: 8B 5E C8 mov bx, point_to_eframe +0A5A: 8D 76 F2 lea si, point_to_hframe +0A5D: BA C6 03 mov dx, 966 +0A60: 39 DE cmp si, bx +0A62: 72 12 jb ._show_space_fb +0A64: 8B 3C mov di, [ si ] +0A66: 83 EE 02 sub si, 2 +0A69: 8B 0C mov cx, [ si ] +0A6B: 29 F9 sub cx, di +0A6D: E8 2B FE call show_name_section +0A70: 81 C2 A0 00 add dx, 160 +0A74: EB EA jmp .home_show_fb +0A76: 83 EA 04 sub dx, 4 +0A79: 68 00 B8 push 0xb800 +0A7C: 07 pop es +0A7D: 81 FA 64 0E cmp dx, 0xE64 +0A81: 77 12 ja .exit_show_fb +0A83: 89 D7 mov di, dx +0A85: 31 C0 xor ax, ax +0A87: B8 20 07 mov ax, 0x0720 +0A8A: B9 27 00 mov cx, 39 +0A8D: F3 rep +0A8E: AB stosw +0A8F: 81 C2 A0 00 add dx, 160 +0A93: EB E8 jmp @b +0A95: C3 ret +0A96: 89 C7 mov di, ax +0A98: 89 D9 mov cx, bx +0A9A: FF 66 FC jmp ret_on_ch +0A9D: C9 leave +0A9E: BE 1A 01 mov si, not_found_def_sect +0AA1: E9 F4 00 jmp err_show_ini +0AA4: C9 leave +0AA5: BE FE 00 mov si, not_found_sec_loader +0AA8: E9 ED 00 jmp err_show_ini +0AAB: C9 leave +0AAC: BE 47 01 mov si, default_eq_loader +0AAF: E9 E6 00 jmp err_show_ini +0AB2: C9 leave +0AB3: BE C4 02 mov si, point_to_default_sec_not_found +0AB6: E9 DF 00 jmp err_show_ini +0AB9: C9 leave +0ABA: BE F7 02 mov si, incorect_section_define +0ABD: E9 D8 00 jmp err_show_ini +0AC0: 68 00 B8 push word 0xb800 +0AC3: 07 pop es +0AC4: C3 ret +0AC5: 00 00 00 20 file_data dw 0x0, ini_data_ +0AC9: 10 00 size_data dw 16 +0ACB: 6B 6F 72 64 2F 73 74 61 72 74 6F 73 2E name_ini_f db 'kord/startos.ini', 0 +0AD8: 69 6E 69 00 +0ADC: 00 00 00 00 loader_callback dd ? +0AE0: 00 00 load_drive dw ? +0AE2: 00 00 load_ft dw ? +0AE4: 2E 89 36 DC 0A mov word [ cs : loader_callback ], si +0AE9: 2E 8C 1E DE 0A mov word [ cs : loader_callback + 2 ], ds +0AEE: 2E A3 E0 0A mov word [ cs : load_drive ], ax +0AF2: 2E 89 1E E2 0A mov word [ cs : load_ft ], bx +0AF7: 8C C8 mov ax, cs +0AF9: 8E D0 mov ss, ax +0AFB: 31 E4 xor sp, sp +0AFD: 8E D8 mov ds, ax +0AFF: 8E C0 mov es, ax +0B01: FC cld +0B02: FB sti +0B03: B8 03 00 mov ax, 3 +0B06: CD 10 int 0x10 +0B08: BE 03 00 mov si, version +0B0B: E8 36 FD call printplain +0B0E: B0 23 mov al, '#' +0B10: B9 50 00 mov cx, 80 +0B13: E8 27 FD call putchar +0B16: E2 FB loop @b +0B18: BE C8 03 mov si, stack_msg +0B1B: E8 26 FD call printplain +0B1E: 31 DB xor bx, bx +0B20: 8E DB mov ds, bx +0B22: FF 77 1A push word [ bx + 6 * 4 + 2 ] +0B25: FF 77 18 push word [ bx + 6 * 4 ] +0B28: C7 47 18 4A 0B mov word [ bx + 6 * 4 ], ud16 +0B2D: 8C 4F 1A mov word [ bx + 6 * 4 + 2 ], cs +0B30: 66 31 C0 xor eax, eax +0B33: 0F A2 cpuid +0B35: 66 85 C0 test eax, eax +0B38: 74 10 jz cpubad +0B3A: 66 31 C0 xor eax, eax +0B3D: 40 inc ax +0B3E: 0F A2 cpuid +0B40: F6 C2 10 test dl, 10h +0B43: 74 05 jz cpubad +0B45: F6 C2 20 test dl, 20h +0B48: 75 12 jnz cpugood +0B4A: 8F 06 18 00 pop word [ 6 * 4 ] +0B4E: 8F 06 1A 00 pop word [ 6 * 4 + 2 ] +0B52: 0E push cs +0B53: 1F pop ds +0B54: BE 4C 00 mov si, badprocessor +0B57: E8 EA FC call printplain +0B5A: EB FE jmp $ +0B5C: 66 8F 06 18 00 pop dword [ 6 * 4 ] +0B61: 0E push cs +0B62: 1F pop ds +0B63: 66 0F B7 E4 movzx esp, sp +0B67: B9 03 00 mov cx, loop_read_startos_file +0B6C: 31 C0 xor ax, ax +0B6E: BF C5 0A mov di, file_data +0B71: 40 inc ax +0B72: 51 push cx +0B73: FF 1E DC 0A call far dword [ loader_callback ] +0B77: 59 pop cx +0B78: 0E push cs +0B79: 0E push cs +0B7A: 1F pop ds +0B7B: 07 pop es +0B7C: 85 DB test bx, bx +0B7E: 74 28 jz check_conf_file +0B80: 49 dec cx +0B81: 75 E9 jnz load_startos_file +0B83: BE 68 00 mov si, error_ini_f1 +0B86: 4B dec bx +0B87: 74 0F jz err_show_ini +0B89: BE 95 00 mov si, error_ini_f2 +0B8C: 4B dec bx +0B8D: 74 09 jz err_show_ini +0B8F: BE B0 00 mov si, error_ini_f3 +0B92: 4B dec bx +0B93: 74 03 jz err_show_ini +0B95: BE CD 00 mov si, error_ini_nf +0B98: E8 A9 FC call printplain +0B9B: BE 26 02 mov si, error_ini_common +0B9E: E8 A3 FC call printplain +0BA1: 31 C0 xor ax, ax +0BA3: CD 16 int 16h +0BA5: EB FE jmp $ +0BA8: 50 push ax +0BA9: B9 0A 00 mov cx, 0x0a +0BAC: BF 00 04 mov di, show_decode +0BAF: E8 73 FC call decode +0BB2: BE EF 03 mov si, show_string +0BB5: E8 8C FC call printplain +0BB8: BE 90 02 mov si, load_ini +0BBB: E8 86 FC call printplain +0BBE: 59 pop cx +0BBF: C8 00 01 00 enter 256, 0 +0BC3: 89 2E E2 1A mov word [ save_bp_from_timer ], bp +0BC7: 89 4E FE mov save_cx, cx +0BCA: C4 3E C5 0A les di, dword [ file_data ] +0BCE: 31 C0 xor ax, ax +0BD0: 89 46 F8 mov status_flag, ax +0BD3: C7 46 C4 00 30 mov info_real_mode_size, ini_data_ + 0x1000 +0BD8: FC cld +0BD9: C7 46 FC EE 0B mov ret_on_ch, .start +0BDE: 26 8A 05 mov al, byte [ es : di ] +0BE1: 68 F1 0B push word .first_ret +0BE4: 3C 20 cmp al, ' ' +0BE6: 74 03 jz .first_sp_1 +0BE8: E9 AB FC jmp get_firs_sym.not_space +0BEB: E9 9D FC jmp get_firs_sym.first_sp +0BEE: E8 82 FC call get_firs_sym +0BF1: 85 C9 test cx, cx +0BF3: 0F 84 AD FE jz error.not_loader +0BF7: 3C 5B cmp al, '[' +0BF9: 74 02 jz .parse_loader +0BFB: EB F1 jmp .start +0BFD: 89 CB mov bx, cx +0BFF: 89 F8 mov ax, di +0C01: BE AC 07 mov si, parse_loader +0C04: B9 08 00 mov cx, parse_loader_e - parse_loader +0C07: F3 repe +0C08: A6 cmpsb +0C09: 0F 85 89 FE jnz error.rest_value +0C0D: 89 46 F6 mov point_loader, ax +0C10: 83 EB 08 sub bx, parse_loader_e - parse_loader +0C13: 01 CB add bx, cx +0C15: 89 D9 mov cx, bx +0C17: 60 pusha +0C18: BE 35 04 mov si, lm_l_found +0C1B: E8 26 FC call printplain +0C1E: 61 popa +0C1F: 89 FA mov dx, di +0C21: E8 4F FC call get_firs_sym +0C24: E3 04 jcxz .loader_f_end +0C26: 3C 5B cmp al, '[' +0C28: 75 F7 jnz @b +0C2A: 29 CB sub bx, cx +0C2C: 89 D7 mov di, dx +0C2E: 89 D9 mov cx, bx +0C30: C7 46 FC 35 0C mov ret_on_ch, .get_next_str +0C35: E8 3B FC call get_firs_sym +0C38: 85 C9 test cx, cx +0C3A: 0F 84 57 01 jz .end_loader +0C3E: 3C 74 cmp al, 't' +0C40: 0F 84 DE 00 jz .loader_timeout +0C44: 3C 64 cmp al, 'd' +0C46: 75 ED jnz .get_next_str +0C48: 89 CB mov bx, cx +0C4A: 89 F8 mov ax, di +0C4C: BE BB 07 mov si, parse_l_default +0C4F: B9 07 00 mov cx, parse_l_default_e - parse_l_default +0C52: F3 repe +0C53: A6 cmpsb +0C54: 0F 85 3E FE jnz error.rest_value +0C58: 83 EB 07 sub bx, parse_l_default_e - parse_l_default +0C5B: 01 CB add bx, cx +0C5D: 89 D9 mov cx, bx +0C5F: F7 46 F8 01 00 test status_flag, flag_found_default +0C64: 74 08 jz .correct_is_not_set +0C66: BE 7A 01 mov si, found_equal_default +0C69: E8 D8 FB call printplain +0C6C: EB C7 jmp .get_next_str +0C6E: B8 20 3D mov ax, 0x3d20 +0C71: F3 repe +0C72: AE scasb +0C73: 85 C9 test cx, cx +0C75: 0F 84 1C 01 jz .end_loader +0C79: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +0C7D: 75 B6 jnz .get_next_str +0C7F: F3 repe +0C80: AE scasb +0C81: 41 inc cx +0C82: 4F dec di +0C83: 89 CB mov bx, cx +0C85: 89 FA mov dx, di +0C87: 26 8A 05 mov al, byte [ es : di ] +0C8A: 47 inc di +0C8B: 49 dec cx +0C8C: 85 C9 test cx, cx +0C8E: 0F 84 0B FE jz error.error_get_size_d_sect +0C92: 3C 20 cmp al, ' ' +0C94: 74 F1 jz @b +0C96: 3C 0D cmp al, 0xd +0C98: 74 04 jz .found_size_d_sect +0C9A: 3C 0A cmp al, 0xa +0C9C: 75 E9 jnz @b +0C9E: 41 inc cx +0C9F: 89 D8 mov ax, bx +0CA1: 29 CB sub bx, cx +0CA3: 89 5E FA mov save_cx_d, bx +0CA6: 89 D7 mov di, dx +0CA8: 89 D9 mov cx, bx +0CAA: 89 C3 mov bx, ax +0CAC: 89 D0 mov ax, dx +0CAE: BE AC 07 mov si, parse_loader +0CB1: 46 inc si +0CB2: F3 repe +0CB3: A6 cmpsb +0CB4: 75 03 jnz .check_section +0CB6: E9 F2 FD jmp error.default_eq_loader +0CB9: 89 D9 mov cx, bx +0CBB: 89 C7 mov di, ax +0CBD: 89 FE mov si, di +0CBF: 57 push di +0CC0: 51 push cx +0CC1: 8B 4E FE mov cx, save_cx +0CC4: C4 3E C5 0A les di, dword [ file_data ] +0CC8: 26 8A 05 mov al, byte [ es : di ] +0CCB: 68 DB 0C push word .first_ret_d +0CCE: 3C 20 cmp al, ' ' +0CD0: 74 03 jz .first_sp_1_d +0CD2: E9 C1 FB jmp get_firs_sym.not_space +0CD5: E9 B3 FB jmp get_firs_sym.first_sp +0CD8: E8 98 FB call get_firs_sym +0CDB: E3 38 jcxz .correct_exit +0CDD: 3C 5B cmp al, '[' +0CDF: 74 02 jz .found_sect_d +0CE1: EB F5 jmp .start_d +0CE3: 89 CB mov bx, cx +0CE5: 89 F8 mov ax, di +0CE7: 56 push si +0CE8: 8B 4E FA mov cx, save_cx_d +0CEB: 06 push es +0CEC: 1F pop ds +0CED: 47 inc di +0CEE: F3 repe +0CEF: A6 cmpsb +0CF0: 0E push cs +0CF1: 1F pop ds +0CF2: 5E pop si +0CF3: 75 1A jnz .not_compare_d_s +0CF5: 26 80 3D 5D cmp byte [ es : di ], ']' +0CF9: 75 14 jnz .not_compare_d_s +0CFB: 83 4E F8 01 or status_flag, flag_found_default +0CFF: 59 pop cx +0D00: 5F pop di +0D01: 89 46 F4 mov point_default, ax +0D04: 60 pusha +0D05: BE 96 04 mov si, lm_lf_default_f +0D08: E8 39 FB call printplain +0D0B: 61 popa +0D0C: E9 26 FF jmp .get_next_str +0D0F: 89 D9 mov cx, bx +0D11: 89 C7 mov di, ax +0D13: EB C3 jmp .start_d +0D15: 59 pop cx +0D16: 5F pop di +0D17: 60 pusha +0D18: BE 58 04 mov si, lm_lf_default +0D1B: E8 26 FB call printplain +0D1E: 61 popa +0D1F: E9 13 FF jmp .get_next_str +0D22: 89 CB mov bx, cx +0D24: 89 F8 mov ax, di +0D26: BE B4 07 mov si, parse_l_timeout +0D29: B9 07 00 mov cx, parse_l_timeout_e - parse_l_timeout +0D2C: F3 repe +0D2D: A6 cmpsb +0D2E: 0F 85 64 FD jnz error.rest_value +0D32: 83 EB 07 sub bx, parse_l_timeout_e - parse_l_timeout +0D35: 01 CB add bx, cx +0D37: 89 D9 mov cx, bx +0D39: F7 46 F8 02 00 test status_flag, flag_found_timeout +0D3E: 74 09 jz .correct_is_not_set_t +0D40: BE B0 01 mov si, found_equal_timeout +0D43: E8 FE FA call printplain +0D46: E9 EC FE jmp .get_next_str +0D49: B8 20 3D mov ax, 0x3d20 +0D4C: F3 repe +0D4D: AE scasb +0D4E: E3 35 jcxz .timeout_sec_end_d +0D50: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +0D54: 0F 85 DD FE jnz .get_next_str +0D58: F3 repe +0D59: AE scasb +0D5A: 41 inc cx +0D5B: 4F dec di +0D5C: 51 push cx +0D5D: 31 DB xor bx, bx +0D5F: B9 02 00 mov cx, 2 +0D62: 26 8A 05 mov al, byte [ es : di ] +0D65: 3C 30 cmp al, '0' +0D67: 72 0B jb .end_get_val_t +0D69: 3C 39 cmp al, '9' +0D6B: 77 07 ja .end_get_val_t +0D6D: 6B DB 0A imul bx, 10 +0D70: 34 30 xor al, 0x30 +0D72: 00 C3 add bl, al +0D74: 47 inc di +0D75: E2 EB loop @b +0D77: 89 1E D2 1A mov word [ value_timeout ], bx +0D7B: 60 pusha +0D7C: BE 47 04 mov si, lm_lf_timeout +0D7F: E8 C2 FA call printplain +0D82: 61 popa +0D83: EB 0C jmp @f +0D85: C7 06 D2 1A 05 00 mov word [ value_timeout ], default_timeout_value +0D8B: BE E6 01 mov si, set_default_timeout_val +0D8E: E8 B3 FA call printplain +0D91: 59 pop cx +0D92: E9 A0 FE jmp .get_next_str +0D95: 60 pusha +0D96: BE AD 04 mov si, lm_l_end +0D99: E8 A8 FA call printplain +0D9C: 61 popa +0D9D: 31 C0 xor ax, ax +0D9F: CD 16 int 16h +0DA1: 60 pusha +0DA2: A1 D2 1A mov ax, word [ value_timeout ] +0DA5: B9 0A 00 mov cx, 0x0a +0DA8: BF 07 04 mov di, show_db1 +0DAB: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' +0DB2: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' +0DB7: E8 6B FA call decode +0DBA: BE 07 04 mov si, show_db1 +0DBD: E8 84 FA call printplain +0DC0: 61 popa +0DC1: 85 C0 test ax, ax +0DC3: 0F 84 53 03 jz .parse_run_only +0DC7: 60 pusha +0DC8: BE C5 04 mov si, show_all_sect +0DCB: E8 76 FA call printplain +0DCE: 61 popa +0DCF: B0 F6 mov al, 0xf6 +0DD1: E6 60 out 0x60, al +0DD3: 31 C9 xor cx, cx +0DD5: E4 64 in al, 64h +0DD7: 24 02 and al, 00000010b +0DD9: E0 FA loopnz .wait_loop +0DDB: B0 F3 mov al, 0xf3 +0DDD: E6 60 out 0x60, al +0DDF: 31 C9 xor cx, cx +0DE1: E4 64 in al, 64h +0DE3: A8 02 test al, 2 +0DE5: E0 FA loopnz @b +0DE7: B0 00 mov al, 0 +0DE9: E6 60 out 0x60, al +0DEB: 31 C9 xor cx, cx +0DED: E4 64 in al, 64h +0DEF: A8 02 test al, 2 +0DF1: E0 FA loopnz @b +0DF3: E8 E9 FB call gettime +0DF6: 66 A3 D8 1A mov dword [ start_timer ], eax +0DFA: C7 06 DC 1A EA 09 mov word [ timer_ ], newtimer +0E00: 8C 0E DE 1A mov word [ timer_ + 2 ], cs +0E04: FA cli +0E05: 6A 00 push 0 +0E07: 07 pop es +0E08: 26 66 FF 36 20 00 push dword [ es : 8 * 4 ] +0E0E: 66 8F 06 D4 1A pop dword [ old_timer ] +0E13: 66 FF 36 DC 1A push dword [ timer_ ] +0E18: 26 66 8F 06 20 00 pop dword [ es : 8 * 4 ] +0E1E: FB sti +0E1F: C7 46 BE 12 00 mov save_descript_size, 18 +0E24: 31 C0 xor ax, ax +0E26: B8 20 07 mov ax, 0x0720 +0E29: 68 00 B8 push 0xb800 +0E2C: 07 pop es +0E2D: 31 FF xor di, di +0E2F: B9 D0 07 mov cx, 25 * 80 +0E32: F3 rep +0E33: AB stosw +0E34: BF A4 00 mov di, 164 +0E37: BE 03 00 mov si, version +0E3A: B9 19 00 mov cx, version_end - version +0E3D: B4 0E mov ah, color_sym_yellow +0E3F: AC lodsb +0E40: AB stosw +0E41: E2 FC loop @b +0E43: BF 1E 01 mov di, 286 +0E46: B4 0C mov ah, color_sym_pink +0E48: B0 4B mov al, 'K' +0E4A: AB stosw +0E4B: B0 20 mov al, ' ' +0E4D: AB stosw +0E4E: B4 07 mov ah, color_sym_lightgray +0E50: BE 3F 00 mov si, soft_mes +0E53: B9 0D 00 mov cx, soft_mes_end - soft_mes +0E56: AC lodsb +0E57: AB stosw +0E58: E2 FC loop @b +0E5A: BF E0 01 mov di, 480 +0E5D: B4 0E mov ah, color_sym_yellow +0E5F: B0 C4 mov al, 'Д' +0E61: B9 3D 00 mov cx, 61 +0E64: F3 rep +0E65: AB stosw +0E66: BF 24 03 mov di, 804 +0E69: BE 1C 00 mov si, select_section +0E6C: B9 0F 00 mov cx, select_section_end - select_section +0E6F: B4 07 mov ah, color_sym_lightgray +0E71: AC lodsb +0E72: AB stosw +0E73: E2 FC loop @b +0E75: BF 70 03 mov di, 880 +0E78: BE 2B 00 mov si, section_description +0E7B: B9 14 00 mov cx, section_description_end - section_description +0E7E: AC lodsb +0E7F: AB stosw +0E80: E2 FC loop @b +0E82: 8B 4E FE mov cx, save_cx +0E85: C4 3E C5 0A les di, dword [ file_data ] +0E89: 89 FE mov si, di +0E8B: 89 CB mov bx, cx +0E8D: BA 12 00 mov dx, size_show_section +0E90: 26 8A 05 mov al, byte [ es : di ] +0E93: 68 B9 0E push word .first_ret_bl_sc +0E96: 3C 20 cmp al, ' ' +0E98: 74 03 jz .first_bl_sc +0E9A: E9 F9 F9 jmp get_firs_sym.not_space +0E9D: E9 EB F9 jmp get_firs_sym.first_sp +0EA0: E8 D0 F9 call get_firs_sym +0EA3: 85 C9 test cx, cx +0EA5: 0F 84 09 FC jz error.correct_exit_bl +0EA9: 3C 5B cmp al, '[' +0EAB: 75 F3 jnz .start_hbl +0EAD: 89 FE mov si, di +0EAF: 89 CB mov bx, cx +0EB1: BA 12 00 mov dx, size_show_section +0EB4: EB 09 jmp .analisist_al +0EB6: E8 BA F9 call get_firs_sym +0EB9: 85 C9 test cx, cx +0EBB: 0F 84 F3 FB jz error.correct_exit_bl +0EBF: 3C 5B cmp al, '[' +0EC1: 75 F3 jnz .start_bl +0EC3: 3B 7E F6 cmp di, point_loader +0EC6: 74 EE jz .start_bl +0EC8: 3B 7E F4 cmp di, point_default +0ECB: 74 05 jz .save_point_def +0ECD: 4A dec dx +0ECE: 75 E6 jnz .start_bl +0ED0: EB CE jmp .start_hbl +0ED2: 89 F7 mov di, si +0ED4: 89 D9 mov cx, bx +0ED6: 8D 76 F2 lea si, point_to_hframe +0ED9: BA 13 00 mov dx, size_show_section + 1 +0EDC: 26 8A 05 mov al, byte [ es : di ] +0EDF: 68 EF 0E push word .first_ret_mfb +0EE2: 3C 20 cmp al, ' ' +0EE4: 74 03 jz .first_bl_mbf +0EE6: E9 AD F9 jmp get_firs_sym.not_space +0EE9: E9 9F F9 jmp get_firs_sym.first_sp +0EEC: E8 84 F9 call get_firs_sym +0EEF: E3 13 jcxz .val_buff_comp +0EF1: 3C 5B cmp al, '[' +0EF3: 75 F7 jnz .start_mfb +0EF5: 3B 7E F6 cmp di, point_loader +0EF8: 74 F2 jz .start_mfb +0EFA: 89 3C mov [ si ], di +0EFC: 83 EE 02 sub si, 2 +0EFF: 4A dec dx +0F00: 75 EA jnz .start_mfb +0F02: EB 08 jmp @f +0F04: FF 76 FE push save_cx +0F07: 8F 04 pop word [ si ] +0F09: 83 EE 02 sub si, 2 +0F0C: 83 C6 04 add si, 4 +0F0F: 89 76 C8 mov point_to_eframe, si +0F12: E8 42 FB call show_bl_sc_sect +0F15: 8D 76 F2 lea si, point_to_hframe +0F18: BF 22 03 mov di, 962 - 160 +0F1B: 8B 46 F4 mov ax, point_default +0F1E: B9 12 00 mov cx, size_show_section +0F21: 8B 1C mov bx, [ si ] +0F23: 81 C7 A0 00 add di, 160 +0F27: 39 C3 cmp bx, ax +0F29: 74 05 jz .show_cursor_activ +0F2B: 83 EE 02 sub si, 2 +0F2E: E2 F1 loop .home_show_cur +0F30: 89 76 CA mov point_to_point_def, si +0F33: B8 10 04 mov ax, ( color_sym_red * 0x100 + 0x10 ) +0F36: AB stosw +0F37: 83 C7 44 add di, 68 +0F3A: 40 inc ax +0F3B: AB stosw +0F3C: 8B 7E F4 mov di, point_default +0F3F: 68 00 20 push ini_data_ +0F42: 8B 76 CA mov si, point_to_point_def +0F45: 07 pop es +0F46: 83 EE 02 sub si, 2 +0F49: 8B 0C mov cx, [ si ] +0F4B: 29 F9 sub cx, di +0F4D: E8 23 F9 call get_firs_sym +0F50: 85 C9 test cx, cx +0F52: 0F 84 91 00 jz .exit?0Pz +0F56: 3C 64 cmp al, 'd' +0F58: 75 F3 jnz .start_p_sh_d?0Py +0F5A: 89 CB mov bx, cx +0F5C: 89 F8 mov ax, di +0F5E: BE C5 07 mov si, parse_descript +0F61: B9 08 00 mov cx, parse_descript_e - parse_descript +0F64: F3 repe +0F65: A6 cmpsb +0F66: 75 78 jnz .rest_value_loop_sh_d?0Q0 +0F68: 83 EB 08 sub bx, parse_descript_e - parse_descript +0F6B: 01 CB add bx, cx +0F6D: 89 D9 mov cx, bx +0F6F: B8 20 3D mov ax, 0x3d20 +0F72: F3 repe +0F73: AE scasb +0F74: E3 6A jcxz .rest_value_loop_sh_d?0Q0 +0F76: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +0F7A: 75 64 jnz .rest_value_loop_sh_d?0Q0 +0F7C: F3 repe +0F7D: AE scasb +0F7E: 41 inc cx +0F7F: 4F dec di +0F80: 57 push di +0F81: 5E pop si +0F82: 06 push es +0F83: 1F pop ds +0F84: 68 00 B8 push 0xb800 +0F87: 07 pop es +0F88: BF 10 04 mov di, 1040 +0F8B: BB 12 00 mov bx, 18 +0F8E: 89 7E C6 mov find_sec_di, di +0F91: 89 5E FA mov save_cx_d, bx +0F94: 57 push di +0F95: 31 C0 xor ax, ax +0F97: B9 26 00 mov cx, 38 +0F9A: 57 push di +0F9B: F3 rep +0F9C: AB stosw +0F9D: 5F pop di +0F9E: 39 5E BE cmp save_descript_size, bx +0FA1: 74 07 jz @f +0FA3: 81 C7 A0 00 add di, 160 +0FA7: 4B dec bx +0FA8: 75 ED jnz @b +0FAA: 5F pop di +0FAB: AC lodsb +0FAC: B4 0A mov ah, color_sym_lettuce +0FAE: 3C 22 cmp al, '"' +0FB0: 74 04 jz .loop_message?0Q2 +0FB2: 3C 27 cmp al, ''' +0FB4: 75 20 jnz .end_sh_desc_sec?0Q1 +0FB6: B9 26 00 mov cx, 38 +0FB9: AC lodsb +0FBA: 3C 22 cmp al, '"' +0FBC: 74 18 jz .end_sh_desc_sec?0Q1 +0FBE: 3C 27 cmp al, ''' +0FC0: 74 14 jz .end_sh_desc_sec?0Q1 +0FC2: AB stosw +0FC3: E2 F4 loop @b +0FC5: 81 46 C6 A0 00 add find_sec_di, 160 +0FCA: 8B 7E C6 mov di, find_sec_di +0FCD: FF 4E FA dec save_cx_d +0FD0: 83 7E FA 00 cmp save_cx_d, 0 +0FD4: 75 E0 jnz .loop_message?0Q2 +0FD6: FF 76 FA push save_cx_d +0FD9: 8F 46 BE pop save_descript_size +0FDC: 0E push cs +0FDD: 1F pop ds +0FDE: EB 07 jmp .exit?0Pz +0FE0: 89 C7 mov di, ax +0FE2: 89 D9 mov cx, bx +0FE4: E9 66 FF jmp .start_p_sh_d?0Py +0FE7: 66 A1 D4 1A mov eax, dword [ old_timer ] +0FEB: 66 3B 06 DC 1A cmp eax, dword [ timer_ ] +0FF0: 74 5E jz .interrupt_16 +0FF2: 31 C0 xor ax, ax +0FF4: BF 20 0D mov di, 3360 +0FF7: B9 40 01 mov cx, 80 * 4 +0FFA: F3 rep +0FFB: AB stosw +0FFC: BF 22 0D mov di, 3362 +0FFF: B4 0C mov ah, color_sym_pink +1001: B0 DA mov al, 0xDA +1003: AB stosw +1004: B0 C4 mov al, 0xc4 +1006: B9 4C 00 mov cx, 76 +1009: F3 rep +100A: AB stosw +100B: B0 BF mov al, 0xBF +100D: AB stosw +100E: 83 C7 04 add di, 4 +1011: B0 B3 mov al, 0xb3 +1013: AB stosw +1014: 81 C7 98 00 add di, 152 +1018: AB stosw +1019: 83 C7 04 add di, 4 +101C: AB stosw +101D: 81 C7 98 00 add di, 152 +1021: AB stosw +1022: 83 C7 04 add di, 4 +1025: B0 C0 mov al, 0xc0 +1027: AB stosw +1028: B0 C4 mov al, 0xc4 +102A: B9 4C 00 mov cx, 76 +102D: F3 rep +102E: AB stosw +102F: B0 D9 mov al, 0xd9 +1031: AB stosw +1032: BE 2E 03 mov si, start_msg +1035: B9 4A 00 mov cx, start_msg_e - start_msg +1038: BF C6 0D mov di, 3526 +103B: AC lodsb +103C: AB stosw +103D: E2 FC loop @b +103F: 83 C7 2C add di, 44 +1042: BE 78 03 mov si, time_msg +1045: B9 2D 00 mov cx, time_msg_e - time_msg +1048: AC lodsb +1049: AB stosw +104A: E2 FC loop @b +104C: 89 26 E0 1A mov word [ start_stack ], sp +1050: 31 C0 xor ax, ax +1052: CD 16 int 0x16 +1054: 66 8B 1E D4 1A mov ebx, dword [ old_timer ] +1059: 66 3B 1E DC 1A cmp ebx, dword [ timer_ ] +105E: 74 2A jz @f +1060: FA cli +1061: 6A 00 push 0 +1063: 07 pop es +1064: 26 66 89 1E 20 00 mov [ es : 8 * 4 ], ebx +106A: 66 89 1E DC 1A mov dword [ timer_ ], ebx +106F: FB sti +1070: 50 push ax +1071: 68 00 B8 push 0xb800 +1074: 07 pop es +1075: 31 C0 xor ax, ax +1077: B8 20 07 mov ax, 0x0720 +107A: BF 20 0D mov di, 3360 +107D: B9 40 01 mov cx, 80 * 4 +1080: F3 rep +1081: AB stosw +1082: 68 00 20 push ini_data_ +1085: 07 pop es +1086: E8 CE F9 call show_bl_sc_sect +1089: 58 pop ax +108A: E8 23 F9 call clean_active_cursor +108D: 80 FC 48 cmp ah, 0x48 +1090: 74 21 jz .up +1092: 80 FC 50 cmp ah, 0x50 +1095: 74 3A jz .down +1097: 80 FC 49 cmp ah, 0x49 +109A: 74 53 jz .pgup +109C: 80 FC 51 cmp ah, 0x51 +109F: 74 5B jz .pgdown +10A1: 80 FC 47 cmp ah, 0x47 +10A4: 74 63 jz .home +10A6: 80 FC 4F cmp ah, 0x4f +10A9: 74 66 jz .end +10AB: 3C 0D cmp al, 0xD +10AD: 0F 85 64 FE jnz .show_active_cursor +10B1: EB 6F jmp .end_show_all +10B3: 8B 76 CA mov si, point_to_point_def +10B6: 83 C6 02 add si, 2 +10B9: 8D 46 F2 lea ax, point_to_hframe +10BC: 39 C6 cmp si, ax +10BE: 77 0B ja @f +10C0: 89 76 CA mov point_to_point_def, si +10C3: 8B 04 mov ax, [ si ] +10C5: 89 46 F4 mov point_default, ax +10C8: E9 4A FE jmp .show_active_cursor +10CB: E8 52 F8 call find_before_sect +10CE: E9 B1 FD jmp .show_all_scr +10D1: 8B 76 CA mov si, point_to_point_def +10D4: 8B 46 C8 mov ax, point_to_eframe +10D7: 83 EE 02 sub si, 2 +10DA: 39 C6 cmp si, ax +10DC: 72 0B jb @f +10DE: 89 76 CA mov point_to_point_def, si +10E1: 8B 04 mov ax, [ si ] +10E3: 89 46 F4 mov point_default, ax +10E6: E9 2C FE jmp .show_active_cursor +10E9: E8 8D F8 call find_next_sect +10EC: E9 93 FD jmp .show_all_scr +10EF: B9 12 00 mov cx, size_show_section +10F2: 51 push cx +10F3: E8 2A F8 call find_before_sect +10F6: 59 pop cx +10F7: E2 F9 loop @b +10F9: E9 86 FD jmp .show_all_scr +10FC: B9 12 00 mov cx, size_show_section +10FF: 51 push cx +1100: E8 76 F8 call find_next_sect +1103: 59 pop cx +1104: E2 F9 loop @b +1106: E9 79 FD jmp .show_all_scr +1109: 31 FF xor di, di +110B: E8 79 F8 call find_next_sect.h +110E: E9 71 FD jmp .show_all_scr +1111: 8B 7E FE mov di, save_cx +1114: E8 0C F8 call find_before_sect.e +1117: E9 68 FD jmp .show_all_scr +111A: 60 pusha +111B: BE D7 04 mov si, no_show_only_w +111E: E8 23 F7 call printplain +1121: 61 popa +1122: 8B 7E F4 mov di, point_default +1125: 68 00 20 push ini_data_ +1128: 07 pop es +1129: 8B 76 CA mov si, point_to_point_def +112C: 83 EE 02 sub si, 2 +112F: 8B 0C mov cx, [ si ] +1131: 31 C0 xor ax, ax +1133: 29 F9 sub cx, di +1135: 89 4E FA mov save_cx_d, cx +1138: 89 46 F8 mov status_flag, ax +113B: BE 2B 05 mov si, ramdiskFS_st +113E: E8 03 F7 call printplain +1141: 31 C0 xor ax, ax +1143: 89 46 C0 mov show_errors_sect, ax +1146: B4 88 mov ah, 0x88 +1148: CD 15 int 0x15 +114A: 73 02 jnc ._support_function_use_free_memory +114C: 31 C0 xor ax, ax +114E: 89 46 C2 mov free_ad_memory, ax +1151: 60 pusha +1152: 66 0F B7 C0 movzx eax, ax +1156: B9 0A 00 mov cx, 0x0a +1159: BF 46 05 mov di, free_memory_msg +115C: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' +1163: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' +1168: E8 BA F6 call decode +116B: BE 46 05 mov si, free_memory_msg +116E: E8 D3 F6 call printplain +1171: 61 popa +1172: 8B 7E F4 mov di, point_default +1175: 8B 4E FA mov cx, save_cx_d +1178: E8 F8 F6 call get_firs_sym +117B: 85 C9 test cx, cx +117D: 74 6E jz ._end_parse_RS?0k2 +117F: 3C 52 cmp al, 'R' +1181: 75 F5 jnz .start_p_RS?0ju +1183: 89 CB mov bx, cx +1185: 89 F8 mov ax, di +1187: BE D9 07 mov si, parse_RamdiskSize +118A: B9 0B 00 mov cx, parse_RamdiskSize_e - parse_RamdiskSize +118D: F3 repe +118E: A6 cmpsb +118F: 75 4C jnz .rest_value_loop_RS?0jz +1191: 83 EB 0B sub bx, parse_RamdiskSize_e - parse_RamdiskSize +1194: 01 CB add bx, cx +1196: 89 D9 mov cx, bx +1198: F7 46 F8 02 00 test status_flag, flag_found_RS +119D: 74 00 jz .correct_is_not_set_RS?0jv +119F: B8 20 3D mov ax, 0x3d20 +11A2: F3 repe +11A3: AE scasb +11A4: E3 3D jcxz .end_get_RS_ERROR_1?0k0 +11A6: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +11AA: 75 CC jnz .start_p_RS?0ju +11AC: F3 repe +11AD: AE scasb +11AE: 41 inc cx +11AF: 4F dec di +11B0: 31 DB xor bx, bx +11B2: B9 05 00 mov cx, 5 +11B5: 26 8A 05 mov al, byte [ es : di ] +11B8: 3C 30 cmp al, '0' +11BA: 72 04 jb .CS?0jw +11BC: 3C 39 cmp al, '9' +11BE: 76 06 jbe .correct_val_RS?0jx +11C0: 3C 4B cmp al, 'K' +11C2: 74 0C jz .correct_size_RS?0jy +11C4: EB 23 jmp .end_get_RS_ERROR_2?0k1 +11C6: 6B DB 0A imul bx, 10 +11C9: 34 30 xor al, 0x30 +11CB: 00 C3 add bl, al +11CD: 47 inc di +11CE: E2 E5 loop @b +11D0: 85 DB test bx, bx +11D2: 75 07 jnz @f +11D4: 83 4E C0 04 or show_errors_sect, show_error_3 +11D8: BB 40 00 mov bx, 64 +11DB: EB 10 jmp ._end_parse_RS?0k2 +11DD: 89 C7 mov di, ax +11DF: 89 D9 mov cx, bx +11E1: EB 95 jmp .start_p_RS?0ju +11E3: 83 4E C0 01 or show_errors_sect, show_error_1 +11E7: EB 04 jmp ._end_parse_RS?0k2 +11E9: 83 4E C0 02 or show_errors_sect, show_error_2 +11ED: 60 pusha +11EE: 66 0F B7 C3 movzx eax, bx +11F2: B9 0A 00 mov cx, 0x0a +11F5: BF 71 05 mov di, RamdiskSize_msg +11F8: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' +11FF: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' +1204: E8 1E F6 call decode +1207: BE 71 05 mov si, RamdiskSize_msg +120A: E8 37 F6 call printplain +120D: 61 popa +120E: 39 5E C2 cmp free_ad_memory, bx +1211: 0F 86 80 07 jbe ._not_memory_in_sys?0iL +1215: 66 0F B7 C3 movzx eax, bx +1219: 66 C1 E0 0A shl eax, 10 +121D: 66 89 46 BA mov save_ramdisksize, eax +1221: 8B 7E F4 mov di, point_default +1224: 8B 4E FA mov cx, save_cx_d +1227: E8 49 F6 call get_firs_sym +122A: 85 C9 test cx, cx +122C: 0F 84 5D 07 jz ._end_parse_FRS +1230: 3C 52 cmp al, 'R' +1232: 75 F3 jnz .start_g_tpe_RFS +1234: 89 CB mov bx, cx +1236: 89 F8 mov ax, di +1238: BE E4 07 mov si, parse_RamdiskFS +123B: B9 09 00 mov cx, parse_RamdiskFS_e - parse_RamdiskFS +123E: F3 repe +123F: A6 cmpsb +1240: 0F 85 38 07 jnz .start_g_tpe_RFS_rest_v +1244: 83 EB 09 sub bx, parse_RamdiskFS_e - parse_RamdiskFS +1247: 01 CB add bx, cx +1249: 89 D9 mov cx, bx +124B: F7 46 F8 04 00 test status_flag, flag_found_GTRFMS +1250: 74 00 jz .correct_is_not_set_FRS +1252: B8 20 3D mov ax, 0x3d20 +1255: F3 repe +1256: AE scasb +1257: 85 C9 test cx, cx +1259: 0F 84 26 07 jz .end_get_FRS_ERROR_1 +125D: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +1261: 75 C4 jnz .start_g_tpe_RFS +1263: F3 repe +1264: AE scasb +1265: 41 inc cx +1266: 4F dec di +1267: 89 CB mov bx, cx +1269: 89 F8 mov ax, di +126B: BE 08 08 mov si, parse_RFS_FAT +126E: B9 03 00 mov cx, parse_RFS_FAT_e - parse_RFS_FAT +1271: F3 repe +1272: A6 cmpsb +1273: 0F 85 F7 06 jnz .krfs_cmp +1277: 8B 7E F4 mov di, point_default +127A: 8B 4E FA mov cx, save_cx_d +127D: E8 F3 F5 call get_firs_sym +1280: 85 C9 test cx, cx +1282: 74 54 jz .end_RamdiskSector +1284: 3C 52 cmp al, 'R' +1286: 75 F5 jnz .start_RamdiskSector +1288: 89 CB mov bx, cx +128A: 89 F8 mov ax, di +128C: BE ED 07 mov si, parse_RamdiskSector +128F: B9 0D 00 mov cx, parse_RamdiskSector_e - parse_RamdiskSector +1292: F3 repe +1293: A6 cmpsb +1294: 75 3C jnz .RamdiskSector_rest_val +1296: 83 EB 0D sub bx, parse_RamdiskSector_e - parse_RamdiskSector +1299: 01 CB add bx, cx +129B: 89 D9 mov cx, bx +129D: F7 46 F8 08 00 test status_flag, flag_found_RamdiskSector +12A2: 74 00 jz .correct_is_not_set_RamdiskSector +12A4: B8 20 3D mov ax, 0x3d20 +12A7: F3 repe +12A8: AE scasb +12A9: E3 2D jcxz .end_get_RamS_ERROR_1 +12AB: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +12AF: 75 CC jnz .start_RamdiskSector +12B1: F3 repe +12B2: AE scasb +12B3: 41 inc cx +12B4: 4F dec di +12B5: 31 DB xor bx, bx +12B7: B9 04 00 mov cx, 4 +12BA: 26 0F B6 05 movzx ax, byte [ es : di ] +12BE: 3C 30 cmp al, '0' +12C0: 72 16 jb .end_RamdiskSector +12C2: 3C 39 cmp al, '9' +12C4: 77 12 ja .end_RamdiskSector +12C6: 6B DB 0A imul bx, 10 +12C9: 34 30 xor al, 0x30 +12CB: 01 C3 add bx, ax +12CD: 47 inc di +12CE: E2 EA loop @b +12D0: EB 06 jmp .end_RamdiskSector +12D2: 89 D9 mov cx, bx +12D4: 89 C7 mov di, ax +12D6: EB A5 jmp .start_RamdiskSector +12D8: 89 D8 mov ax, bx +12DA: 60 pusha +12DB: 66 0F B7 C3 movzx eax, bx +12DF: B9 0A 00 mov cx, 0x0a +12E2: BF 8E 05 mov di, RamdiskSector_msg +12E5: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' +12EC: 66 C7 45 04 20 20 20 20 mov dword [ ds : di + 4 ], ' ' +12F4: E8 2E F5 call decode +12F7: BE 8E 05 mov si, RamdiskSector_msg +12FA: E8 47 F5 call printplain +12FD: 61 popa +12FE: 3D 00 10 cmp ax, 4096 +1301: 77 04 ja .RS1?0sn +1303: 85 C0 test ax, ax +1305: 75 06 jnz @f +1307: C7 06 87 1A 00 02 mov word [ fat12_buffer.BPB_BytsPerSec ], 512 +130D: A3 87 1A mov word [ fat12_buffer.BPB_BytsPerSec ], ax +1310: 8B 7E F4 mov di, point_default +1313: 8B 4E FA mov cx, save_cx_d +1316: E8 5A F5 call get_firs_sym +1319: 85 C9 test cx, cx +131B: 74 47 jz .end_RamdiskCluster +131D: 3C 52 cmp al, 'R' +131F: 75 F5 jnz .start_RamdiskCluster +1321: 89 CB mov bx, cx +1323: 89 F8 mov ax, di +1325: BE FA 07 mov si, parse_RamdiskCluster +1328: B9 0E 00 mov cx, parse_RamdiskCluster_e - parse_RamdiskCluster +132B: F3 repe +132C: A6 cmpsb +132D: 75 2F jnz .RamdiskCluster_rest_val +132F: 83 EB 0E sub bx, parse_RamdiskCluster_e - parse_RamdiskCluster +1332: 01 CB add bx, cx +1334: 89 D9 mov cx, bx +1336: F7 46 F8 16 00 test status_flag, flag_found_RamdiskCluster +133B: 74 00 jz .correct_is_not_set_RamdiskCluster +133D: B8 20 3D mov ax, 0x3d20 +1340: F3 repe +1341: AE scasb +1342: E3 20 jcxz .end_get_RamSC_ERROR_1 +1344: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +1348: 75 CC jnz .start_RamdiskCluster +134A: F3 repe +134B: AE scasb +134C: 41 inc cx +134D: 4F dec di +134E: 26 0F B6 05 movzx ax, byte [ es : di ] +1352: 3C 30 cmp al, '0' +1354: 72 0E jb .end_RamdiskCluster +1356: 3C 39 cmp al, '9' +1358: 77 0A ja .end_RamdiskCluster +135A: 34 30 xor al, 0x30 +135C: EB 06 jmp .end_RamdiskCluster +135E: 89 D9 mov cx, bx +1360: 89 C7 mov di, ax +1362: EB B2 jmp .start_RamdiskCluster +1364: 60 pusha +1365: B9 0A 00 mov cx, 0x0a +1368: BF AA 05 mov di, RamdiskCluster_msg +136B: E8 B7 F4 call decode +136E: BE AA 05 mov si, RamdiskCluster_msg +1371: E8 D0 F4 call printplain +1374: 61 popa +1375: 3C 80 cmp al, 128 +1377: 77 6B ja @f +1379: A2 89 1A mov byte [ fat12_buffer.BPB_SecPerClus ], al +137C: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] +1382: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] +1388: 66 0F AF D8 imul ebx, eax +138C: 66 8B 46 BA mov eax, save_ramdisksize +1390: 66 99 cdq +1392: 66 F7 FB idiv ebx +1395: 66 3D F5 0F 00 00 cmp eax, 4085 +139B: 0F 82 8E 00 jb .fat12?0so +139F: 66 3D F5 FF 00 00 cmp eax, 65525 +13A5: 72 18 jb .fat16?0sp +13A7: C7 46 B4 20 00 mov set_ramfs, 32 +13AC: C7 06 8A 1A 20 00 mov word [ fat12_buffer.BPB_RsvdSecCnt ], 32 +13B2: 66 31 C0 xor eax, eax +13B5: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax +13B8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax +13BB: 66 A3 9C 1A mov dword [ fat12_buffer.BPB_TotSec32 ], eax +13BF: EB FE jmp $ +13C1: C7 46 B4 10 00 mov set_ramfs, 16 +13C6: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] +13CC: 66 0F AF C3 imul eax, ebx +13D0: 66 3D 00 00 01 00 cmp eax, 0x10000 +13D6: 73 0C jae @f +13D8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax +13DB: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 +13E4: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count +13EA: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax +13ED: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] +13F3: 66 6B C0 20 imul eax, 32 +13F7: 66 01 D8 add eax, ebx +13FA: 66 48 dec eax +13FC: 66 99 cdq +13FE: 66 F7 FB idiv ebx +1401: 66 0F B7 1E 8A 1A movzx ebx, word [ fat12_buffer.BPB_RsvdSecCnt ] +1407: 66 01 C3 add ebx, eax +140A: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] +1410: 66 29 D8 sub eax, ebx +1413: 66 C1 E7 08 shl edi, 8 +1417: 66 0F B6 0E 8C 1A movzx ecx, byte [ fat12_buffer.BPB_NumFATs ] +141D: 66 01 CF add edi, ecx +1420: 66 01 F8 add eax, edi +1423: 66 48 dec eax +1425: 66 99 cdq +1427: 66 F7 FF idiv edi +142A: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax +142D: C7 46 B4 0C 00 mov set_ramfs, 12 +1432: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] +1438: 66 0F AF C3 imul eax, ebx +143C: 66 3D 00 00 01 00 cmp eax, 0x10000 +1442: 73 0C jae @f +1444: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax +1447: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 +1450: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count +1456: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax +1459: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] +145F: 66 6B C0 0C imul eax, 12 +1463: 66 C1 E8 03 shr eax, 3 +1467: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] +146D: 66 99 cdq +146F: 66 F7 FB idiv ebx +1472: 40 inc ax +1473: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax +1476: A1 92 1A mov ax, word [ fat12_buffer.BPB_FATSz16 ] +1479: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] +147E: 0F AF C3 imul ax, bx +1481: 8B 1E 8D 1A mov bx, word [ fat12_buffer.BPB_RootEntCnt ] +1485: C1 EB 04 shr bx, 4 +1488: 01 D8 add ax, bx +148A: 89 5E B0 mov size_root_dir, bx +148D: 0F B6 1E 8A 1A movzx bx, byte [ fat12_buffer.BPB_RsvdSecCnt ] +1492: 01 D8 add ax, bx +1494: 89 46 AE mov firstDataSect, ax +1497: 8B 1E 8F 1A mov bx, word [ fat12_buffer.BPB_TotSec16 ] +149B: 29 C3 sub bx, ax +149D: 89 D8 mov ax, bx +149F: 0F B6 1E 89 1A movzx bx, byte [ fat12_buffer.BPB_SecPerClus ] +14A4: 99 cwd +14A5: F7 FB idiv bx +14A7: 89 46 AC mov DataClasters, ax +14AA: 60 pusha +14AB: 8B 46 AE mov ax, firstDataSect +14AE: B9 0A 00 mov cx, 0x0a +14B1: BF 44 06 mov di, firstDataSect_msg +14B4: E8 6E F3 call decode +14B7: BE 44 06 mov si, firstDataSect_msg +14BA: E8 87 F3 call printplain +14BD: 8B 46 B0 mov ax, size_root_dir +14C0: B9 0A 00 mov cx, 0x0a +14C3: BF 79 06 mov di, size_root_dir_msg +14C6: E8 5C F3 call decode +14C9: BE 79 06 mov si, size_root_dir_msg +14CC: E8 75 F3 call printplain +14CF: 8B 46 AC mov ax, DataClasters +14D2: B9 0A 00 mov cx, 0x0a +14D5: BF 9B 06 mov di, DataClasters_msg +14D8: E8 4A F3 call decode +14DB: BE 9B 06 mov si, DataClasters_msg +14DE: E8 63 F3 call printplain +14E1: 61 popa +14E2: A0 91 1A mov al, byte [ fat12_buffer.BPB_Media ] +14E5: 1E push ds +14E6: 8B 7E C4 mov di, info_real_mode_size +14E9: 81 C7 00 10 add di, 0x1000 +14ED: 57 push di +14EE: 31 FF xor di, di +14F0: 89 7E AA mov point_to_free_root, di +14F3: 1F pop ds +14F4: 88 05 mov byte [ di ], al +14F6: 83 C8 FF or ax, - 1 +14F9: 47 inc di +14FA: 89 05 mov word [ di ], ax +14FC: 1F pop ds +14FD: C7 46 B2 03 00 mov point_next_fat_str, 3 +1502: 60 pusha +1503: 8B 46 B2 mov ax, point_next_fat_str +1506: B9 0A 00 mov cx, 0x0a +1509: BF DA 05 mov di, fat_create_msg +150C: E8 16 F3 call decode +150F: BE DA 05 mov si, fat_create_msg +1512: E8 2F F3 call printplain +1515: 61 popa +1516: B8 7C 1A mov ax, fat12_buffer +1519: BE 3C 1A mov si, table_15_87 +151C: 01 44 12 add word [ si + 8 * 2 + 2 ], ax +151F: 06 push es +1520: 1E push ds +1521: 07 pop es +1522: B9 1F 00 mov cx, 31 +1525: B4 87 mov ah, 0x87 +1527: CD 15 int 0x15 +1529: 07 pop es +152A: 60 pusha +152B: 8B 44 12 mov ax, word [ si + 8 * 2 + 2 ] +152E: B9 0A 00 mov cx, 0x0a +1531: BF 0E 06 mov di, BPB_msg +1534: E8 EE F2 call decode +1537: BE 0E 06 mov si, BPB_msg +153A: E8 07 F3 call printplain +153D: 61 popa +153E: 8B 7E F4 mov di, point_default +1541: 8B 4E FA mov cx, save_cx_d +1544: C7 46 A6 00 00 mov data_offset, 0 +1549: E8 27 F3 call get_firs_sym +154C: 85 C9 test cx, cx +154E: 0F 84 B3 03 jz ._end?1D2 +1552: 3C 52 cmp al, 'R' +1554: 75 F3 jnz .start_loop?1D1 +1556: 89 CB mov bx, cx +1558: 89 F8 mov ax, di +155A: BE 1A 08 mov si, parse_RamdiskFile +155D: B9 0B 00 mov cx, parse_RamdiskFile_e - parse_RamdiskFile +1560: F3 repe +1561: A6 cmpsb +1562: 0F 85 98 03 jnz .rest_value_loop?1D3 +1566: 83 EB 0B sub bx, parse_RamdiskFile_e - parse_RamdiskFile +1569: 01 CB add bx, cx +156B: 89 D9 mov cx, bx +156D: B8 20 3D mov ax, 0x3d20 +1570: F3 repe +1571: AE scasb +1572: 66 85 C9 test ecx, ecx +1575: 0F 84 85 03 jz .rest_value_loop?1D3 +1579: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +157D: 0F 85 7D 03 jnz .rest_value_loop?1D3 +1581: F3 repe +1582: AE scasb +1583: 41 inc cx +1584: 4F dec di +1585: 89 7E A2 mov save_di_RAMDISK, di +1588: 89 4E A0 mov save_cx_RAMDISK, cx +158B: 26 8A 05 mov al, byte [ es : di ] +158E: 3C 2C cmp al, ',' +1590: 74 04 jz .found_end_str +1592: 47 inc di +1593: 49 dec cx +1594: 75 F5 jnz @b +1596: 89 7E A8 mov point_to_dest_file_name, di +1599: 47 inc di +159A: BE BA 1A mov si, shot_name_fat +159D: 83 4E A4 FF or first_input, - 1 +15A1: B9 0B 00 mov cx, 11 +15A4: 26 8A 05 mov al, byte [ es : di ] +15A7: 3C 0A cmp al, 0xa +15A9: 74 7D jz .st4_s?1GP +15AB: 3C 0D cmp al, 0xd +15AD: 74 79 jz .st4_s?1GP +15AF: 3C 20 cmp al, 0x20 +15B1: 74 75 jz .st4_s?1GP +15B3: 3C 20 cmp al, 0x20 +15B5: 72 7A jb .error?1GK +15B7: 3C 22 cmp al, 0x22 +15B9: 74 76 jz .error?1GK +15BB: 3C 2A cmp al, 0x2a +15BD: 74 72 jz .error?1GK +15BF: 3C 2B cmp al, 0x2b +15C1: 74 6E jz .error?1GK +15C3: 3C 2C cmp al, 0x2c +15C5: 74 6A jz .error?1GK +15C7: 3C 2F cmp al, 0x2F +15C9: 74 66 jz .error?1GK +15CB: 3C 3A cmp al, 0x3a +15CD: 74 62 jz .error?1GK +15CF: 3C 3B cmp al, 0x3b +15D1: 74 5E jz .error?1GK +15D3: 3C 3C cmp al, 0x3c +15D5: 74 5A jz .error?1GK +15D7: 3C 3D cmp al, 0x3d +15D9: 74 56 jz .error?1GK +15DB: 3C 3E cmp al, 0x3E +15DD: 74 52 jz .error?1GK +15DF: 3C 3F cmp al, 0x3F +15E1: 74 4E jz .error?1GK +15E3: 3C 5B cmp al, 0x5b +15E5: 74 4A jz .error?1GK +15E7: 3C 5C cmp al, 0x5c +15E9: 74 46 jz .error?1GK +15EB: 3C 5D cmp al, 0x5d +15ED: 74 42 jz .error?1GK +15EF: 3C 7C cmp al, 0x7c +15F1: 74 3E jz .error?1GK +15F3: 83 7E A4 FF cmp first_input, - 1 +15F7: 75 08 jnz .next_step?1GJ +15F9: 83 66 A4 00 and first_input, 0 +15FD: 3C 2E cmp al, '.' +15FF: 74 30 jz .error?1GK +1601: 3C 2E cmp al, 0x2e +1603: 75 13 jnz .st2?1GM +1605: B0 20 mov al, ' ' +1607: 80 F9 03 cmp cl, 3 +160A: 76 0C jbe .st2?1GM +160C: 88 04 mov byte [ si ], al +160E: 46 inc si +160F: 49 dec cx +1610: 83 F9 03 cmp cx, 3 +1613: 77 F7 ja .st3?1GO +1615: 47 inc di +1616: EB 8C jmp @b +1618: 3C 60 cmp al, 0x60 +161A: 76 02 jbe .st2_l?1GN +161C: 34 20 xor al, 0x20 +161E: 88 04 mov byte [ si ], al +1620: 47 inc di +1621: 46 inc si +1622: E2 80 loop @b +1624: 31 C0 xor ax, ax +1626: EB 0C jmp @f +1628: B0 20 mov al, ' ' +162A: 88 04 mov byte [ si ], al +162C: 46 inc si +162D: E2 FB loop .st4?1GQ +162F: EB F3 jmp .st5?1GR +1631: 83 C8 FF or ax, - 1 +1634: 60 pusha +1635: B9 0A 00 mov cx, 0x0a +1638: BF F5 06 mov di, convertion_file_name_msg +163B: E8 E7 F1 call decode +163E: BE F5 06 mov si, convertion_file_name_msg +1641: E8 00 F2 call printplain +1644: BE BA 1A mov si, shot_name_fat +1647: C6 44 0C 00 mov byte [ si + 12 ], 0 +164B: E8 F6 F1 call printplain +164E: 61 popa +164F: 85 C0 test ax, ax +1651: 75 39 jnz .exit?1GI +1653: BE BA 1A mov si, shot_name_fat +1656: 8B 7E AE mov di, firstDataSect +1659: 2B 7E B0 sub di, size_root_dir +165C: C1 E7 09 shl di, 9 +165F: BA E0 00 mov dx, root_dir_entry_count +1662: 8B 46 C4 mov ax, info_real_mode_size +1665: 05 00 10 add ax, 0x1000 +1668: 8E E8 mov gs, ax +166A: B9 0B 00 mov cx, 11 +166D: 8A 00 mov al, byte [ ds : si + bx ] +166F: 65 8A 21 mov ah, byte [ gs : di + bx ] +1672: 43 inc bx +1673: 38 C4 cmp ah, al +1675: 75 07 jnz .no_equal?1GH +1677: E2 F4 loop @b +1679: 83 C8 FF or ax, - 1 +167C: EB 0E jmp .exit?1GI +167E: B9 0B 00 mov cx, 11 +1681: 31 DB xor bx, bx +1683: 83 C7 20 add di, 32 +1686: 4A dec dx +1687: 75 E4 jnz @b +1689: 83 E0 00 and ax, 0 +168C: 60 pusha +168D: B9 0A 00 mov cx, 0x0a +1690: BF B9 06 mov di, check_name_fat_msg +1693: 66 C7 05 20 20 20 20 mov dword [ di ], ' ' +169A: C7 45 04 20 20 mov word [ di + 4 ], ' ' +169F: E8 83 F1 call decode +16A2: BE B9 06 mov si, check_name_fat_msg +16A5: E8 9C F1 call printplain +16A8: 61 popa +16A9: 8B 7E A2 mov di, save_di_RAMDISK +16AC: 8B 4E A0 mov cx, save_cx_RAMDISK +16AF: 84 C0 test al, al +16B1: 0F 85 94 FE jnz .start_loop?1D1 +16B5: 26 66 FF 75 FA push dword [ es : di - 6 ] +16BA: 8D 75 FA lea si, [ di - 6 ] +16BD: 26 FF 75 FE push word [ es : di - 2 ] +16C1: 57 push di +16C2: 31 C0 xor ax, ax +16C4: 26 89 45 FA mov word [ es : di - 6 ], ax +16C8: 8B 46 C4 mov ax, info_real_mode_size +16CB: 26 89 45 FC mov word [ es : di - 4 ], ax +16CF: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 +16D5: 8B 7E A8 mov di, point_to_dest_file_name +16D8: 26 FF 35 push word [ es : di ] +16DB: 51 push cx +16DC: 31 C0 xor ax, ax +16DE: 26 89 05 mov word [ es : di ], ax +16E1: 57 push di +16E2: 89 F7 mov di, si +16E4: 40 inc ax +16E5: 56 push si +16E6: 06 push es +16E7: 55 push bp +16E8: 06 push es +16E9: 1F pop ds +16EA: 0E push cs +16EB: 07 pop es +16EC: 26 FF 1E DC 0A call far dword [ es : loader_callback ] +16F1: 0E push cs +16F2: 1F pop ds +16F3: 5D pop bp +16F4: 07 pop es +16F5: 5E pop si +16F6: 83 FB 02 cmp bx, 2 +16F9: 0F 87 01 02 ja .error?1D4 +16FD: 89 5E 9E mov status_flag_loader_f, bx +1700: 66 C1 E2 10 shl edx, 16 +1704: 89 C2 mov dx, ax +1706: 66 89 56 B6 mov save_file_size, edx +170A: 66 89 D0 mov eax, edx +170D: 5F pop di +170E: 59 pop cx +170F: 26 8F 05 pop word [ es : di ] +1712: 5F pop di +1713: 26 8F 45 FE pop word [ es : di - 2 ] +1717: 26 66 8F 45 FA pop dword [ es : di - 6 ] +171C: 60 pusha +171D: B9 0A 00 mov cx, 0x0a +1720: BF C1 05 mov di, RamdiskFile_msg +1723: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' +172A: E8 F8 F0 call decode +172D: BE C1 05 mov si, RamdiskFile_msg +1730: E8 11 F1 call printplain +1733: 61 popa +1734: 06 push es +1735: 8B 46 C4 mov ax, info_real_mode_size +1738: 05 00 10 add ax, 0x1000 +173B: 8E C0 mov es, ax +173D: 8B 7E AE mov di, firstDataSect +1740: 2B 7E B0 sub di, size_root_dir +1743: C1 E7 09 shl di, 9 +1746: 03 7E AA add di, point_to_free_root +1749: BE BA 1A mov si, shot_name_fat +174C: B9 0B 00 mov cx, 11 +174F: AC lodsb +1750: AA stosb +1751: E2 FC loop @b +1753: 31 C0 xor ax, ax +1755: B4 08 mov ah, ATTR_VOLUME_ID +1757: 26 89 05 mov word [ es : di ], ax +175A: 83 C7 02 add di, 2 +175D: 26 C6 05 64 mov byte [ es : di ], 100 +1761: 47 inc di +1762: 26 C7 05 2B 03 mov word [ es : di ], 0x032b +1767: 83 C7 02 add di, 2 +176A: 26 C7 05 00 00 mov word [ es : di ], 0x0 +176F: 83 C7 02 add di, 2 +1772: 26 C7 05 2B 03 mov word [ es : di ], 0x032b +1777: 83 C7 02 add di, 2 +177A: 26 C7 05 00 00 mov word [ es : di ], 0x0 +177F: 83 C7 02 add di, 2 +1782: 26 C7 05 00 00 mov word [ es : di ], 0x0 +1787: 83 C7 02 add di, 2 +178A: 26 C7 05 2B 03 mov word [ es : di ], 0x032b +178F: 83 C7 02 add di, 2 +1792: 8B 46 B2 mov ax, point_next_fat_str +1795: 26 89 05 mov word [ es : di ], ax +1798: 83 C7 02 add di, 2 +179B: 57 push di +179C: 89 C3 mov bx, ax +179E: D1 EB shr bx, 1 +17A0: 01 D8 add ax, bx +17A2: 8B 1E 87 1A mov bx, word [ fat12_buffer.BPB_BytsPerSec ] +17A6: 99 cwd +17A7: F7 FB idiv bx +17A9: 89 C6 mov si, ax +17AB: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] +17B1: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] +17B7: 66 0F AF C3 imul eax, ebx +17BB: 66 8B 5E B6 mov ebx, save_file_size +17BF: 66 29 C3 sub ebx, eax +17C2: 66 39 C3 cmp ebx, eax +17C5: 76 29 jbe .eof_file?1US +17C7: FF 46 B2 inc point_next_fat_str +17CA: 8B 4E B2 mov cx, point_next_fat_str +17CD: 89 C2 mov dx, ax +17CF: D1 EA shr dx, 1 +17D1: 01 D1 add cx, dx +17D3: F7 C6 01 00 test si, 0x1 +17D7: 74 0B jz .step2?1UP +17D9: C1 E1 04 shl cx, 4 +17DC: 26 89 0C mov word [ es : si ], cx +17DF: 46 inc si +17E0: 01 C1 add cx, ax +17E2: EB DB jmp @b +17E4: 81 E1 FF 0F and cx, 0x0FFF +17E8: 26 89 0C mov word [ es : si ], cx +17EB: 46 inc si +17EC: 01 C1 add cx, ax +17EE: EB CF jmp @b +17F0: B9 FF 0F mov cx, 0x0fff +17F3: F7 C6 01 00 test si, 0x1 +17F7: 74 08 jz .step3?1UQ +17F9: C1 E1 04 shl cx, 4 +17FC: 26 89 0C mov word [ es : si ], cx +17FF: EB 07 jmp .end?1UR +1801: 81 E1 FF 0F and cx, 0x0FFF +1805: 26 89 0C mov word [ es : si ], cx +1808: FF 46 B2 inc point_next_fat_str +180B: 5F pop di +180C: 66 8B 46 B6 mov eax, save_file_size +1810: 26 66 89 05 mov dword [ es : di ], eax +1814: 66 60 pushad +1816: 8B 7E AE mov di, firstDataSect +1819: 2B 7E B0 sub di, size_root_dir +181C: C1 E7 09 shl di, 9 +181F: 03 7E AA add di, point_to_free_root +1822: BE C6 1A mov si, dest_name_fat +1825: B9 0B 00 mov cx, 11 +1828: 26 8A 05 mov al, byte [ es : di ] +182B: 47 inc di +182C: 88 04 mov byte [ ds : si ], al +182E: 46 inc si +182F: E2 F7 loop @b +1831: 31 C0 xor ax, ax +1833: 88 04 mov byte [ si ], al +1835: BE C6 1A mov si, dest_name_fat +1838: E8 09 F0 call printplain +183B: 66 61 popad +183D: 83 46 AA 20 add point_to_free_root, 32 +1841: 07 pop es +1842: 8B 46 C4 mov ax, info_real_mode_size +1845: BE 3C 1A mov si, table_15_87 +1848: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax +184B: 66 0F B7 46 AE movzx eax, firstDataSect +1850: 66 0F B7 56 A6 movzx edx, data_offset +1855: 66 01 D0 add eax, edx +1858: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] +185E: 66 0F B6 16 89 1A movzx edx, byte [ fat12_buffer.BPB_SecPerClus ] +1864: 0F AF DA imul bx, dx +1867: 66 53 push ebx +1869: 66 0F AF C3 imul eax, ebx +186D: 60 pusha +186E: B9 0A 00 mov cx, 0x0a +1871: BF 07 04 mov di, show_db1 +1874: E8 AE EF call decode +1877: BE 07 04 mov si, show_db1 +187A: E8 C7 EF call printplain +187D: 61 popa +187E: B2 10 mov dl, 0x10 +1880: 66 3D 00 00 01 00 cmp eax, 0x00010000 +1886: 72 0A jb @f +1888: 66 2D 00 00 01 00 sub eax, 0x00010000 +188E: FE C2 inc dl +1890: EB EE jmp @b +1892: 88 54 1B mov byte [ si + 8 * 3 + 3 ], dl +1895: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax +1898: 66 8B 4E B6 mov ecx, save_file_size +189C: 66 81 F9 FF FF 00 00 cmp ecx, 0x0000ffff +18A3: 76 0A jbe .correct_on_byte?1cJ +18A5: 66 B9 00 00 01 00 mov ecx, 0x00010000 +18AB: 66 29 4E B6 sub save_file_size, ecx +18AF: 66 58 pop eax +18B1: 66 51 push ecx +18B3: FF 46 A6 inc data_offset +18B6: 66 39 C8 cmp eax, ecx +18B9: 73 05 jae @f +18BB: 66 29 C1 sub ecx, eax +18BE: EB F3 jmp @b +18C0: 66 59 pop ecx +18C2: 66 F7 C1 01 00 00 00 test ecx, 0x1 +18C9: 74 02 jz .st1?1cI +18CB: 66 41 inc ecx +18CD: 66 D1 E9 shr ecx, 1 +18D0: 06 push es +18D1: 1E push ds +18D2: 07 pop es +18D3: B4 87 mov ah, 0x87 +18D5: CD 15 int 0x15 +18D7: 07 pop es +18D8: 60 pusha +18D9: B9 0A 00 mov cx, 0x0a +18DC: BF 46 07 mov di, return_code_af_move +18DF: E8 43 EF call decode +18E2: BE 46 07 mov si, return_code_af_move +18E5: E8 5C EF call printplain +18E8: 61 popa +18E9: 83 7E 9E 01 cmp status_flag_loader_f, 0x1 +18ED: 75 00 jnz @f +18EF: 8B 7E A2 mov di, save_di_RAMDISK +18F2: 8B 4E A0 mov cx, save_cx_RAMDISK +18F5: 60 pusha +18F6: 31 C0 xor ax, ax +18F8: CD 16 int 0x16 +18FA: 61 popa +18FB: E9 4B FC jmp .start_loop?1D1 +18FE: 89 C7 mov di, ax +1900: 89 D9 mov cx, bx +1902: E9 44 FC jmp .start_loop?1D1 +1905: 8B 46 C4 mov ax, info_real_mode_size +1908: 05 00 10 add ax, 0x1000 +190B: BE 3C 1A mov si, table_15_87 +190E: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax +1911: B8 00 02 mov ax, 512 +1914: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax +1917: 66 0F B7 0E 92 1A movzx ecx, word [ fat12_buffer.BPB_FATSz16 ] +191D: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] +1922: 0F AF CB imul cx, bx +1925: 03 4E B0 add cx, size_root_dir +1928: 66 C1 E1 09 shl ecx, 9 +192C: 66 F7 C1 01 00 00 00 test ecx, 0x1 +1933: 74 02 jz .st1?1ho +1935: 66 41 inc ecx +1937: 66 D1 E9 shr ecx, 1 +193A: 06 push es +193B: 1E push ds +193C: 07 pop es +193D: B4 87 mov ah, 0x87 +193F: CD 15 int 0x15 +1941: 07 pop es +1942: 60 pusha +1943: B9 0A 00 mov cx, 0x0a +1946: BF 77 07 mov di, return_code_af_fat_m +1949: E8 D9 EE call decode +194C: BE 77 07 mov si, return_code_af_fat_m +194F: E8 F2 EE call printplain +1952: 61 popa +1953: 60 pusha +1954: B9 0A 00 mov cx, 0x0a +1957: BF 07 04 mov di, show_db1 +195A: E8 C8 EE call decode +195D: BE 07 04 mov si, show_db1 +1960: E8 E1 EE call printplain +1963: 61 popa +1964: 60 pusha +1965: BE 21 07 mov si, make_fat12_RFS_msg +1968: E8 D9 EE call printplain +196B: 61 popa +196C: EB 1F jmp ._end_parse_FRS +196E: 89 D9 mov cx, bx +1970: 89 C7 mov di, ax +1972: BE 0B 08 mov si, parse_RFS_KRFS +1975: B9 04 00 mov cx, parse_RFS_KRFS_e - parse_RFS_KRFS +1978: F3 repe +1979: A6 cmpsb +197A: EB 11 jmp ._end_parse_FRS +197C: 89 D9 mov cx, bx +197E: 89 C7 mov di, ax +1980: E9 A4 F8 jmp .start_g_tpe_RFS +1983: 83 4E C0 01 or show_errors_sect, show_error_1 +1987: EB 04 jmp ._end_parse_FRS +1989: 83 4E C0 02 or show_errors_sect, show_error_2 +198D: 60 pusha +198E: BE 34 07 mov si, get_type_FS_msg +1991: E8 B0 EE call printplain +1994: 61 popa +1995: 31 C0 xor ax, ax +1997: CD 16 int 0x16 +1999: 8B 7E F4 mov di, point_default +199C: 8B 4E FA mov cx, save_cx_d +199F: E8 D1 EE call get_firs_sym +19A2: 85 C9 test cx, cx +19A4: 0F 84 8E 00 jz ._afterLoaderModule +19A8: 3C 4C cmp al, 'L' +19AA: 75 F3 jnz .start_p_LM +19AC: 89 CB mov bx, cx +19AE: 89 F8 mov ax, di +19B0: BE CD 07 mov si, parse_LoaderModule +19B3: B9 0C 00 mov cx, parse_LoaderModule_e - parse_LoaderModule +19B6: F3 repe +19B7: A6 cmpsb +19B8: 75 75 jnz .rest_value_loop_LM +19BA: 83 EB 0C sub bx, parse_LoaderModule_e - parse_LoaderModule +19BD: 01 CB add bx, cx +19BF: 89 D9 mov cx, bx +19C1: F7 46 F8 01 00 test status_flag, flag_found_LM +19C6: 74 00 jz .correct_is_not_set_LM +19C8: B8 20 3D mov ax, 0x3d20 +19CB: F3 repe +19CC: AE scasb +19CD: E3 60 jcxz .rest_value_loop_LM +19CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] +19D3: 75 5A jnz .rest_value_loop_LM +19D5: F3 repe +19D6: AE scasb +19D7: 41 inc cx +19D8: 4F dec di +19D9: 26 66 FF 75 FA push dword [ es : di - 6 ] +19DE: 8D 75 FA lea si, [ di - 6 ] +19E1: 26 FF 75 FE push word [ es : di - 2 ] +19E5: 31 C0 xor ax, ax +19E7: 26 89 45 FA mov word [ es : di - 6 ], ax +19EB: 8B 46 C4 mov ax, info_real_mode_size +19EE: 26 89 45 FC mov word [ es : di - 4 ], ax +19F2: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 +19F8: 26 8A 05 mov al, byte [ es : di ] +19FB: 3C 20 cmp al, ' ' +19FD: 74 0C jz .found_end_str?1mb +19FF: 3C 0A cmp al, 0xa +1A01: 74 08 jz .found_end_str?1mb +1A03: 3C 0D cmp al, 0xd +1A05: 74 04 jz .found_end_str?1mb +1A07: 47 inc di +1A08: 49 dec cx +1A09: 75 ED jnz @b +1A0B: 26 FF 35 push word [ es : di ] +1A0E: 31 C0 xor ax, ax +1A10: 26 89 05 mov word [ es : di ], ax +1A13: 89 F7 mov di, si +1A15: 40 inc ax +1A16: 56 push si +1A17: 06 push es +1A18: 06 push es +1A19: 1F pop ds +1A1A: 0E push cs +1A1B: 07 pop es +1A1C: 26 FF 1E DC 0A call far dword [ es : loader_callback ] +1A21: 0E push cs +1A22: 1F pop ds +1A23: 07 pop es +1A24: 5E pop si +1A25: 85 DB test bx, bx +1A27: 75 03 jnz .error_LM +1A29: 26 FF 2C jmp far dword [ es : si ] +1A2C: E8 91 F0 call error.LoaderModule +1A2F: 89 C7 mov di, ax +1A31: 89 D9 mov cx, bx +1A33: E9 69 FF jmp .start_p_LM +1A36: EB FE jmp $ +1A38: E9 6A F1 jmp ini_loaded +1A3C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A44: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A4C: FF FF db 0xff, 0xff +1A4E: 00 10 db 0x0, 0x10 +1A50: 00 93 00 00 db 0x00, 0x93, 0x0, 0x0 +1A54: FF FF 00 00 10 93 00 00 db 0xff, 0xff, 0x0, 0x00, 0x10, 0x93, 0x0, 0x0 +1A5C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A64: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A6C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A74: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 +1A7C: 90 90 90 .BS_jmpBoot db 0x90, 0x90, 0x90 +1A7F: 4B 20 53 79 53 20 36 34 .BS_OEMName db 'K SyS 64' +1A87: 00 02 .BPB_BytsPerSec dw 512 +1A89: 01 .BPB_SecPerClus db 0x1 +1A8A: 01 00 .BPB_RsvdSecCnt dw 0x1 +1A8C: 01 .BPB_NumFATs db 0x1 +1A8D: 00 02 .BPB_RootEntCnt dw 512 +1A8F: 00 00 .BPB_TotSec16 dw 0x0 +1A91: F0 .BPB_Media db 0xF0 +1A92: 00 00 .BPB_FATSz16 dw 0x0 +1A94: 00 00 .BPB_SecPerTrk dw 0x0 +1A96: 00 00 .BPB_NumHeads dw 0x0 +1A98: 00 00 00 00 .BPB_HiddSec dd 0x0 +1A9C: 00 00 00 00 .BPB_TotSec32 dd 0x0 +1AA0: 52 .BS_DrvNum db 'R' +1AA1: 00 .BS_Reserved1 db 0x0 +1AA2: 29 .BS_BootSig db 0x29 +1AA3: 52 46 4B 53 .BS_VolID db 'RFKS' +1AA7: 52 41 4D 20 44 49 53 4B 20 46 53 .BS_VolLab db 'RAM DISK FS' +1AB2: 46 41 54 31 32 20 20 20 .BS_FilSysType db 'FAT12 ' +1ABA: shot_name_fat rb 11 +1AC5: rb 1 +1AC6: dest_name_fat rb 12 +1AD2: value_timeout rw 1 +1AD4: old_timer rd 1 +1AD8: start_timer rd 1 +1ADC: timer_ rd 1 +1AE0: start_stack rw 1 +1AE2: save_bp_from_timer rw 1 +3 passes, 0.8 seconds, 6842 bytes. diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse.inc new file mode 100644 index 000000000..595c1f3e7 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse.inc @@ -0,0 +1,118 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; Модуль парсинга - это стандартный компонент, встраиваемый во вторичный загрузчик. +; Данный модуль позволяет стандартно произвести разбор ini файла +; (и с использованием полученных данных ОС будет загружаться дальше). +; В начале найдем открывающий "[" - это будет указывать на начало +; секции. Поддерживается 1 секция это [loader], остальные секции могут иметь +; любые имена, но они должны быть заключены в в скобки [] +macro use_parse +{ +;input cx=size of ini file +parse_start: +;es:di as 2000:0000 new segment +;установим указатель на загруженный блок + enter 256,0 ;set 16 byte for current task in stack +;we are is not use bp because bp is pointer on array 16 byte + mov word [save_bp_from_timer],bp ;save point to own data array + mov save_cx,cx ;it's placed size of ini file + les di,dword [file_data] +;обнулим все переменные выделенные из стека +;init flag + xor ax,ax + mov status_flag,ax +;set data size + mov info_real_mode_size,ini_data_ +0x1000 ;изменим значение занятости памяти + +;поиск начала блока. +;///////////check [loader] + cld + + mov ret_on_ch,.start ;set return + mov al,byte [es:di] + push word .first_ret + cmp al,' ' + jz .first_sp_1 + jmp get_firs_sym.not_space +.first_sp_1: + jmp get_firs_sym.first_sp + +.start: + call get_firs_sym ;get first symbol on new line +.first_ret: ;первый возврат +; jcxz .end_file ;.end_loader ;found or not found parametrs in section exit in section + test cx,cx + jz error.not_loader + cmp al,'[' + jz .parse_loader + jmp .start +;////// проверка на наличее секции loader +use_parse_loader +;pause +if DEBUG + xor ax,ax + int 16h +end if +;////// вывод графического экрана, выбор, секции под дефолту +use_any_sec +;парсинг выбраной или дефолтной секции т.е. разбор параметров выполнение сценария +use_parse_def_sect + +;////////////////// +;/end parse block +;////////////////// +;.end_bl: +; mov cx,bx +; +; jmp .start + +.exit: + +; mov si,parse_ini_end +; call printplain +; +;if DEBUG +; pusha +; mov ax,cx +; mov cx,0x0a +; mov di,show_db1_dec +; mov dword[ds:di],' ' +; call decode +;Show size +; mov si,show_db1 +; call printplain +; +; popa +;end if + jmp $ + +;///////////////////procedure ////////// +;input es:di - is pointer to date +;cx - counter +;return: cx - status if =0 - end of date else es:di point to first symbol on new line + +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_any.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_any.inc new file mode 100644 index 000000000..1ae93fb83 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_any.inc @@ -0,0 +1,683 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;тут распологается модуль с помощью которого будут парситься все остальные секции +color_sym_black equ 0 +color_sym_blue equ 1 +color_sym_green equ 2 +color_sym_turquoise equ 3 +color_sym_red equ 4 + +color_sym_lightgray equ 7 + +color_sym_lightblue equ 9 +color_sym_lettuce equ 10 +color_sym_pink equ 12 +color_sym_yellow equ 14 + +macro use_any_sec +{ +;узнаем работу предыдущего шага т.е. чему = timeout, если он 0, то визуальная часть не будет отображена на дисплее с выбором загрузочных секций. +;иначе мы ее должны отобразить и ждать заявленое время для выбора и конигурирования пукнктов секции от пользователя. + +if DEBUG + pusha + mov ax,word [value_timeout] ;идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти +; mov ax,cx + mov cx,0x0a + mov di,show_db1 + mov dword[ds:di],' ' + mov word [ds:di+4],' ' + call decode +;Show size + mov si,show_db1 + call printplain +; + popa +end if + + test ax,ax + jz .parse_run_only + +;отобразим полный список всех найденых секций. +if DEBUG + pusha + mov si,show_all_sect + call printplain + popa +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование + out 0x60, al + xor cx, cx +.wait_loop: ; variant 2 +; reading state of port of 8042 controller + in al, 64h + and al, 00000010b ; ready flag +; wait until 8042 controller is ready + loopnz .wait_loop + + +; set keyboard typematic rate & delay + mov al, 0xf3 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b + mov al, 0 + out 0x60, al + xor cx, cx +@@: + in al, 64h + test al, 2 + loopnz @b +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; get start time + call gettime + mov dword [start_timer],eax + mov word [timer_],newtimer + mov word [timer_+2],cs +;установить свое прерывание на таймер т.е. код будет перрываться ~18 раз в сек и переходить на обработчик + cli + push 0 + pop es + push dword [es:8*4] + pop dword [old_timer] + push dword [timer_] + pop dword [es:8*4] + sti + +;процедура формирования буфера для скролинга секций +;if DEBUG +; pusha +; mov ax,point_default +; mov ax,cx +; mov cx,0x0a +; mov di,show_db1 +; mov dword[ds:di],' ' +; mov word [ds:di+4],' ' +; call decode +;Show size +; mov si,show_db1 +; call printplain +; +; xor ax,ax +; int 0x16 +; popa +;end if +;;;;;;;;;;;;;размер предыдущей сеции установим =0 + mov save_descript_size,18 +;отобразить black screen +show_bl_sc ;es=0xb800 +.show_all_scr: +get_frame_buffer ;es=0x2000 +;отображение секций + call show_bl_sc_sect ;es=0xb800 +;отобразить активный курсор +.show_active_cursor: +show_act_cursor +show_descript ;макрос по отображению описания секции + +;отобразить Press any key .... + mov eax,dword [old_timer] + cmp eax,dword [timer_] + jz .interrupt_16 + +show_timer_message + mov word [start_stack],sp +.interrupt_16: + xor ax,ax ;получим информацию о том что нажато + int 0x16 +;check on change + mov ebx,dword [old_timer] + cmp ebx,dword [timer_] + jz @f +;restore timer interrupt + cli + push 0 + pop es +; mov eax,dword [old_timer] ; восстановим прежднее прерывание + mov [es:8*4],ebx + mov dword [timer_],ebx + sti + + push ax +clear_timer_msg + pop ax +@@: + call clean_active_cursor ;clean old cursor ;es=0xb800 + + cmp ah,0x48 ;реакция системы на события + jz .up + cmp ah,0x50 + jz .down + cmp ah,0x49 + jz .pgup + cmp ah,0x51 + jz .pgdown + cmp ah,0x47 + jz .home + cmp ah,0x4f + jz .end + + cmp al,0xD + jnz .show_active_cursor + + jmp .end_show_all ;парсинг секции которая указана в point_default +.up: + mov si,point_to_point_def ;значение указателя + add si,2 + lea ax,point_to_hframe + + cmp si,ax + ja @f + + mov point_to_point_def,si + mov ax,[si] + mov point_default,ax + jmp .show_active_cursor +@@: + call find_before_sect + jmp .show_all_scr + + + +.down: + mov si,point_to_point_def ;значение указателя + mov ax,point_to_eframe ;указатель на последний элемент + sub si,2 + cmp si,ax + jb @f + + mov point_to_point_def,si + mov ax,[si] + mov point_default,ax + jmp .show_active_cursor + +@@: call find_next_sect + jmp .show_all_scr + +.pgup: + mov cx,size_show_section +@@: + push cx + call find_before_sect + pop cx + loop @b + jmp .show_all_scr + + +.pgdown: + mov cx,size_show_section +@@: + push cx + call find_next_sect + pop cx + loop @b + jmp .show_all_scr + +.home: + xor di,di + call find_next_sect.h + jmp .show_all_scr + +.end: + mov di,save_cx + call find_before_sect.e + jmp .show_all_scr + + + + +; тут мы будем парсить только дефолтную секцию и выполнять ее ничего не предлагая пользователю из диалогов. +.parse_run_only: +if DEBUG + pusha + mov si,no_show_only_w + call printplain + popa +end if + + +.end_show_all: +} + + + + + + + + + + + + + + + +;show black screen SL +macro show_bl_sc +{ +;;;;;;;;;;;;;;; +;очистим экран и выведем меню +; draw frames + xor ax,ax +if DEBUG + mov ax,0x0720 +end if + push 0xb800 + pop es + xor di, di +; draw top + mov cx, 25 * 80 + rep stosw +;;;;;;;;;;;;;;;;;;;;;;; show 'Secondary Loader v0.xxx' + mov di,164 + mov si,version + mov cx,version_end-version + mov ah,color_sym_yellow +@@: + lodsb + stosw + loop @b +;;;;;;;;;;;;;;;;;;;;;;; show firm )) + mov di,(2*160-(2*(soft_mes_end-soft_mes+4))) ;286 + mov ah,color_sym_pink;color_sym_red + mov al,'K' + stosw + mov al,' ' + stosw + mov ah,color_sym_lightgray;color_sym_lightblue;color_sym_pink + mov si,soft_mes + mov cx,soft_mes_end- soft_mes +@@: + lodsb + stosw + loop @b +;;;;;;;;;;;;;;;;;;;;;;; show '__________________________' + mov di,480 + mov ah,color_sym_yellow + mov al,'Д' + mov cx,61 + rep stosw +;;;;;;;;;;;;;;;;;;;;;;; show 'Select section' + mov di,804 + mov si,select_section + mov cx,select_section_end - select_section + mov ah,color_sym_lightgray +@@: + lodsb + stosw + loop @b +;;;;;;;;;;;;;;;;;;;;;;; show 'Section description' + mov di,880 + mov si,section_description + mov cx,section_description_end - section_description +; mov ah,color_sym_lightgray +@@: + lodsb + stosw + loop @b + +} + +macro show_timer_message +{ +;;;;;;;;;;;;;;;;;;;;; show Press any key +;;;;;;;;;;;;;;;;;;;;; show ramk + + xor ax,ax + mov di,3360 + mov cx,80*4 + rep stosw + + mov di,3362 + mov ah,color_sym_pink + mov al,0xDA + stosw + mov al,0xc4 + mov cx,76 + rep stosw + mov al,0xBF + stosw + add di,4 + mov al,0xb3 + stosw + add di,152 + stosw + add di,4 + stosw + add di,152 + stosw + add di,4 + mov al,0xc0 + stosw + mov al,0xc4 + mov cx,76 + rep stosw + mov al,0xd9 + stosw +;;;;;;;;;;;;;;;;;;;;;;;;ramk is complete show +;show first message + mov si,start_msg + mov cx,start_msg_e-start_msg + mov di,3526 +@@: + lodsb + stosw + loop @b +;;;;;;;;;;;;;;;;;;;; show press Enter to.... + add di,44 + mov si,time_msg + mov cx,time_msg_e-time_msg +@@: + lodsb + stosw + loop @b +} + + + + + + + + +macro get_frame_buffer +{ + mov cx,save_cx ;it's placed size of ini file + les di,dword [file_data] + + mov si,di ;point frame + mov bx,cx + mov dx,size_show_section +; mov point_to_hframe,di ; внесем значение, так подстраховка не более + + mov al,byte [es:di] + push word .first_ret_bl_sc + cmp al,' ' + jz .first_bl_sc + jmp get_firs_sym.not_space +.first_bl_sc: + jmp get_firs_sym.first_sp + +.start_hbl: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before + cmp al,'[' + jnz .start_hbl + + mov si,di ;point frame + mov bx,cx + mov dx,size_show_section + jmp .analisist_al + + +.start_bl: + call get_firs_sym ;get first symbol on new line +.first_ret_bl_sc: ;первый возврат + test cx,cx + jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before +.analisist_al: + cmp al,'[' + jnz .start_bl +;просматриваем ini файл с начала в поисках секции указаной как default +;поиск фрейма в котором содержиться значение default +.found_sect_bl: + cmp di,point_loader + jz .start_bl + cmp di,point_default + jz .save_point_def + + dec dx + jnz .start_bl + + jmp .start_hbl + + +.save_point_def: +;итак далее мы должны заполнить frame буфер адресов секций, что бы потом по нему быстро перемещаться не вычисляя снова адреса + mov di,si ;указатель на начало + mov cx,bx + lea si,point_to_hframe + mov dx,size_show_section+1 ;т.к. у нас структура содержит размер между первым и вторым указателем, то нам нужно на 1 адрес больше обсчитать секций. +;переходим на обработку значения указателя + mov al,byte [es:di] + push word .first_ret_mfb + cmp al,' ' + jz .first_bl_mbf + jmp get_firs_sym.not_space +.first_bl_mbf: + jmp get_firs_sym.first_sp + +.start_mfb: + call get_firs_sym ;get first symbol on new line +.first_ret_mfb: ;первый возврат + jcxz .val_buff_comp ;.end_loader ;found or not found parametrs in section exit in section + cmp al,'[' + jnz .start_mfb + +.found_sect_mfb: + cmp di,point_loader ;if we have section loader + jz .start_mfb + + mov [si],di + + sub si,2 + dec dx + jnz .start_mfb +;bufer is full + jmp @f +.val_buff_comp: + push save_cx + pop word [si] + sub si,2 +@@: + + add si,4 + mov point_to_eframe,si + +} + +macro show_act_cursor +{ +;отображение курсора по умолчанию + lea si,point_to_hframe + mov di,962-160 + mov ax,point_default + mov cx,size_show_section +.home_show_cur: + mov bx,[si] + add di,160 + cmp bx,ax + jz .show_cursor_activ + sub si,2 + loop .home_show_cur + +.show_cursor_activ: +; push 0xb800 +; pop es + mov point_to_point_def,si + mov ax,(color_sym_red*0x100+0x10) + stosw + add di,68 + inc ax + stosw +} + +macro clear_timer_msg +{ + push 0xb800 + pop es + xor ax,ax +if DEBUG + mov ax,0x0720 +end if +;;;;;;;;;;;;;;;;;;;;; show Press any key + mov di,3360 + mov cx,80*4 + rep stosw + +;show sect + push ini_data_ + pop es + call show_bl_sc_sect ;es=0xb800 + +} + +macro show_descript +;Этот макрос показывает краткое описание, если оно есть у секции в пункте +;Section description +{ +local .start_p_sh_d +local .exit +local .rest_value_loop_sh_d +local .end_sh_desc_sec +local .loop_message +local .show_mess_prev_eq + mov di,point_default + push ini_data_ + mov si,point_to_point_def + pop es + sub si,2 + mov cx,[si] ;загрузим указатель наследующию секцию + sub cx,di ;вот теперь имеем истиный размер +;di - указатель на дефолтную секцию т.е. выбранную cx - размер области. для просмотра + +.start_p_sh_d: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz .exit ;нету? ну ладно - следующее значение тогда ) + cmp al,'d' + jnz .start_p_sh_d +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov bx,cx + mov ax,di + + mov si,parse_descript + mov cx,parse_descript_e - parse_descript + repe cmpsb + jnz .rest_value_loop_sh_d ;is not compare + + sub bx,parse_descript_e - parse_descript ;correct cx + add bx,cx + mov cx,bx +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; разбор аля ' = ' + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .rest_value_loop_sh_d ;not found param timeout + + cmp ah,byte [es:di-1] ;find '=' + jnz .rest_value_loop_sh_d + + repe scasb ;cut ' ' + inc cx + dec di +;;;;;;;;;;;;;;;;;;;;di указывает на строчку, которую нам нужно выводить. +;строчка будет выводиться блоками по 37 символов. +;настроим куда будем выводить т.е. начало +;es:di - указывают на строчку из которой мы берем символ, ds:si куда будем выводить + push di + pop si + + push es + pop ds + + push 0xb800 + pop es + + mov di,1040 + mov bx,18 + mov find_sec_di,di + mov save_cx_d,bx +;;;;;;;;;;;;;;;;;;;;;;;;;; +;clean string + + push di + xor ax,ax + +@@: mov cx,38 + push di + rep stosw + pop di + + cmp save_descript_size,bx + jz @f + + + add di,160 + dec bx + jnz @b + +@@: pop di +;enter in mess +.show_mess_prev_eq: + lodsb + mov ah,color_sym_lettuce;color_sym_turquoise +; sub di,2 + cmp al,'"' + jz .loop_message + cmp al,"'" + jnz .end_sh_desc_sec + +.loop_message: + mov cx,38 +@@: + lodsb + cmp al,'"' + jz .end_sh_desc_sec + cmp al,"'" + jz .end_sh_desc_sec + stosw + loop @b + + add find_sec_di,160 + mov di,find_sec_di + dec save_cx_d + cmp save_cx_d,0 + jnz .loop_message + +.end_sh_desc_sec: + push save_cx_d + pop save_descript_size + + push cs + pop ds + jmp .exit + + +.rest_value_loop_sh_d: + mov di,ax + mov cx,bx + jmp .start_p_sh_d + +.exit: +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_dat.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_dat.inc new file mode 100644 index 000000000..8279f2517 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_dat.inc @@ -0,0 +1,56 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;Тут представленны теги, для сравнения +parse_loader db '[loader]' +parse_loader_e: +parse_l_timeout db 'timeout' +parse_l_timeout_e: +parse_l_default db 'default' +parse_l_default_e: +parse_name db 'ame' +parse_name_e: +parse_descript db 'descript' +parse_descript_e: + +parse_LoaderModule db 'LoaderModule' +parse_LoaderModule_e: +parse_RamdiskSize db 'RamdiskSize' +parse_RamdiskSize_e: +parse_RamdiskFS db 'RamdiskFS' +parse_RamdiskFS_e: +parse_RamdiskSector db 'RamdiskSector' +parse_RamdiskSector_e: +parse_RamdiskCluster db 'RamdiskCluster' +parse_RamdiskCluster_e: +parse_RFS_FAT db 'FAT' +parse_RFS_FAT_e: +parse_RFS_KRFS db 'KRFS' +parse_RFS_KRFS_e: +parse_Loader_Image db 'LoaderImage' +parse_Loader_Image_e: +parse_RamdiskFile db 'RamdiskFile' +parse_RamdiskFile_e: diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_def_sect.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_def_sect.inc new file mode 100644 index 000000000..c36665208 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_def_sect.inc @@ -0,0 +1,2094 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; в этой секции идет разбор параметров указатель на секцию храниться в point_default +;типы ошибок при обработке макроса +;Макрос RamdiskFS +;/определение флагов в записи корневой директории +ATTR_READ_ONLY equ 0x01 +ATTR_HIDDEN equ 0x02 +ATTR_SYSTEM equ 0x04 +ATTR_VOLUME_ID equ 0x08 +ATTR_DIRECTORY equ 0x10 +ATTR_ARCHIVE equ 0x20 + + + +show_error_1 equ 0x1 ;кончились данные - не запланированный конец секции +show_error_2 equ 0x2 ;нет завершающего символа в размере рам диска. +show_error_3 equ 0x4 ; рам диск будет иметь размер =64 кб. +show_error_4 equ 0x8 ; + +macro use_parse_def_sect +{ + mov di,point_default + push ini_data_ + pop es + mov si,point_to_point_def + sub si,2 + mov cx,[si] ;загрузим указатель наследующию секцию + + xor ax,ax ;обнулим аx для очистки флагов + + sub cx,di ;вот теперь имеем истиный размер + mov save_cx_d,cx ;сохраним значение cx своей переменной +;обнулим переменную флагов, это необходимо, для того, что бы избежать обработку повторяющихся значений + + mov status_flag,ax +;;;; +;ВХод в обработку парсинга значений секций. es:di - указатель на начало секции cx размер секции доступной для парсинга +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;соглашение не разрушаем bp, es, cs, sp +;use_Loader_Image ;загрузить образ выше 1 мб +use_RamdiskFS +;проверяется самый последний. +use_LoaderModule ;особенность - передает управление на загруженный модуль. +} + +macro use_LoaderModule +;как вариант сейчас используется модель, при загрузке модуля на него передается управление, решение временое +;управление будет передаваться только после обработки всей секции +{ +local .found_end_str + + mov di,point_default ;restore value + mov cx,save_cx_d +;обработка конструкции типа LoaderModule=kord/kolibri.ldm +.start_p_LM: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz ._afterLoaderModule ;нету? ну ладно - следующее значение тогда ) + cmp al,'L' + jnz .start_p_LM +;проверка на значение LoaderModule +; parse_LoaderModule + mov bx,cx + mov ax,di + + mov si,parse_LoaderModule + mov cx,parse_LoaderModule_e - parse_LoaderModule + repe cmpsb + jnz .rest_value_loop_LM ;is not compare + + sub bx,parse_LoaderModule_e - parse_LoaderModule ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_LM ;оценка флагов + jz .correct_is_not_set_LM + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +.correct_is_not_set_LM: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .rest_value_loop_LM ;not found param timeout + + cmp ah,byte [es:di-1] ;find '=' + jnz .rest_value_loop_LM + + repe scasb ;cut ' ' + inc cx + dec di +;di указывает на начало блока информации, в cx длинна до конца секции. +;после загрузки заноситься значение занятой памяти. +;для того что бы загрузить модуль, воспользуемся callback сервисом +;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 +;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader +;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем +;сохранили певые 2 word + push dword [es:di-6] + lea si,[di-6] + + push word [es:di-2] + xor ax,ax + mov word [es:di-6],ax ;вносим нужные значения +;info_real_mode_size размер и указатель на область в которую можно загрузиться + mov ax,info_real_mode_size ;0x3000 ;следующий сегмент за данными + + + mov word [es:di-4],ax + mov word [es:di-2],16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем +;;;;;; поиск конца строчки +@@: mov al,byte [es:di] + cmp al,' ' + jz .found_end_str + cmp al,0xa + jz .found_end_str + cmp al,0xd + jz .found_end_str + inc di + dec cx + jnz @b +;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки +.found_end_str: + + push word [es:di] + xor ax,ax + mov word [es:di],ax +; xor ax,ax ; function 1 - read file + mov di,si ;file_data + inc ax + push si + push es + + push es + pop ds + push cs + pop es + + call far dword [es:loader_callback] + + push cs + pop ds + + pop es + pop si + + test bx,bx + jnz .error_LM + + + jmp far dword [es:si] + + +.error_LM: + call error.LoaderModule +.rest_value_loop_LM: + mov di,ax + mov cx,bx + jmp .start_p_LM + +._afterLoaderModule: +} + +macro use_RamdiskFS +; формирование рам диска, + обработка всего связанного. +{ +if DEBUG +local ._not_memory_in_sys +;//////// clear window + mov ax,3 + int 0x10 +;\\\\\\\\\ clear window is end + mov si,ramdiskFS_st + call printplain +end if +; обнулим регистр состояния ошибок + xor ax,ax + mov show_errors_sect,ax +use_free_memory ; узнаем какого объема у нас доступна память. значение возаращается в ax +;узнаем сколько у нас есть памяти и сможем ли мы сформировать нужного размера рам диск. +use_RamdiskSize ;значение возвращается в bx + cmp free_ad_memory,bx ; размерность в кб. + jbe ._not_memory_in_sys + movzx eax,bx + shl eax,10 ;*1024 = get size in byte + mov save_ramdisksize,eax ; сорханим размер в byte + +get_type_FS ;получим тип файловой системы + создадим ее + + +._not_memory_in_sys: + +if DEBUG +;pause + xor ax,ax + int 0x16 +end if +} +macro use_RamdiskSize +{ +local .start_p_RS +local .correct_is_not_set_RS +local .CS +local .correct_val_RS +local .correct_size_RS +local .rest_value_loop_RS +local .end_get_RS_ERROR_1 +local .end_get_RS_ERROR_2 +local ._end_parse_RS +;обрабатывается размер формируемого рам диска +;загрузим начало секции, т.к. будем просматривать с начала и всю секцию + mov di,point_default ;restore value + mov cx,save_cx_d +.start_p_RS: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz ._end_parse_RS ;нету? ну ладно - следующее значение тогда ) + cmp al,'R' + jnz .start_p_RS +;проверка на значения RamdiskSize +; parse_RamdiskSize + mov bx,cx + mov ax,di + + mov si,parse_RamdiskSize + mov cx,parse_RamdiskSize_e - parse_RamdiskSize + repe cmpsb + jnz .rest_value_loop_RS ;is not compare + + sub bx,parse_RamdiskSize_e - parse_RamdiskSize ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_RS ;оценка флагов + jz .correct_is_not_set_RS + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +.correct_is_not_set_RS: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .end_get_RS_ERROR_1 ;not found param + + cmp ah,byte [es:di-1] ;find '=' + jnz .start_p_RS ; перейдем на начало и попробуем найти еще секцию + + repe scasb ;cut ' ' + inc cx + dec di +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Тут нужно преобразовывать строчку в цифровое значение. +;;;;;;;;;;;;;;;;;;;;;;;;;; + xor bx,bx + mov cx,5 +@@: mov al,byte [es:di] + cmp al,'0' + jb .CS + cmp al,'9' + jbe .correct_val_RS +.CS: + cmp al,'K' + jz .correct_size_RS + jmp .end_get_RS_ERROR_2 +.correct_val_RS: + imul bx,10 + xor al,0x30 + add bl,al + inc di + loop @b + +.correct_size_RS: +;возможен 1 вариант, когда размер задан в K киллобайтах +;внутренный формат данных это кол-во запрощеной памяти в кб. + test bx,bx + jnz @f ;если значение отлично от 0 +;;;;;сообщение об ошибке, размер "найденого" блока =0 минимально мы должны +;установить 64 кб размер рам диска. + or show_errors_sect,show_error_3 + mov bx,64 +@@: + jmp ._end_parse_RS + + +.rest_value_loop_RS: + mov di,ax + mov cx,bx + jmp .start_p_RS + + + +.end_get_RS_ERROR_1: +;сообщение об ошибке - данный участок кода не был корректно обработан :( + or show_errors_sect,show_error_1 + jmp ._end_parse_RS +.end_get_RS_ERROR_2: + or show_errors_sect,show_error_2 + +._end_parse_RS: +if DEBUG + pusha + movzx eax,bx + mov cx,0x0a + mov di,RamdiskSize_msg + mov dword[ds:di],' ' + mov word [ds:di+4],' ' + call decode +;Show size + mov si,RamdiskSize_msg + call printplain + + popa +end if + +} + +macro use_free_memory +{ +local _support_function_use_free_memory +;макрос для получения общего числа доступной памяти в кб, для формирования рам диска за пределами 1 мб. +;используется 0х88 функция 0х15 прерывания +; если поддерживается функция, то в ax значение в кб, если нет, то в ax=0 + mov ah,0x88 ;ah,0x88 + int 0x15 + jnc ._support_function_use_free_memory + xor ax,ax +;возвращает в ax число в кб +._support_function_use_free_memory: + mov free_ad_memory,ax ; если не поддерживается биосом, то в ax=0 +if DEBUG + pushad + movzx eax,ax + mov cx,0x0a + mov di,free_memory_msg + mov dword[ds:di],' ' + mov word [ds:di+4],' ' + call decode +;Show size + mov si,free_memory_msg + call printplain + + popad +end if + + + + +} +macro show_ERRORS +{ + +} + +macro get_type_FS ;получить и создать образ для заданной RFS. +{ + mov di,point_default ;restore value + mov cx,save_cx_d +.start_g_tpe_RFS: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz ._end_parse_FRS ;._end_get_type_RFS ;нету? ну ладно - следующее значение тогда ) + cmp al,'R' + jnz .start_g_tpe_RFS +;проверка на значения RamdiskSize +; parse_RamdiskSize + mov bx,cx + mov ax,di + + mov si,parse_RamdiskFS + mov cx,parse_RamdiskFS_e - parse_RamdiskFS + repe cmpsb + jnz .start_g_tpe_RFS_rest_v ;is not compare + + sub bx,parse_RamdiskFS_e - parse_RamdiskFS ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_GTRFMS ;оценка флагов + jz .correct_is_not_set_FRS + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +.correct_is_not_set_FRS: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + test cx,cx + jz .end_get_FRS_ERROR_1 ;not found param + + cmp ah,byte [es:di-1] ;find '=' + jnz .start_g_tpe_RFS ; перейдем на начало и попробуем найти еще секцию + + repe scasb ;cut ' ' + inc cx + dec di +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Тут нужно преобразовывать строчку в цифровое значение. +;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx,cx + mov ax,di + + mov si,parse_RFS_FAT + mov cx,parse_RFS_FAT_e - parse_RFS_FAT + repe cmpsb + jnz .krfs_cmp ;is not compare + +make_FAT_RamFS ;сделать + +if DEBUG + pusha + mov si,make_fat12_RFS_msg + call printplain + popa +end if + jmp ._end_parse_FRS + +.krfs_cmp: + mov cx,bx + mov di,ax + + mov si,parse_RFS_KRFS + mov cx,parse_RFS_KRFS_e - parse_RFS_KRFS + repe cmpsb +; jnz @f ;is not compare + + jmp ._end_parse_FRS + + +.start_g_tpe_RFS_rest_v: + mov cx,bx + mov di,ax + jmp .start_g_tpe_RFS + + + +.end_get_FRS_ERROR_1: +;сообщение об ошибке - данный участок кода не был корректно обработан :( + or show_errors_sect,show_error_1 + jmp ._end_parse_FRS +.end_get_FRS_ERROR_2: + or show_errors_sect,show_error_2 + +._end_parse_FRS: +if DEBUG + pusha + mov si,get_type_FS_msg + call printplain + popa +end if + + + +} +macro make_FAT_RamFS +{ +local .RS1 +local .fat12 +local .fat16 +; мы должны сформировать в начальный образ Ram FS, а потом записать его за область выше 1 мб.. +;для случая с FAT12 +; mov di,fat12_buffer ;ds должен быть = cs +;es:di - указывают на начало блока для формирования рам фс. +use_RamdiskSector ;возращаемое значение в ax размер сектора в байтах + cmp ax,4096 ;по спецификации значение должно быть в пределах от 1 до 4096 + ja .RS1 + test ax,ax + jnz @f ;ошибка если сюда прыгнули все таки ... + +.RS1: mov word [fat12_buffer.BPB_BytsPerSec],512 +;;;;;;;;;;скажем что по дефолту будем юзать значение... +@@: mov word [fat12_buffer.BPB_BytsPerSec],ax ;тут все ок + +;BPB_SecPerClus кол-во секторов в кластере +use_RamdiskCluster ;возращаемое значение в al + cmp al,128 + ja @f +; test al,0x1 ;проверка на кратность ) +; jnz @f + + mov byte [fat12_buffer.BPB_SecPerClus],al + + ;incorrect value will be set dafault + +;ниже некорректное значение в т.к. размер кратен 2 и в диапазоне от 1 до 128 включительно +; мы должны ругнуться на это +;@@: ;mov byte [fat12_buffer.BPB_SecPerClus],1 + +;;;;; определеим какая у нас будет использоваться FAT +;по условию, fat12<4085<=fat16<65525<=fat32 +; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = кол-во секторов + movzx eax,word [fat12_buffer.BPB_BytsPerSec] + movzx ebx,byte [fat12_buffer.BPB_SecPerClus] + + imul ebx,eax ;тут размерность сектора + mov eax,save_ramdisksize ;размер запрошенного рам диска в байтах + cdq + idiv ebx +;;;;;;;; сейчас частное в eax, а остаток в edx +;получим кол-во секторов, и можем уже определить тип FAT которую нужно делать. + cmp eax,4085 + jb .fat12 + cmp eax,65525 + jb .fat16 +;;;;;;;;;;;;;;;;;;;;;;;; тут fat32 + mov set_ramfs,32 ;установим тип файловой системы + mov word [fat12_buffer.BPB_RsvdSecCnt],32 + xor eax,eax + mov word [fat12_buffer.BPB_RootEntCnt],ax + mov word [fat12_buffer.BPB_TotSec16],ax + mov dword [fat12_buffer.BPB_TotSec32],eax + + +.fat16: ;fat16 +;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). + jmp $ + mov set_ramfs,16 ;установим тип файловой системы + movzx ebx,byte [fat12_buffer.BPB_SecPerClus] + imul eax,ebx + + cmp eax,0x10000 + jae @f + mov word [fat12_buffer.BPB_TotSec16],ax + mov dword [fat12_buffer.BPB_TotSec32],0 +@@: +;количество секторов занимаемое одной копией фат +; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? +;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число +;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно +;быть 0. Пока константа, нужно будет позже доделать. + mov eax,root_dir_entry_count + mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) +;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб +;;;;;;; +;Для FAT16 это количество секторов одной FAT. Для FAT32 это значение +;равно 0, а количество секторов одной FAT содержится в BPB_FATSz32. +;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec; + +;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); +;TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs; +;If(FATType == FAT32) +; TmpVal2 = TmpVal2 / 2; +;FATSz = (TMPVal1 + (TmpVal2 - 1)) / TmpVal2; +;If(FATType == FAT32) { +; BPB_FATSz16 = 0; +; BPB_FATSz32 = FATSz; +;} else { +; BPB_FATSz16 = LOWORD(FATSz); +; /* there is no BPB_FATSz32 in a FAT16 BPB */ +;} +;===================================== +;RootDirSectors + movzx ebx, word [fat12_buffer.BPB_BytsPerSec] + imul eax,32 + add eax,ebx + dec eax + + cdq + idiv ebx +;;;;;;;; сейчас частное в eax, а остаток в edx для дискеты 1.44 у нас должно быть значение =14 +;BPB_ResvdSecCnt + RootDirSectors + movzx ebx, word [fat12_buffer.BPB_RsvdSecCnt] + add ebx,eax + +;DskSize у нас это значение уже получено и доступно + movzx eax,word [fat12_buffer.BPB_TotSec16] ;должен быть в секторах + sub eax,ebx + + +;TmpVal1=eax + shl edi,8 ;=edi*256 + movzx ecx,byte [fat12_buffer.BPB_NumFATs] + add edi,ecx +;TmpVal2=edi + add eax,edi + dec eax + cdq + idiv edi +;FATSz = сейчас частное в eax, а остаток в edx + mov word [fat12_buffer.BPB_FATSz16],ax + + + + + + + + +.fat12: ;fat12 +if DEBUG +; выведем в отладке, что собираемся делать образ диска c FS=fat12 + pushad + mov si,start_making_FAT12_msg + call printplain + popad +end if + + + +;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). + mov set_ramfs,12 ;установим тип файловой системы + movzx ebx,byte [fat12_buffer.BPB_SecPerClus] + imul eax,ebx + + cmp eax,0x10000 + jae @f + mov word [fat12_buffer.BPB_TotSec16],ax + mov dword [fat12_buffer.BPB_TotSec32],0 +@@: +;количество секторов занимаемое одной копией фат +; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? +;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число +;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно +;быть 0. Пока константа, нужно будет позже доделать. + mov eax,root_dir_entry_count + mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) +;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб +;;;;;;; +;DskSize(в секторах)*12 (размерность файловой системы, т.е предположим сколько битов потребуется для адресации этого объема) /8 (что получить размер в байтах) +;полученное число округляем в большую сторону кратное сектору т.е. 512 байт Такой подход не универсален, но пока пойдет +;вообще у мелкософт это все считается ручками, но мы будем юзать только под коос рам диск с фат12 + movzx eax, word [fat12_buffer.BPB_TotSec16] + imul eax,12 + shr eax,3 ;делим на 8 но т.е. нам нужно делить еще и на 512 или более в зависимости от размеров кластера + movzx ebx,word [fat12_buffer.BPB_BytsPerSec] ;размер сектора + cdq + idiv ebx ;разделим на размер кластера +;сейчас у нас в eax значение его нужно округлить в большую сторону кратному 512 байтам +;применим следующее очистим and и добавим 512 байт. таким образом выравним на 512 байт +;но т.к. все равно делить нижний код нам не нужен +; and eax,0xfff200 +; add eax,0x200 ;добавим 512 байт для 1.44 дискеты идеально подходит )) + + inc ax +;по идее должно на каждую фат таблицу +;резервироваться 9 секторов т.е. получается 2*9=18+1 =19 секторов т.е. рут дир находиться на с 20 сетора т.е. с адреса 0х2600 +;сейчас нужно вычислить сколько будет секторов занимать фат ) нужно разделить на 512 +;FATSz = сейчас частное в eax + mov word [fat12_buffer.BPB_FATSz16],ax +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +get_firstDataSector ;получить смещение до данных +;создадим певую запись в фат по определенному адресу. +first_create_fat_table +;закиним BPB файловой системы за 1 мб. +use_BPB_RAM +; +;копирование файла. +use_RamdiskFile + +;;;; вычисляем указатель на корневую дир FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); +; movzx ebx, [fat12_buffer.BPB_NumFATs] +; movzx eax,ax +; imul eax,ebx +;eax=(BPB_NumFATs * BPB_FATSz16) +; inc eax +; BPB_ResvdSecCnt значение только 1 для fat12/16 +;в eax указатель на root dir. для дискеты fat12 должно получиться при кол-во копий fat 1 = 1+ (1*1) =2 или 3 + +if DEBUG + pusha +; mov ax,point_default +; mov ax,cx + mov cx,0x0a + mov di,show_db1 +; mov dword[ds:di],' ' +; mov word [ds:di+4],' ' + call decode +;Show size + mov si,show_db1 + call printplain +; +; xor ax,ax +; int 0x16 + popa +end if + + + + + + + +} + +macro use_RamdiskSector +{ +;для некоторых FS будет игнорироваться + mov di,point_default ;restore value + mov cx,save_cx_d + +.start_RamdiskSector: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz .end_RamdiskSector ;нету? ну ладно - следующее значение тогда ) + + cmp al,'R' + jnz .start_RamdiskSector +;проверка на значения RamdiskSize +; parse_RamdiskSize + + mov bx,cx + mov ax,di + + mov si,parse_RamdiskSector + mov cx,parse_RamdiskSector_e - parse_RamdiskSector + repe cmpsb + jnz .RamdiskSector_rest_val ;is not compare + + sub bx,parse_RamdiskSector_e - parse_RamdiskSector ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_RamdiskSector ;оценка флагов + jz .correct_is_not_set_RamdiskSector + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +.correct_is_not_set_RamdiskSector: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .end_get_RamS_ERROR_1 ;not found param + + cmp ah,byte [es:di-1] ;find '=' + jnz .start_RamdiskSector ; перейдем на начало и попробуем найти еще секцию + + repe scasb ;cut ' ' + inc cx + dec di +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor bx,bx + mov cx,4 +@@: movzx ax,byte [es:di] + cmp al,'0' + jb .end_RamdiskSector + cmp al,'9' + ja .end_RamdiskSector +;;;;;;;;;;;;;;;;;;; + + imul bx,10 + xor al,0x30 + add bx,ax + + inc di + + loop @b + jmp .end_RamdiskSector + + +.RamdiskSector_rest_val: + mov cx,bx + mov di,ax + jmp .start_RamdiskSector +.end_get_RamS_ERROR_1: + +.end_RamdiskSector: + mov ax,bx + +if DEBUG + pusha + movzx eax,bx;save_cx_d;point_default + mov cx,0x0a + mov di,RamdiskSector_msg + mov dword[ds:di],' ' + mov dword [ds:di+4],' ' + call decode +;Show size + mov si,RamdiskSector_msg + call printplain + + popa +end if + +; pop di +; pop es +} + +macro use_RamdiskCluster +{ +;для некоторых FS будет игнорироваться +; push es +; push di + mov di,point_default ;restore value + mov cx,save_cx_d +; push ini_data_ +; pop es +.start_RamdiskCluster: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz .end_RamdiskCluster ;нету? ну ладно - следующее значение тогда ) + cmp al,'R' + jnz .start_RamdiskCluster +;проверка на значения RamdiskSize +; parse_RamdiskSize + + mov bx,cx + mov ax,di + + mov si,parse_RamdiskCluster + mov cx,parse_RamdiskCluster_e - parse_RamdiskCluster + repe cmpsb + jnz .RamdiskCluster_rest_val ;is not compare + + sub bx,parse_RamdiskCluster_e - parse_RamdiskCluster ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_RamdiskCluster ;оценка флагов + jz .correct_is_not_set_RamdiskCluster + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +.correct_is_not_set_RamdiskCluster: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .end_get_RamSC_ERROR_1 ;not found param + + cmp ah,byte [es:di-1] ;find '=' + jnz .start_RamdiskCluster ; перейдем на начало и попробуем найти еще секцию + + repe scasb ;cut ' ' + inc cx + dec di +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +@@: movzx ax,byte [es:di] + cmp al,'0' + jb .end_RamdiskCluster + cmp al,'9' + ja .end_RamdiskCluster +;;;;;;;;;;;;;;;;;;; + xor al,0x30 + + jmp .end_RamdiskCluster + + +.RamdiskCluster_rest_val: + mov cx,bx + mov di,ax + jmp .start_RamdiskCluster +.end_get_RamSC_ERROR_1: + +.end_RamdiskCluster: +if DEBUG + pusha + mov cx,0x0a + mov di,RamdiskCluster_msg +; mov word[ds:di],' ' + call decode +;Show size + mov si,RamdiskCluster_msg + call printplain + + popa +end if + +} + +macro use_Loader_Image +;предназначен для загрузки образов выше 1 Мб. +;первоначальная версия загружает образ дискеты 1.44 мб +{ +local .start_p_LI +local .exit +local .error_LI +local .rest_value_loop +local .found_end_str + mov di,point_default ;restore value + mov cx,save_cx_d +;обработка конструкции типа LoaderModule=kord/kolibri.ldm +.start_p_LI: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz .exit ;нету? ну ладно - следующее значение тогда ) + cmp al,'L' + jnz .start_p_LI +;проверка на значение LoaderModule +; parse_LoaderModule + mov bx,cx + mov ax,di + + mov si,parse_LoaderImage + mov cx,parse_LoaderImage_e - parse_LoaderImage + repe cmpsb + jnz .rest_value_loop ;is not compare + + sub bx,parse_LoaderImage_e - parse_LoaderImage ;correct cx + add bx,cx + mov cx,bx + +; test status_flag,flag_found_LM ;оценка флагов +; jz .correct_is_not_set_LI + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +;.correct_is_not_set_LI: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .rest_value_loop_LI ;not found param timeout + + cmp ah,byte [es:di-1] ;find '=' + jnz .rest_value_loop_LI + + repe scasb ;cut ' ' + inc cx + dec di +;di указывает на начало блока информации, в cx длинна до конца секции. +;после загрузки заноситься значение занятой памяти. +;для того что бы загрузить модуль, воспользуемся callback сервисом +;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 +;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader +;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем +;сохранили певые 2 word + push dword [es:di-6] + lea si,[di-6] + + push word [es:di-2] + xor ax,ax + mov word [es:di-6],ax ;вносим нужные значения +;info_real_mode_size размер и указатель на область в которую можно загрузиться + mov ax,info_real_mode_size ;0x3000 ;следующий сегмент за данными + + + mov word [es:di-4],ax + mov word [es:di-2],16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем +;;;;;; поиск конца строчки +@@: mov al,byte [es:di] + cmp al,' ' + jz .found_end_str + cmp al,0xa + jz .found_end_str + cmp al,0xd + jz .found_end_str + inc di + dec cx + jnz @b +;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки +.found_end_str: +; чтение блока по 64 кб в сегмент и забрасывание его выше 1 мб. + push word [es:di] + xor ax,ax + mov word [es:di],ax +; xor ax,ax ; function 1 - read file + mov di,si ;file_data + inc ax + push si + push es + call far dword [loader_callback] + push cs + pop ds + + pop es + pop si + + test bx,bx + jnz .error_LM + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; забрасывание блока в 64 кб выше 1 мб. + mov si,table_15_87 + push es + push ds + pop es + mov cx, 256*18 + mov ah, 0x87 + int 0x15 + pop es + pop dx cx + test ah, ah + + + + jmp far dword [es:si] + + + + +.rest_value_loop: + mov di,ax + mov cx,bx + jmp .start_p_LI + +.exit: + + + +} + + + +macro name_in_root_fat +;макрос, который записывает информацию о загруженном файле в корневую фат таблицу +{ + +} + + + +macro use_RamdiskFile +{ +;загрузка файлов с использование callback сервиса первичного загрузчика +;используется только для загрузки необходимых и небольших файлов, т.к. достаточно медленно работает +;для загрузки использует 0х87 функцию int 0x15 прерывания - загрузка блоков данных до 64 кб выше 1 мб +local .start_loop +local ._end +local .rest_value_loop +local .error + mov di,point_default ;restore value + mov cx,save_cx_d + mov data_offset,0 ;clean offset +;обработка конструкции типа LoaderModule=kord/kolibri.ldm +.start_loop: + call get_firs_sym ;get first symbol on new line + test cx,cx + jz ._end ;нету? ну ладно - следующее значение тогда ) + cmp al,'R' + jnz .start_loop +;проверка на значение RamdiskFile + mov bx,cx + mov ax,di + + mov si,parse_RamdiskFile + mov cx,parse_RamdiskFile_e - parse_RamdiskFile + repe cmpsb + jnz .rest_value_loop ;is not compare + + sub bx,parse_RamdiskFile_e - parse_RamdiskFile ;correct cx + add bx,cx + mov cx,bx +; test status_flag,flag_found_LM ;оценка флагов +; jz .correct_is_not_set_LM + +; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем +; call printplain +; jmp .get_next_str + +;.correct_is_not_set_LM: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + test ecx,ecx + jz .rest_value_loop ;not found param timeout + + cmp ah,byte [es:di-1] ;find '=' + jnz .rest_value_loop + + repe scasb ;cut ' ' + inc cx + dec di + + mov save_di_RAMDISK,di + mov save_cx_RAMDISK,cx +;di указывает на начало блока информации, в cx длинна до конца секции. +;после загрузки заноситься значение занятой памяти. +;для того что бы загрузить модуль, воспользуемся callback сервисом +;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 +;это выглядит так: в ini файле существует строчка RamdiskFile = @menu,@menu +;мы ее модифицируем до такого состояния dw,dw,db'@menu',0 конечно сохранив те значения которые мы заменяем +;сохранили певые 2 word + +; +@@: mov al,byte [es:di] + cmp al,',' ; т.е. ищем разделитель + jz .found_end_str + inc di + dec cx + jnz @b +;;;not found допустим,что это конец файла и он не имеет привычного завершения строки +.found_end_str: +; mov al,byte [es:di] +; cmp al,' ' ; убираем пробелы, если они есть +; jnz @f +; inc di +; dec cx +; jnz .found_end_str + +;@@: + mov point_to_dest_file_name,di + inc di +;проверка индивидуальности имени файла +check_name_file +;/restore di - point and cx -size section + mov di,save_di_RAMDISK + mov cx,save_cx_RAMDISK + + test al,al + jnz .start_loop ;если в al значение не =0, то такое имя уже существует в системе. + + + + push dword [es:di-6] + lea si,[di-6] + + push word [es:di-2] + push di + xor ax,ax + mov word [es:di-6],ax ;вносим нужные значения +;info_real_mode_size размер и указатель на область в которую можно загрузиться + mov ax,info_real_mode_size ;0x3000 ;следующий сегмент за данными + + + mov word [es:di-4],ax + mov word [es:di-2],16 ;кол-во блоков по 4 кб =64 кб т.е. больше не читаем + + mov di,point_to_dest_file_name + +if DEBUG + pushad +; mov ax,di + mov cx,0x0a + mov di,name_of_seg_get_64 + mov dword[ds:di],' ' + mov word[ds:di+4],' ' + call decode +;Show size + mov si,name_of_seg_get_64 + call printplain + + popad +end if + + push word [es:di] + push cx + xor ax,ax + mov word [es:di],ax +; xor ax,ax ; function 1 - read file + push di + mov di,si ;file_data + inc ax + push si + push es + push bp + + push es + pop ds + push cs + pop es + + call far dword [es:loader_callback] + + + push cs + pop ds + + pop bp + pop es + pop si + + cmp bx,2 + ja .error +; сейчас у нас в dx:ax размер файла, который мы загрузили. +; возможна ситуация, когда в bx=1 т.е. есть еще данные на диске + mov status_flag_loader_f,bx + + shl edx,16 + mov dx,ax +; shr edx,10 ;размер файла в кб. +;;в edx размер в байтах. + mov save_file_size,edx + mov eax,edx +;восстановим полностью файл сценария + pop di + pop cx ;длинна остатка с 2-ой частью имени т.е. с именем назначением. + pop word [es:di] + pop di + pop word [es:di-2] + pop dword [es:di-6] + + +if DEBUG + pushad + mov cx,0x0a + mov di,RamdiskFile_msg + mov dword[ds:di],' ' + call decode +;Show size + mov si,RamdiskFile_msg + call printplain + + popad +end if + + + + + + + + + + +; загрузим чему у нас равен кластер +; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта +; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;кол-во секторов в кластере +; imul ax,bx +;сейчас в eax размер кластера (512) байт +;в edx длина файла в байтах до 64 кб +;закиним файл за 1 мб +;1 нам нужно составить фат таблицу т.е. произвести разметку рамдиска, затем перенесем по адресу файл + +;записать инфорамацию о файле в корневую директорию +register_file_in_fat +;перенести за 1 мб содержимое файла +move_file_up + +;проверим, загружен ли до конца файл? т.е. если размер файла больше чем 64 кб, то будет подгружать оставшиеся блоки + cmp status_flag_loader_f,0x1 + jnz @f +;нужно дозагузить данные файла и перенести их за 1-ый мб согласно фат структуре + + + + + + + + + +@@: +;тут организован цикл по загрузке файлов в корневую директорию + mov di,save_di_RAMDISK + mov cx,save_cx_RAMDISK +if DEBUG + pusha + xor ax,ax + int 0x16 + popa +end if + + + jmp .start_loop + + +.error: + ;call error.LoaderModule +;fixme! +.rest_value_loop: + mov di,ax + mov cx,bx + jmp .start_loop + +._end: +;перенесем за 1-ый мб фат и рут дир +move_up_fat_and_root_d + + + + + + +;загрузка блока +; mov ah,0x87 +; mov cx, ;size in byte + + +;es:si point to descripts + + +} + +macro use_BPB_RAM ;закинуть самые первые 512 байт за 1-й мб +;данный макрос закидывает BPB структуру т.е. первые 512 байт, пока только фат12 за 1 мб +{ + mov ax,fat12_buffer + mov si,table_15_87 + add word [si+8*2+2],ax + push es + push ds + pop es + mov cx,256 ;бут сектор укладывается в 512 байт 512/2=256 + mov ah, 0x87 + int 0x15 + pop es +;add 512 byte for destination adress +; add dword [si+8*3+2], 512 +; test ah, ah +; jz +if DEBUG + pusha + mov ax,word [si+8*2+2] + mov cx,0x0a + mov di,BPB_msg + call decode +;Show size + mov si,BPB_msg + call printplain + popa +end if +} +macro first_create_fat_table +;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение +;для смещения в корневой таблице. +{ + mov al,byte [fat12_buffer.BPB_Media] + + + push ds + + + mov di,info_real_mode_size + add di,0x1000 + +if DEBUG + pushad + + mov ax,info_real_mode_size + add ax,0x1000 +; mov ax,ds + mov cx,0xa + + mov di,first_entry_in_fat + mov dword [di],' ' + mov word [di+4],' ' + call decode +;Show size + mov si,first_entry_in_fat + call printplain + + xor ax,ax + int 0x16 + + popad +end if + + + push di ; push word info_real_mode_size+0x1000 ;cледующий сегмент за загруженным участком + + xor di,di + mov point_to_free_root,di ;значение смещения =0 в корневой фат таблице описания + + pop ds ; загружен следующий сегмент т.е. пустой сегмент + + mov byte [di],al + or ax,-1 + inc di + mov word [di],ax + + pop ds + mov point_next_fat_str,3 + +if DEBUG + pushad + mov ax,point_next_fat_str + mov cx,0x0a + mov di,fat_create_msg + call decode +;Show size + mov si,fat_create_msg + call printplain + popad +end if + +} +macro register_file_in_fat +;макрос регистрации файла в файловой структуре Fat +;пока поддерживается только фат12, пока )) +;вычисление смежных кластеров и занесение инфы в fat/ +{ +local .step2 +local .step3 +local .end +local .eof_file + +;di point on root dir на фри секцию. + push es + + mov ax,info_real_mode_size + add ax,0x1000 + mov es,ax ; push word info_real_mode_size+0x1000 ;сегмент следующий за загруженным блоком в 64 кб + +; определяем тип фат пока не определяем, пока только фат 12 +; 12 бит, для вычесления соседних каластеров. + mov di,firstDataSect ;в секторах + sub di,size_root_dir +;теперь в ax размер в секторах начала рут дир + shl di,9 ;imul 512 + add di,point_to_free_root ;смещение в уже записанных 32-х структурах. +;необходимо внести значение в рут дир т.е. 32 байта +if DEBUG + pushad +; mov ax,point_default +; mov ax, + mov cx,0x0a + mov di,show_db2 + mov dword[ds:di],' ' + mov word [ds:di+4],' ' + call decode +;Show size + mov si,show_db2 + call printplain +; +; xor ax,ax +; int 0x16 + popad +end if + + + +;gs:di - указатель для внесения инфорации в рут область фат таблицы инормации о файле. + mov si,shot_name_fat + mov cx,11 +;запишем в структуру имя +@@: lodsb + stosb + loop @b + +;запишем атрибуты файла и DIR_NTRes - зарезеврированный байт =0 + xor ax,ax + mov ah,ATTR_VOLUME_ID + mov word [es:di],ax + add di,2 +;DIR_CrtTimeTenth + mov byte [es:di],100 + inc di +;DIR_CrtTime + mov word [es:di],0x032b ;дата + add di,2 +;DIR_CrtDate + mov word [es:di],0x0 ;время >< + add di,2 +;DIR_LstAccDate + mov word [es:di],0x032b ;дата моего + add di,2 +;DIR_FstClusHI + mov word [es:di],0x0 ;время для фат12 /16 всегда 0 + add di,2 +;DIR_WrtTime + mov word [es:di],0x0 ;время >< + add di,2 +;DIR_WrtDate + mov word [es:di],0x032b + add di,2 + + mov ax,point_next_fat_str + mov word [es:di],ax + add di,2 + + push di +;DIR_FstClusLO Младшее слово номера первого кластера. + ; mov ax,point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи +;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат + mov bx,ax + shr bx,1 + add ax,bx +;в ах сейчас FATOffset +;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec); + mov bx, word [fat12_buffer.BPB_BytsPerSec] + cwd + idiv bx +;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) четный или нечетный указатель. + mov si,ax +;нам нужно в цикле записать все кластеры которые будут использованы для размещения файла. +;узнаем размер кластера. + movzx eax,word [fat12_buffer.BPB_BytsPerSec] + movzx ebx,byte [fat12_buffer.BPB_SecPerClus] + imul eax,ebx +;ax - размер кластера. +;сейчас будем записывать во временный буфер фат таблицу для выбранного файла. Поскольку мы его загрузили возможно не полностью +;мы обработаем запись для фат полностью, в не зависимости от предела буфера где возможна часть файла. + mov ebx,save_file_size ;размер файла в байтах + +@@: sub ebx,eax + cmp ebx,eax + jbe .eof_file + + inc point_next_fat_str + mov cx,point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи +;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат + mov dx,ax + shr dx,1 + add cx,dx + + + + test si,0x1 + jz .step2 + shl cx,4 + mov word[es:si],cx + inc si + add cx,ax + jmp @b + +.step2: and cx,0x0FFF + mov word[es:si],cx + inc si + add cx,ax + jmp @b + +.eof_file: + mov cx,0x0fff + test si,0x1 + jz .step3 + shl cx,4 + mov word[es:si],cx + jmp .end + +.step3: and cx,0x0FFF + mov word[es:si],cx + +.end: inc point_next_fat_str + + pop di +;DIR_FileSize 32-битный DWORD содержит размер файла в байтах. + mov eax,save_file_size + mov dword [es:di],eax + +if DEBUG + pushad + + mov di,firstDataSect ;в секторах + sub di,size_root_dir +;теперь в ax размер в секторах начала рут дир + shl di,9 ;imul 512 + add di,point_to_free_root ;смещение в уже записанных 32-х структурах. + + push di + + mov si,dest_name_fat + mov cx,11 + +;запишем в структуру имя +@@: mov al,byte [es:di] + inc di + mov byte [ds:si],al + inc si + loop @b + + mov di,si + inc di + pop ax + mov cx,0xa + call decode + + mov si,dest_name_fat + call printplain + popad + +END IF + + + + + + add point_to_free_root,32 ;увелицим смещение до следующего значения. + pop es + +} + + + + + +macro get_firstDataSector +;макрос для вычисления певого сектора данных т.е. данных файлов в фате +;вычислим FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; +{ + mov ax,word [fat12_buffer.BPB_FATSz16] + movzx bx,byte [fat12_buffer.BPB_NumFATs] + imul ax,bx ;9x1=9 +;ax=BPB_NumFATs * FATSz + mov bx,word [fat12_buffer.BPB_RootEntCnt] ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) + shr bx,4 ;imul bx,32 and then div 512 -> in bx size in sectors + add ax,bx ;9+14=23 + mov size_root_dir,bx + movzx bx,byte [fat12_buffer.BPB_RsvdSecCnt] ;add 1 for fat 16/12 + add ax,bx +;ax=firstDataSector - где начинается первый секторо от 0 сектора в секторах. - фактически = 24 сектор + mov firstDataSect,ax ;сохраним для вычисления +; получимзначение кластеров, это объем в который мы можем записать данные + mov bx,word [fat12_buffer.BPB_TotSec16] + sub bx,ax + mov ax,bx + movzx bx,byte [fat12_buffer.BPB_SecPerClus] + cwd + idiv bx + mov DataClasters,ax + +if DEBUG + pushad + mov ax,firstDataSect ;первый сектор данных + mov cx,0x0a + mov di,firstDataSect_msg + call decode +;Show size + mov si,firstDataSect_msg + call printplain +;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax,size_root_dir ;размер рут дир в сетокторах + mov cx,0x0a + mov di,size_root_dir_msg + call decode +;Show size + mov si,size_root_dir_msg + call printplain +;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax,DataClasters ;кластеры + mov cx,0x0a + mov di,DataClasters_msg + call decode +;Show size + mov si,DataClasters_msg + call printplain + popad + +end if + +} + +macro use_RamdiskPATHS +;парсинг пути источника файлов. +{ + +} + +macro use_RamdiskPATHD +;парсинг пути назначения файлов. +{ + +} +macro check_name_file +;макрос проверки имени на повтор, имя должно быть уникальным. +;входные данные: es- сегмент где лежит файл для парсинга т.е. startos.ini +;di - указатель на имя файла т.е. es:di указывает на имя файла назначения +;выходные данные eax =-1 имя совпало, eax=0 имя не совпало. +{ +local .no_equal +local .exit +local .loop_size_root_dir +;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. +;преобразуем в аналог фат записи сточку с именем назначения + convertion_file_name ; преобразовали имя по нужным правилам + test ax,ax + jnz .exit + + lea si,[shot_name_fat] ; desination name of file + +;вычислим указатель на корневую директорию + mov di,firstDataSect + sub di,size_root_dir +;теперь в ax размер в секторах начала рут дир + shl di,9 ;imul 512 +;di= Это смещение от начала буфера до рут директории. в пределах 64 кб. +;загрузим значение - т.е. кол-во элементов, которые мы можем просматривать. + mov dx,root_dir_entry_count + + mov ax,info_real_mode_size + add ax,0x1000 + + + mov gs,ax +.loop_size_root_dir: +DEBUG1 equ 0 +if DEBUG1 + pushad + push di + mov eax,dword[gs:di] + lea si,[check_root_fat_+14] + mov dword [ds:si],'----' + mov dword [ds:si+4],'----' + mov dword [ds:si+8],'----' + mov dword[ds:si],eax + mov eax,dword[gs:di+4] + mov dword[ds:si+4],eax + mov eax,dword[gs:di+8] + mov dword[ds:si+8],eax + +; + xor eax,eax + mov ax,gs;point_next_fat_str + mov cx,0x0a + mov di,check_root_fat_ + mov dword [di],' ' + mov word [di+4],' ' + call decode + xor eax,eax + pop ax + mov di,(check_root_fat_+7) + mov dword [di],' ' + mov word [di+4],' ' + call decode + +;Show size + lea si,[check_root_fat_] + call printplain + + lea si,[shot_name_fat] + call printplain + + xor ax,ax + int 0x16 + popad +end if + + xor bx,bx + mov cx,11 ;size of name in struct FAT + +@@: + mov al,byte [ds:si+bx] ;ds:si - point to name of convertion variable. + mov ah,byte [gs:di+bx] ;gs:di - point to name in fat struct + inc bx + +if DEBUG +; pushad +; lea si,[check_root_fat_+14] +; mov dword [ds:si],'----' +; mov word [ds:si],ax +; call printplain + +; xor ax,ax +; int 0x16 + +; popad +end if + + + + cmp ah,al + jnz .no_equal + +; dec cx +; jnz @b + loop @b + +;.succesfuly: +;печально, такое имя уже имеется :( + or ax,-1 + jmp .exit + + +.no_equal: + add di,32 ;fat struct =32 byte + dec dx + jnz .loop_size_root_dir + +;.exit_check_name: + and ax,0 + +.exit: + +if DEBUG + pushad +;Show size + lea si,[check_name_fat_msg_n] + test ax,ax + jz @f + lea si,[check_name_fat_msg_y] + call printplain + lea si,[alarm_msg] +@@: call printplain + popad +end if + +} + + +macro convertion_file_name +;макрос конвертации имени, это нужно поскольку формат представленный не соответсвует фат и напрямую редко можно когда использовать +;преобразование имени типа hello.asm в 'HELLO ASM', в соответствии с правилами fat. +;входные параметры es:di указатель на имя файла которое нужно преобразовать, конечный буфер shot_name_fat +{ +local .next_step +local .error +local .st1 +local .st2 +local .st2_l +local .st3 +local .st4_s +local .st4 +local .st5 + +;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. +; mov di,point_to_dest_file_name входной параметр + mov si,shot_name_fat + or first_input,-1 ;при первом входе устанавливаем флаг + mov cx,11 ;длинна имени в стуктуре фат таблицы + +@@: + mov al,byte [es:di] + cmp al,0xa + jz .st4_s + cmp al,0xd + jz .st4_s + cmp al,0x20 + jz .st4_s + + cmp al,0x20 + jb .error + cmp al,0x22 + jz .error + cmp al,0x2a + jz .error + cmp al,0x2b + jz .error + cmp al,0x2c + jz .error + cmp al,0x2F + jz .error + + cmp al,0x3a + jz .error + cmp al,0x3b + jz .error + cmp al,0x3c + jz .error + cmp al,0x3d + jz .error + cmp al,0x3E + jz .error + cmp al,0x3F + jz .error + + cmp al,0x5b + jz .error + cmp al,0x5c + jz .error + cmp al,0x5d + jz .error + + cmp al,0x7c + jz .error + + + cmp first_input,-1 + jnz .next_step + and first_input,0 ;сборосим флаг. + cmp al,'.' + jz .error ;обработка точки, файл не может начинаться с точки + +.next_step: + cmp al,0x2e + jnz .st2 ;обработка точки, в середине файла +;тут у нас установлен разделитель +;все остальнео место займут пробелы + mov al,' ' + +;!fixme обработаны не все исключения :( + cmp cl,3 ;формат файла такой GIDGIDIIASM т.е. gidgidii.asm + jbe .st2 + + +.st3: + mov byte [si],al + inc si + dec cx + cmp cx,3 + ja .st3 +; inc cx + inc di + jmp @b + +.st2: + cmp al,0x60 + jbe .st2_l + + xor al,0x20 ;сделаем заглавные буквы +.st2_l: mov byte [si],al + inc di + inc si +; dec cx +; jnz @b + loop @b +.st5: xor ax,ax + jmp @f + +;;;;;;;;файл закончился, и нужно внести в конец пробелы +.st4_s: mov al,' ' +.st4: mov byte [si],al + inc si + loop .st4 + jmp .st5 + +.error: or ax,-1 +@@: + +if DEBUG + pushad + + mov si,convertion_file_name_msg_y + test ax,ax + jz @f + mov si,convertion_file_name_msg_n +@@: call printplain + + mov si,shot_name_fat + mov byte [si+12],0 + call printplain + popad + +end if +} + +macro move_file_up +;макрос который перемещает за 1 мб с правилами фат данные файла. +{ +local .st1 +local .correct_on_byte +;сейчас имеет быть ситуация, когда BPB уже перемещен за 1 мб, фат, и рут дир будут позже перемещены, +;а нам нужно вычислить место, и перенести туда содержимое файла +;полученое значение указывает в байтах на начало данных + + mov ax,info_real_mode_size ; сегмент где расположены данные + mov si,table_15_87 + mov word [si+8*2+2],ax +;смещение до данных уже за 1-м мб + movzx eax,firstDataSect + movzx edx,data_offset + add eax,edx + + movzx ebx,word [fat12_buffer.BPB_BytsPerSec] + movzx edx,byte [fat12_buffer.BPB_SecPerClus] + imul bx,dx ;получим размер кластера + + + + push ebx ;save bx + + imul eax,ebx +; shl eax,9 ;умножим на 512 + +if DEBUG + pushad + xor eax,eax + mov ax,info_real_mode_size + mov cx,0x0a + mov di,seg_where_get_data + mov dword [di],' ' + mov word [di+4],' ' + call decode +;Show size + mov si,seg_where_get_data + call printplain + popad + +end if + +; mov bx,word [fat12_buffer.BPB_BytsPerSec] +; movzx dx,byte [fat12_buffer.BPB_SecPerClus] +; imul bx,dx +; cwd +; idiv bx + + mov dl,0x10 + +@@: cmp eax,0x00010000 + jb @f + + sub eax,0x00010000 + inc dl + jmp @b + + +@@: mov byte [si+8*3+3],dl ;куда писать + mov word [si+8*3+2],ax + + mov ecx,save_file_size ;размер файла в байтах. + cmp ecx,0x0000ffff ;размер блока т.е. 64 кб + jbe .correct_on_byte ;корректировка на байт значения + + + + mov ecx,0x00010000 ;65536 + sub save_file_size,ecx ;отнимим +; jmp .st1 ;получим 0х8000 + + + + +;корректировка значения должна быть выполенена на размер кластера +.correct_on_byte: +;/узнаем размер кластера + pop eax ;restore size of claster + push ecx +@@: inc data_offset + + cmp eax,ecx + jae @f + sub ecx,eax + jmp @b +@@: pop ecx + + + + + test ecx,0x1 + jz .st1 + inc ecx +.st1: shr ecx,1 ; преобразовать значение для 0x87 function + +;перенесем блок за 1 мб + push es + push ds + pop es + + mov ah, 0x87 + int 0x15 + pop es + +if DEBUG + pusha +; mov ax,point_next_fat_str + mov cx,0x0a + mov di,return_code_af_move + call decode +;Show size + mov si,return_code_af_move + call printplain + popa + +end if + +} + + +macro move_up_fat_and_root_d +;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию +{ +local .st1 + + mov ax,info_real_mode_size + add ax,0x1000 + + mov si,table_15_87 + mov word [si+8*2+2],ax +;смещение до данных + mov ax,512 + mov word [si+8*3+2],ax +;fixme! тут необходимо сделать подержку т.е. формировать смещение файла в уже записанных данных. + + movzx ecx,word [fat12_buffer.BPB_FATSz16] + movzx bx,byte [fat12_buffer.BPB_NumFATs] + imul cx,bx ;9x1=9 + + add cx,size_root_dir ;размер корневой дирректории + shl ecx,9 ;imul 512 + + +;корректировка значения + test ecx,0x1 + jz .st1 + inc ecx +.st1: shr ecx,1 + + push es + push ds + pop es + + mov ah, 0x87 + int 0x15 + pop es + +if DEBUG + pusha +; mov ax,point_next_fat_str + mov cx,0x0a + mov di,return_code_af_fat_m + call decode +;Show size + mov si,return_code_af_fat_m + call printplain + popa + +end if + +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_err.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_err.inc new file mode 100644 index 000000000..380c90afc --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_err.inc @@ -0,0 +1,66 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +error: +.rest_value: + mov di,ax ;restore value after repe cmpsb + mov cx,bx + jmp ret_on_ch ;return + +;///// ошибка при находжении длинны секции в параметре default +.error_get_size_d_sect: + leave ;clear array in stack + mov si,not_found_def_sect + jmp err_show_ini + +;/////ERROR +.not_loader: + leave ;clear array in stack + mov si,not_found_sec_loader + jmp err_show_ini + +.default_eq_loader: ;критическая ошибка default секция = loader + leave + mov si,default_eq_loader + jmp err_show_ini +.correct_exit_bl: + leave + mov si,point_to_default_sec_not_found + jmp err_show_ini +.incorect_section_def: + leave + mov si,incorect_section_define + jmp err_show_ini +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;show message error +.LoaderModule: + push word 0xb800 + pop es + + + + + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_loader.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_loader.inc new file mode 100644 index 000000000..ed229d9d9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/parse_loader.inc @@ -0,0 +1,332 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +;блок макросов по обработке секции [loader] +;входные данные: +;es:di - указатель на секцию начинающиюся с '[' встечающиюся после 0хa +;cx - счетчик кол-во байт для проверке в кадре +; +macro use_parse_loader +{ +.parse_loader: +;////////////////// +;/ parse [loader] +;////////////////// + mov bx,cx ;cохраним в регистры значения счетчика и указателя + mov ax,di + +; mov word [bp-4],.start ;is alredy set, see up + mov si,parse_loader + mov cx,parse_loader_e - parse_loader + repe cmpsb + jnz error.rest_value ;цепочка не совпала :( перейдем далее т.е. будем снова искать)) + + ;сохраним указательна loader, что бы потом больше его не искать + mov point_loader,ax + sub bx,parse_loader_e - parse_loader ;correct cx + add bx,cx + mov cx,bx + +if DEBUG + pusha + mov si,lm_l_found + call printplain + popa +end if +;/////////////////end check [loader]. [loader] is found +;parsing section [loader] +;first found end section,let's found '[' -it's start next section +;in previosly steep bx =cx we are not need save cx, save only di - point + mov dx,di +@@: + call get_firs_sym + jcxz .loader_f_end ;.end_loader ; end даже если мы не нашли секцию предположим что секция [loader] стоит в конце + cmp al,'[' + jnz @b + +.loader_f_end: + sub bx,cx ;bx = n byte presend in section [loader] + mov di,dx ;restore di +;////////////////parse parametrs in section [loader] +;//timeout=5 +;//default=main +; mov di,dx ;set pointer on section [loader] i think it's not need + mov cx,bx ;set counter for parsing section [loader] cx= кол-ву символов в секции [loader] + mov ret_on_ch,.get_next_str ; return point +;;;;;;; parse timeout & default +.get_next_str: + call get_firs_sym ;get first symbol on new line + + test cx,cx + jz .end_loader +; jcxz .end_loader ;завершение парсинга значений timeout & default + cmp al,'t' + jz .loader_timeout + cmp al,'d' + jnz .get_next_str +;//////[loader].default +;input di point to data cx=size [loader] + mov bx,cx + mov ax,di + + mov si,parse_l_default + mov cx,parse_l_default_e - parse_l_default + repe cmpsb + + jnz error.rest_value ;is not compare цепочка не совпала + + sub bx,parse_l_default_e - parse_l_default ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_default + jz .correct_is_not_set + + mov si,found_equal_default ;мы нашли что флаг уже установлен, информируем + call printplain + jmp .get_next_str + +.correct_is_not_set: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + test cx,cx + jz .end_loader + + cmp ah,byte [es:di-1] ;find '=' + jnz .get_next_str + + repe scasb ;cut ' ' + inc cx + dec di +;сейчас es:di указывают на название секции, имя секции по дефолту не должно быть loader т.е. иначе возможно зацикливание +;установим указатель si на это значение и сначала проверим + +;получение длинны секции +; cx=bx содержит длинну остатка секции +; di=ax указатель на текущию секцию + mov bx,cx + mov dx,di + +@@: mov al,byte [es:di] + inc di + dec cx + test cx,cx + jz error.error_get_size_d_sect ;переход на обработку ошибки по нахождению длины дефолтной секции + cmp al,' ' + jz @b + cmp al,0xd + jz .found_size_d_sect + cmp al,0xa + jnz @b +.found_size_d_sect: +; + inc cx ;correct cx + mov ax,bx + sub bx,cx ; в bx длина секции которая определена по дефолту + mov save_cx_d,bx + mov di,dx + + mov cx,bx ;set size default section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;проверка на =loader +;save in reg point and счетчик +;check on loader + mov bx,ax + mov ax,dx + + mov si,parse_loader + inc si ;set only loader and 6 char in counter + repe cmpsb + jnz .check_section ;цепочка не совпала :( перейдем далее )) значит не исключение + + jmp error.default_eq_loader ;error критическая ошибка т.е. в дефолте присутствует имя [loader] + +.check_section: ;поиск соответствующей секции нам нужно будет узнать адрес этой секции + mov cx,bx + mov di,ax + +;///////////////////////////// +; mov ret_on_ch,.start_d ;set return + mov si,di ;установим указатель на нашу секцию, которая по дефолту + + push di ;save point di + + push cx ;save cx +;установим указатель es:di на начало ini файла + mov cx,save_cx ;it's placed size of ini file + les di,dword [file_data] + + + mov al,byte [es:di] + push word .first_ret_d + cmp al,' ' + jz .first_sp_1_d + jmp get_firs_sym.not_space +.first_sp_1_d: + jmp get_firs_sym.first_sp + +.start_d: + call get_firs_sym ;get first symbol on new line +.first_ret_d: ;первый возврат + jcxz .correct_exit ;.end_loader ;found or not found parametrs in section exit in section + cmp al,'[' + jz .found_sect_d + jmp .start_d +;просматриваем ini файл с начала в поисках секции указаной как default +;идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти +.found_sect_d: + +;check on name section + mov bx,cx + mov ax,di + push si ;save point + +; mov si,parse_loader + mov cx,save_cx_d ;load size section + push es + pop ds + + inc di + repe cmpsb + push cs + pop ds + pop si + + jnz .not_compare_d_s ;цепочка не совпала :( перейдем далее )) значит не исключение + cmp byte[es:di],']' + jnz .not_compare_d_s ;нет в конце нашей секции завершающего символа :( + + + +;set flag -we have found default -not enter again in this prosedure + or status_flag,flag_found_default + pop cx + pop di + mov point_default,ax ;point to [ + +if DEBUG + pusha + mov si,lm_lf_default_f + call printplain + popa +end if + + jmp .get_next_str + +.not_compare_d_s: + + mov cx,bx + mov di,ax + jmp .start_d + +.correct_exit: + pop cx ;восстановим значение счетчика + pop di + + +if DEBUG + pusha + mov si,lm_lf_default + call printplain + popa +end if + jmp .get_next_str + +;//////////[loader].timeout +.loader_timeout: + mov bx,cx + mov ax,di + + mov si,parse_l_timeout + mov cx,parse_l_timeout_e - parse_l_timeout + repe cmpsb + jnz error.rest_value ;is not compare + + sub bx,parse_l_timeout_e - parse_l_timeout ;correct cx + add bx,cx + mov cx,bx + + test status_flag,flag_found_timeout + jz .correct_is_not_set_t + + mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем + call printplain + jmp .get_next_str + +.correct_is_not_set_t: + mov ax,0x3d20 ;cut al=' ' ah='=' + repe scasb + jcxz .timeout_sec_end_d ;not found param timeout + + cmp ah,byte [es:di-1] ;find '=' + jnz .get_next_str + + repe scasb ;cut ' ' + inc cx + dec di +;get timeout value +;2 знакa может быть обработано т.е. значение от 0 до 99 секунд + push cx + xor bx,bx + mov cx,2 +@@: mov al,byte [es:di] + cmp al,'0' + jb .end_get_val_t + cmp al,'9' + ja .end_get_val_t + imul bx,10 + xor al,0x30 + add bl,al +.end_get_val_t: + inc di + loop @b + mov word [value_timeout],bx +; pop cx + +if DEBUG + pusha + mov si,lm_lf_timeout + call printplain + popa +end if + + jmp @f +.timeout_sec_end_d: + mov word [value_timeout],default_timeout_value + mov si,set_default_timeout_val + call printplain +@@: pop cx + jmp .get_next_str + +;///////here end block loader +.end_loader: +if DEBUG + pusha + mov si,lm_l_end + call printplain + popa +end if + +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_equ.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_equ.inc new file mode 100644 index 000000000..c19d2393a --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_equ.inc @@ -0,0 +1,98 @@ +; Copyright (c) 2008-2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** +; Предопределения +DEBUG equ 1 ;компиляция с отладочной информацией =1 без отладочной инфорации =0 +loop_read_startos_file equ 3 ;кол-во попыток считать через callback сервис файл конфигурации блок2 +root_dir_entry_count equ 224 ;кол-во элементов в корневой дирректории +;point_to_fat_struc equ 0xA000 ;временный буфер, куда будет размещена Fat таблица, и затем перенесена за 1 мб +ini_data_ equ 0x2000 ;файл где размещен файл сценария загрузки, там происходит синтаксический разбор +size_show_section equ 18 +default_timeout_value equ 5 ;default value to timeout is will was some errors +flag_found_default equ 0x1 ;default value is found +flag_found_timeout equ 0x2 ;timeout value is found +flag_found_LM equ 0x1 ;found LM value +flag_found_RS equ 0x2 ;found RS value +flag_found_GTRFMS equ 0x4 ;found type RamFS +flag_found_RamdiskSector equ 0x8 ;found RamdiskSector +flag_found_RamdiskCluster equ 0x16 ;found RamdiskCluster +;statick data эти данные не предопределяются в течении выполнения всей программы. +save_cx equ word [bp-2] ;save cx size ini file +ret_on_ch equ word [bp-4] ;point to return разрушаемое значение +save_cx_d equ word [bp-6] ;save cx - size default section and working section +status_flag equ word [bp-8] ;status flag +point_loader equ word [bp-10] +point_default equ word [bp-12] ;point to default + +;данные которые зависимы от ветки выполнения и которые могут быть переопределены в процессе выполнения программы. +point_to_hframe equ word [bp-14] ;point on start frame (for change section) +point_to_1 equ word [bp-16] +point_to_2 equ word [bp-18] +point_to_3 equ word [bp-20] +point_to_4 equ word [bp-22] +point_to_5 equ word [bp-24] +point_to_6 equ word [bp-26] +point_to_7 equ word [bp-28] +point_to_8 equ word [bp-30] +point_to_9 equ word [bp-32] +point_to_10 equ word [bp-34] +point_to_11 equ word [bp-36] +point_to_12 equ word [bp-38] +point_to_13 equ word [bp-40] +point_to_14 equ word [bp-42] +point_to_15 equ word [bp-44] +point_to_16 equ word [bp-46] +point_to_16 equ word [bp-48] +point_to_17 equ word [bp-50] +point_to_18 equ word [bp-52] +;here array for fast scroling 16 word - poin to start section +point_to_point_def equ word [bp-54] +point_to_eframe equ word [bp-56] ;point on point frame + + + +; тут расположено временное хранилище для cx и di при переходе на следующий буфер при поиске секций +find_sec_di equ word [bp-58] ;тут будет храниться di +info_real_mode_size equ word [bp-60];тут храниться информация о занятой области т.е. размер, можно узнать сколько осталось места вычислив +free_ad_memory equ word [bp-62] ;сколько у нас расширенной памяти для формирования рам диска и загрузки модулей +show_errors_sect equ word [bp-64] ;переменая которая хранит биты ошибок для каждой логической секции. +save_descript_size equ word [bp-66] ;save descript size previos section сохраним размер предыдущей секции которую выводили +save_ramdisksize equ dword [bp-70] ;save size of ramdisk in byte +save_file_size equ dword [bp-74] ;save size of reading file +set_ramfs equ word [bp-76] ;определенный тип файловой системы,нужно для формирования рам диска +point_next_fat_str equ word [bp-78] ;указатель на следующий элемент fat таблицы +size_root_dir equ word [bp-80] ;кол-во элементов в секторах по 512 байт корневой директории +firstDataSect equ word [bp-82] ;первый сектор данных в сеторах от 0 +DataClasters equ word [bp-84] ;размер массива доступной для записи данных в кластерах. +point_to_free_root equ word [bp-86] ;указатель на следующий пустую запись в рут дир +point_to_dest_file_name equ word [bp-88] ;указывает на начало имени файла назначения. в формате es:point_to_dest_file_name, где es =0x2000 +data_offset equ word [bp-90] ;смещение в кластерах для записанных данных т.е перекинутых за 1-й мб +first_input equ word [bp-92] ;поле для флагов в преобразовании имени. +save_di_RAMDISK equ word [bp-94] ;сохраним di -указателя при обработке секции +save_cx_RAMDISK equ word [bp-96] ;сохраним размер остатка секции +status_flag_loader_f equ word [bp-98] ;сохраним результат выполенения загрузки файла +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;данные которые используются при обработке секции, т.е. после нажатия Enter, уже не возможно вернуться в первоначальный экран +;для возврата, необходимо перезапустить полностью код т.е. стартовать с 0х1000:0000 diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_proc.inc b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_proc.inc new file mode 100644 index 000000000..d480e4399 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/sl_proc.inc @@ -0,0 +1,524 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; тут описываются процедуры которые используются в secondary loader +color_sym_black equ 0 +color_sym_blue equ 1 +color_sym_green equ 2 +color_sym_turquoise equ 3 +color_sym_red equ 4 + +color_sym_lightgray equ 7 + +color_sym_lightblue equ 9 +color_sym_lettuce equ 10 +color_sym_pink equ 12 +color_sym_yellow equ 14 +color_sym_white equ 15 +if DEBUG +decode: +;input eax - число, es:di куда писать, cx=10 + cmp eax,ecx + jb @f + xor edx,edx + div ecx + push edx + call decode + pop eax + @@: or al,0x30 + mov [ds:di],al + inc di + ret + +end if + + +putchar: +; in: al=character + mov ah, 0Eh + mov bh, 0 + int 10h + ret + +printplain: +; in: si->string + pushad + lodsb +@@: + call putchar + lodsb + test al,al + jnz @b + mov al,13 + call putchar + + mov al,10 + call putchar + popad + ret +getkey: +; get number in range [bl,bh] (bl,bh in ['0'..'9']) +; in: bx=range +; out: ax=digit (1..9, 10 for 0) + mov ah, 0 + int 16h + cmp al, bl + jb getkey + cmp al, bh + ja getkey + push ax + call putchar + pop ax + and ax, 0Fh + jnz @f + mov al, 10 +@@: + ret + +;setcursor: +; in: dl=column, dh=row +; mov ah, 2 +; mov bh, 0 +; int 10h +; ret + +;macro _setcursor row,column +;{ +; mov dx, row*256 + column +; call setcursor +;} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +get_firs_sym: +.start: + mov al,byte [es:di] + inc di + dec cx + jcxz .exit + + cmp al,0xa ;cmp al,0xa + jz ._entry + + cmp al,';' + jnz .start + +.first_com: + + mov al,0xa + repnz scasb + jcxz .exit +._entry: + mov al,byte [es:di] +.first_sp: + cmp al,' ' + jnz .not_space + +; mov al,' ' ;cut ' ' + repe scasb + dec di + inc cx + mov al,byte [es:di] +.not_space: + cmp al,';' + jz .first_com +.exit: ret +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +show_name_section: + push si + push ini_data_ + pop es + + + mov al,']' + repnz scasb + test cx,cx + jz error.incorect_section_def +.find_val_name_fb1: + mov al,'n' +.find_val_name_fb: + repnz scasb + jcxz .not_name_sec_fb + + mov si,parse_name + + push cx + push di + + mov cx,parse_name_e -parse_name + repe cmpsb + pop di + pop cx + jz .yaaa_find_value + + + jmp .find_val_name_fb + +.yaaa_find_value: + sub cx,parse_name_e -parse_name + add di,parse_name_e -parse_name + + mov ax,0x3d20 ; ah='=' + repe scasb + test cx,cx + jz .not_name_sec_fb + + cmp ah,byte [es:di-1] ;find '=' + jnz .find_val_name_fb1 + + repe scasb ;cut ' ' + inc cx + dec di + + +;все вырезали и все готово для вывода имени секции )) + push es + pop ds + +.def_sect_name: + push 0xb800 + pop es +;clear array for message + xor ax,ax +if DEBUG + mov ax,0x0720 +end if + + mov cx,39 + mov si,di + mov di,dx + sub di,2 + rep stosw +;////////////////////// + + + mov di,dx + mov ah,color_sym_white;color_sym_lightblue + mov cx,36 + lodsb + sub di,2 + cmp al,'"' + jz @f + cmp al,"'" + jnz .end_sh_name_sec +@@: lodsb +@@: + stosw + lodsb + cmp al,'"' + jz .end_sh_name_sec + cmp al,"'" + jz .end_sh_name_sec + loop @b + + mov al,'}' + mov ah,color_sym_yellow + stosw +.end_sh_name_sec: + push cs + pop ds + + pop si + ret + +.not_name_sec_fb: ;нет имени в названии секции - значит так и скажем об этом + push cs + pop ds + mov di,default_section_name + jmp .def_sect_name + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;процедура поиска вверх следующей секции +;в point_default содержиться указатель на дефаулт секцию, и в пределах врейма мы бегаем по заранее пропарсеными значениям указателей +;для того что бы отобразить и пропарсить следующий фрейм, нам нужно получить за пердыдущий или следующий указатель +find_before_sect: + mov di,point_default +.e: + push ini_data_ + pop es + mov cx,di ;предположим будем просматривать к началу, текущая позиция di = сколько символов от начала документа имеется + mov bx,cx ;копия + +;настроили указатель на дефаулт секцию +;будем искать вверх +.find_start_section: + std ;установка флага направления - будем просматирвать к началу нашего ини файла +;будем искать начало секции т.е. '[' этот символ + mov al,0xa + repnz scasb ;просканируем на наличее символа начала секции + jcxz .go_ ;мы просмотрели до начала файла, но так и ничего не нашли ;(( по тихому выйдем ) + + mov find_sec_di,di ;сохраним данные + mov cx,di ; + + sub bx,cx + mov cx,bx ;в сx значение - кол-во символов + cld + call get_firs_sym +.ret_go: + jcxz ._not_section ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее + + cmp di,point_loader ; секцию loader мы не заносим иначе крах + jz ._not_section +;все удачно мы нашли вхождение секции предыдущей + cmp al,'[' + jnz ._not_section + mov point_default,di +.exit_scan_sect: + ret +;;;;;;;; восстановим значения и продолжим поиски начала секции которая нас устроит )) +._not_section: + mov di,find_sec_di + mov cx,di + mov bx,cx + jmp .find_start_section +.go_: + cld + mov cx,bx ;в сx значение - кол-во символов + + mov al,byte [es:di] + push word .f_go + cmp al,' ' + jz @f + jmp get_firs_sym.not_space +@@: + jmp get_firs_sym.first_sp + +.f_go: + jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее + + cmp di,point_loader ; секцию loader мы не заносим иначе крах + jz .exit_scan_sect +;все удачно мы нашли вхождение секции предыдущей + cmp al,'[' + jnz .exit_scan_sect + mov point_default,di + ret + + + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +find_next_sect: + mov di,point_default + push ini_data_ + pop es + mov cx,save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется + sub cx,di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало + jmp .let_s_go +.h: + push ini_data_ + pop es + mov cx,save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется +; sub cx,di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало + + mov al,byte [es:di] + push word .let_s_go_ret + cmp al,' ' + jz @f + jmp get_firs_sym.not_space +@@: + jmp get_firs_sym.first_sp + + + + +;настроили указатель на дефаулт секцию +;будем искать вниз +.let_s_go: + call get_firs_sym +.let_s_go_ret: + jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее + cmp al,'[' + jnz .let_s_go + cmp di,point_loader + jz .let_s_go +;все удачно мы нашли вхождение секции предыдущей + mov point_default,di +.exit_scan_sect: + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;; +;clean old cursor +clean_active_cursor: +;не изменяет значение ax +;отображение курсора по умолчанию + lea si,point_to_hframe + mov di,962-160 + mov dx,point_default + mov cx,18 +.clean_show_cur: + mov bx,[si] + add di,160 + cmp bx,dx + jz .clean_cursor_ + sub si,2 + loop .clean_show_cur + +; jmp $ + +.clean_cursor_: + push 0xb800 + pop es + push ax + mov point_to_point_def,si + xor ax,ax +if DEBUG + mov ax,0x0720 +end if + stosw + add di,68 + stosw + pop ax + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;установка таймера и отображение счетчика времени +gettime: + mov ah,0 + int 1Ah + xchg ax, cx + shl eax, 10h + xchg ax, dx + ret +newtimer: + push ds + + push cs + pop ds + + pushf + call far dword [old_timer] + + pushad + call gettime + + sub eax, dword[start_timer] + mov bx, word [value_timeout] + imul bx,18 + sub bx, ax + jbe .timergo + + push es + + push 0xb800 + pop es + mov ax,bx + + mov bx, 18 + xor dx, dx + div bx + + mov bx,10 + mov di,3734 + call .decode + + xor ax,ax + stosw + +; wait 5/4/3/2 seconds, 1 second + pop es + popad + pop ds + + iret +.timergo: + push 0 + pop es + mov eax,dword [old_timer] + mov [es:8*4], eax + mov dword [timer_],eax + mov sp, word [start_stack] + mov bp,word [save_bp_from_timer] +;;не восстановленый стек :( + sti + jmp parse_start.parse_run_only + + +.decode: +;input ax - число, es:di куда писать, bx=10 + cmp ax,bx + jb @f + xor dx,dx + div bx + push dx + call .decode + pop ax + @@: or al,0x30 + push ax + mov ah,9 + stosw + pop ax + ret + +show_bl_sc_sect: +;1) отображение списка секций. Если секция не имет имя - ошибка - вывод Section unname +;проверка на наличее имени. +;входные данные es:di -указатель на секцию - cx размер секции +; push bp + mov bx,point_to_eframe + lea si,point_to_hframe + mov dx,966 + +.home_show_fb: + cmp si,bx + jb ._show_space_fb + mov di,[si] + sub si,2 + mov cx,[si] + sub cx,di ;home first section it's end before section + call show_name_section + add dx,160 + jmp .home_show_fb +._show_space_fb: + sub dx,4 + push 0xb800 + pop es +@@: + cmp dx,0xE64 + ja .exit_show_fb + mov di,dx +;clear array for message + xor ax,ax +if DEBUG + mov ax,0x0720 +end if + mov cx,39 + rep stosw +;////////////////////// + + add dx,160 + jmp @b +.exit_show_fb: +; pop bp + ret + diff --git a/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/startos.ini b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/startos.ini new file mode 100644 index 000000000..cb9c409e2 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sec_loader/trunk/startos.ini @@ -0,0 +1,98 @@ +; Copyright (c) 2009, +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''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 BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +; это комментарий + [loader] +; секция [loader] содержит параметры загрузчика +; в течение timeout секунд загрузчик будет ждать реакции пользователя, +; если её не последует, будет загружена конфигурация, указанная в default +timeout=5 + default=kolibri_EE +; прочие секции - по одной на каждую конфигурацию +; и по одной на каждый вторичный модуль +[main] +name="Kord OS v 0.00001" +descript="This is x64 OS microkernel" +kernel=kord/kord001.ker +module=kord/fat.mod +module=kord/ntfs.mod +RamdiskFS=fat +RamdiskSector=512 +RamdiskCluster=1 +RamdiskSize=1440K +RamdiskFile=kord/launcher,launcher +RamdiskFile=kord/filema~1/kfar,"File Managers/kfar" +[beta] +name="Kord OS v 0.00002 beta" +descript="This is x64 OS microkernel version 2" +kernel=kord/kord002.ker +module=kord/fat.mod +module=kord/ntfs.mod +RamdiskFS=fat +RamdiskSector=512 +RamdiskCluster=1 +RamdiskSize=1440K +RamdiskFile=kord/launcher,launcher +RamdiskFile=kord/filema~1/kfar,"File Managers/kfar" +[kolibri_EE] +name="KOLIBRY EXCLUSIVE EDITION" +descript="KOLIBRY EXCLUSIVE EDITION BEST OF THE BEST opetation system" +LoaderModule=kolibri/kolibri.ldm +RamdiskFS=FAT +RamdiskSector=512 +RamdiskCluster=1 +RamdiskSize=1440K +LoaderRamImage=kolibri.img +RamdiskPATH=/kolibri/ +RamdiskFile=@menu,@menu +RamdiskFile=@PANEL,@PANEL +RamdiskFile=@RB,@PANEL + +[legacy_kolibri] +name="KolibriOS" +descript="Standart KolibriOS" +LoaderModule=kord/kolibri.ldm +RamdiskFS=fat +RamdiskSector=512 +RamdiskCluster=1 +RamdiskSize=1440K +RamdiskPATH=/kolibri/ +RamdiskFile=@menu,@menu +RamdiskFile=@PANEL,@PANEL +RamdiskFile=@RB,@RB +RamdiskFile=@rcher,@rcher +RamdiskFile=@ss,@ss +RamdiskFile=ac97snd,ac97snd +RamdiskFile=animage,animage +RamdiskFile=AUTOEXEC.CMD,AUTOEXEC.CMD +RamdiskFile=AUTORUN.DAT,AUTORUN.DAT +RamdiskFile=calc,calc +RamdiskFile=calendar,calendar +RamdiskFile=progs/cdp,cdp +RamdiskFile=cmd,cmd +RamdiskFile=config.inc,config.inc +RamdiskFile=copy2,copy2 + diff --git a/kernel/tags/kolibri0.7.7.0/skin/base.bmp b/kernel/tags/kolibri0.7.7.0/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/tags/kolibri0.7.7.0/skin/base_1.bmp b/kernel/tags/kolibri0.7.7.0/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/tags/kolibri0.7.7.0/skin/default.asm b/kernel/tags/kolibri0.7.7.0/skin/default.asm new file mode 100644 index 000000000..88c6f15f1 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/skin/default.asm @@ -0,0 +1,38 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +include 'me_skin.inc' + +SKIN_PARAMS \ + height = bmp_base.height,\ ; skin height + margins = [5:1:43:1],\ ; margins [left:top:right:bottom] + colors active = [binner=0x00081d:\ ; border inner color + bouter=0x00081d:\ ; border outer color + bframe=0x0054e7],\ ; border frame color + colors inactive = [binner=0x00081d:\ ; border inner color + bouter=0x00081d:\ ; border outer color + bframe=0x1a8acc],\ ; border frame color + dtp = 'myblue.dtp' ; dtp colors + +SKIN_BUTTONS \ + close = [-21:3][16:16],\ ; buttons coordinates + minimize = [-39:3][16:16] ; [left:top][width:height] + +SKIN_BITMAPS \ + left active = bmp_left,\ ; skin bitmaps pointers + left inactive = bmp_left1,\ + oper active = bmp_oper,\ + oper inactive = bmp_oper1,\ + base active = bmp_base,\ + base inactive = bmp_base1 + +BITMAP bmp_left ,'left.bmp' ; skin bitmaps +BITMAP bmp_oper ,'oper.bmp' +BITMAP bmp_base ,'base.bmp' +BITMAP bmp_left1,'left_1.bmp' +BITMAP bmp_oper1,'oper_1.bmp' +BITMAP bmp_base1,'base_1.bmp' diff --git a/kernel/tags/kolibri0.7.7.0/skin/left.bmp b/kernel/tags/kolibri0.7.7.0/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/tags/kolibri0.7.7.0/skin/me_skin.inc b/kernel/tags/kolibri0.7.7.0/skin/me_skin.inc new file mode 100644 index 000000000..365964eb3 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/skin/me_skin.inc @@ -0,0 +1,242 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;============================================================================ +; This file should be used to generate skins of new standard +;============================================================================ +; skin file structure: +;---------------------------------------------------------------------------- +; header: +; dd 'SKIN' +; dd = version (1 for now) +; dd @ params +; dd @ buttons +; dd @ bitmaps +; ... +;---------------------------------------------------------------------------- +; NOTE: order of sections listed below is insignificant +; since they're identified by pointer in above header +;---------------------------------------------------------------------------- +; ... +; params: +; dd = skin height +; dw = right margin +; dw = left margin +; dw = bottom margin +; dw = top margin +; dd = inner line color +; dd = outer line color +; dd = frame color +; dd = dtp file size +; ?? = dtp file itself +; ... +;---------------------------------------------------------------------------- +; ... +; buttons: +; dd = button type (1 = close, 2 = minimize) +; dw = left button coord (could be negative) +; dw = top button coord (could be negative) +; dw = button width +; dw = button height +; ... etc for all buttons +; dd = 0 (end of buttons list) +; ... +;---------------------------------------------------------------------------- +; ... +; bitmaps: +; dw = bitmap kind (1 = left, 2 = oper, 3 = base) +; dw = bitmap type (1 = active, 0 = inactive) +; dd @ bitmap +; ... etc for all bitmaps +; dd 0 (end of bitmaps list) +; ... +;---------------------------------------------------------------------------- +; ... +; bitmap: +; dd = bitmap width +; dd = bitmap height +; ?? = raw bitmap data +; ... etc for all bitmaps +; ... +;============================================================================ + +dd 'SKIN',1,__params__,__buttons__,__bitmaps__ + +struc BITMAPFILEHEADER { + .bfType dw ? ; WORD + .bfSize dd ? ; DWORD + .bfReserved1 dw ? ; WORD + .bfReserved2 dw ? ; WORD + .bfOffBits dd ? ; DWORD +} + +struc BITMAPINFOHEADER { + .biSize dd ? ; DWORD + .biWidth dd ? ; LONG + .biHeight dd ? ; LONG + .biPlanes dw ? ; WORD + .biBitCount dw ? ; WORD + .biCompression dd ? ; DWORD + .biSizeImage dd ? ; DWORD + .biXPelsPerMeter dd ? ; LONG + .biYPelsPerMeter dd ? ; LONG + .biClrUsed dd ? ; DWORD + .biClrImportant dd ? ; DWORD +} + +struc _bmp { + .h BITMAPFILEHEADER + .i BITMAPINFOHEADER +} +virtual at 0 + _bmp _bmp +end virtual + +macro BITMAP _name*,_fname* +{ + local w,h,a,r,g,b + virtual at 0 + file _fname + load w dword from _bmp.i.biWidth + load h dword from _bmp.i.biHeight + end virtual + align 4 + label _name + .width = w + .height = h + dd w,h + a=54+(w*3+(w mod 4))*(h-1) + size = $ + repeat h + repeat w + virtual at 0 + file _fname + load r from a+0 + load g from a+1 + load b from a+2 + end virtual + db r,g,b + a=a+3 + end repeat + a=a-w*3*2-(w mod 4) + end repeat +} + +macro define_colors name,[col,val] +{ + common + local a,b,c + forward + match =binner,col \{ a = val \} + match =bouter,col \{ b = val \} + match =bframe,col \{ c = val \} + common + name equ a,b,c +} + +macro SKIN_PARAMS [a] +{ + common + local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz + __params__: + forward + match qq == ww,a + \{ + match =height,qq \\{ _height = ww \\} + match =margins,qq \\{ + match [q1:q2:q3:q4],ww + \\\{ + _margins equ q3,q1,q4,q2 + \\\} + \\} + match =colors =active,qq + \\{ + match [q10==q11:q20==q21:q30==q31],ww + \\\{ + define_colors _colors,q10,q11,q20,q21,q30,q31 + \\\} + \\} + match =colors =inactive,qq + \\{ + match [q10==q11:q20==q21:q30==q31],ww + \\\{ + define_colors _colors_1,q10,q11,q20,q21,q30,q31 + \\\} + \\} + match =dtp,qq \\{ _dtp equ ww \\} + \} + common + dd _height + dw _margins + dd _colors,_colors_1 + virtual at 0 + file _dtp + _dtp_sz = $ + end virtual + dd _dtp_sz + file _dtp +} + +macro SKIN_BUTTONS [a] +{ + common + local btn + __buttons__: + forward + match qq == ww,a + \{ + btn = 0 + match =close,qq \\{ btn = 1 \\} + match =minimize,qq \\{ btn = 2 \\} + match [q1:q2][q3:q4],ww + \\{ + if btn <> 0 + dd btn + dw q1,q2,q3,q4 + end if + \\} + \} + common + dd 0 +} + +macro SKIN_BITMAPS [a] +{ + common + local bmp + __bitmaps__: + forward + match qq == ww,a + \{ + bmp=-1 + match qqq =active,qq \\{ bmp = 1 \\} + match qqq =inactive,qq \\{ bmp = 0 \\} + match =left qqq,qq + \\{ + if bmp >= 0 + dw 1,bmp + dd ww + end if + \\} + match =oper qqq,qq + \\{ + if bmp >= 0 + dw 2,bmp + dd ww + end if + \\} + match =base qqq,qq + \\{ + if bmp >= 0 + dw 3,bmp + dd ww + end if + \\} + \} + common + dd 0 +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.7.7.0/skin/myblue.dtp b/kernel/tags/kolibri0.7.7.0/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/tags/kolibri0.7.7.0/skin/oper.bmp b/kernel/tags/kolibri0.7.7.0/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/tags/kolibri0.7.7.0/skin/oper_1.bmp b/kernel/tags/kolibri0.7.7.0/skin/oper_1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d57bd2d161f9f2364bbb199d087b9f28142bef8d GIT binary patch literal 2694 zcmchZy-Nc@5XH|T{43TJT{S$n-mki6~;4UlN^6oJ^JMVtCDa6rs>lx#k7cHxP{`Q*=A-YkuJ^zo@thEjJY|Q*=A-`_U5ADVHg_9rxpS8B$zq)iSS) zBc|wf+{#J1a+=1g>>- SIMPLY - QUICKLY - SHORTLY -<<< ;; +;; ;; +;; Note: playnote.txt ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +align 4 +sound_interface: + + cmp eax, edi ; this is subfunction #55 ? + jne retFunc55 ; if no then return. + + cmp byte [sound_flag],0 + jne retFunc55 + + movzx eax, byte [countDelayNote] + or al, al ; player is busy ? + jnz retFunc55 ; return counter delay Note + + mov [memAdrNote],edx + call get_pid + mov [pidProcessNote],eax + xor eax, eax ; Ok! EAX = 0 + retFunc55: + mov [esp+36], eax ; return value EAX for application + ret + +iglobal +align 4 + kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562 + dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF + memAdrNote dd 0 + pidProcessNote dd 0 + slotProcessNote dd 0 + count_timer_Note dd 1 + mem8253r42 dw 0 + countDelayNote db 0 +endg + +playNote: +; jmp NotPlayNotes + mov esi, [memAdrNote] + or esi, esi ; ESI = 0 ? - OFF Notes Play ? + jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure + cmp eax, [count_timer_Note] + jb NotPlayNotes + push eax + inc eax + mov [count_timer_Note], eax + mov al, [countDelayNote] + dec al ; decrement counter Delay for Playing Note + jz NewLoadNote@Delay + cmp al, 0xFF ; this is first Note Play ? + jne NextDelayNote + ;This is FIRST Note, save counter channel 2 chip 8253 + mov al, 0xB6 ; control byte to timer chip 8253 + out 0x43, al ; Send it to the control port chip 8253 + in al, 0x42 ; Read Lower byte counter channel 2 chip 8253 + mov ah, al ; AH = Lower byte counter channel 2 + in al, 0x42 ; Read Upper byte counter channel 2 chip 8253 + mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253 + NewLoadNote@Delay: + cld +; lodsb ; load AL - counter Delay + call ReadNoteByte + or al, al ; THE END ? + jz EndPlayNote + cmp al, 0x81 + jnc NoteforOctave + mov [countDelayNote], al +; lodsw ; load AX - counter for Note! + call ReadNoteByte + mov ah,al + call ReadNoteByte + xchg al,ah + jmp pokeNote + + EndPlayNote: ; THE END Play Notes! + in al, 0x61 ; Get contents of system port B chip 8255 + and al, 0xFC ; Turn OFF timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253 + xchg al, ah ; reverse byte in word + out 0x42, al ; restore Lower byte counter channel 2 + mov al, ah ; AL = Upper byte counter channel 2 + out 0x42, al ; restore Upper byte channel 2 + xor eax, eax ; EAX = 0 + mov [memAdrNote], eax ; clear header control Delay-Note string + NextDelayNote: + mov [countDelayNote], al ; save new counter delay Note + pop eax + NotPlayNotes: + RET + + NoteforOctave: + sub al, 0x81 ; correction value for delay Note + mov [countDelayNote], al ; save counter delay this new Note +; lodsb ; load pack control code + call ReadNoteByte + cmp al, 0xFF ; this is PAUSE ? + jne packCode ; no, this is PACK CODE + in al, 0x61 ; Get contents of system port B chip 8255 + and al, 0xFC ; Turn OFF timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + jmp saveESI + + packCode: + mov cl, al ; save code + and al, 0xF ; clear upper bits + dec al ; correction + add al, al ; transform number to offset constant + movsx eax, al ; EAX - offset + add eax, dword kontrOctave ; EAX - address from constant + mov ax, [eax] ; read constant + shr cl, 4 ; transform for number Octave + shr ax, cl ; calculate from Note this Octave! + pokeNote: + out 0x42, al ; Lower byte Out to channel 2 timer chip 8253 + mov al, ah + out 0x42, al ; Upper byte Out to channel 2 timer chip 8253 + in al, 0x61 ; Get contents of system port B chip 8255 + or al, 3 ; Turn ON timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + saveESI: +; mov [memAdrNote], esi ; save new header control Delay-Note string + pop eax + RET +ReadNoteByte: +;result: +; al - note + push eax + push ebx + push ecx + push edx + mov eax,[pidProcessNote] + call pid_to_slot + test eax,eax + jz .failed + lea ebx,[esp+12] + mov ecx,1 + mov edx,[memAdrNote] + inc [memAdrNote] + call read_process_memory +.failed: + pop edx + pop ecx + pop ebx + pop eax + ret +;------------------- END CODE ------------------- diff --git a/kernel/tags/kolibri0.7.7.0/sys.conf b/kernel/tags/kolibri0.7.7.0/sys.conf new file mode 100644 index 000000000..64a0dc295 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/sys.conf @@ -0,0 +1,18 @@ +[path] +/rd/1=/sys +/rd/1/dll=/sys/lib + +[net] +active=1 +addr=192.168.1.2 +mask=255.255.255.0 +gate=192.168.1.1 + +[gui] +mouse_speed=1 +mouse_delay=0x00A + +[dev] +sb16=0x220 +sound_dma=1 +midibase=0x320 diff --git a/kernel/tags/kolibri0.7.7.0/unpacker.inc b/kernel/tags/kolibri0.7.7.0/unpacker.inc new file mode 100644 index 000000000..5e70709f9 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/unpacker.inc @@ -0,0 +1,527 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; void __stdcall unpack(void* packed_data, void* unpacked_data); +unpack: + pushad + mov esi, [esp+32+4] + mov edi, [esp+32+8] + mov eax, [esi+8] + and al, 0xC0 + cmp al, 0xC0 + jz .failed + mov eax, [esi+8] + push eax + add esi, 12 + and al, not 0xC0 + dec eax + jz .lzma +.failed: + pop eax + popad + ret 8 +.lzma: + call .lzma_unpack +.common: + pop eax + test al, 0x80 + jnz .ctr1 + test al, 0x40 + jz .ok + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c1: + lodsb + sub al, 0E8h + cmp al, 1 + ja .c1 + cmp byte [esi], dl + jnz .c1 + lodsd +; "bswap eax" is not supported on i386 + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c1 +.ok: + popad + ret 8 +.ctr1: + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c2: + lodsb +@@: + cmp al, 0xF + jnz .f + lodsb + cmp al, 80h + jb @b + cmp al, 90h + jb @f +.f: + sub al, 0E8h + cmp al, 1 + ja .c2 +@@: + cmp byte [esi], dl + jnz .c2 + lodsd + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c2 + jmp .ok + +.lzma_unpack: + +.pb = 2 ; pos state bits +.lp = 0 ; literal pos state bits +.lc = 3 ; literal context bits +.posStateMask = ((1 shl .pb)-1) +.literalPosMask = ((1 shl .lp)-1) + +.kNumPosBitsMax = 4 +.kNumPosStatesMax = (1 shl .kNumPosBitsMax) + +.kLenNumLowBits = 3 +.kLenNumLowSymbols = (1 shl .kLenNumLowBits) +.kLenNumMidBits = 3 +.kLenNumMidSymbols = (1 shl .kLenNumMidBits) +.kLenNumHighBits = 8 +.kLenNumHighSymbols = (1 shl .kLenNumHighBits) + +.LenChoice = 0 +.LenChoice2 = 1 +.LenLow = 2 +.LenMid = (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits)) +.LenHigh = (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits)) +.kNumLenProbs = (.LenHigh + .kLenNumHighSymbols) + +.kNumStates = 12 +.kNumLitStates = 7 +.kStartPosModelIndex = 4 +.kEndPosModelIndex = 14 +.kNumFullDistances = (1 shl (.kEndPosModelIndex/2)) +.kNumPosSlotBits = 6 +.kNumLenToPosStates = 4 +.kNumAlignBits = 4 +.kAlignTableSize = (1 shl .kNumAlignBits) +.kMatchMinLen = 2 + +.IsMatch = 0 +.IsRep = (.IsMatch + (.kNumStates shl .kNumPosBitsMax)) +.IsRepG0 = (.IsRep + .kNumStates) +.IsRepG1 = (.IsRepG0 + .kNumStates) +.IsRepG2 = (.IsRepG1 + .kNumStates) +.IsRep0Long = (.IsRepG2 + .kNumStates) +.PosSlot = (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax)) +.SpecPos = (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits)) +.Align_ = (.SpecPos + .kNumFullDistances - .kEndPosModelIndex) +.Lencoder = (.Align_ + .kAlignTableSize) +.RepLencoder = (.Lencoder + .kNumLenProbs) +.Literal = (.RepLencoder + .kNumLenProbs) + +.LZMA_BASE_SIZE = 1846 ; must be ==Literal +.LZMA_LIT_SIZE = 768 + +.kNumTopBits = 24 +.kTopValue = (1 shl .kNumTopBits) + +.kNumBitModelTotalBits = 11 +.kBitModelTotal = (1 shl .kNumBitModelTotalBits) +.kNumMoveBits = 5 + + push edi +; int state=0; + xor ebx, ebx + mov [.previousByte], bl +; unsigned rep0=1,rep1=1,rep2=1,rep3=1; + mov eax, 1 + mov edi, .rep0 + stosd + stosd + stosd + stosd +; int len=0; +; result=0; + mov ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp)) + mov eax, .kBitModelTotal/2 + mov edi, [.p] + rep stosd +; RangeDecoderInit +; rd->ExtraBytes = 0 +; rd->Buffer = stream +; rd->BufferLim = stream+bufferSize +; rd->Range = 0xFFFFFFFF + pop edi + mov ebp, [esi-8] ; dest_length + add ebp, edi ; ebp = destination limit + lodsd +; rd->code_ = eax + mov [.code_], eax + or [.range], -1 +.main_loop: + cmp edi, ebp + jae .main_loop_done + mov edx, edi + and edx, .posStateMask + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.IsMatch*4 + eax + edx*4] + add eax, [.p] + call .RangeDecoderBitDecode + jc .1 + movzx eax, [.previousByte] +if .literalPosMask + mov ah, dl + and ah, .literalPosMask +end if + shr eax, 8-.lc + imul eax, .LZMA_LIT_SIZE*4 + add eax, .Literal*4 + add eax, [.p] + cmp ebx, .kNumLitStates + jb .literal + xor edx, edx + sub edx, [.rep0] + mov dl, [edi + edx] + call .LzmaLiteralDecodeMatch + jmp @f +.literal: + call .LzmaLiteralDecode +@@: + mov [.previousByte], al + stosb + mov al, bl + cmp bl, 4 + jb @f + mov al, 3 + cmp bl, 10 + jb @f + mov al, 6 +@@: sub bl, al + jmp .main_loop +.1: + lea eax, [.IsRep*4 + ebx*4] + add eax, [.p] + call .RangeDecoderBitDecode + jnc .10 + lea eax, [.IsRepG0*4 + ebx*4] + add eax, [.p] + call .RangeDecoderBitDecode + jc .111 + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.IsRep0Long*4 + eax + edx*4] + add eax, [.p] + call .RangeDecoderBitDecode + jc .1101 + cmp bl, 7 + setae bl + lea ebx, [9 + ebx + ebx] + xor edx, edx + sub edx, [.rep0] + mov al, [edi + edx] + stosb + mov [.previousByte], al + jmp .main_loop +.111: + lea eax, [.IsRepG1*4 + ebx*4] + add eax, [.p] + call .RangeDecoderBitDecode + mov eax, [.rep1] + jnc .l3 +.l1: + lea eax, [.IsRepG2*4 + ebx*4] + add eax, [.p] + call .RangeDecoderBitDecode + mov eax, [.rep2] + jnc .l2 + xchg [.rep3], eax +.l2: + push [.rep1] + pop [.rep2] +.l3: + xchg eax, [.rep0] + mov [.rep1], eax +.1101: + mov eax, .RepLencoder*4 + add eax, [.p] + call .LzmaLenDecode + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 8 + jmp .repmovsb +.10: + mov eax, [.rep0] + xchg eax, [.rep1] + xchg eax, [.rep2] + xchg eax, [.rep3] + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 7 + mov eax, .Lencoder*4 + add eax, [.p] + call .LzmaLenDecode + mov eax, .kNumLenToPosStates-1 + cmp eax, ecx + jb @f + mov eax, ecx +@@: + push ecx + mov ecx, .kNumPosSlotBits + shl eax, cl + shl eax, 2 + add eax, .PosSlot*4 + add eax, [.p] + call .RangeDecoderBitTreeDecode + mov [.rep0], ecx + cmp ecx, .kStartPosModelIndex + jb .l6 + push ecx + mov eax, ecx + and eax, 1 + shr ecx, 1 + or eax, 2 + dec ecx + shl eax, cl + mov [.rep0], eax + pop edx + cmp edx, .kEndPosModelIndex + jae .l5 + sub eax, edx + shl eax, 2 + add eax, (.SpecPos - 1)*4 + add eax, [.p] + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx + jmp .l6 +.l5: + sub ecx, .kNumAlignBits + call .RangeDecoderDecodeDirectBits + mov ecx, .kNumAlignBits + shl eax, cl + add [.rep0], eax + mov eax, .Align_*4 + add eax, [.p] + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx +.l6: + pop ecx + inc [.rep0] + jz .main_loop_done +.repmovsb: + add ecx, .kMatchMinLen + push esi + mov esi, edi + sub esi, [.rep0] + rep movsb + pop esi + mov al, [edi-1] + mov [.previousByte], al + jmp .main_loop +.main_loop_done: + ret + +.RangeDecoderBitDecode: +; in: eax->prob +; out: CF=bit; destroys eax + push edx + mov edx, [.range] + shr edx, .kNumBitModelTotalBits + imul edx, [eax] + cmp [.code_], edx + jae .ae + mov [.range], edx + mov edx, .kBitModelTotal + sub edx, [eax] + shr edx, .kNumMoveBits + add [eax], edx + clc +.n: + lahf + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + lodsb + mov byte [.code_], al +@@: + sahf + pop edx + ret +.ae: + sub [.range], edx + sub [.code_], edx + mov edx, [eax] + shr edx, .kNumMoveBits + sub [eax], edx + stc + jmp .n + +.RangeDecoderDecodeDirectBits: +; in: ecx=numTotalBits +; out: eax=result; destroys edx + xor eax, eax +.l: + shr [.range], 1 + shl eax, 1 + mov edx, [.code_] + sub edx, [.range] + jb @f + mov [.code_], edx + or eax, 1 +@@: + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + push eax + lodsb + mov byte [.code_], al + pop eax +@@: + loop .l + ret + +.LzmaLiteralDecode: +; in: eax->probs +; out: al=byte; destroys edx + push ecx + mov ecx, 1 +@@: + push eax + lea eax, [eax+ecx*4] + call .RangeDecoderBitDecode + pop eax + adc cl, cl + jnc @b +.LzmaLiteralDecode.ret: + mov al, cl + pop ecx + ret +.LzmaLiteralDecodeMatch: +; in: eax->probs, dl=matchByte +; out: al=byte; destroys edx + push ecx + mov ecx, 1 +.LzmaLiteralDecodeMatch.1: + add dl, dl + setc ch + push eax + lea eax, [eax+ecx*4+0x100*4] + call .RangeDecoderBitDecode + pop eax + adc cl, cl + jc .LzmaLiteralDecode.ret + xor ch, cl + test ch, 1 + mov ch, 0 + jnz @b + jmp .LzmaLiteralDecodeMatch.1 + +.LzmaLenDecode: +; in: eax->prob, edx=posState +; out: ecx=len + push eax + add eax, .LenChoice*4 + call .RangeDecoderBitDecode + pop eax + jnc .0 + push eax + add eax, .LenChoice2*4 + call .RangeDecoderBitDecode + pop eax + jc @f + mov ecx, .kLenNumMidBits + shl edx, cl + lea eax, [eax + .LenMid*4 + edx*4] + call .RangeDecoderBitTreeDecode + add ecx, .kLenNumLowSymbols + ret +@@: + add eax, .LenHigh*4 + mov ecx, .kLenNumHighBits + call .RangeDecoderBitTreeDecode + add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols + ret +.0: + mov ecx, .kLenNumLowBits + shl edx, cl + lea eax, [eax + .LenLow*4 + edx*4] +.RangeDecoderBitTreeDecode: +; in: eax->probs,ecx=numLevels +; out: ecx=length; destroys edx + push ebx + mov edx, 1 + mov ebx, edx +@@: + push eax + lea eax, [eax+edx*4] + call .RangeDecoderBitDecode + pop eax + adc dl, dl + add bl, bl + loop @b + sub dl, bl + pop ebx + mov ecx, edx + ret +.RangeDecoderReverseBitTreeDecode: +; in: eax->probs,ecx=numLevels +; out: ecx=length; destroys edx + push ebx ecx + mov edx, 1 + xor ebx, ebx +@@: + push eax + lea eax, [eax+edx*4] + call .RangeDecoderBitDecode + lahf + adc edx, edx + sahf + rcr ebx, 1 + pop eax + loop @b + pop ecx + rol ebx, cl + mov ecx, ebx + pop ebx + ret + +uglobal +align 4 +;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) +unpack.p dd ? +unpack.code_ dd ? +unpack.range dd ? +unpack.rep0 dd ? +unpack.rep1 dd ? +unpack.rep2 dd ? +unpack.rep3 dd ? +unpack.previousByte db ? +endg diff --git a/kernel/tags/kolibri0.7.7.0/video/arrow.cur b/kernel/tags/kolibri0.7.7.0/video/arrow.cur new file mode 100644 index 0000000000000000000000000000000000000000..eb7ceebab42876bb81952edc1428d93218d4b15c GIT binary patch literal 766 zcmeH_Jr06E5QQITg56TtLg^9g@JMu)?hU*W$Fa1-!esoGpJazvSv&CU%$v86&19ug zh1#}Oibp9O$tP&x0)_UhQp8(h-o2`bNgd;ySSd9O134Ksy)sJ`@T68+{&C%mzzwC+ zVa)x|ho{ryy?5Gdt1bUQVCeY x2 ? + mov edx, ebp ; else (if x1=x2) + call vline + push edx ; necessary to rightly restore stack frame at .exit + jmp .exit +.x2lx1: + neg esi ; get esi absolute value +.no_vline: +; checking y-axis... + sub ebp, ebx ; ebp = y2-y1 + push ebp ; save y2-y1 + jl .y2ly1 ; is y2 less than y1 ? + jg .no_hline ; y1 > y2 ? + mov edx, [dl_x2] ; else (if y1=y2) + call hline + jmp .exit + +.y2ly1: + neg ebp ; get ebp absolute value +.no_hline: + cmp ebp, esi + jle .x_rules ; |y2-y1| < |x2-x1| ? + cmp [dl_y2], ebx ; make sure y1 is at the begining + jge .no_reverse1 + neg dword [dl_dx] + mov edx, [dl_x2] + mov [dl_x2], eax + mov [dl_x1], edx + mov edx, [dl_y2] + mov [dl_y2], ebx + mov [dl_y1], edx +.no_reverse1: + mov eax, [dl_dx] + cdq ; extend eax sing to edx + shl eax, 16 ; using 16bit fix-point maths + idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) + mov edx, ebp ; edx = counter (number of pixels to draw) + mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0 + mov esi, eax ; esi = dx + jmp .y_rules + +.x_rules: + cmp [dl_x2], eax ; make sure x1 is at the begining + jge .no_reverse2 + neg dword [dl_dy] + mov edx, [dl_x2] + mov [dl_x2], eax + mov [dl_x1], edx + mov edx, [dl_y2] + mov [dl_y2], ebx + mov [dl_y1], edx +.no_reverse2: + xor edx, edx + mov eax, [dl_dy] + cdq ; extend eax sing to edx + shl eax, 16 ; using 16bit fix-point maths + idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) + mov edx, esi ; edx = counter (number of pixels to draw) + mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0 + mov ebp, eax ; ebp = dy +.y_rules: + mov eax, [dl_x1] + mov ebx, [dl_y1] + shl eax, 16 + shl ebx, 16 +align 4 +.draw: + push eax ebx + shr eax, 16 + shr ebx, 16 + call [putpixel] + pop ebx eax + add ebx, ebp ; y = y+dy + add eax, esi ; x = x+dx + dec edx + jnz .draw +; force last drawn pixel to be at (x2,y2) + mov eax, [dl_x2] + mov ebx, [dl_y2] + call [putpixel] +.exit: + add esp, 6*4 + popa +; dec [mouse_pause] + call [draw_pointer] + ret + + +hline: +; draw an horizontal line +; eax = x1 +; edx = x2 +; ebx = y +; ecx = color +; edi = force ? + push eax edx + cmp edx, eax ; make sure x2 is above x1 + jge @f + xchg eax, edx +align 4 +@@: + call [putpixel] + inc eax + cmp eax, edx + jle @b + pop edx eax + ret + + +vline: +; draw a vertical line +; eax = x +; ebx = y1 +; edx = y2 +; ecx = color +; edi = force ? + push ebx edx + cmp edx, ebx ; make sure y2 is above y1 + jge @f + xchg ebx, edx +align 4 +@@: + call [putpixel] + inc ebx + cmp ebx, edx + jle @b + pop edx ebx + ret + + +;************************************************* + + +virtual at esp +drbar: + .bar_sx dd ? + .bar_sy dd ? + .bar_cx dd ? + .bar_cy dd ? + .abs_cx dd ? + .abs_cy dd ? + .real_sx dd ? + .real_sy dd ? + .color dd ? + .line_inc_scr dd ? + .line_inc_map dd ? + .stack_data = 4*11 +end virtual + +align 4 +; eax cx +; ebx cy +; ecx xe +; edx ye +; edi color +vesa20_drawbar: + pushad + call [_display.disable_mouse] + sub esp, drbar.stack_data + mov [drbar.color], edi + sub edx, ebx + jle .exit ;// mike.dld, 2005-01-29 + sub ecx, eax + jle .exit ;// mike.dld, 2005-01-29 + mov [drbar.bar_sy], edx + mov [drbar.bar_sx], ecx + mov [drbar.bar_cx], eax + mov [drbar.bar_cy], ebx + mov edi, [TASK_BASE] + add eax, [edi-twdw + WDATA.box.left] ; win_cx + add ebx, [edi-twdw + WDATA.box.top] ; win_cy + mov [drbar.abs_cx], eax + mov [drbar.abs_cy], ebx +; real_sx = MIN(wnd_sx-bar_cx, bar_sx); + mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] + sub ebx, [drbar.bar_cx] + ja @f +.exit: ;// mike.dld, 2005-01-29 + add esp, drbar.stack_data + popad + xor eax, eax + inc eax + ret +@@: + cmp ebx, [drbar.bar_sx] + jbe .end_x + mov ebx, [drbar.bar_sx] +.end_x: + mov [drbar.real_sx], ebx +; real_sy = MIN(wnd_sy-bar_cy, bar_sy); + mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond} + sub ebx, [drbar.bar_cy] + ja @f + add esp, drbar.stack_data + popad + xor eax, eax + inc eax + ret +@@: + cmp ebx, [drbar.bar_sy] + jbe .end_y + mov ebx, [drbar.bar_sy] +.end_y: + mov [drbar.real_sy], ebx +; line_inc_map + mov eax, [Screen_Max_X] + sub eax, [drbar.real_sx] + inc eax + mov [drbar.line_inc_map], eax +; line_inc_scr + mov eax, [drbar.real_sx] + movzx ebx, byte [ScreenBPP] + shr ebx, 3 + imul eax, ebx + neg eax + add eax, [BytesPerScanLine] + mov [drbar.line_inc_scr], eax +; pointer to screen + mov edx, [drbar.abs_cy] + imul edx, [BytesPerScanLine] + mov eax, [drbar.abs_cx] +; movzx ebx, byte [ScreenBPP] +; shr ebx, 3 + imul eax, ebx + add edx, eax +; pointer to pixel map + mov eax, [drbar.abs_cy] + imul eax, [Screen_Max_X] + add eax, [drbar.abs_cy] + add eax, [drbar.abs_cx] + add eax, [_WinMapAddress] + xchg eax, ebp +; get process number + mov ebx, [CURRENT_TASK] + cmp byte [ScreenBPP], 24 + jne draw_bar_end_32 +draw_bar_end_24: + mov eax, [drbar.color] ;; BBGGRR00 + mov bh, al ;; bh = BB + shr eax, 8 ;; eax = RRGG +; eax - color high RRGG +; bl - process num +; bh - color low BB +; ecx - temp +; edx - pointer to screen +; esi - counter +; edi - counter + mov esi, [drbar.real_sy] +align 4 +.new_y: + mov edi, [drbar.real_sx] +align 4 +.new_x: + cmp byte [ebp], bl + jne .skip + + mov [LFB_BASE+edx], bh + mov [LFB_BASE+edx + 1], ax +.skip: +; add pixel + add edx, 3 + inc ebp + dec edi + jnz .new_x +; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] +; 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 [LFB_BASE+edx], eax +.skip: +; add pixel + add edx, 4 + inc ebp + dec edi + jnz .new_x +; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] +; 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 + +align 4 +vesa20_drawbackground_tiled: + call [_display.disable_mouse] + pushad +; External loop for all y from start to end + mov ebx, [draw_data+32+RECT.top] ; y start +dp2: + mov ebp, [draw_data+32+RECT.left] ; x start +; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] +; and LFB data (output for our function) [edi] + mov eax, [BytesPerScanLine] + mul ebx + xchg ebp, eax + add ebp, eax + add ebp, eax + add ebp, eax + cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp, eax +@@: + add ebp, LFB_BASE +; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + call calculate_edi + xchg edi, ebp + add ebp, [_WinMapAddress] +; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress +; 2) Calculate offset in background memory block + push eax + xor edx, edx + mov eax, ebx + div dword [BgrDataHeight] ; edx := y mod BgrDataHeight + pop eax + push eax + mov ecx, [BgrDataWidth] + mov esi, edx + imul esi, ecx ; esi := (y mod BgrDataHeight) * BgrDataWidth + xor edx, edx + div ecx ; edx := x mod BgrDataWidth + sub ecx, edx + add esi, edx ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth) + pop eax + lea esi, [esi*3] + add esi, [img_background] + xor edx, edx + inc edx +; 3) Loop through redraw rectangle and copy background data +; Registers meaning: +; eax = x, ebx = y (screen coordinates) +; ecx = deltax - number of pixels left in current tile block +; edx = 1 +; esi -> bgr memory, edi -> output +; ebp = offset in WinMapAddress +dp3: + cmp [ebp], dl + jnz nbgp + movsb + movsb + movsb + jmp @f +nbgp: + add esi, 3 + add edi, 3 +@@: + cmp [ScreenBPP], byte 25 ; 24 or 32 bpp? + sbb edi, -1 ; +1 for 32 bpp +; I do not use 'inc eax' because this is slightly slower then 'add eax,1' + add ebp, edx + add eax, edx + cmp eax, [draw_data+32+RECT.right] + ja dp4 + sub ecx, edx + jnz dp3 +; next tile block on x-axis + mov ecx, [BgrDataWidth] + sub esi, ecx + sub esi, ecx + sub esi, ecx + jmp dp3 +dp4: +; next scan line + inc ebx + cmp ebx, [draw_data+32+RECT.bottom] + jbe dp2 + popad + mov [EGA_counter], 1 + call VGA_drawbackground + ret + +; ---------- + + +vesa20_drawbackground_stretch: + call [_display.disable_mouse] + pushad +; Helper variables +; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1) + mov eax, [BgrDataWidth] + dec eax + xor edx, edx + div dword [Screen_Max_X] + push eax ; high + xor eax, eax + div dword [Screen_Max_X] + push eax ; low +; the same for height + mov eax, [BgrDataHeight] + dec eax + xor edx, edx + div dword [Screen_Max_Y] + push eax ; high + xor eax, eax + div dword [Screen_Max_Y] + push eax ; low +; External loop for all y from start to end + mov ebx, [draw_data+32+RECT.top] ; y start + mov ebp, [draw_data+32+RECT.left] ; x start +; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] +; and LFB data (output for our function) [edi] + mov eax, [BytesPerScanLine] + mul ebx + xchg ebp, eax + add ebp, eax + add ebp, eax + add ebp, eax + cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp, eax +@@: +; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + call calculate_edi + xchg edi, ebp +; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress + push ebx + push eax +; 2) Calculate offset in background memory block + mov eax, ebx + imul ebx, dword [esp+12] + mul dword [esp+8] + add edx, ebx ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1) + mov esi, edx + imul esi, [BgrDataWidth] + push edx + push eax + mov eax, [esp+8] + mul dword [esp+28] + push eax + mov eax, [esp+12] + mul dword [esp+28] + add [esp], edx + pop edx ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1) + add esi, edx + lea esi, [esi*3] + add esi, [img_background] + push eax + push edx + push esi +; 3) Smooth horizontal +bgr_resmooth0: + mov ecx, [esp+8] + mov edx, [esp+4] + mov esi, [esp] + push edi + mov edi, bgr_cur_line + call smooth_line +bgr_resmooth1: + mov eax, [esp+16+4] + inc eax + cmp eax, [BgrDataHeight] + jae bgr.no2nd + mov ecx, [esp+8+4] + mov edx, [esp+4+4] + mov esi, [esp+4] + add esi, [BgrDataWidth] + add esi, [BgrDataWidth] + add esi, [BgrDataWidth] + mov edi, bgr_next_line + call smooth_line +bgr.no2nd: + pop edi +sdp3: + xor esi, esi + mov ecx, [esp+12] +; 4) Loop through redraw rectangle and copy background data +; Registers meaning: +; esi = offset in current line, edi -> output +; ebp = offset in WinMapAddress +; dword [esp] = offset in bgr data +; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1) +; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1) +; dword [esp+20] = x +; dword [esp+24] = y +; precalculated constants: +; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1) +; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1) +sdp3a: + mov eax, [_WinMapAddress] + cmp [ebp+eax], byte 1 + jnz snbgp + mov eax, [bgr_cur_line+esi] + test ecx, ecx + jz .novert + mov ebx, [bgr_next_line+esi] + call [overlapping_of_points_ptr] +.novert: + + mov [LFB_BASE+edi], ax + shr eax, 16 + + mov [LFB_BASE+edi+2], al +snbgp: + cmp [ScreenBPP], byte 25 + sbb edi, -4 + add ebp, 1 + mov eax, [esp+20] + add eax, 1 + mov [esp+20], eax + add esi, 4 + cmp eax, [draw_data+32+RECT.right] + jbe sdp3a +sdp4: +; next y + mov ebx, [esp+24] + add ebx, 1 + mov [esp+24], ebx + cmp ebx, [draw_data+32+RECT.bottom] + ja sdpdone +; advance edi, ebp to next scan line + sub eax, [draw_data+32+RECT.left] + sub ebp, eax + add ebp, [Screen_Max_X] + add ebp, 1 + sub edi, eax + sub edi, eax + sub edi, eax + cmp [ScreenBPP], byte 24 + jz @f + sub edi, eax +@@: + add edi, [BytesPerScanLine] +; restore ecx,edx; advance esi to next background line + mov eax, [esp+28] + mov ebx, [esp+32] + add [esp+12], eax + mov eax, [esp+16] + adc [esp+16], ebx + sub eax, [esp+16] + mov ebx, eax + lea eax, [eax*3] + imul eax, [BgrDataWidth] + sub [esp], eax + mov eax, [draw_data+32+RECT.left] + mov [esp+20], eax + test ebx, ebx + jz sdp3 + cmp ebx, -1 + jnz bgr_resmooth0 + push edi + mov esi, bgr_next_line + mov edi, bgr_cur_line + mov ecx, [Screen_Max_X] + inc ecx + rep movsd + jmp bgr_resmooth1 +sdpdone: + add esp, 44 + popad + mov [EGA_counter],1 + call VGA_drawbackground + ret + +uglobal +align 4 +bgr_cur_line rd 1280 ; maximum width of screen +bgr_next_line rd 1280 +endg + +smooth_line: + mov al, [esi+2] + shl eax, 16 + mov ax, [esi] + test ecx, ecx + jz @f + mov ebx, [esi+2] + shr ebx, 8 + call [overlapping_of_points_ptr] +@@: + stosd + mov eax, [esp+20+8] + add eax, 1 + mov [esp+20+8], eax + cmp eax, [draw_data+32+RECT.right] + ja @f + add ecx, [esp+36+8] + mov eax, edx + adc edx, [esp+40+8] + sub eax, edx + lea eax, [eax*3] + sub esi, eax + jmp smooth_line +@@: + mov eax, [draw_data+32+RECT.left] + mov [esp+20+8], eax + ret + +align 16 +overlapping_of_points: +if 0 +; this version of procedure works, but is slower than next version + push ecx edx + mov edx, eax + push esi + shr ecx, 24 + mov esi, ecx + mov ecx, ebx + movzx ebx, dl + movzx eax, cl + sub eax, ebx + movzx ebx, dh + imul eax, esi + add dl, ah + movzx eax, ch + sub eax, ebx + imul eax, esi + add dh, ah + ror ecx, 16 + ror edx, 16 + movzx eax, cl + movzx ebx, dl + sub eax, ebx + imul eax, esi + pop esi + add dl, ah + mov eax, edx + pop edx + ror eax, 16 + pop ecx + ret +else + push ecx edx + mov edx, eax + push esi + shr ecx, 26 + mov esi, ecx + mov ecx, ebx + shl esi, 9 + movzx ebx, dl + movzx eax, cl + sub eax, ebx + movzx ebx, dh + add dl, [BgrAuxTable+(eax+0x100)+esi] + movzx eax, ch + sub eax, ebx + add dh, [BgrAuxTable+(eax+0x100)+esi] + ror ecx, 16 + ror edx, 16 + movzx eax, cl + movzx ebx, dl + sub eax, ebx + add dl, [BgrAuxTable+(eax+0x100)+esi] + pop esi + mov eax, edx + pop edx + ror eax, 16 + pop ecx + ret +end if + +iglobal +align 4 +overlapping_of_points_ptr dd overlapping_of_points +endg + +init_background: + mov edi, BgrAuxTable + xor edx, edx +.loop2: + mov eax, edx + shl eax, 8 + neg eax + mov ecx, 0x200 +.loop1: + mov byte [edi], ah + inc edi + add eax, edx + loop .loop1 + add dl, 4 + jnz .loop2 + test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8) + jz @f + mov [overlapping_of_points_ptr], overlapping_of_points_mmx +@@: + ret + +align 16 +overlapping_of_points_mmx: + movd mm0, eax + movd mm4, eax + movd mm1, ebx + pxor mm2, mm2 + punpcklbw mm0, mm2 + punpcklbw mm1, mm2 + psubw mm1, mm0 + movd mm3, ecx + psrld mm3, 24 + packuswb mm3, mm3 + packuswb mm3, mm3 + pmullw mm1, mm3 + psrlw mm1, 8 + packuswb mm1, mm2 + paddb mm4, mm1 + movd eax, mm4 + ret diff --git a/kernel/tags/kolibri0.7.7.0/video/vga.inc b/kernel/tags/kolibri0.7.7.0/video/vga.inc new file mode 100644 index 000000000..bd23d1a1c --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/video/vga.inc @@ -0,0 +1,450 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; VGA.INC ;; +;; ;; +;; 640x480 mode 0x12 VGA functions for MenuetOS ;; +;; ;; +;; Paul Butcher, paul.butcher@asa.co.uk ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +paletteVGA: + +;16 colour palette + mov dx,0x3c8 + mov al,0 + out dx,al + + mov ecx,16 + mov dx,0x3c9 + xor eax,eax + + palvganew: + + mov al,0 + test ah,4 + jz palvgalbl1 + add al,31 + test ah,8 + jz palvgalbl1 + add al,32 + palvgalbl1: + out dx,al ; red 0,31 or 63 + mov al,0 + test ah,2 + jz palvgalbl2 + add al,31 + test ah,8 + jz palvgalbl2 + add al,32 + palvgalbl2: + out dx,al ; blue 0,31 or 63 + mov al,0 + test ah,1 + jz palvgalbl3 + add al,31 + test ah,8 + jz palvgalbl3 + add al,32 + palvgalbl3: + out dx,al ; green 0,31 or 63 + add ah,1 + loop palvganew +; mov dx, 3ceh +; mov ax, 0005h +; out dx, ax + ret + +palette320x200: + + mov edx,0x3c8 + xor eax, eax + out dx,al + mov ecx,256 + mov edx,0x3c9 + xor eax,eax + + palnew: + mov al,0 + test ah,64 + jz pallbl1 + add al,21 + pallbl1: + test ah,128 + jz pallbl2 + add al,42 + pallbl2: + out dx,al + mov al,0 + test ah,8 + jz pallbl3 + add al,8 + pallbl3: + test ah,16 + jz pallbl4 + add al,15 + pallbl4: + test ah,32 + jz pallbl5 + add al,40 + pallbl5: + out dx,al + mov al,0 + test ah,1 + jz pallbl6 + add al,8 + pallbl6: + test ah,2 + jz pallbl7 + add al,15 + pallbl7: + test ah,4 + jz pallbl8 + add al,40 + pallbl8: + out dx,al + add ah,1 + loop palnew + + ret +align 4 +uglobal + novesachecksum dd 0x0 + EGA_counter db 0 + VGA_drawing_screen db 0 + VGA_8_pixels: + rb 16 + temp: + .cx dd 0 +endg +align 4 +checkVga_N13: + + cmp [SCR_MODE],dword 0x13 + jne @f + +; cnvl: + pushad + cmp [EGA_counter],1 + je novesal + mov ecx,[MOUSE_X] + cmp ecx,[novesachecksum] + jne novesal + popad + @@: + ret + + novesal: + mov [novesachecksum],ecx + mov ecx,0 + movzx eax,word [MOUSE_Y] + cmp eax,100 + jge m13l3 + mov eax,100 + m13l3: + cmp eax,480-100 + jbe m13l4 + mov eax,480-100 + m13l4: + sub eax,100 + imul eax,640*4 + add ecx,eax + movzx eax,word [MOUSE_X] + cmp eax,160 + jge m13l1 + mov eax,160 + m13l1: + cmp eax,640-160 + jbe m13l2 + mov eax,640-160 + m13l2: + sub eax,160 + shl eax,2 + add ecx,eax + mov esi,[LFBAddress] + add esi,ecx + mov edi,VGABasePtr + mov edx,200 + mov ecx,320 + cld + m13pix: + lodsd + test eax,eax + jz .save_pixel + push eax + mov ebx,eax + and eax,(128+64+32) ; blue + shr eax,5 + and ebx,(128+64+32)*256 ; green + shr ebx,8+2 + add eax,ebx + pop ebx + and ebx,(128+64)*256*256 ; red + shr ebx,8+8 + add eax,ebx + .save_pixel: + stosb + loop m13pix + mov ecx,320 + add esi,4*(640-320) + dec edx + jnz m13pix + mov [EGA_counter],0 + popad + ret + +VGA_drawbackground: +; draw all + cmp [SCR_MODE],dword 0x12 + jne .end + pushad + mov esi,[LFBAddress] + mov edi,VGABasePtr + mov ebx,640/32 ; 640*480/(8*4) + mov edx,480 + @@: + push ebx edx esi edi + shl edx,9 + lea edx,[edx+edx*4] + add esi,edx + shr edx,5 + add edi,edx + call VGA_draw_long_line + pop edi esi edx ebx + dec edx + jnz @r + call VGA_draw_long_line_1 + popad + .end: + ret + +VGA_draw_long_line: + mov dx,3ceh + mov ax,0ff08h + cli + out dx, ax + mov ax,0005h + out dx, ax + m12pix: + call VGA_draw_32_pixels + dec ebx + jnz m12pix + mov dx,3c4h + mov ax,0ff02h + out dx,ax + mov dx,3ceh + mov ax,0205h + out dx,ax + mov dx,3ceh + mov al,08h + out dx,al + sti + ret + +VGA_draw_32_pixels: + xor eax,eax + mov ebp,VGA_8_pixels + mov [ebp],eax + mov [ebp+4],eax + mov [ebp+8],eax + mov [ebp+12],eax + mov ch,4 + .main_loop: + mov cl,8 + .convert_pixels_to_VGA: + lodsd ; eax = 24bit colour + test eax,eax + jz .end + rol eax,8 + mov al,ch + ror eax,8 + mov ch,1 + dec cl + shl ch,cl + cmp al,85 + jbe .p13green + or [ebp],ch + cmp al,170 + jbe .p13green + or [ebp+12],ch + .p13green: + cmp ah,85 + jbe .p13red + or [ebp+4],ch + cmp ah,170 + jbe .p13red + or [ebp+12],ch + .p13red: + shr eax,8 + cmp ah,85 + jbe .p13cont + or [ebp+8],ch + cmp ah,170 + jbe .p13cont + or [ebp+12],ch + .p13cont: + ror eax,8 + mov ch,ah + inc cl + .end: + dec cl + jnz .convert_pixels_to_VGA + inc ebp + dec ch + jnz .main_loop + push esi + sub ebp,4 + mov esi,ebp + mov dx, 3c4h + mov ah, 1h + @@: + mov al, 02h + out dx,ax + xchg ax,bp + lodsd + mov [edi],eax + xchg ax,bp + shl ah, 1 + cmp ah, 10h + jnz @r + add edi,4 + pop esi + ret + +VGA_putpixel: + ; eax = x + ; ebx = y + mov ecx,eax + mov eax, [esp+32-8+4] ; color + shl ebx,9 + lea ebx,[ebx+ebx*4] ; умножение на 5 + lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32) + mov edi,edx + add edi, [LFBAddress] ; + LFB address + mov [edi], eax ; write to LFB for Vesa2.0 + shr edx,5 ; change BytesPerPixel to 1/8 + mov edi,edx + add edi, VGABasePtr ; address of pixel in VGA area + and ecx,0x07 ; bit no. (modulo 8) + pushfd + ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) + xor edx,edx + test eax,eax + jz .p13cont + cmp al,85 + jbe .p13green + or dl,0x01 + cmp al,170 + jbe .p13green + or dl,0x08 +.p13green: + cmp ah,85 + jbe .p13red + or dl,0x02 + cmp ah,170 + jbe .p13red + or dl,0x08 +.p13red: + shr eax,8 + cmp ah,85 + jbe .p13cont + or dl,0x04 + cmp ah,170 + jbe .p13cont + or dl,0x08 +.p13cont: + ror edx,8 + inc cl + xor eax,eax + inc ah + shr ax,cl + mov dx,3cfh + cli + out dx,al + mov al,[edi] ; dummy read + rol edx,8 + mov [edi],dl + popfd +;.end: + ret + +VGA__putimage: +; ecx = size [x|y] +; edx = coordinates [x|y] + cmp [SCR_MODE],dword 0x12 + jne @f + pushad + rol edx,16 + movzx eax,dx + rol edx,16 + movzx ebx,dx + movzx edx,cx + rol ecx,16 + movzx ecx,cx + call VGA_draw_bar_1 + popad +@@: + ret + +VGA_draw_bar: +; eax cx +; ebx cy +; ecx xe +; edx ye + cmp [SCR_MODE],dword 0x12 + jne @f + pushad + sub ecx,eax + sub edx,ebx + and eax,0xffff + and ebx,0xffff + and ecx,0xffff + and edx,0xffff + call VGA_draw_bar_1 + popad +@@: + ret + +VGA_draw_bar_1: + mov [temp.cx],eax + mov eax, [TASK_BASE] + add ebx, [eax-twdw + 4] + mov eax, [eax-twdw + 0] + add eax, [temp.cx] + and eax,0xfff8 + shl ebx,9 + lea ebx,[ebx+ebx*4] ; умножение на 5 + lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) + mov esi,ebx + add esi, [LFBAddress] ; + LFB address + shr ebx,5 ; change BytesPerPixel to 1/8 + mov edi,ebx + add edi, VGABasePtr ; address of pixel in VGA area + mov ebx,ecx + shr ebx,5 + inc ebx +.main_loop: + call VGA_draw_long_line_1 + dec edx + jnz .main_loop + call VGA_draw_long_line_1 + ret + +VGA_draw_long_line_1: + push ebx edx esi edi + shl edx,9 + lea edx,[edx+edx*4] + add esi,edx + shr edx,5 + add edi,edx + call VGA_draw_long_line + pop edi esi edx ebx + ret + + diff --git a/kernel/tags/kolibri0.7.7.0/vmodeint.inc b/kernel/tags/kolibri0.7.7.0/vmodeint.inc new file mode 100644 index 000000000..80eb1c043 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/vmodeint.inc @@ -0,0 +1,58 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; +; Call of videomode driver's functions +; +; (Add in System function 21 (and/or 26) as a subfunction 13) +; +; Author: Trans +; Date: 19.07.2003 +; +; Include in MeOS kernel and compile with FASM +; + +uglobal + old_screen_width dd ? + old_screen_height dd ? +endg + +; cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS + dec ebx + jnz .no_vmode_drv_access + pushd [Screen_Max_X] [Screen_Max_Y] + popd [old_screen_height] [old_screen_width] + or eax,-1 ; If driver is absent then eax does not change + call (VMODE_BASE+0x100) ; Entry point of video driver + mov [esp+36-4],eax + mov [esp+24-4],ebx + mov [esp+32-4],ecx +; mov [esp+28],edx + mov eax,[old_screen_width] + mov ebx,[old_screen_height] + sub eax,[Screen_Max_X] + jnz @f + sub ebx,[Screen_Max_Y] + jz .resolution_wasnt_changed + jmp .lp1 + @@: sub ebx,[Screen_Max_Y] + .lp1: sub [screen_workarea.right],eax + sub [screen_workarea.bottom],ebx + + call repos_windows + xor eax,eax + xor ebx,ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + + .resolution_wasnt_changed: + ret + .no_vmode_drv_access: diff --git a/kernel/tags/kolibri0.7.7.0/vmodeld.inc b/kernel/tags/kolibri0.7.7.0/vmodeld.inc new file mode 100644 index 000000000..3c5e512a2 --- /dev/null +++ b/kernel/tags/kolibri0.7.7.0/vmodeld.inc @@ -0,0 +1,35 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +; +; Load of videomode driver in memory +; +; (driver is located at VMODE_BASE - 32kb) // if this area not occuped anything +; +; Author: Trans +; Date: 19.07.2003 +; +; Include in MeOS kernel and compile with FASM +; + + +; LOAD VIDEOMODE DRIVER + ; If vmode.mdr file not found + or eax,-1 ; Driver ID = -1 (not present in system) + mov [VMODE_BASE],eax ; + mov [VMODE_BASE+0x100],byte 0xC3 ; Instruction RETN - driver loop + + stdcall read_file, vmode, VMODE_BASE, 0, 0x8000 ;{SPraid.simba} +; mov esi, vmode +; xor ebx, ebx +; mov ecx, 0x8000 ; size of memory area for driver +; mov edx, VMODE_BASE ; Memory position of driver +; xor ebp, ebp +; call fs_RamdiskRead