home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / ranish / SOURCES.ZIP / MANAGER.ASM < prev    next >
Assembly Source File  |  1998-11-19  |  45KB  |  2,687 lines

  1. .MODEL LARGE
  2. ASSUME    CS:ADV_MAN_TEXT, DS:BOOT_DATA, ES:BOOT_DATA, SS:BOOT_DATA
  3. PUBLIC _ADV_IPL, _ADV_MANAGER, _encrypt_password
  4. LOCALS
  5.  
  6. SECT_SIZE    EQU      512
  7.  
  8. MAX_MENU_ROWS    EQU       16
  9. MAX_PART_ROWS    EQU       32
  10.  
  11. ADV_CODE_SIZE    EQU     8192
  12. ADV_DATA_SIZE    EQU     2048
  13.  
  14. ADV_CODE_SECT    EQU    (ADV_CODE_SIZE/SECT_SIZE)
  15. ADV_DATA_SECT    EQU    (ADV_DATA_SIZE/SECT_SIZE)
  16.  
  17. ADV_CODE_ADDR    EQU    (800h)
  18. ADV_DATA_ADDR    EQU    (800h+ADV_CODE_SIZE)
  19.  
  20. ADV_MAGIC_VALUE    EQU    0ABCDh
  21.  
  22. ADV_OPT_VIR_CHECK    EQU    1
  23. ADV_OPT_CLEAR_SCR    EQU    2
  24. ADV_OPT_DEF_MENU    EQU    4
  25. ADV_OPT_IGN_UNUSED    EQU    8
  26.  
  27. OS_HIDDEN    EQU    0FF80h
  28. OS_ADV        EQU    0FF81h
  29. OS_UNKN        EQU    0FFFFh
  30.  
  31. M_BOOT_EMPTY    EQU    0
  32. M_BOOT_PART    EQU    1
  33. M_BOOT_NEXT_HD    EQU    2
  34. M_BOOT_FLOPPY    EQU    3
  35.  
  36. SHOW_ONE    EQU    0
  37. SHOW_LAST    EQU    1
  38. SHOW_NEXT    EQU    2
  39. SHOW_PREV    EQU    3
  40. SHOW_LAST3    EQU    4
  41.  
  42. M_OPT_PASSW    EQU    1
  43.  
  44. INCLUDE COLORS.INC
  45.  
  46.     X    EQU    30
  47.     Y    EQU    2
  48.     W    EQU    50
  49. ;    H    EQU    16
  50.  
  51.     KEYS_X    EQU    (X+4)
  52. ;    KEYS_Y    EQU    (Y+H-2)
  53.     KEYS_W  EQU    (31+12)
  54.  
  55.     DOT_X    EQU    (KEYS_X+11)
  56.     DOT_Y    EQU    (KEYS_Y)
  57.     DOT_NUM    EQU    (31)
  58.  
  59.  
  60.     DOT1    EQU    07h
  61.     DOT2    EQU    0FAh
  62.  
  63. TITLE_COLOR    EQU    Yellow+BakBlack
  64. MENU_COLOR    EQU    BrWhite+BakBlack
  65. ACTIVE_COLOR    EQU    Black+BakCyan
  66. KEYS_KEY_COLOR    EQU    Yellow+BakBlack
  67. KEYS_TXT_COLOR    EQU    BrCyan+BakBlack
  68. BORDER_COLOR    EQU    BrGreen+BakBlack    ; Yellow+BakBlue
  69. DOTBAR_COLOR    EQU    BrWhite+BakBlack
  70.  
  71.  
  72. BOOT_DATA    SEGMENT    AT 0h
  73.  
  74.         ORG 600h
  75.  
  76. MBR_SECT    DB     512 Dup(?)
  77.  
  78.         ORG 7B0h
  79.  
  80. ADV_REL_SECT    DD    ?
  81. ADV_RESERVED    DD    ?
  82. adv_act_menu    DB    ?
  83. adv_boptions    DB    ?
  84. adv_abmmagic    DB    4 Dup(?)
  85.  
  86. mbr_part_rec    STRUC        ; 16 bytes
  87.   b_boot_flag    DB    ?
  88.   b_chs_start    DB    3 Dup(?)
  89.   b_os_id    DB    ?
  90.   b_chs_end    DB    3 Dup(?)
  91.   b_rel_sect    DD    ?
  92.   b_num_sect    DD    ?
  93. ENDS
  94.  
  95. part_rec    mbr_part_rec     4 DUP(?)
  96.  
  97.         ORG    ADV_DATA_ADDR
  98.  
  99. ADV_SIGNATURE    DB    15 Dup(?) ; "AdvBootManager",0
  100. ADV_VERSION    DB    ?
  101. adv_def_menu    DB    ?
  102. adv_timeout    DB    ?
  103. adv_options    DB    ?
  104. adv_options2    DB    ?
  105. adv_password    DW    ?
  106. adv_reserved2    DB    26 Dup(?)
  107. adv_title    DB    32 Dup(?)
  108.  
  109. adv_menu_rec    STRUC            ; 80 bytes
  110.   m_type    DB     ?
  111.   m_options    DB     ?
  112.   m_name    DB    30 Dup(?)
  113.   m_tag        DB     ?
  114.   m_show    DB     ?
  115.   m_reserved    DB    14 Dup(?)
  116.   m_num_keys    DW     ?
  117.   m_keys        DW    15 Dup(?)
  118. ENDS
  119.  
  120. adv_part_rec    STRUC            ; 16 bytes
  121.   p_os_id    DW    ?
  122.   p_tag        DB    ?
  123.   p_orig_row    DB    ?
  124.   p_reserved    DB    4 Dup(?)
  125.   p_rel_sect    DD    ?
  126.   p_num_sect    DD    ?
  127. ENDS
  128.  
  129. menu        adv_menu_rec    MAX_MENU_ROWS  Dup(?)
  130. part        adv_part_rec    MAX_PART_ROWS  Dup(?)
  131.  
  132.         ORG    ADV_DATA_ADDR + ADV_DATA_SIZE
  133.  
  134. NUM_DISKS    DB    ?
  135. DISK        DB    ?
  136. DISK_NUM_CYLS    DW    ?
  137. DISK_NUM_HEADS    DW    ?
  138. DISK_NUM_SECTS    EQU    SECT_PER_TRACK
  139. SECT_PER_CYL    DW    ?
  140. SECT_PER_TRACK    DW    ?
  141.  
  142. _ScreenArea    DD   ?    ; B800h:0000h
  143. _ScreenWidth    DB   ?    ;  80
  144. _ScreenHeight    DB   ?    ;  25
  145. _ScreenLength    DW   ?    ; 80*25
  146.  
  147. NUM_MENUS    DW    ?
  148. ACT_MENU    DW    ?
  149. MENU_PTR    DW    MAX_MENU_ROWS Dup(?)
  150. PART_PTR    DW    MAX_MENU_ROWS Dup(?)
  151.  
  152. ACT_MBR_REC    DW    ?
  153. ACT_PART_PTR    DW    ?
  154. PART_TMP    adv_part_rec    4 Dup(?)
  155. PART_TMP2    adv_part_rec    ?
  156. MBR_SECT_BAK    DB    512 Dup(?) 
  157.  
  158. TMP        DB      80 Dup(?)
  159. SAV_BUFFER    DB    4096 Dup(?)
  160. SAV_BUFFER_ERR    DB     640 Dup(?)
  161. CURSOR_SAVE_XY    DW    ?
  162. TICKS_PER_DOT    DW    ?
  163. H        DB    ?
  164. KEYS_Y        DB    ?
  165. PASS_VALIDATED    DW    ?
  166. FILL_KB_BUFFER    DW    ?
  167. ALT_ENTER    DW    ?
  168. LAST_PART    DW    ?
  169. IMPORTED_FLAG    DW    ?
  170. FD_PARAMS    DB    4 Dup(?)
  171.  
  172.  
  173. STACK_AREA    DB    1024    Dup(?)    ; Reserving at list 1k for stack
  174.  
  175.         ORG    7C00h
  176.         
  177. OS_BOOT_SECT    DB    SECT_SIZE Dup(?)
  178.  
  179.  
  180. BOOT_DATA    ENDS
  181.  
  182.  
  183. ;----------------------------------------------------------------------
  184. PUSH_REGS    MACRO
  185.         push    ax
  186.         push    bx
  187.         push    cx
  188.         push    dx
  189.         push    di
  190.         push    si
  191.         push    ds
  192.         push    es
  193. ENDM
  194. ;----------------------------------------------------------------
  195. POP_REGS    MACRO
  196.         pop    es
  197.         pop    ds
  198.         pop    si
  199.         pop    di
  200.         pop    dx
  201.         pop    cx
  202.         pop    bx
  203.         pop    ax
  204. ENDM
  205. ;----------------------------------------------------------------
  206.  
  207. ADV_MAN_TEXT    SEGMENT    PARA PRIVATE    'CODE'
  208.  
  209.         mov    ax, cs
  210.         mov    ds, ax
  211.         mov    es, ax
  212.         mov    ss, ax
  213.         mov    sp, 7C00h
  214.         xor    cx, cx
  215.         mov    dl, 80h
  216.         mov    Word Ptr ADV_REL_SECT, 7
  217.         mov    Word Ptr ADV_REL_SECT+2, 0
  218.         jmp    debug_entry
  219.  
  220.         ORG    600h
  221.  
  222. _ADV_IPL    PROC    NEAR
  223.         ;
  224.         ;  BIOS loads MBR at 0000:7C00h
  225.         ;
  226.         ;  Lets move code to 0000:0600h
  227.         ;
  228.         xor    ax, ax
  229.         mov    ds, ax
  230.         mov    es, ax
  231.         mov    ss, ax    ;  CPU clears interrupt flag for next command
  232.         mov    sp, 7C00h
  233.         cld
  234.         mov    si, sp
  235.         mov    di, 0600h
  236.         mov    cx, 0100h
  237.         rep
  238.          movsw
  239.     ;    jmp    0000:@@ENTRY
  240.         DB    0EAh
  241.         DW    (@@ENTRY-_ADV_IPL+600h), 0000
  242.         ;
  243.         ;
  244. ErrBootMan    EQU    (@@M1-_ADV_IPL+600h)
  245. BootAorHD    EQU    (@@M2-_ADV_IPL+600h)
  246. ErrBootSct    EQU    (@@M3-_ADV_IPL+600h)
  247. MsgNL        EQU    (@@M4-_ADV_IPL+600h)
  248.         ;
  249. @@M1:        DB "Cannot load Boot Manager.",0Dh,0Ah
  250. @@M2:        DB "Boot from A or hard disk? ",0
  251. @@M3:        DB "Error reading Boot Sector."
  252. @@M4:        DB 0Dh,0Ah,0
  253.         ;
  254. ADV_CODE_CHECK_SUM    DW    0
  255.         ;
  256. debug_entry:
  257. @@ENTRY:
  258. ;GET_DISK_INFO    PROC    NEAR
  259.         ;
  260.         ;  dl - disk number
  261.         ;
  262.         cmp    dl, 80h
  263.         jae    @@skip
  264.         mov    dl, 80h
  265. @@skip:
  266.         mov    DISK, dl
  267.         mov    cl, 3
  268. @@get_again:
  269.         mov    ah, 08        ; Get disk parameters
  270.         int    13h
  271.         jnc    @@eval
  272.         mov    ah, 0
  273.         int    13h
  274.         loop    @@get_again
  275.         jmp    @@err1        ; Error
  276. @@eval:
  277. ;        mov    NUM_DISKS, dl
  278.         xor    ah, ah
  279.         mov    al, dh
  280.         inc    ax        ; AX - Number of HEADS (SIDES)
  281.         mov    DISK_NUM_HEADS, ax 
  282.         xor    bh, bh
  283.         mov    bl, cl
  284.         and    bl, 3Fh        ; BX - Number of SECTORS / TRACK
  285.         mul    bx
  286.         mov    SECT_PER_CYL, ax
  287.         mov    SECT_PER_TRACK, bx
  288.  
  289.         mov    bl, ch
  290.         shl    cx, 1
  291.         shl    cx, 1
  292.         and    ch, 3
  293.         mov    bh, ch
  294.         inc    bx
  295.         mov    DISK_NUM_CYLS, bx
  296. ;GET_DISK_INFO    ENDP
  297.         ;
  298.         ;    Read Advanced Boot Manager Data and Code
  299.         ;
  300.         mov    ax, Word Ptr ADV_REL_SECT
  301.         mov    dx, Word Ptr ADV_REL_SECT+2
  302.  
  303.         mov    bx, ADV_DATA_ADDR
  304.         mov    cx, ADV_DATA_SECT
  305.         
  306.         call    READ_N_SECT
  307.         jc    @@err1
  308.         
  309.         add    ax, ADV_DATA_SECT
  310.         adc    dx, 0
  311.  
  312.         mov    bx, ADV_CODE_ADDR
  313.         mov    cx, ADV_CODE_SECT
  314.  
  315.         call    READ_N_SECT
  316.         jc    @@err1
  317.  
  318.         cmp    [bx], ADV_MAGIC_VALUE
  319.         jne    @@err1
  320.         ;
  321.         jmp    adv_code_entry_point
  322.     ;    jmp    0000h:0800h        ; Jump to Boot Manager
  323.     ;    DB    0EAh
  324.     ;    DW    0800h,0000h
  325.         ;
  326. bad_boot_man:
  327. @@err1:
  328.         mov    si, ErrBootMan
  329. @@err2:
  330.         call    PRINT
  331.         mov    ah, 0
  332.         int    16h        ;  Get a key
  333.         mov    si, MsgNL
  334.         call    PRINT
  335.         cmp    al, 'A'
  336.         je    @@floppy    ;  Boot from floppy
  337.         cmp    al, 'a'
  338.         je    @@floppy
  339.         ;
  340.         ;  Find active partition on hard disk
  341.         ;
  342. @@part_tab:
  343.         mov    cx, 4
  344.         mov    di, 7BEh        ; Address of the first record
  345. @@next_part:
  346.         cmp    Byte Ptr [di], 00
  347.         jnz    @@read_hd        ; Active partition found
  348.         add    di, 10h
  349.         loop    @@next_part
  350. @@floppy:                    ; No active partition found
  351.         xor    dx, dx
  352.         ;mov    dx, 0000        ; Lets boot from floppy
  353.         mov    cx, 0001
  354.         jmp    @@read_sect
  355. @@read_hd:
  356.         mov    dx, [di]
  357.         mov    cx, [di+2]
  358. @@read_sect:
  359.         mov    bx, 7C00h
  360.         call    READ_SECT
  361.         jnc    @@go_boot
  362.         ;
  363.         mov    si, ErrBootSct
  364.         call    PRINT
  365.         mov    si, BootAorHD
  366.         jmp    @@err2
  367.         ;
  368. @@go_boot:
  369.         mov    dl, [di]    ; Boot sector expects Drive# in DL
  370.     ;    jmp    0000h:7C00h    ; Transfer control to loaded BootSector
  371.         DB    0EAh
  372.         DW    7C00h,0000h
  373.         ;
  374.         ;
  375.         ;
  376. REL_SECT_TO_CHS    PROC    NEAR
  377.         ;
  378.         ;  Input:    DX:AX - relative sector
  379.         ;  Output:   DH,CX - CHS and DL - disk
  380.         ;  Destroys: AX
  381.         ;
  382.         div    SECT_PER_CYL        ; AX=CYL, DX=SECT on CYL
  383.         mov    cx, ax
  384.         shr    cx, 1
  385.         shr    cx, 1
  386.         and    cl, 0C0h
  387.         mov    ch, al
  388.         mov    ax, dx
  389.         xor    dx, dx
  390.         div    SECT_PER_TRACK        ; AX=HEAD, DX=SECT
  391.         mov    dh, al
  392.         inc    dl
  393.         and    dl, 3Fh
  394.         or    cl, dl
  395.         mov    dl, DISK
  396.         ret
  397. REL_SECT_TO_CHS    ENDP
  398.         ;
  399.         ;
  400. READ_N_SECT    PROC    NEAR
  401.         ;
  402.         ;
  403.         ;    ES:BX - Destination address
  404.         ;    DX:AX - Relative sector on disk
  405.         ;    CX    - Number of sectors to read
  406.         ;
  407.         ;    Returns: Flag CF set if error
  408.         ;
  409.         push    ax
  410.         push    bx
  411.         push    cx
  412.         push    dx
  413. @@next_sect:
  414.         push    ax
  415.         push    cx
  416.         push    dx
  417.         call    REL_SECT_TO_CHS
  418.         call    READ_SECT
  419.         pop    dx
  420.         pop    cx
  421.         pop    ax
  422.         jc    @@end
  423.  
  424.         add    ax, 1
  425.         adc    dx, 0
  426.  
  427.         add    bx, SECT_SIZE
  428.  
  429.         loop    @@next_sect
  430. @@end:
  431.         pop    dx
  432.         pop    cx
  433.         pop    bx
  434.         pop    ax
  435.         ret
  436. READ_N_SECT    ENDP
  437.         ;
  438.         ;
  439.         ;
  440. READ_SECT    PROC    NEAR
  441.         ;
  442.         ;   ES:BX - Address
  443.         ;   CX,DX - CHS
  444.         ;
  445.         ;   Returns: CF set if error
  446.         ;
  447.         push    si
  448.         mov    si, 3        ; We will try at most three times
  449. @@try_again:
  450.         mov    ax, 0201h    ; Read (AH=02) 1 Sector (AL=01)
  451.         int    13h
  452.         jnc    @@end
  453.                     ; We get here if there was an error
  454.         mov    ah, 0        ; We will try to reset device
  455.         int    13h
  456.     
  457.         dec    si
  458.         jnz    @@try_again
  459.         ;
  460.         ; We have tried three times, so we will give up
  461.         ;
  462.         stc
  463.     @@end:
  464.         pop    si
  465.         ret
  466. READ_SECT    ENDP
  467.         ;
  468.         ;
  469. PRINT        PROC    NEAR
  470.         ;
  471.         ;  ds:si - address of null terminated string to print
  472.         ;
  473.         push    ax
  474.         push    bx
  475.         push    si
  476.         mov    ah, 0Eh
  477.         mov    bh, 00h
  478. @@pr1:
  479.         lodsb
  480.         or    al, al
  481.         jz    @@pr2
  482.         int    10h
  483.         jmp    @@pr1
  484. @@pr2:
  485.         pop    si
  486.         pop    bx
  487.         pop    ax
  488.         ret
  489. PRINT        ENDP
  490.         ;
  491.         ;
  492. GAP1        PROC
  493. GAPLEN1        EQU    (01B0h-(GAP1-_ADV_IPL))
  494. IF GAPLEN1
  495.         DB    GAPLEN1 DUP(0)    
  496. ENDIF
  497. GAP1        ENDP
  498.  
  499. ADV_MBR_MISC    DB    14+64+2 Dup(0)
  500.  
  501. _ADV_IPL    ENDP
  502.         ;
  503.         ;
  504.         ;
  505.         ;
  506. _ADV_MANAGER    PROC    NEAR
  507.         ;
  508.         ;  IPL loads MANAGER at 0000h:0800h = 0800h
  509.         ;
  510.         ;               SS:SP = 0000h:7C00h = 7C00h
  511.         ;
  512. ADV_MAGIC_NUM    DW    ADV_MAGIC_VALUE
  513.         ;
  514. adv_code_entry_point:
  515.         ;
  516.         ;  First of all lets check integrity of code
  517.         ;
  518. CHECK_CODE_INTEGRITY    PROC    NEAR
  519.         xor    bx, bx
  520.         mov    cx, ADV_CODE_SIZE
  521.         shr    cx, 1
  522.         mov    si, ADV_CODE_ADDR
  523. @@add_next_word:
  524.         lodsw
  525.         add    bx, ax
  526.         loop    @@add_next_word
  527.         cmp    ADV_CODE_CHECK_SUM, 0
  528.         je    @@initialize_sum
  529.         cmp    ADV_CODE_CHECK_SUM, bx
  530.         je    @@check_data_header
  531.         jmp    bad_boot_man
  532. @@initialize_sum:
  533.         mov    ADV_CODE_CHECK_SUM, bx
  534. @@check_data_header:
  535.         mov    cx, 15
  536.         lea    si, ADV_SIGNATURE
  537.         lea    di, ADV_SIGNATURE2
  538.         repe
  539.           cmpsb
  540.         je    @@data_header_valid
  541.         jmp    bad_boot_man
  542. @@data_header_valid:
  543. CHECK_CODE_INTEGRITY    ENDP
  544.         ;
  545. CHECK_INTERRUPT_VECTORS    PROC
  546.         test    adv_options, ADV_OPT_VIR_CHECK
  547.         jz    @@ints_okay
  548.         mov    cx, 1Dh            ;  Check interrupts 0h to 1Ch
  549.         mov    bx, 3
  550. @@next_int:
  551.         cmp    byte ptr [bx], 0C0h    ;  They must be >= C000:0000h
  552.         jb    @@int_changed
  553.         add    bx, 4
  554.         loop    @@next_int
  555.  
  556.         mov    bx, 4Ah*4-1        ; int 4Ah - User Alarm
  557.         cmp    byte ptr [bx], 0C0h
  558.         jb    @@int_changed
  559.  
  560.         mov    bx, 70h*4-1        ; int 70h - Real-Time Clock
  561.         cmp    byte ptr [bx], 0C0h
  562.         jb    @@int_changed
  563.         
  564.         jmp    @@ints_okay
  565. @@int_changed:
  566.         lea    si, VirusWarning
  567.         call    PRINT
  568. @@wait_enter:
  569.         mov    ah, 0
  570.         int    16h        ;  Get a key
  571.         cmp    al, 0Dh
  572.         jne    @@wait_enter    ;  And loop until ENTER is pressed
  573.         lea    si, VirusNL
  574.         call    PRINT
  575. @@ints_okay:
  576. CHECK_INTERRUPT_VECTORS    ENDP
  577.         ;
  578.         ;
  579.         jmp    @@start
  580.         ;
  581.         ;   Messages
  582.         ;
  583. ADV_SIGNATURE2    DB  "AdvBootManager",0
  584. Border        DB  "╔═╗║ ║╚═╝"
  585. Border1        DB  "┌─┐│ │└─┘"
  586. Mesg_OK        DB  " OK ",0
  587. BottomKeysESC    DB  "ESC",0
  588. BottomKeysText    DB  "ESC - Boot",0
  589. BottomKeysEnt    DB  "Enter",0
  590. BottomKeysText2    DB  "Press Enter to boot from selected partition",0
  591. MesgSetTimeout    DB  "Select menu timeout (+/-): ",0
  592. MesgErrorRead    DB  "Error reading boot sector",0
  593. MesgErrorSave    DB  "Error saving MBR to disk",0
  594. MesgErrorSaveAdv DB "Error saving Advanced MBR to disk",0
  595. MesgEnterPassword DB "Enter password:",0
  596. MesgPasswordInvalid DB "Password invalid",0
  597. MesgBootInvalid    DB  "Boot sector is invalid",0
  598. MesgImported    DB  "One or more partitions was changed in MBR. Please, run PART.EXE",0
  599. VirusWarning    DB  0Dh, 0Ah
  600.         DB  "One or more interrupts does not point to BIOS.", 0Dh, 0Ah
  601.         DB  "This may be a sign of a stealth boot virus.", 0Dh, 0Ah
  602.         DB  "Turn the computer OFF then ON and run antivirus.", 0Dh, 0Ah
  603.         DB  "Or press ENTER to continue booting... ", 0
  604. VirusNL        DB  0Dh, 0Ah, 0
  605.         ;
  606.         ;
  607. @@start:
  608.         call    _conio_init
  609.         call    CHECK_LAST_CYL
  610.         call    IMPORT_NEW_PART
  611.         call    PREP_MENU_LIST
  612.         call    BACKUP_MBR_SECT
  613.  
  614.     @@menu:
  615.         mov    ax, NUM_MENUS
  616.         add    ax, 6
  617.         mov    H, al
  618.         add    al, Y
  619.         sub    al, 2
  620.         mov    KEYS_Y, al
  621.  
  622.         mov    PASS_VALIDATED, 0
  623.         
  624.         call    INIT_SCREEN
  625.         call    MAIN_MENU
  626.         call    DONE_SCREEN
  627.         
  628.         cmp    ALT_ENTER, 1
  629.         jne    @@no_need_to_wait
  630.         
  631.         mov    cx, 24    ; If user presses ALT-ENTER we will wait
  632.     @@L3:            ; for about 1.5 seconds before proceding.
  633.         push    cx
  634.         mov    ah, 0
  635.         int    1Ah        ; Read System Timer
  636.         mov    bx, dx
  637.  
  638.     @@WT1:    int    1Ah        ; Wait one timer tick
  639.         cmp    bx, dx
  640.         je     @@WT1
  641.         pop    cx
  642.         loop    @@L3
  643.  
  644. @@no_need_to_wait:
  645.  
  646.         mov    di, ACT_MBR_REC
  647.         mov    dl, [di]    ; Boot sector expects Drive# in DL
  648.     ;    jmp    0000h:7C00h    ; Transfer control to loaded BootSector
  649.         DB    0EAh
  650.         DW    7C00h,0000h
  651. _ADV_MANAGER    ENDP
  652.         ;
  653.         ;
  654.         ;
  655. INIT_SCREEN    PROC    NEAR
  656.  
  657.         test    adv_options, ADV_OPT_CLEAR_SCR
  658.         jz    @@skip1
  659.         mov    ah, White+BakBlack
  660.         mov    bl, 1
  661.         mov    bh, 1
  662.         mov    dl, 80
  663.         mov    dh, 25
  664.         call    _clear_window
  665.         mov    bl, 1
  666.         mov    bh, 1
  667.         call    _move_cursor
  668. @@skip1:
  669.         call    _save_cursor
  670.         call    _hide_cursor
  671.  
  672.         mov    bl, X
  673.         mov    bh, Y
  674.         mov    dl, W
  675.         mov    dh, H
  676.         lea    si, SAV_BUFFER
  677.         call    _save_window
  678.  
  679.         mov    ah, BORDER_COLOR
  680.         lea    si, Border
  681.         call    _border_window
  682.         
  683.         mov    ah, TITLE_COLOR
  684.         add    bx, 0109h
  685.         lea    si, adv_title
  686.         call    _write_string
  687.         
  688.         mov    ah, KEYS_TXT_COLOR
  689.         mov    bl, KEYS_X
  690.         mov    bh, KEYS_Y
  691.         lea    si, BottomKeysText2
  692.         call    _write_string
  693.         
  694.         mov    ah, KEYS_KEY_COLOR
  695.         add    bl, 6
  696.         lea    si, BottomKeysEnt
  697.         call    _write_string
  698.  
  699.         
  700.         ret
  701. INIT_SCREEN    ENDP
  702.         ;
  703.         ;
  704.         ;
  705. DONE_SCREEN    PROC    NEAR
  706.         mov    bl, X
  707.         mov    bh, Y
  708.         mov    dl, W
  709.         mov    dh, H
  710.         lea    si, SAV_BUFFER
  711.         call    _load_window
  712.         
  713.         call    _restore_cursor
  714.         ret
  715. DONE_SCREEN    ENDP
  716.         ;
  717.         ;
  718.         ;
  719. PREP_MENU_LIST    PROC    NEAR
  720.         test    adv_options, ADV_OPT_DEF_MENU
  721.         jz    @@no_def_menu
  722.         mov    al, adv_def_menu
  723.         mov    adv_act_menu, al
  724.     @@no_def_menu:
  725.         mov    ACT_MENU, 0
  726.         mov    NUM_MENUS, 0
  727.         mov    cx, 0
  728.         lea    si, menu
  729.         mov    di, 0
  730.     @@next:
  731.         cmp    [si].m_type, M_BOOT_EMPTY
  732.         je    @@cont
  733.  
  734.         mov    MENU_PTR[di], si
  735.         mov    al, [si].m_tag
  736.         call    PART_NUM_BY_TAG
  737.         jnc    @@part_ok
  738.         cmp    [si].m_type, M_BOOT_PART
  739.         je    @@cont
  740.         mov    ax, 0
  741.     @@part_ok:
  742.         mov    PART_PTR[di], ax
  743.  
  744.         cmp    cl, adv_act_menu
  745.         jne    @@skip
  746.         mov    ax, NUM_MENUS
  747.         mov    ACT_MENU, ax
  748.     @@skip:
  749.         add    di, 2
  750.         inc    NUM_MENUS
  751.     @@cont:
  752.         add    si, SIZE adv_menu_rec
  753.         inc    cx
  754.         cmp    cx, MAX_MENU_ROWS
  755.         jne    @@next
  756.         ret
  757. PREP_MENU_LIST    ENDP
  758.         ;
  759.         ;
  760.         ;
  761. PART_NUM_BY_TAG    PROC    NEAR
  762.         ;
  763.         ;  Input:  AL - Tag
  764.         ;  Output: AX - Pointer to partition
  765.         ;
  766.         ;  CF - Set if part not found, AX=0
  767.         ;
  768.         push    bx
  769.         push    cx
  770.         cmp    al, 0
  771.         je    @@fail
  772.         xor    cx, cx
  773.         lea    bx, part
  774.     @@next:
  775.         cmp    [bx].p_tag, al
  776.         jne    @@cont
  777.         clc
  778.         mov    ax, bx
  779.         jmp    @@end
  780.     @@cont:
  781.         add    bx, SIZE adv_part_rec
  782.         inc    cx
  783.         cmp    cx, MAX_PART_ROWS
  784.         jne    @@next
  785.     @@fail:
  786.         stc
  787.         mov    ax, 0
  788.     @@end:
  789.         pop    cx
  790.         pop    bx
  791.         ret
  792. PART_NUM_BY_TAG    ENDP
  793.         ;
  794.         ;
  795.         ;
  796. MAIN_MENU    PROC    NEAR
  797.         ;
  798.         ;    Main loop        
  799.         ;
  800.         cmp    IMPORTED_FLAG, 10h
  801.         jb    @@no_import
  802.         lea    si, MesgImported
  803.         call    SHOW_ERROR
  804. @@no_import:
  805.         mov    di, 0
  806.         mov    FILL_KB_BUFFER, 1
  807. @@while1:
  808.         mov    ax, 0
  809.         jmp    @@cond1
  810.     @@next1:
  811.         call    SPRINTF_MENU
  812.         push    ax
  813.         mov    bl, (X+3)
  814.         mov    bh, (Y+3)
  815.         add    bh, al
  816.         cmp    ax, ACT_MENU
  817.         mov    ah, MENU_COLOR
  818.         jne    @@norm1
  819.         mov    ah, ACTIVE_COLOR
  820.     @@norm1:
  821.         lea    si, TMP
  822.         call    _write_string
  823.         pop    ax
  824.         inc    ax
  825.     @@cond1:
  826.         cmp    ax, NUM_MENUS
  827.         jne    @@next1
  828.  
  829.  
  830.         mov    ALT_ENTER, 0
  831.  
  832.         cmp    di, 0
  833.         jne    @@wait_key
  834.                     ; First time here
  835.         cmp    adv_timeout, 0
  836.         je    @@wait_key
  837.  
  838.         xor    ah, ah
  839.         mov    al, adv_timeout
  840.         inc    ax
  841.         shr    ax, 1
  842.         mov    TICKS_PER_DOT, ax
  843.         call    DOT_BAR
  844.         jnc    @@no_keys    ; no keys was pressed - time run out
  845.         mov    ah, 10h
  846.         int    16h
  847.         cmp    al, ' '
  848.         jne    @@cmp_keys
  849.         jmp    @@wait_key
  850.     @@no_keys:
  851.         jmp    @@boot
  852.     @@wait_key:
  853.         mov    ah, 10h
  854.         int    16h
  855.     @@cmp_keys:
  856.         cmp    ax, 48E0h
  857.         je    @@up
  858.         cmp    ax, 4800h
  859.         je    @@up
  860.         cmp    ax, 50E0h
  861.         je    @@down
  862.         cmp    ax, 5000h
  863.         je    @@down
  864.         cmp    ax, 47E0h
  865.         je    @@home
  866.         cmp    ax, 4700h
  867.         je    @@home
  868.         cmp    ax, 4FE0h
  869.         je    @@end
  870.         cmp    ax, 4F00h
  871.         je    @@end
  872.         cmp    ax, 3920h    ; Space
  873.         je    @@space
  874.         cmp    ax, 1C0Dh    ; Enter
  875.         je    @@boot2short
  876.         cmp    ax, 0E00Dh    ; Enter
  877.         je    @@boot2short
  878.         cmp    ax, 1C00h    ; Alt-Enter
  879.         je    @@alt_boot2short
  880.         cmp    ax, 0A600h    ; Alt-Enter
  881.         je    @@alt_boot2short
  882.         cmp    ax, 011Bh    ; ESC
  883.         je    @@boot_esc2short
  884.         cmp    al, 'A'
  885.         je    @@boot_a_short
  886.         cmp    al, 'a'
  887.         je    @@boot_a_short
  888.         cmp    al, 9    ; Tab
  889.         je    @@boot_d_short
  890.         cmp    al, 'H'
  891.         je    @@hide_all
  892.         cmp    al, 'h'
  893.         je    @@hide_all
  894.         sub    al, '1'
  895.         xor    ah, ah
  896.         cmp    ax, NUM_MENUS
  897.         jb    @@boot_n_short
  898.         jmp    @@wait_key
  899.     @@up:
  900.         cmp    ACT_MENU, 0
  901.         jz    @@cont2short
  902.         dec    ACT_MENU
  903.         jmp    @@cont2
  904.     @@down:
  905.         mov    ax, NUM_MENUS
  906.         dec    ax
  907.         jb    @@cont2short
  908.         cmp    ACT_MENU, ax
  909.         jnb    @@cont2short
  910.         inc    ACT_MENU
  911.         jmp    @@cont2
  912.     @@home:
  913.         mov    ACT_MENU, 0
  914.         jmp    @@cont2
  915.     @@end:
  916.         mov    ax, NUM_MENUS
  917.         dec    ax
  918.         jb    @@cont2short
  919.         mov    ACT_MENU, ax
  920.         jmp    @@cont2
  921.     @@space:
  922.         call    SETUP_MENU
  923.         xor    di, di
  924.         jmp    @@while1
  925.     @@boot_a_short:
  926.         jmp    @@boot_a
  927.     @@boot_d_short:
  928.         jmp    @@boot_d
  929.     @@boot_n_short:
  930.         jmp    @@boot_n
  931.     @@boot2short:
  932.         jmp    @@boot
  933.     @@alt_boot2short:
  934.         jmp    @@alt_boot
  935.     @@cont2short:
  936.         jmp    @@cont2
  937.     @@boot_esc2short:
  938.         jmp    @@boot_esc
  939.     @@hide_all:
  940.         mov    bx, 0
  941.         call    CHECK_PASSWORD
  942.         jc    @@cont2short
  943.         mov    ax, ACT_MENU
  944.         push    ax
  945.         mov    ax, -1
  946.         mov    ACT_MENU, ax
  947.         mov    dl, 0
  948.         call    PREP_BOOT_SECT_X
  949.         pop    ax
  950.         mov    ACT_MENU, ax
  951.         jnc    @@break_out_short
  952.         jmp    @@cont2
  953.     @@break_out_short:
  954.         jmp    @@break_out
  955.     @@alt_boot:
  956.         mov    ALT_ENTER, 1
  957.         jmp    @@boot
  958.     @@boot_a:
  959.         mov    bx, 0
  960.         call    CHECK_PASSWORD
  961.         jc    @@cont2short
  962.         mov    dl, 0
  963.         call    PREP_BOOT_SECT_X
  964.         jnc    @@break_out_short
  965.         jmp    @@cont2
  966.     @@boot_d:
  967.         mov    bx, 0
  968.         call    CHECK_PASSWORD
  969.         jc    @@cont2short
  970.         mov    dl, DISK
  971.         inc    dl
  972.         call    PREP_BOOT_SECT_X
  973.         jnc    @@break_out
  974.         jmp    @@cont2
  975.     @@boot_n:
  976.         mov    ACT_MENU, ax
  977.     @@boot:
  978.         cmp    NUM_MENUS, 0
  979.         je    @@boot_a
  980.         mov    bx, ACT_MENU
  981.         shl    bx, 1
  982.         mov    ax, MENU_PTR[bx]
  983.         lea    bx, menu
  984.         sub    ax, bx
  985.         mov    bl, SIZE adv_menu_rec
  986.         div    bl
  987.         mov    adv_act_menu, al
  988.     @@boot_esc:
  989.         cmp    NUM_MENUS, 0
  990.         je    @@boot_a
  991.         
  992.  
  993.         mov    bx, ACT_MENU
  994.         shl    bx, 1
  995.         mov    bx, MENU_PTR[bx]
  996.  
  997.         push    bx
  998.         call    CHECK_PASSWORD
  999.         pop    bx
  1000.         jc    @@cont2
  1001.  
  1002.         cmp    [bx].m_type, M_BOOT_PART
  1003.         je    @@boot_type_part
  1004.         cmp    [bx].m_type, M_BOOT_NEXT_HD
  1005.         je    @@boot_type_next_hd
  1006.         cmp    [bx].m_type, M_BOOT_FLOPPY
  1007.         je    @@boot_type_floppy
  1008.         jmp    @@cont2        ; We dont know what it is - ingnoring 
  1009. @@boot_type_part:
  1010.         call    PREP_BOOT_SECT
  1011.         jnc    @@break_out
  1012.         jmp    @@cont2
  1013. @@boot_type_next_hd:
  1014.         mov    dl, DISK
  1015.         inc    dl
  1016.         call    PREP_BOOT_SECT_X
  1017.         jc    @@cont2
  1018.         call    FILL_KEYB_BUFFER
  1019.         jmp    @@break_out
  1020. @@boot_type_floppy:
  1021.         mov    dl, 0
  1022.         call    PREP_BOOT_SECT_X
  1023.         jc    @@cont2
  1024.         call    FILL_KEYB_BUFFER
  1025.         jmp    @@break_out
  1026.     @@cont2:
  1027.         mov    di, 1
  1028.         jmp    @@while1
  1029.     @@break_out:
  1030.         ret
  1031. MAIN_MENU    ENDP
  1032.         ;
  1033.         ;
  1034. CHECK_PASSWORD    PROC    NEAR
  1035.         ;
  1036.         ; Input:   bx - pointer to ActiveMenu, or 0 if no menu
  1037.         ;
  1038.         ; Output:  CF - clear if password validated
  1039.         ;       CF - set if user cannot proceed
  1040.         ;
  1041.         PUSH_REGS
  1042.  
  1043.         cmp    PASS_VALIDATED, 1
  1044.         je    @@valid
  1045.  
  1046.         cmp    bx, 0
  1047.         jz    @@do_check
  1048.  
  1049.         test    [bx].m_options, M_OPT_PASSW
  1050.         jz    @@valid        ; This menu item needs no validation
  1051. @@do_check:
  1052.         cmp    adv_password, 0
  1053.         je    @@valid        ; No master password set
  1054.  
  1055.         call    GET_PASSWORD
  1056.  
  1057.         cmp    ax, adv_password
  1058.         je    @@valid
  1059. @@invalid:
  1060.         lea    si, MesgPasswordInvalid
  1061.         call    SHOW_ERROR
  1062.         stc
  1063.         jmp    @@end
  1064. @@valid:
  1065.         mov    PASS_VALIDATED, 1
  1066.               clc
  1067. @@end:
  1068.         POP_REGS
  1069.         ret
  1070. CHECK_PASSWORD    ENDP
  1071.         ;
  1072.         ;
  1073.         ;
  1074. PREP_BOOT_SECT    PROC    NEAR
  1075.         ;
  1076.         ;  Output:  CF - set if error
  1077.         ;
  1078.         PUSH_REGS
  1079.         
  1080.         call    MAKE_PART_TAB
  1081.         
  1082.         mov    di, ACT_MBR_REC
  1083.  
  1084.         mov    bx, Offset OS_BOOT_SECT
  1085.         mov    dx, [di]
  1086.         mov    cx, [di+2]
  1087.         call    READ_SECT
  1088.         jc    @@err_read
  1089.         
  1090.         mov    di, Offset OS_BOOT_SECT
  1091.         mov    cx, 512
  1092.         mov    al, 0
  1093.         repe
  1094.            scasb
  1095.         jcxz    @@sect_empty
  1096.  
  1097.         call    COMPARE_MBR_SECT    ; did we change boot sector
  1098.         jnc    @@not_changed        ; no need to save
  1099.  
  1100.         mov    bx, Offset MBR_SECT
  1101.         xor    dx, dx
  1102.         xor    ax, ax
  1103.         mov    cx, 1
  1104.         call    WRITE_N_SECT
  1105.         jc    @@err_save
  1106. @@not_changed:
  1107.         call    FILL_KEYB_BUFFER
  1108.         clc
  1109.         jmp    @@end
  1110. @@err_read:
  1111.         lea    si, MesgErrorRead
  1112.         call    SHOW_ERROR
  1113.         stc
  1114.         jmp    @@end
  1115. @@sect_empty:
  1116.         lea    si, MesgBootInvalid
  1117.         call    SHOW_ERROR
  1118.         stc
  1119.         jmp    @@end
  1120. @@err_save:
  1121.         lea    si, MesgErrorSave
  1122.         call    SHOW_ERROR
  1123.         stc
  1124. @@end:
  1125.         POP_REGS
  1126.         ret
  1127. PREP_BOOT_SECT    ENDP
  1128.         ;
  1129.         ;
  1130. PREP_BOOT_SECT_X PROC    NEAR
  1131.         ;
  1132.         ; Input:   DL - Disk number
  1133.         ; Output:  CF - set if error
  1134.         ;
  1135.         PUSH_REGS
  1136.         
  1137.         push    dx
  1138.         call    MAKE_PART_TAB
  1139.         pop    dx
  1140.         
  1141.         lea    di, FD_PARAMS
  1142.         mov    cx, 1
  1143.         mov    dh, 0
  1144.         mov    [di], dx
  1145.         mov    [di+2],cx
  1146.         mov    ACT_MBR_REC, di
  1147.         mov    bx, Offset OS_BOOT_SECT
  1148.  
  1149.         call    READ_SECT
  1150.         jc    @@err_read
  1151.  
  1152.         call    COMPARE_MBR_SECT    ; did we change boot sector
  1153.         jnc    @@not_changed        ; no need to save
  1154.  
  1155.         mov    bx, Offset MBR_SECT
  1156.         xor    dx, dx
  1157.         xor    ax, ax
  1158.         mov    cx, 1
  1159.         call    WRITE_N_SECT
  1160.         jc    @@err_save
  1161. @@not_changed:
  1162.         clc
  1163.         jmp    @@end
  1164. @@err_read:
  1165.         lea    si, MesgErrorRead
  1166.         call    SHOW_ERROR
  1167.         stc
  1168.         jmp    @@end
  1169. @@err_save:
  1170.         lea    si, MesgErrorSave
  1171.         call    SHOW_ERROR
  1172.         clc            ; We still want to boot from A: (or D:)
  1173. @@end:
  1174.         POP_REGS
  1175.         ret
  1176. PREP_BOOT_SECT_X ENDP
  1177.         ;
  1178.         ;
  1179.         ;
  1180. BACKUP_MBR_SECT PROC    NEAR
  1181.         push    cx
  1182.         push    si
  1183.         push    di
  1184.  
  1185.         mov    cx, 512
  1186.         mov    si, Offset MBR_SECT
  1187.         mov    di, Offset MBR_SECT_BAK
  1188.         
  1189.         rep
  1190.           movsb
  1191.  
  1192.         pop    di
  1193.         pop    si
  1194.         pop    cx
  1195.         ret
  1196. BACKUP_MBR_SECT ENDP
  1197.         ;
  1198.         ;
  1199.         ;
  1200. COMPARE_MBR_SECT PROC    NEAR
  1201.         ;
  1202.         ; CF - set if boot sector was changed
  1203.         ;
  1204.         push    cx
  1205.         push    si
  1206.         push    di
  1207.  
  1208.         mov    cx, 512
  1209.         mov    si, Offset MBR_SECT
  1210.         mov    di, Offset MBR_SECT_BAK
  1211.         
  1212.         repe
  1213.          cmpsb
  1214.  
  1215.         je    @@equal
  1216.         stc
  1217.         jmp    @@end
  1218.     @@equal:
  1219.         clc
  1220.     @@end:
  1221.         pop    di
  1222.         pop    si
  1223.         pop    cx
  1224.         ret
  1225. COMPARE_MBR_SECT ENDP
  1226.         ;
  1227.         ;
  1228.         ;
  1229. MAKE_PART_TAB    PROC    NEAR
  1230.         ;
  1231.         ;  Input:  ACT_MENU
  1232.         ;
  1233.         ;  Output: ACT_MBR_REC - points to active mbr_part_rec
  1234.         ;
  1235.         push    bp
  1236.  
  1237.         mov    ACT_PART_PTR, 0
  1238.         ;
  1239.         ;  Clearing PART_TMP and MBR part_rec
  1240.         ;
  1241.         xor    ax, ax
  1242.         lea    di, PART_TMP
  1243.         mov    cx, SIZE PART_TMP
  1244.         rep
  1245.           stosb
  1246.         lea    di, PART_TMP2
  1247.         mov    cx, SIZE PART_TMP2
  1248.         rep
  1249.           stosb
  1250.         lea    di, part_rec
  1251.         mov    cx, SIZE part_rec
  1252.         rep
  1253.           stosb
  1254.         ;
  1255.         ; Lets find last partition
  1256.         ;
  1257.         xor    bp, bp
  1258.         xor    si, si
  1259.         lea    di, part
  1260.         mov    cx, MAX_PART_ROWS
  1261.         mov    bx, di
  1262. @@next_step:
  1263.         mov    ax, Word Ptr [di].p_num_sect
  1264.         or    ax, Word Ptr [di].p_num_sect+2
  1265.         jz    @@last_found
  1266.         add    di, SIZE adv_part_rec
  1267.         loop    @@next_step
  1268. @@last_found:
  1269.         cmp    bx, di
  1270.         je    @@show_one_je_short
  1271.         sub    di, SIZE adv_part_rec
  1272.  
  1273.         cmp    NUM_MENUS, 0
  1274. @@show_one_je_short:
  1275.         je    @@show_one
  1276.  
  1277.         mov    bx, ACT_MENU
  1278.         cmp    bx, -1
  1279.         je    @@show_unused
  1280.         shl    bx, 1
  1281.         mov    si, MENU_PTR[bx]
  1282.         mov    al, [si].m_show
  1283.         mov    si, PART_PTR[bx]
  1284.         mov    ACT_PART_PTR, si
  1285.         cmp    si, 0
  1286.         jne    @@not_zero
  1287.         xor    di, di        ; No partition associated with menu
  1288.         xor    bp, bp        ; so we will hide everything
  1289.         jmp    @@eval_part
  1290.     @@not_zero:
  1291.         ;
  1292.         ;  SI -> active partition
  1293.         ;  DI -> last partition
  1294.         ;  AL - representation mode
  1295.         ;
  1296.         cmp    al, SHOW_NEXT
  1297.         je    @@show_next
  1298.         cmp    al, SHOW_PREV
  1299.         je    @@show_prev
  1300.         cmp    al, SHOW_LAST
  1301.         je    @@show_last
  1302.         cmp    al, SHOW_LAST3
  1303.         je    @@show_last3
  1304.         jmp    @@show_one
  1305. @@show_prev:
  1306.         lea    bx, part
  1307.         cmp    bx, si
  1308.         je    @@show_one
  1309.         mov    di, si
  1310.         sub    si, SIZE adv_part_rec
  1311.         jmp    @@eval_part
  1312. @@show_next:
  1313.         cmp    si, di
  1314.         je    @@show_one
  1315.         mov    di, si
  1316.         add    di, SIZE adv_part_rec
  1317.         jmp    @@eval_part
  1318. @@show_last:
  1319.         cmp    si, di
  1320.         jne    @@eval_part
  1321.         jmp    @@show_one
  1322. @@show_last3:
  1323.         push    di
  1324.         sub    di, SIZE adv_part_rec
  1325.         sub    di, SIZE adv_part_rec
  1326.         cmp    di, Offset part
  1327.         jnb    @@now_check_si
  1328.         pop    di
  1329.         jmp    @@show_last
  1330. @@now_check_si:
  1331.         cmp    si, di
  1332.         pop    di
  1333.         jb    @@show_last
  1334.         mov    bp, di
  1335.         sub    di, SIZE adv_part_rec
  1336.         mov    si, di
  1337.         sub    si, SIZE adv_part_rec
  1338.         jmp    @@eval_part
  1339. @@show_one:
  1340.         xor    di, di
  1341.         jmp    @@eval_part
  1342. @@show_unused:                    ; Show first unused space
  1343.         xor    di, di            ; greater than 63 sectors
  1344.         lea    si, part
  1345.         mov    cx, MAX_PART_ROWS
  1346. @@unused_next:
  1347.         cmp    [si].p_os_id, 0
  1348.         jne    @@unused_cont
  1349.         cmp    Word Ptr [si].p_num_sect+2, 0
  1350.         jne    @@eval_part
  1351.         cmp    Word Ptr [si].p_num_sect, 63
  1352.         ja    @@eval_part
  1353. @@unused_cont:
  1354.         add    si, SIZE adv_part_rec
  1355.         loop    @@unused_next
  1356.         xor    si, si            ; didn't find any
  1357. @@eval_part:
  1358.         ;
  1359.         ;  SI -> first partition, or zero
  1360.         ;  DI -> second partition, or zero
  1361.         ;  BP -> third partition, or zero
  1362.         ;
  1363.         lea    bx, part
  1364.         mov    ax, Word Ptr [bx].p_rel_sect
  1365.         mov    dx, Word Ptr [bx].p_rel_sect+2
  1366.         
  1367.         lea    bx, PART_TMP
  1368.         mov    cx, 0
  1369.  
  1370.         mov    LAST_PART, 0
  1371. @@next_row:
  1372.         cmp    si, 0
  1373.         jne    @@check_gap
  1374.         jmp    @@tail
  1375. @@check_gap:
  1376.         cmp    Word Ptr [si].p_rel_sect+2, dx
  1377.         ja    @@fill_gap
  1378.         cmp    Word Ptr [si].p_rel_sect, ax
  1379.         ja    @@fill_gap
  1380.  
  1381.         mov    ax, [si].p_os_id
  1382.         mov    [bx].p_os_id, ax
  1383.         mov    al, [si].p_orig_row
  1384.         mov    [bx].p_orig_row, al
  1385.         mov    al, 0
  1386.         cmp    si, ACT_PART_PTR
  1387.         jne    @@not_active
  1388.         mov    al, DISK
  1389. @@not_active:
  1390.         mov    [bx].p_tag, al
  1391.  
  1392.         mov    ax, Word Ptr [si].p_rel_sect
  1393.         mov    dx, Word Ptr [si].p_rel_sect+2
  1394.         mov    Word Ptr [bx].p_rel_sect, ax
  1395.         mov    Word Ptr [bx].p_rel_sect+2, dx
  1396.         mov    ax, Word Ptr [si].p_num_sect
  1397.         mov    dx, Word Ptr [si].p_num_sect+2
  1398.         mov    Word Ptr [bx].p_num_sect, ax
  1399.         mov    Word Ptr [bx].p_num_sect+2, dx
  1400.         add    ax, Word Ptr [si].p_rel_sect
  1401.         adc    dx, Word Ptr [si].p_rel_sect+2
  1402.  
  1403.         mov    LAST_PART, si
  1404.         mov    si, di
  1405.         mov    di, bp
  1406.         mov    bp, 0
  1407.         add    bx, SIZE adv_part_rec
  1408.         inc    cx
  1409.         cmp    cx, 4
  1410.         je    @@table_filled_short
  1411.         jmp    @@next_row
  1412. @@table_filled_short:
  1413.         jmp    @@table_filled
  1414. @@fill_gap:
  1415.         test    adv_options, ADV_OPT_IGN_UNUSED
  1416.         jz    @@go_fill_gap
  1417.         cmp    LAST_PART, 0
  1418.         je    @@go_fill_gap
  1419.         push    si
  1420.         sub    si, SIZE adv_part_rec
  1421.         cmp    si, LAST_PART
  1422.         pop    si
  1423.         jne    @@go_fill_gap
  1424.         mov    ax, Word Ptr [si].p_rel_sect
  1425.         mov    dx, Word Ptr [si].p_rel_sect+2
  1426.         jmp    @@next_row
  1427. @@go_fill_gap:
  1428.         mov    [bx].p_os_id, OS_HIDDEN
  1429.         mov    [bx].p_tag, 0
  1430.         mov    [bx].p_orig_row, 0
  1431.         mov    Word Ptr [bx].p_rel_sect, ax
  1432.         mov    Word Ptr [bx].p_rel_sect+2, dx
  1433.         mov    ax, Word Ptr [si].p_rel_sect
  1434.         mov    dx, Word Ptr [si].p_rel_sect+2
  1435.         sub    ax, Word Ptr [bx].p_rel_sect
  1436.         sbb    dx, Word Ptr [bx].p_rel_sect+2
  1437.         mov    Word Ptr [bx].p_num_sect, ax
  1438.         mov    Word Ptr [bx].p_num_sect+2, dx
  1439.         mov    ax, Word Ptr [si].p_rel_sect
  1440.         mov    dx, Word Ptr [si].p_rel_sect+2
  1441.         
  1442.         add    bx, SIZE adv_part_rec
  1443.         inc    cx
  1444.         cmp    cx, 4
  1445.         je    @@table_filled
  1446.         jmp    @@next_row
  1447. @@tail:
  1448.         mov    Word Ptr [bx].p_rel_sect, ax
  1449.         mov    Word Ptr [bx].p_rel_sect+2, dx
  1450.         mov    ax, SECT_PER_CYL
  1451.         mov    dx, DISK_NUM_CYLS
  1452.         mul    dx
  1453.         sub    ax, Word Ptr [bx].p_rel_sect
  1454.         sbb    dx, Word Ptr [bx].p_rel_sect+2
  1455.         mov    Word Ptr [bx].p_num_sect, ax
  1456.         mov    Word Ptr [bx].p_num_sect+2, dx
  1457.         or    ax, dx                ; is part size zero
  1458.         jz    @@table_filled
  1459.  
  1460.         mov    [bx].p_os_id, OS_HIDDEN
  1461.         mov    [bx].p_tag, 0
  1462.         mov    [bx].p_orig_row, 0
  1463.  
  1464.         cmp    bx, offset PART_TMP
  1465.         jne    @@table_filled
  1466.         mov    al, DISK
  1467.         mov    [bx].p_tag, al
  1468. @@table_filled:
  1469.         ;
  1470.         ;    Now lets make sure that active partition occupies
  1471.         ;    slot in partition table from which it was taken
  1472.         ;
  1473. @@check_locations:
  1474.         mov    cx, 4
  1475.         lea    si, PART_TMP
  1476. @@check_next_part:
  1477.         mov    ah, 0
  1478.         mov    al, [si].p_orig_row
  1479.         cmp    al, 0
  1480.         jne    @@row_is_not_0
  1481.         add    si, SIZE adv_part_rec
  1482.         loop    @@check_next_part
  1483.         jmp    @@nothing_to_move
  1484. @@row_is_not_0:
  1485.         dec    ax
  1486.         mov    bl, SIZE adv_part_rec
  1487.         mul    bl
  1488.         lea    bx, PART_TMP
  1489.         add    bx, ax
  1490.         cmp    bx, si
  1491.         je    @@part_in_place
  1492.  
  1493.         push    bx    ; that's where partition supposed to be
  1494.         push    si    ; that's where it is
  1495.         lea    di, PART_TMP2
  1496.         mov    cx, SIZE adv_part_rec
  1497.         rep        ; moving partition to PART_TMP2
  1498.           movsb
  1499.         pop    di
  1500.         pop    si
  1501.         push    si
  1502.         mov    cx, SIZE adv_part_rec
  1503.         rep        ; moving whatever occupies place out
  1504.           movsb
  1505.         pop    di
  1506.         push    di
  1507.         lea    si, PART_TMP2
  1508.         mov    cx, SIZE adv_part_rec
  1509.         rep        ; moving partition to its proper place
  1510.           movsb
  1511.         pop    si
  1512. @@part_in_place:
  1513.         mov    [si].p_orig_row, 0    ; so we won't move it again
  1514.         jmp    @@check_locations
  1515. @@nothing_to_move:
  1516.         ;
  1517.         ;    Converting temporary structures
  1518.         ;    into records in the partition table
  1519.         ;
  1520.         mov    cx, 4
  1521.         lea    si, PART_TMP
  1522.         lea    di, part_rec
  1523. @@next_part_rec:
  1524.         push    cx
  1525.         push    si
  1526.         push    di
  1527.         cmp    [si].p_os_id, 0
  1528.         je    @@cont
  1529.         mov    ax, Word Ptr [si].p_rel_sect
  1530.         mov    dx, Word Ptr [si].p_rel_sect+2
  1531.         push    dx
  1532.         push    ax
  1533.         call    REL_SECT_TO_CHS
  1534.         mov    dl, [si].p_tag
  1535.         or    dl, dl
  1536.         jz    @@part_not_active
  1537.         mov    ACT_MBR_REC, di
  1538. @@part_not_active:
  1539.         mov    ax, dx
  1540.         stosw
  1541.         mov    ax, cx
  1542.         stosw
  1543.         pop    ax
  1544.         pop    dx
  1545.         add    ax, Word Ptr [si].p_num_sect
  1546.         adc    dx, Word Ptr [si].p_num_sect+2
  1547.         sub    ax, 1
  1548.         sbb    dx, 0
  1549.         call    REL_SECT_TO_CHS
  1550.         mov    dl, Byte Ptr [si].p_os_id+1
  1551.         mov    ax, dx
  1552.         stosw
  1553.         mov    ax, cx
  1554.         stosw
  1555.         lea    si, [si].p_rel_sect
  1556.         movsw
  1557.         movsw
  1558.         movsw
  1559.         movsw
  1560.     @@cont:
  1561.         pop    di
  1562.         pop    si
  1563.         add    si, SIZE adv_part_rec
  1564.         add    di, SIZE mbr_part_rec
  1565.         pop    cx
  1566.         loop    @@next_part_rec
  1567.     @@end:
  1568.         pop    bp
  1569.         ret        
  1570. MAKE_PART_TAB    ENDP
  1571.         ;
  1572.         ;
  1573.         ;
  1574. IMPORT_NEW_PART    PROC    NEAR
  1575.         push    bp
  1576.         mov    IMPORTED_FLAG, 0
  1577.         mov    cx, 1
  1578.         lea    si, part_rec
  1579. @@next_mbr_part:
  1580.         push    cx
  1581.         cmp    [si].b_os_id, 0        ; Unused - ignore it
  1582.         je    @@mbr_cont_short
  1583.         cmp    [si].b_os_id, 0FFh    ; Hidden - ignore it
  1584.         je    @@mbr_cont_short
  1585.         jmp    @@test_part
  1586. @@mbr_cont_short:
  1587.         jmp    @@mbr_cont
  1588.      @@test_part:
  1589.         mov    ax, Word Ptr [si].b_rel_sect
  1590.         mov    dx, Word Ptr [si].b_rel_sect+2
  1591.         push    ax
  1592.         or    ax, dx
  1593.         pop    ax
  1594.         jz    @@mbr_cont        ; Empty - ignore it
  1595.         mov    cx, MAX_PART_ROWS
  1596.         lea    di, part
  1597.      @@next_part:
  1598.              cmp    ax, Word Ptr [di].p_rel_sect
  1599.              jne    @@part_cont
  1600.              cmp    dx, Word Ptr [di].p_rel_sect+2
  1601.              jne    @@part_cont
  1602.              ; Relative sectors matched
  1603.         mov    ax, Word Ptr [si].b_num_sect
  1604.         mov    dx, Word Ptr [si].b_num_sect+2
  1605.  
  1606.              cmp    ax, Word Ptr [di].p_num_sect
  1607.              jne    @@import_part
  1608.              cmp    dx, Word Ptr [di].p_num_sect+2
  1609.              jne    @@import_part
  1610.              ; Number of sectors also same
  1611.              jmp    @@check_id
  1612.      @@part_cont:
  1613.              add    di, SIZE adv_part_rec
  1614.              loop    @@next_part
  1615.              jmp    @@import_part
  1616.       @@check_id:
  1617.               mov    ax, [di].p_os_id
  1618.               cmp    ax, OS_ADV
  1619.               je    @@import_part
  1620.               cmp    ah, [si].b_os_id
  1621.               je    @@mbr_cont
  1622.               mov    ah, [si].b_os_id
  1623.               mov    al, 0
  1624.               mov    [di].p_os_id, ax
  1625.               mov    IMPORTED_FLAG, 1
  1626.               jmp    @@mbr_cont
  1627.      @@import_part:
  1628.              mov    cx, MAX_PART_ROWS
  1629.              lea    di, part + SIZE part
  1630.      @@step_back:
  1631.              sub    di, SIZE adv_part_rec
  1632.              cmp    [di].p_os_id, 0
  1633.              je    @@copy_part
  1634.              loop    @@step_back
  1635.              jmp    @@mbr_cont
  1636.      @@copy_part:
  1637.              mov    ah, [si].b_os_id
  1638.              mov    al, 0
  1639.              stosw    ; p_os_id
  1640.              mov    al, 0
  1641.              stosb    ; p_tag
  1642.              pop    ax
  1643.              push    ax
  1644.              stosb    ; p_orig_row
  1645.              xor    ax, ax
  1646.              stosw    ; reserved
  1647.              stosw    ; reserved
  1648.              push    si
  1649.              add    si, 8
  1650.              movsw    ; rel_sect
  1651.              movsw
  1652.              movsw    ; num_sect
  1653.              movsw
  1654.              pop    si
  1655.               mov    IMPORTED_FLAG, 10h
  1656. @@mbr_cont:
  1657.         add    si, SIZE mbr_part_rec
  1658.         pop    cx
  1659.         inc    cx
  1660.         cmp    cx, 5
  1661.         je    @@break_out
  1662.         jmp    @@next_mbr_part
  1663. @@break_out:
  1664.         cmp    IMPORTED_FLAG, 0
  1665.         je    @@end
  1666.  
  1667.         mov    ax, Word Ptr ADV_REL_SECT
  1668.         mov    dx, Word Ptr ADV_REL_SECT+2
  1669.  
  1670.         mov    bx, ADV_DATA_ADDR
  1671.         mov    cx, ADV_DATA_SECT
  1672.         
  1673.         call    WRITE_N_SECT
  1674.         jnc    @@end
  1675.         lea    si, MesgErrorSaveAdv
  1676.         call    SHOW_ERROR
  1677.     @@end:
  1678.         pop    bp
  1679.         ret
  1680. IMPORT_NEW_PART    ENDP
  1681.         ;
  1682.         ;
  1683.         ;
  1684. SPRINTF_MENU    PROC    NEAR
  1685.         ;
  1686.         ;  Input:  AX - Menu number
  1687.         ;  Output: TMP - Filled with menu line
  1688.         ;
  1689.         PUSH_REGS
  1690.         push    ax
  1691.         inc    ax
  1692.         lea    si, TMP
  1693.         mov    cx, 3
  1694.         call    SPRINTF_INT
  1695.         lea    di, TMP+3
  1696.         mov    al, ' '
  1697.         stosb
  1698.         stosb
  1699.         mov    cx, 30
  1700.         pop    bx
  1701.         shl    bx, 1
  1702.         mov    si, MENU_PTR[bx]
  1703.         lea    si, [si].m_name
  1704.     @@char:
  1705.         lodsb
  1706.         or    al, al
  1707.         jz    @@break
  1708.         stosb
  1709.         loop    @@char
  1710.     @@break:
  1711.         mov    al, ' '
  1712.         jcxz    @@no_spaces
  1713.     @@space:
  1714.         rep
  1715.          stosb
  1716.     @@no_spaces:
  1717.         stosb
  1718.         mov    si, PART_PTR[bx]
  1719.         cmp    si, 0
  1720.         je    @@no_part
  1721.         mov    ax, Word Ptr [si].p_num_sect
  1722.         mov    dx, Word Ptr [si].p_num_sect+2
  1723.         mov    cl, 11
  1724.         shr    ax, cl
  1725.         mov    cl, 5
  1726.         shl    dx, cl
  1727.         or    ax, dx
  1728.         mov    cx, 6
  1729.         mov    si, di
  1730.         call    SPRINTF_INT
  1731.         add    di, 6
  1732.         mov    al, 'M'
  1733.         stosb
  1734.         mov    al, ' '
  1735.         stosb
  1736.         jmp    @@end
  1737.     @@no_part:
  1738.         mov    cx, 8
  1739.         mov    al,' '
  1740.         rep
  1741.          stosb
  1742.     @@end:
  1743.         mov    al, 0
  1744.         stosb
  1745.         POP_REGS
  1746.         ret
  1747. SPRINTF_MENU    ENDP
  1748.         ;
  1749.         ;
  1750.         ;
  1751. SPRINTF_INT    PROC    NEAR
  1752.         ;
  1753.         ;  Input:  AX - Integer to print
  1754.         ;          CX - Field len
  1755.         ;       DS:SI - String to fill
  1756.         ;
  1757.         PUSH_REGS
  1758.         mov    di, cx
  1759.         mov    bx, 10
  1760.         xor    cx, cx
  1761. @@next:
  1762.         xor    dx, dx
  1763.         div    bx
  1764.         push    dx
  1765.         inc    cx
  1766.         cmp    ax, 0
  1767.         jne    @@next
  1768.         mov    bx, di
  1769.         cmp    cx, bx
  1770.         jae    @@digit
  1771.         sub    bx, cx
  1772.         mov    al, ' '
  1773. @@space:
  1774.         mov    [si], al
  1775.         inc    si
  1776.         dec    bx
  1777.         jne    @@space
  1778. @@digit:
  1779.         pop    ax
  1780.         add    ax, '0'
  1781.         mov    [si], al
  1782.         inc    si
  1783.         dec    cx
  1784.         jne    @@digit
  1785.  
  1786.         xor    ax, ax
  1787.         mov    [si], al
  1788.         POP_REGS
  1789.         ret
  1790. SPRINTF_INT    ENDP
  1791.         ;
  1792.         ;
  1793.         ;
  1794. SHOW_ERROR    PROC    NEAR
  1795.         ;
  1796.         ;  DS:SI - String to print
  1797.         ;
  1798.         PUSH_REGS
  1799.         
  1800.         push    ds
  1801.         mov    di, si
  1802.         pop    es
  1803.         mov    cx, 76
  1804.         mov    al, 0
  1805.         repne
  1806.           scasb
  1807.         inc    cx
  1808.         mov    dx, 80
  1809.         sub    dx, cx
  1810.         mov    dh, 4
  1811.         mov    bx, cx
  1812.         shr    bx, 1
  1813.         mov    bh, 12
  1814.         
  1815.         push    si
  1816.         lea    si, SAV_BUFFER_ERR
  1817.         call    _save_window
  1818.         mov    ah, Yellow+BakRed
  1819.         lea    si, Border
  1820.         call    _border_window
  1821.         pop    si
  1822.         
  1823.         push    bx
  1824.         push    dx
  1825.  
  1826.         mov    ah, BrWhite+BakRed
  1827.         add    bx, 0102h
  1828.         xor    cx, cx
  1829.         mov    cl, dl
  1830.         sub    cl, 4
  1831.  
  1832.         call _write_string
  1833.         
  1834.         mov    ah, Black+BakWhite
  1835.         mov    bl, 38
  1836.         inc    bh
  1837.         lea    si, Mesg_OK
  1838.         call    _write_string
  1839. @@again:
  1840.         mov    ah, 0
  1841.         int    16h
  1842.         cmp    al, 0Dh    ; Enter
  1843.         je    @@end
  1844.         cmp    al, 1Bh    ; ESC
  1845.         jne    @@again
  1846. @@end:
  1847.         pop    dx
  1848.         pop    bx
  1849.         lea    si, SAV_BUFFER_ERR
  1850.         call    _load_window
  1851.         
  1852.         POP_REGS
  1853.         ret
  1854. SHOW_ERROR    ENDP
  1855.         ;
  1856.         ;
  1857.         ;
  1858.  
  1859. GET_PASSWORD    PROC    NEAR
  1860.         ;
  1861.         ;  Input:  none
  1862.         ;  Output: AX - encrypted password
  1863.         ;
  1864.         mov    bl, 20
  1865.         mov    bh, DOT_Y
  1866.         mov    dl, 28
  1867.         mov    dh, 3
  1868.         lea    si, SAV_BUFFER_ERR
  1869.         call    _save_window
  1870.         mov    ah, Yellow+BakWhite
  1871.         lea    si, Border
  1872.         call    _border_window
  1873.  
  1874.         push    bx
  1875.         push    dx
  1876.  
  1877.         mov    ah, Black+BakWhite
  1878.         add    bl, 2
  1879.         add    bh, 1
  1880.         lea    si, MesgEnterPassword
  1881.         call    _write_string
  1882.  
  1883.         add    bl, 16
  1884.         mov    dl, 8
  1885.         mov    dh, 1
  1886.         lea    si, TMP
  1887. @@clear_it:
  1888.         mov    cx, 0
  1889. @@next_key:        
  1890.         mov    di, si
  1891.         add    di, cx
  1892.         mov    al, 0
  1893.         stosb
  1894.         sub    di, 1
  1895.  
  1896.         mov    ah, BrWhite+BakBlack
  1897.         call    _clear_window
  1898.  
  1899.         push    cx
  1900.         push    bx
  1901.         jcxz    @@empty
  1902.         mov    al, '*'
  1903. @@next_char:
  1904.         call    _write_char
  1905.         add    bx, 1
  1906.         loop    @@next_char
  1907. @@empty:
  1908.         call    _move_cursor
  1909.         pop    bx
  1910.         pop    cx
  1911.  
  1912.         mov    ah, 10h
  1913.         int    16h
  1914.         cmp    al, 0Dh    ; Enter
  1915.         je    @@break_out
  1916.         cmp    al, 1Bh    ; ESC
  1917.         je    @@clear_it
  1918.         cmp    al, 08h    ; BkSp
  1919.         je    @@bk_sp
  1920.  
  1921.         cmp    cx, 8
  1922.         je    @@next_key
  1923.         stosb
  1924.         inc    cx
  1925.         jmp    @@next_key
  1926. @@bk_sp:
  1927.         cmp    cx, 0
  1928.         je    @@next_key
  1929.         dec    cx
  1930.         
  1931.         jmp    @@next_key
  1932. @@break_out:
  1933.         call    _hide_cursor
  1934.  
  1935.         pop    dx
  1936.         pop    bx
  1937.  
  1938.         lea    si, SAV_BUFFER_ERR
  1939.         call    _load_window
  1940.  
  1941.         push    ds
  1942.         lea    si, TMP
  1943.         push    si
  1944.  
  1945.         call    _encrypt_password
  1946.         add    sp, 4
  1947.         
  1948.         push    ax
  1949.         mov    al, 0
  1950.         mov    cx, 9
  1951.         lea    di, TMP
  1952.         rep
  1953.           stosb
  1954.         pop    ax
  1955.  
  1956.         ret
  1957. GET_PASSWORD    ENDP
  1958.  
  1959.         ;
  1960.         ;
  1961.         ;
  1962.  
  1963. SETUP_MENU    PROC    NEAR
  1964.         PUSH_REGS
  1965.         mov    bl, 29
  1966.         mov    bh, 12
  1967.         mov    dl, 34
  1968.         mov    dh, 3
  1969.         lea    si, SAV_BUFFER_ERR
  1970.         call    _save_window
  1971.         mov    ah, Yellow+BakWhite
  1972.         lea    si, Border
  1973.         call    _border_window
  1974.         mov    ah, Black+BakWhite
  1975.         add    bx, 0102h
  1976.         lea    si, MesgSetTimeout
  1977.         call    _write_string
  1978.  
  1979.         mov    dl, adv_timeout
  1980.     @@while:
  1981.         xor    ax, ax
  1982.         mov    al, dl
  1983.         mov    cx, 3
  1984.         lea    si, TMP
  1985.         call    SPRINTF_INT
  1986.         mov    ah, BrWhite+BakBlack
  1987.         mov    bl, 58
  1988.         mov    bh, 13
  1989.         call    _write_string
  1990.     @@keys:
  1991.         mov    ah, 10h
  1992.         int    16h
  1993.         cmp    ax, 011Bh    ; ESC
  1994.         je    @@break
  1995.         cmp    ax, 1C0Dh    ; Enter
  1996.         je    @@save
  1997.         cmp    al, 2Bh      ; '+'
  1998.         je    @@inc
  1999.         cmp    al, 2Dh      ; '-'
  2000.         jne    @@keys
  2001.         cmp    dl, 0
  2002.         jz    @@keys
  2003.         dec    dl
  2004.         jmp    @@while
  2005.     @@inc:
  2006.         cmp    dl, 100
  2007.         je    @@keys
  2008.         inc    dl
  2009.         jmp    @@while
  2010.     @@save:
  2011.         mov    adv_timeout, dl
  2012.     @@break:
  2013.         mov    bl, 29
  2014.         mov    bh, 12
  2015.         mov    dl, 34
  2016.         mov    dh, 3
  2017.         lea    si, SAV_BUFFER_ERR
  2018.         call    _load_window
  2019.  
  2020.         POP_REGS
  2021.         ret
  2022. SETUP_MENU    ENDP
  2023.  
  2024.         ;
  2025.         ;
  2026.         ;
  2027.  
  2028. FILL_KEYB_BUFFER    PROC    NEAR
  2029.         cmp    ALT_ENTER, 1
  2030.         je    @@alt_enter
  2031.         cmp    FILL_KB_BUFFER, 0
  2032.         je    @@end
  2033.         mov    bx, ACT_MENU
  2034.         shl    bx, 1
  2035.         mov    bx, MENU_PTR[bx]
  2036.         mov    cx, [bx].m_num_keys
  2037.         cmp    cx, 0
  2038.         je    @@end
  2039.  
  2040.         push    es
  2041.         mov    ax, 0
  2042.         mov    es, ax
  2043.         lea    si, [bx].m_keys
  2044.         mov    di, 41Ah
  2045.         mov    ax, 01Eh
  2046.         stosw
  2047.         add    ax, cx
  2048.         add    ax, cx
  2049.         stosw
  2050.         rep
  2051.           movsw
  2052.         pop    es
  2053.         jmp    @@end
  2054.     @@alt_enter:        ; We have to wait until user releases ALT key
  2055.     @@not_yet:
  2056.         mov    ah, 02
  2057.         int    16h        ; Read keyboard status
  2058.         test    al, 8
  2059.         jnz    @@not_yet
  2060.     @@end:
  2061.         ret
  2062. FILL_KEYB_BUFFER    ENDP
  2063.  
  2064.         ;
  2065.         ;
  2066.         ;
  2067.  
  2068. DOT_BAR        PROC    NEAR
  2069.         ;
  2070.         ;  Print dots and check if key is pressed (key in al)
  2071.         ;
  2072.         ;  CF - set if key was pressed
  2073.         ;
  2074.         PUSH_REGS
  2075.  
  2076.         mov    bl, KEYS_X
  2077.         mov    bh, KEYS_Y
  2078.         mov    dl, KEYS_W
  2079.         mov    dh, 1
  2080.         lea    si, SAV_BUFFER_ERR
  2081.         call    _save_window
  2082.  
  2083.         mov    bl, DOT_X-1
  2084.         mov    bh, DOT_Y
  2085.         mov    dl, DOT_NUM+2
  2086.         mov    dh, 1
  2087.         mov    ah, DOTBAR_COLOR
  2088.         call    _clear_window
  2089.  
  2090.         mov    ah, KEYS_TXT_COLOR
  2091.         mov    bl, KEYS_X
  2092.         mov    bh, KEYS_Y
  2093.         lea    si, BottomKeysText
  2094.         call    _write_string
  2095.         mov    ah, KEYS_KEY_COLOR
  2096.         lea    si, BottomKeysESC
  2097.         call    _write_string
  2098.  
  2099.         mov    cx, DOT_NUM
  2100.         mov    al, DOT1
  2101.         mov    ah, DOTBAR_COLOR
  2102.         mov    bl, DOT_X
  2103.         mov    bh, DOT_Y
  2104.     @@L1:
  2105.         call    _write_char
  2106.         inc    bl
  2107.         loop    @@L1
  2108.  
  2109.         mov    cx, DOT_NUM
  2110.         mov    bl, DOT_X
  2111.         mov    bh, DOT_Y
  2112.     @@L2:
  2113.         mov    ah, 11h        ; Check if key is pressed
  2114.         int    16h
  2115.         jnz    @@key        ; There is no key waiting
  2116.  
  2117.         mov    al, DOT2
  2118.         mov    ah, DOTBAR_COLOR
  2119.         call    _write_char
  2120.         inc    bl
  2121.  
  2122.         push    bx
  2123.         push    cx
  2124.         mov    cx, TICKS_PER_DOT
  2125.     @@L3:
  2126.         push    cx
  2127.         mov    ah, 0
  2128.         int    1Ah        ; Read System Timer
  2129.         mov    bx, dx
  2130.  
  2131.     @@WT1:    int    1Ah        ; Wait one timer tick
  2132.         cmp    bx, dx
  2133.         je     @@WT1
  2134.         pop    cx
  2135.         loop    @@L3
  2136.  
  2137.         pop    cx
  2138.         pop    bx
  2139.  
  2140.         loop    @@L2
  2141.         clc
  2142.         jmp    @@end
  2143.     @@key:
  2144.         mov    al, DOT2
  2145.         mov    ah, DOTBAR_COLOR
  2146.         call    _write_char
  2147.         inc    bl
  2148.         loop    @@key
  2149.         stc
  2150.     @@end:
  2151.         pushf
  2152.         mov    bl, KEYS_X
  2153.         mov    bh, KEYS_Y
  2154.         mov    dl, KEYS_W
  2155.         mov    dh, 1
  2156.         lea    si, SAV_BUFFER_ERR
  2157.         call    _load_window
  2158.         popf
  2159.  
  2160.         POP_REGS
  2161.         ret
  2162. DOT_BAR        ENDP
  2163.  
  2164. ;----------------------------------------------------------------
  2165. CHECK_LAST_CYL    PROC    NEAR
  2166.         mov    ax, SECT_PER_TRACK
  2167.         mov    dx, DISK_NUM_CYLS
  2168.         cmp    dx, 1024
  2169.         je    @@end
  2170.         mul    dx
  2171.         mov    cx, 1
  2172.         mov    bx, 7C00h
  2173.         call    READ_N_SECT
  2174.         jc    @@end
  2175.         inc    DISK_NUM_CYLS
  2176.     @@end:
  2177.         ret
  2178. CHECK_LAST_CYL    ENDP
  2179.  
  2180. ;----------------------------------------------------------------
  2181.  
  2182. WRITE_N_SECT    PROC    NEAR
  2183.         ;
  2184.         ;
  2185.         ;    ES:BX - Destination address
  2186.         ;    DX:AX - Relative sector on disk
  2187.         ;    CX    - Number of sectors to read
  2188.         ;
  2189.         ;    Returns: Flag CF set if error
  2190.         ;
  2191.         push    ax
  2192.         push    bx
  2193.         push    cx
  2194.         push    dx
  2195. @@next_sect:
  2196.         push    ax
  2197.         push    cx
  2198.         push    dx
  2199.         call    REL_SECT_TO_CHS
  2200.         call    WRITE_SECT
  2201.         pop    dx
  2202.         pop    cx
  2203.         pop    ax
  2204.         jc    @@end
  2205.  
  2206.         add    ax, 1
  2207.         adc    dx, 0
  2208.  
  2209.         add    bx, SECT_SIZE
  2210.  
  2211.         loop    @@next_sect
  2212. @@end:
  2213.         pop    dx
  2214.         pop    cx
  2215.         pop    bx
  2216.         pop    ax
  2217.         ret
  2218. WRITE_N_SECT    ENDP
  2219.         ;
  2220.         ;
  2221.         ;
  2222. WRITE_SECT    PROC    NEAR
  2223.         ;
  2224.         ;   ES:BX - Address
  2225.         ;   CX,DX - CHS
  2226.         ;
  2227.         ;   Returns: CF set if error
  2228.         ;
  2229.         push    si
  2230.         mov    si, 3        ; We will try at most three times
  2231. @@try_again:
  2232.         mov    ax, 0301h    ; Write (AH=03) 1 Sector (AL=01)
  2233.         int    13h
  2234.         jnc    @@end
  2235.                     ; We get here if there was an error
  2236.         mov    ah, 0        ; We will try to reset device
  2237.         int    13h
  2238.     
  2239.         dec    si
  2240.         jnz    @@try_again
  2241.         ;
  2242.         ; We have tried three times, so we will give up
  2243.         ;
  2244.         stc
  2245.     @@end:
  2246.         pop    si
  2247.         ret
  2248. WRITE_SECT    ENDP
  2249. ;----------------------------------------------- CONIO ROUTINES -------
  2250.  
  2251. _conio_init    PROC    NEAR
  2252.         push    ax
  2253.         push    bx
  2254.  
  2255.         mov    ah,0Fh        ; Check current video mode
  2256.         int    10h
  2257.  
  2258.         cmp    al,07h
  2259.         je    @@Mono
  2260.         cmp    al,03h
  2261.         je    @@Color
  2262.     @@Reset:
  2263.         mov    ax,03        ; If unknown set Color 80x25
  2264.         int    10h
  2265.     @@Color:  
  2266.         mov    Word Ptr _ScreenArea+2, 0B800h
  2267.         jmp    @@skip1
  2268.     @@Mono:
  2269.         mov    Word Ptr _ScreenArea+2, 0B000h
  2270.     @@skip1:
  2271.         push    ds
  2272.         mov    ax, 0
  2273.         mov    ds, ax
  2274.         mov    bx, 484h
  2275.         mov    al, [bx]
  2276.         pop    ds
  2277.         inc    al
  2278.         mov    _ScreenHeight, al
  2279.         mov    ah,0Fh
  2280.         int    10h
  2281.         mov    _ScreenWidth, ah
  2282.         mov    al, _ScreenHeight
  2283.         mov    ah, _ScreenWidth
  2284.         mul    ah
  2285.         mov    _ScreenLength, ax
  2286.         mov    Word Ptr _ScreenArea, 0h
  2287.  
  2288.         pop    bx
  2289.         pop    ax        
  2290.         ret
  2291. _conio_init    ENDP
  2292.  
  2293.  
  2294. _conio_exit    PROC    NEAR
  2295.         ret
  2296. _conio_exit    ENDP
  2297.  
  2298.  
  2299. ;----------------------------------------------------------------
  2300.         
  2301.         ;
  2302.         ;  Cursor position:  BL=X  BH=Y
  2303.         ;
  2304.         
  2305. _move_cursor    PROC    NEAR
  2306.         PUSH_REGS
  2307.         mov    dx, bx
  2308.         sub    dx, 0101h
  2309.         mov    ah, 02h
  2310.         mov    bh, 0
  2311.         int    10h
  2312.         POP_REGS
  2313.         ret
  2314. _move_cursor    ENDP
  2315.  
  2316.  
  2317. _hide_cursor    PROC    NEAR
  2318.         push    bx
  2319.         mov    bl, 1
  2320.         mov    bh, 26
  2321.         call    _move_cursor
  2322.         pop    bx
  2323.         ret
  2324. _hide_cursor    ENDP
  2325.  
  2326.  
  2327. _save_cursor    PROC    NEAR
  2328.         PUSH_REGS
  2329.         mov    ah, 3
  2330.         mov    bh, 0
  2331.         int    10h
  2332.         mov    CURSOR_SAVE_XY, dx
  2333.         POP_REGS
  2334.         ret
  2335. _save_cursor    ENDP
  2336.  
  2337.  
  2338. _restore_cursor    PROC    NEAR
  2339.         PUSH_REGS
  2340.         mov    ah, 2
  2341.         mov    bh, 0
  2342.         mov    dx, CURSOR_SAVE_XY
  2343.         int    10h
  2344.         POP_REGS
  2345.         ret
  2346. _restore_cursor    ENDP
  2347.  
  2348. ;----------------------------------------------------------------
  2349. WINDOW_XY    MACRO
  2350.         push    ax
  2351.         mov    al, _ScreenWidth
  2352.         sub    bx, 0101h
  2353.         mul    bh
  2354.         xor    bh, bh
  2355.         add    ax, bx
  2356.         shl    ax, 1
  2357.         add    di, ax
  2358.         pop    ax
  2359. ENDM
  2360.  
  2361. WINDOW_WH    MACRO
  2362.         xor    cx, cx
  2363.         xor    bx, bx
  2364.         mov    cl, dl
  2365.         mov    bl, _ScreenWidth
  2366.         sub    bx, cx
  2367.         shl    bx, 1
  2368.         xor    cx, cx
  2369. ENDM
  2370. ;----------------------------------------------------------------
  2371.  
  2372.  
  2373. _write_char    PROC    NEAR
  2374.         ;
  2375.         ; Input: AL=Char  BL=X
  2376.         ;     AH=Attr  BH=Y
  2377.         ;
  2378.         PUSH_REGS
  2379.  
  2380.         les    di, _ScreenArea
  2381.  
  2382.         WINDOW_XY
  2383.  
  2384.         stosw
  2385.  
  2386.         POP_REGS
  2387.         ret
  2388. _write_char    ENDP
  2389.  
  2390.  
  2391.  
  2392. _write_string    PROC    NEAR
  2393.         ;
  2394.         ; Input: DS:SI=Str   BL=X
  2395.         ;        AH=Attr  BH=Y
  2396.         ;
  2397.         PUSH_REGS
  2398.  
  2399.         les    di, _ScreenArea
  2400.  
  2401.         WINDOW_XY
  2402.  
  2403.         jmp    @@first
  2404.     @@next:
  2405.         stosw
  2406.     @@first:
  2407.         lodsb
  2408.         cmp    al, 0
  2409.         jne    @@next
  2410.  
  2411.         POP_REGS
  2412.         ret
  2413. _write_string    ENDP
  2414.  
  2415.  
  2416. ;----------------------------------------------------------------
  2417.  
  2418.  
  2419. _save_window    PROC    NEAR
  2420.         ;
  2421.         ; Input: DS:SI=Buf  BL=X  DL=W
  2422.         ;                BH=Y  DH=H
  2423.         ;
  2424.         PUSH_REGS
  2425.         
  2426.         les    di, _ScreenArea
  2427.         
  2428.         WINDOW_XY
  2429.         WINDOW_WH
  2430.         
  2431.         push    es
  2432.         push    ds
  2433.         xchg    si, di
  2434.         pop    es
  2435.         pop    ds
  2436.  
  2437.     @@next_row:
  2438.         mov    cl, dl
  2439.         rep
  2440.          movsw
  2441.         add    si, bx
  2442.         dec    dh
  2443.         jne    @@next_row
  2444.  
  2445.         POP_REGS
  2446.         ret
  2447. _save_window    ENDP
  2448.  
  2449.  
  2450.  
  2451. _load_window    PROC    NEAR
  2452.         ;
  2453.         ; Input: DS:SI=Buf  BL=X  DL=W
  2454.         ;                BH=Y  DH=H
  2455.         ;
  2456.         PUSH_REGS
  2457.  
  2458.         les    di, _ScreenArea
  2459.         
  2460.         WINDOW_XY
  2461.         WINDOW_WH
  2462.  
  2463.     @@next_row:
  2464.         mov    cl, dl
  2465.         rep
  2466.          movsw
  2467.         add    di, bx
  2468.         dec    dh
  2469.         jne    @@next_row
  2470.  
  2471.         POP_REGS
  2472.         ret
  2473. _load_window ENDP
  2474.  
  2475.  
  2476. ;----------------------------------------------------------------
  2477.  
  2478.  
  2479. _clear_window    PROC    NEAR
  2480.         ;
  2481.         ; Input: AH=Attr  BL=X  DL=W
  2482.         ;              BH=Y  DH=H
  2483.         ;
  2484.         PUSH_REGS
  2485.  
  2486.         les    di, _ScreenArea
  2487.         
  2488.         WINDOW_XY
  2489.         WINDOW_WH
  2490.  
  2491.         mov    al,' '
  2492.     @@next_row:
  2493.         mov    cl, dl
  2494.         rep
  2495.          stosw
  2496.         add    di, bx
  2497.         dec    dh
  2498.         jne    @@next_row
  2499.  
  2500.         POP_REGS
  2501.         ret
  2502. _clear_window    ENDP
  2503.  
  2504.  
  2505.  
  2506. _scroll_window    PROC    NEAR
  2507.         ;
  2508.         ; Input: AL=Len   BL=X  DL=W
  2509.         ;     AH=Attr  BH=Y  DH=H
  2510.         ;
  2511.         PUSH_REGS
  2512.  
  2513.         les    di, _ScreenArea
  2514.         
  2515.         WINDOW_XY
  2516.         WINDOW_WH
  2517.         
  2518.         push    ax
  2519.         imul    Byte Ptr _ScreenWidth
  2520.         shl    ax, 1
  2521.         mov    si, di
  2522.         add    si, ax
  2523.         pop    ax
  2524.         cmp    si, di
  2525.         ja    @@scroll
  2526.  
  2527.         push    ax
  2528.         mov    al, dh
  2529.         dec    al
  2530.         mul    Byte Ptr _ScreenWidth
  2531.         add    di, ax
  2532.         add    si, ax
  2533.         mov    bl, dl
  2534.         shl    bx, 1
  2535.         neg    bx
  2536.         pop    ax
  2537.         neg    al
  2538.  
  2539.     @@scroll:
  2540.             push    es
  2541.         pop    ds
  2542.     @@next_row:
  2543.         mov    cl, dl
  2544.         rep
  2545.          movsw
  2546.         add    si, bx
  2547.         add    di, bx
  2548.         dec    dh
  2549.         jne    @@next_row
  2550.  
  2551.         mov    dh, al
  2552.         mov    al,' '
  2553.     @@clr_row:
  2554.         mov    cl, dl
  2555.         rep
  2556.          stosw
  2557.         add    si, bx
  2558.         add    di, bx
  2559.         dec    dh
  2560.         jne    @@clr_row
  2561.  
  2562.         POP_REGS
  2563.         ret
  2564. _scroll_window    ENDP
  2565.  
  2566.  
  2567.  
  2568. _border_window    PROC    NEAR
  2569.         ;
  2570.         ; Input: DS:SI=Brdr  BL=X  DL=W
  2571.         ;        AH=Attr  BH=Y  DH=H
  2572.         ;
  2573.         PUSH_REGS
  2574.  
  2575.         les    di, _ScreenArea
  2576.         
  2577.         WINDOW_XY
  2578.         WINDOW_WH
  2579.  
  2580.         sub    dx, 0202h
  2581.  
  2582.         lodsb            ; Upper row
  2583.         stosw
  2584.         mov    cl, dl
  2585.         lodsb
  2586.         rep
  2587.           stosw
  2588.         lodsb
  2589.         stosw
  2590.         add    di, bx
  2591.         cmp    dh, 00
  2592.         je    @@NoMiddleRows
  2593.     
  2594.     @@next_row:
  2595.         lodsb            ; All rows in the middle
  2596.         stosw
  2597.         mov    cl, dl
  2598.         lodsb
  2599.         cmp    al, 00
  2600.         je    @@NoFill
  2601.         rep
  2602.           stosw
  2603.         jmp    @@FillDone
  2604.     @@NoFill:
  2605.         add    di, cx
  2606.         add    di, cx
  2607.     @@FillDone:
  2608.         lodsb
  2609.         stosw
  2610.         add    di, bx
  2611.         sub    si, 03
  2612.         dec    dh
  2613.         jne    @@next_row
  2614.  
  2615.  @@NoMiddleRows:
  2616.         add    si, 03        ; Bottom row
  2617.         lodsb
  2618.         stosw
  2619.         mov    cl, dl
  2620.         lodsb
  2621.         rep
  2622.           stosw
  2623.         lodsb
  2624.         stosw
  2625.  
  2626.         POP_REGS
  2627.         ret
  2628. _border_window    ENDP
  2629.  
  2630. ;----------------------------------------------------------------------
  2631. _encrypt_password    PROC    FAR
  2632.     push    bp
  2633.     mov    bp,sp
  2634.     push    ds
  2635.     push    si
  2636.     push    di
  2637.  
  2638.     lds    si, dword ptr [bp+6]
  2639.     mov    bx, 12345
  2640.     mov    di, 0
  2641.  
  2642.     jmp    @@check_cond
  2643. @@next_char:
  2644.  
  2645.     mov    ah, 0
  2646.     
  2647.     mov    cx, ax
  2648.     xor    cx, bx
  2649.  
  2650.     shl    ax, 2
  2651.     add    ax, 7
  2652.     
  2653.     shr    bx, 1
  2654.     add    bx, 3
  2655.     
  2656.     mul    bx
  2657.     add    ax, cx
  2658.  
  2659.     mov    bx, ax
  2660.     mov    di, ax
  2661.  
  2662. @@check_cond:
  2663.     lodsb
  2664.     or    al, al
  2665.     jne    @@next_char
  2666.     
  2667.     mov    ax, di
  2668.  
  2669.     pop    di
  2670.     pop    si
  2671.     pop    ds
  2672.     pop    bp
  2673.     retf
  2674. _encrypt_password    ENDP
  2675. ;----------------------------------------------------------------------
  2676. GAP2        PROC
  2677. GAPLEN2        EQU    (ADV_CODE_SIZE-(GAP2-_ADV_MANAGER))
  2678. IF GAPLEN2
  2679.         DB    GAPLEN2 DUP(0)    
  2680. ENDIF
  2681. GAP2        ENDP
  2682. ;----------------------------------------------------------------------
  2683.  
  2684. ADV_MAN_TEXT    ENDS
  2685.  
  2686.         END
  2687.