Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; KolibriOS bootloader
  2. ; this code has been written by diamond in 2005,2006 specially for KolibriOS
  3.  
  4.         format  binary
  5.         use16
  6.  
  7.         org     0xD000
  8.  
  9. ; may be changed from ldklbr.vxd
  10. partition_start dd -1
  11. boot_drive db 80h
  12. imgnameofs      dw      menuet_img_name - 0xD000
  13.  
  14. macro out_delay port
  15. {
  16.         out     port, al
  17.         jcxz    $+2
  18. }
  19.  
  20.         cli
  21. ; reprogram IRQs
  22.         mov     al, 11h
  23.         out_delay 20h
  24.         out_delay 0A0h
  25.         mov     al, 8
  26.         out_delay 21h
  27.         mov     al, 70h
  28.         out_delay 0A1h
  29.         mov     al, 4
  30.         out_delay 21h
  31.         mov     al, 2
  32.         out_delay 0A1h
  33.         mov     al, 1
  34.         out_delay 21h
  35.         out_delay 0A1h
  36.  
  37.         mov     al, 0
  38.         out_delay 21h
  39.         out_delay 0A1h
  40.        
  41. ; set videomode
  42.         mov     ax, 3
  43.         int     10h
  44. ; reprogram timer
  45.         mov     al, 00110100b
  46.         out_delay 43h
  47.         mov     al, 0FFh
  48.         out_delay 40h
  49.         out_delay 40h
  50.  
  51. ; reset mouse
  52.         mov     ax, 0C201h
  53.         int     15h
  54.  
  55.         jmp     start
  56.  
  57. out_string:
  58.         lodsb
  59.         test    al, al
  60.         jz      .xxx
  61.         mov     ah, 0Eh
  62.         mov     bx, 7
  63.         int     10h
  64.         jmp     out_string
  65. .xxx:   ret
  66.  
  67. relative_read:
  68.         add     eax, [partition_start]
  69.  
  70. ; read from hard disk
  71. ; drive_size must be already initialized
  72. ; in: eax = absolute sector
  73. ;     cx = number of sectors
  74. ;     es:bx -> buffer
  75. read:
  76.         pushad
  77.         cmp     eax, [drive_size]
  78.         jb      .old_style
  79. ; new style - LBA, function 42
  80.         cmp     [has_lba], 0
  81.         jz      disk_error
  82. ; allocate disk address packet on the stack
  83. ; qword +8: absolute block number
  84.         push    dword 0         ; dword +C is high dword
  85.         push    eax             ; dword +8 is low dword
  86. ; dword +4: buffer address
  87.         push    es              ; word +6 is segment
  88.         push    bx              ; word +4 is offset
  89. ; word +2: number of blocks = 1
  90. ; word +0: size of packet = 10h
  91.         push    dword 10010h
  92. ; now pair ss:sp contain address of disk address packet
  93. .patch1:
  94.         mov     ax, 4200h
  95.         mov     dl, [boot_drive]
  96.         mov     si, sp
  97.         push    ds
  98.         push    ss
  99.         pop     ds
  100.         int     13h
  101.         pop     ds
  102.         add     sp, 10h
  103. .end:
  104.         popad
  105.         jc      disk_error
  106.         add     bx, 200h
  107.         inc     eax
  108.         dec     cx
  109.         jnz     read
  110.         ret
  111. .old_style:
  112. ; old style - CHS, function 2
  113. ; convert absolute sector in eax to cylinder-head-sector coordinates
  114. ; calculate sector
  115.         xor     edx, edx
  116.         movzx   ecx, [sectors]
  117.         div     ecx
  118. ; sectors are counted from 1
  119.         inc     dl
  120.         mov     cl, dl          ; low 6 bits of cl = sector number
  121. ; calculate head number
  122.         shld    edx, eax, 10h   ; convert eax to dx:ax
  123.         div     [heads]
  124.         mov     dh, dl          ; dh = head
  125.         mov     ch, al          ; ch = low 8 bits of cylinder
  126.         shl     ah, 6
  127.         or      cl, ah          ; high 2 bits of cl = high 2 bits of cylinder
  128. .patch2:
  129.         mov     ax, 201h        ; function 2, al=1 - number of sectors
  130.         mov     dl, [boot_drive]
  131.         int     13h
  132.         jmp     .end
  133.  
  134. disk_error:
  135.         mov     si, disk_error_msg
  136.         call    out_string
  137.         jmp     $
  138.  
  139. has_lba db      0
  140.  
  141. disk_error_msg  db      'Disk read error!',0
  142. start_msg       db      2,' KolibriOS bootloader, running on ',0
  143. errfs_msg       db      'unknown filesystem, cannot continue',0
  144. fat16_msg       db      'FAT12/FAT16 - unsupported',13,10,0
  145. fat32_msg       db      'FAT32',13,10,0
  146. ntfs_msg        db      'NTFS',13,10,0
  147. error_msg       db      'Error'
  148. colon           db      ': ',0
  149. mft_string      db      'MFT',0
  150. root_string     db      '\',0
  151. noindex_string  db      '$INDEX_ROOT not found',0
  152. invalid_read_request_string db 'cannot read attribute',0
  153. nodata_string   db      '$DATA '
  154. notfound_string db      'not found',0
  155. directory_string db     'is a directory',0
  156. notdir_string   db      'not a directory',0
  157. fragmented_string db    'too fragmented file',0
  158. exmem_string    db      'extended memory error',0
  159. bad_cluster_string db   'bad cluster',0
  160. data_error_msg db       'data error',0
  161.  
  162. start:
  163.         xor     ax, ax
  164.         mov     ds, ax
  165.         mov     es, ax
  166. ; our stack is 4Kb-2b!!! (0xFFE)
  167.         mov     ss, ax
  168.         mov     esp, 0FFFEh
  169.         cld
  170.         sti
  171. ; calculate drive size
  172.         mov     dl, [boot_drive]
  173.         mov     ah, 8   ; 8 = get drive parameters
  174.         int     13h
  175. ; now: CF is set on error;
  176. ; ch = low 8 bits of maximum cylinder number
  177. ; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number
  178. ; dh = maximum head number
  179.         jnc     @f
  180.         mov     cx, -1
  181.         mov     dh, cl
  182. @@:
  183.         movzx   ax, dh
  184.         inc     ax
  185. ; ax = number of heads
  186.         mov     [heads], ax
  187.         mov     dl, cl
  188.         and     dx, 3Fh
  189. ; dx = number of sectors
  190. ; (note that sectors are counted from 1, and maximum sector number = number of sectors)
  191.         mov     [sectors], dx
  192.         mul     dx
  193.         xchg    cl, ch
  194.         shr     ch, 6
  195.         inc     cx
  196. ; cx = number of cylinders
  197.         mov     [cyls], cx
  198.         mul     cx
  199.         mov     word [drive_size], ax
  200.         mov     word [drive_size+2], dx
  201. ; this drive supports LBA?
  202.         mov     dl, [boot_drive]
  203.         mov     ah, 41h
  204.         mov     bx, 55AAh
  205.         int     13h
  206.         jc      .no_lba
  207.         cmp     bx, 0AA55h
  208.         jnz     .no_lba
  209.         test    cl, 1
  210.         jz      .no_lba
  211.         inc     [has_lba]
  212. .no_lba:
  213. ; say hi to user
  214.         mov     si, start_msg
  215.         call    out_string
  216.         mov     eax, [partition_start]
  217.         cmp     eax, -1
  218.         jnz     @f
  219. ; now read first sector to determine file system type
  220. ; first sector of disk is MBR sector
  221.         xor     eax, eax
  222.         mov     cx, 1
  223.         mov     bx, 500h
  224.         call    read
  225.         mov     eax, [6C6h]     ; first disk
  226.         mov     [partition_start], eax
  227. @@:
  228.         mov     cx, 1
  229.         mov     bx, 500h
  230.         call    read
  231.         movzx   ax, byte [50Dh]
  232.         mov     [sect_per_clust], ax
  233. ; determine file system
  234.         cmp     dword [536h], 'FAT1'
  235.         jz      fat1x
  236.         cmp     dword [552h], 'FAT3'
  237.         jz      fat32
  238.         cmp     dword [503h], 'NTFS'
  239.         jz      ntfs
  240. ;       mov     si, errfs_msg           ; already is
  241.         call    out_string
  242.         jmp     $
  243. fat1x:
  244.         mov     si, fat16_msg
  245.         call    out_string
  246.         jmp     $
  247. fat32:
  248.         mov     si, fat32_msg
  249.         call    out_string
  250.         movzx   eax, word [50Bh]        ; bytes_per_sect
  251.         movzx   ebx, byte [50Dh]        ; sects_per_clust
  252.         mul     ebx
  253.         mov     [cluster_size], eax
  254.         movzx   ebx, word [50Eh]        ; reserved_sect
  255.         mov     [fat_start], ebx
  256.         movzx   eax, byte [510h]        ; num_fats
  257.         mul     dword [524h]            ; sect_fat
  258.         add     eax, ebx
  259. ; cluster 2 begins from sector eax
  260.         movzx   ebx, byte [50Dh]        ; sects_per_clust
  261.         sub     eax, ebx
  262.         sub     eax, ebx
  263.         mov     [data_start], eax
  264. ; parse image name
  265.         add     [imgnameofs], 0xD000
  266.         mov     eax, [52Ch]     ; root_cluster
  267.         mov     [cur_obj], root_string
  268. .parsedir:
  269.         push    ax
  270.         mov     si, [imgnameofs]
  271.         push    si
  272. @@:
  273.         lodsb
  274.         cmp     al, '\'
  275.         jz      @f
  276.         cmp     al, 0
  277.         jnz     @b
  278. @@:
  279.         xchg    ax, [esp+2]
  280.         mov     byte [si-1], 0
  281.         mov     [imgnameofs], si
  282.         call    fat32_parse_dir
  283.         pop     cx
  284.         test    cl, cl
  285.         jz      .end
  286.         test    byte [di+0Bh], 10h
  287.         mov     si, notdir_string
  288.         jz      find_error_si
  289.         jmp     .parsedir
  290. .end:
  291.         test    byte [di+0Bh], 10h
  292.         mov     si, directory_string
  293.         jnz     find_error_si
  294. ; parse FAT chunk
  295. ; runlist at 2000:0000
  296.         mov     di, 5
  297.         push    2000h
  298.         pop     es
  299.         mov     byte [es:di-5], 1       ; of course, non-resident
  300.         mov     dword [es:di-4], 1
  301.         stosd
  302. .parsefat:
  303.         push    es
  304.         push    ds
  305.         pop     es
  306.         call    next_cluster
  307.         pop     es
  308.         jnc     .done
  309.         mov     ecx, [es:di-8]
  310.         add     ecx, [es:di-4]
  311.         cmp     eax, ecx
  312.         jz      .contc
  313.         mov     dword [es:di], 1
  314.         scasd
  315.         stosd
  316.         jmp     .parsefat
  317. .contc:
  318.         inc     dword [es:di-8]
  319.         jmp     .parsefat
  320. .done:
  321.         xor     eax, eax
  322.         stosd
  323.         jmp     read_img_file
  324.  
  325. ntfs:
  326.         mov     si, ntfs_msg
  327.         call    out_string
  328.         movzx   eax, word [50Bh]        ; bpb_bytes_per_sect
  329.         push    eax
  330.         movzx   ebx, byte [50Dh]        ; bpb_sects_per_clust
  331.         mul     ebx
  332.         mov     [cluster_size], eax
  333.         mov     [data_start], 0
  334.         mov     ecx, [540h]             ; frs_size
  335.         cmp     cl, 0
  336.         jg      .1
  337.         neg     cl
  338.         xor     eax, eax
  339.         inc     eax
  340.         shl     eax, cl
  341.         jmp     .2
  342. .1:
  343.         mul     ecx
  344. .2:
  345.         mov     [frs_size], eax
  346.         pop     ebx
  347.         xor     edx, edx
  348.         div     ebx
  349.         mov     [frs_sectors], ax
  350. ; read first MFT record - description of MFT itself
  351.         mov     [cur_obj], mft_string
  352.         movzx   eax, byte [50Dh]        ; bpb_sects_per_clust
  353.         mul     dword [530h]            ; mft_cluster
  354.         mov     cx, [frs_sectors]
  355.         mov     bx, 4000h
  356.         mov     di, bx
  357.         push    bx
  358.         call    relative_read
  359.         call    restore_usa
  360. ; scan for unnamed $DATA attribute
  361.         pop     di
  362.         mov     ax, 80h         ; $DATA
  363.         mov     bx, 700h
  364.         call    load_attr
  365.         mov     si, nodata_string
  366.         jc      find_error_si
  367.         mov     [free], bx
  368. ; load menuet.img
  369. ; parse image name
  370.         add     [imgnameofs], 0xD000
  371.         mov     eax, 5          ; root cluster
  372.         mov     [cur_obj], root_string
  373. .parsedir:
  374.         push    ax
  375.         mov     si, [imgnameofs]
  376.         push    si
  377. @@:
  378.         lodsb
  379.         cmp     al, '\'
  380.         jz      @f
  381.         cmp     al, 0
  382.         jnz     @b
  383. @@:
  384.         xchg    ax, [esp+2]
  385.         mov     byte [si-1], 0
  386.         mov     [imgnameofs], si
  387.         call    ntfs_parse_dir
  388.         pop     cx
  389.         test    cl, cl
  390.         jnz     .parsedir
  391. read_img_file:
  392.         xor     si, si
  393.         push    es
  394.         pop     fs
  395. ; yes! Now read file to 0x100000
  396.         lods byte [fs:si]
  397.         cmp     al, 0   ; assume nonresident attr
  398.         mov     si, invalid_read_request_string
  399.         jz      find_error_si
  400.         mov     si, 1
  401.         xor     edi, edi
  402. ; read buffer to 1000:0000 and move it to extended memory
  403.         push    1000h
  404.         pop     es
  405.         xor     bx, bx
  406. .img_read_block:
  407.         lods dword [fs:si]              ; eax=length
  408.         xchg    eax, ecx
  409.         jecxz   .img_read_done
  410.         lods dword [fs:si]              ; eax=disk cluster
  411. .img_read_cluster:
  412.         pushad
  413. ; read part of file
  414.         movzx   ecx, byte [50Dh]
  415.         mul     ecx
  416.         add     eax, [data_start]
  417.         call    relative_read
  418. ; move it to extended memory
  419.         mov     ah, 87h
  420.         mov     ecx, [cluster_size]
  421.         push    ecx
  422.         shr     cx, 1
  423.         mov     si, movedesc
  424.         push    es
  425.         push    ds
  426.         pop     es
  427.         int     15h
  428.         pop     es
  429.         test    ah, ah
  430.         mov     si, exmem_string
  431.         jnz     find_error_si
  432.         pop     ecx
  433.         add     [dest_addr], ecx
  434.         popad
  435.         inc     eax
  436.         loop    .img_read_cluster
  437.         jmp     .img_read_block
  438. .img_read_done:
  439. ; menuet.img loaded; now load kernel.mnt
  440. load_kernel:
  441.         push    ds
  442.         pop     es
  443.         mov     [cur_obj], kernel_mnt_name
  444. ; read boot sector
  445.         xor     eax, eax
  446.         mov     bx, 500h
  447.         mov     cx, 1
  448.         call    read_img
  449. ; init vars
  450.         mov     ax, [50Eh]      ; reserved_sect
  451.         add     ax, [51Ch]      ; hidden
  452.         mov     word [fat_start], ax
  453.         xchg    ax, bx
  454.         movzx   ax, byte [510h]         ; num_fats
  455.         mul     word [516h]             ; fat_length
  456.         add     ax, bx
  457. ; read root dir
  458.         mov     bx, 700h
  459.         mov     cx, [511h]      ; dir_entries
  460.         add     cx, 0Fh
  461.         shr     cx, 4
  462.         call    read_img
  463.         add     ax, cx
  464.         mov     [img_data_start], ax
  465.         shl     cx, 9
  466.         mov     di, bx
  467.         add     bx, cx
  468.         mov     byte [bx], 0
  469. .scan_loop:
  470.         cmp     byte [di], 0
  471.         mov     si, notfound_string
  472.         jz      find_error_si
  473.         mov     si, kernel_mnt_name
  474.         call    fat_compare_name
  475.         jz      .found
  476.         and     di, not 1Fh
  477.         add     di, 20h
  478.         jmp     .scan_loop
  479. .found:
  480.         and     di, not 1Fh
  481.         mov     si, directory_string
  482.         test    byte [di+0Bh], 10h
  483.         jnz     find_error_si
  484. ; found, now load it to 1000h:0000h
  485.         mov     ax, [di+1Ah]
  486. ; first cluster of kernel.mnt in ax
  487. ; translate it to sector on disk in menuet.img
  488.         push    ax
  489.         dec     ax
  490.         dec     ax
  491.         movzx   cx, byte [50Dh]
  492.         mul     cx
  493.         add     ax, [img_data_start]
  494. ; now ax is sector in menuet.img
  495.         mov     [kernel_mnt_in_img], ax
  496.         div     [sect_per_clust]
  497. ; now ax is cluster in menuet.img and
  498. ; dx is offset from the beginning of cluster
  499.         movzx   eax, ax
  500.         push    2000h
  501.         pop     ds
  502.         mov     si, 1
  503. .scani:
  504.         sub     eax, [si]
  505.         jb      .scanidone
  506. ; sanity check
  507.         cmp     dword [si], 0
  508.         push    invalid_read_request_string
  509.         jz      find_error_sp
  510.         pop     cx
  511. ; next chunk
  512.         add     si, 8
  513.         jmp     .scani
  514. .scanidone:
  515.         add     eax, [si]       ; undo last subtract
  516.         add     eax, [si+4]     ; get cluster
  517.         push    0
  518.         pop     ds
  519.         movzx   ecx, [sect_per_clust]
  520.         push    dx
  521.         mul     ecx             ; get sector
  522.         pop     dx
  523.         movzx   edx, dx
  524.         add     eax, edx
  525.         add     eax, [data_start]
  526.         mov     [kernel_mnt_1st], eax
  527.         pop     ax
  528.         push    1000h
  529.         pop     es
  530. .read_loop:
  531.         push    ax
  532.         xor     bx, bx
  533.         call    img_read_cluster
  534.         shl     cx, 9-4
  535.         mov     ax, es
  536.         add     ax, cx
  537.         mov     es, ax
  538.         pop     ax
  539.         call    img_next_cluster
  540.         jc      .read_loop
  541.         mov     ax, 'KL'
  542.         mov     si, loader_block
  543.         jmp     1000h:0000h
  544.  
  545. img_next_cluster:
  546.         mov     bx, 700h
  547.         push    ax
  548.         shr     ax, 1
  549.         add     ax, [esp]
  550.         mov     dx, ax
  551.         shr     ax, 9
  552.         add     ax, word [fat_start]
  553.         mov     cx, 2
  554.         push    es
  555.         push    ds
  556.         pop     es
  557.         call    read_img
  558.         pop     es
  559.         and     dx, 1FFh
  560.         add     bx, dx
  561.         mov     ax, [bx]
  562.         pop     cx
  563.         test    cx, 1
  564.         jz      .1
  565.         shr     ax, 4
  566. .1:
  567.         and     ax, 0FFFh
  568.         mov     si, bad_cluster_string
  569.         cmp     ax, 0FF7h
  570.         jz      find_error_si
  571.         ret
  572. img_read_cluster:
  573.         dec     ax
  574.         dec     ax
  575.         movzx   cx, byte [50Dh] ; sects_per_clust
  576.         mul     cx
  577.         add     ax, [img_data_start]
  578.         movzx   eax, ax
  579. ;       call    read_img
  580. ;       ret
  581. read_img:
  582. ; in: ax = sector, es:bx->buffer, cx=length in sectors
  583.         pushad
  584.         movzx   ebx, bx
  585.         mov     si, movedesc
  586.         shl     eax, 9
  587.         add     eax, 93100000h
  588.         mov     dword [si+sou_addr-movedesc], eax
  589.         mov     eax, 9300000h
  590.         mov     ax, es
  591.         shl     eax, 4
  592.         add     eax, ebx
  593.         mov     [si+dest_addr-movedesc], eax
  594.         mov     ah, 87h
  595.         shl     cx, 8   ; mul 200h/2
  596.         push    es
  597.         push    0
  598.         pop     es
  599.         int     15h
  600.         pop     es
  601.         cmp     ah, 0
  602.         mov     si, exmem_string
  603.         jnz     find_error_si
  604.         popad
  605.         ret
  606.  
  607. movedesc:
  608.         times 16 db 0
  609. ; source
  610.         dw      0xFFFF          ; segment length
  611. sou_addr dw     0000h           ; linear address
  612.         db      1               ; linear address
  613.         db      93h             ; access rights
  614.         dw      0
  615. ; destination
  616.         dw      0xFFFF          ; segment length
  617. dest_addr dd    93100000h       ; high byte contains access rights
  618.                                 ; three low bytes contains linear address (updated when reading)
  619.         dw      0
  620.         times 32 db 0
  621.  
  622. find_error_si:
  623.         push    si
  624. find_error_sp:
  625.         mov     si, error_msg
  626.         call    out_string
  627.         mov     si, [cur_obj]
  628.         call    out_string
  629.         mov     si, colon
  630.         call    out_string
  631.         pop     si
  632.         call    out_string
  633.         jmp     $
  634.  
  635. file_not_found:
  636.         mov     si, [esp+2]
  637.         mov     [cur_obj], si
  638.         push    notfound_string
  639.         jmp     find_error_sp
  640.  
  641.         include 'fat32.inc'
  642.         include 'ntfs.inc'
  643.  
  644. write1st:
  645. ; callback from kernel.mnt
  646. ; write first sector of kernel.mnt from 1000:0000 back to disk
  647.         push    cs
  648.         pop     ds
  649.         push    cs
  650.         pop     es
  651. ; sanity check
  652.         mov     bx, 500h
  653.         mov     si, bx
  654.         mov     cx, 1
  655.         push    cx
  656.         mov     eax, [kernel_mnt_1st]
  657.         push    eax
  658.         call    relative_read
  659.         push    1000h
  660.         pop     es
  661.         xor     di, di
  662.         mov     cx, 8
  663.         repz    cmpsw
  664.         mov     si, data_error_msg
  665.         jnz     find_error_si
  666. ; ok, now write back to disk
  667.         or      byte [read.patch1+2], 1
  668.         or      byte [read.patch2+2], 1
  669.         xor     bx, bx
  670.         pop     eax
  671.         pop     cx
  672.         call    relative_read
  673.         and     byte [read.patch1+1], not 1
  674.         and     byte [read.patch2+2], not 2
  675. ; and to image in memory (probably this may be done by kernel.mnt itself?)
  676.         mov     dword [sou_addr], 93010000h
  677.         movzx   eax, [kernel_mnt_in_img]
  678.         shl     eax, 9
  679.         add     eax, 93100000h
  680.         mov     dword [dest_addr], eax
  681.         mov     si, movedesc
  682.         push    ds
  683.         pop     es
  684.         mov     ah, 87h
  685.         mov     cx, 100h
  686.         int     15h
  687.         cmp     ah, 0
  688.         mov     si, exmem_string
  689.         jnz     find_error_si
  690.         retf
  691.  
  692. loader_block:
  693.         db      1       ; version
  694.         dw      1       ; flags - image is loaded
  695.         dw      write1st        ; offset
  696.         dw      0               ; segment
  697.  
  698. fat_cur_sector dd -1
  699.  
  700. ; -----------------------------------------------
  701. ; ------------------ Settings -------------------
  702. ; -----------------------------------------------
  703.  
  704. ; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
  705. kernel_mnt_name         db      'kernel.mnt',0
  706.  
  707. ; uninitialized data follows
  708. drive_size              dd      ?       ; in sectors
  709. heads                   dw      ?
  710. sectors                 dw      ?
  711. cyls                    dw      ?
  712. free                    dw      ?
  713. cur_obj                 dw      ?
  714. data_start              dd      ?
  715. img_data_start          dw      ?
  716. sect_per_clust          dw      ?
  717. kernel_mnt_in_img       dw      ?
  718. kernel_mnt_1st          dd      ?
  719. ; NTFS data
  720. cluster_size            dd      ?       ; in bytes
  721. frs_size                dd      ?       ; in bytes
  722. frs_sectors             dw      ?       ; in sectors
  723. mft_data_attr           dw      ?
  724. index_root              dw      ?
  725. index_alloc             dw      ?
  726. ofs                     dw      ?
  727. dir                     dw      ?
  728. ; FAT32 data
  729. fat_start               dd      ?
  730. cur_cluster             dd      ?
  731.  
  732. ; will be initialized by ldklbr.vxd
  733. menuet_img_name         rb      300
  734.