source: xtideuniversalbios/trunk/Configurator/Src/Libraries/menu/menudraw.asm @ 181

Last change on this file since 181 was 181, checked in by krille_n_@…, 12 years ago

Changes to all parts of the project:

  • Size optimizations.
  • Added a define (EXCLUDE_FROM_XTIDECFG) to exclude unused library code from XTIDECFG.
  • Tried to minimize time spent with interrupts disabled.
  • Some minor attempts to improve speed (reordering instructions etc).
  • Tried to improve readability, did some cleanup and fixed some errors in comments.
File size: 14.1 KB
Line 
1; Project name  :   Menu library
2; Description   :   ASM library to menu system.
3;                   Contains menu drawing functions.
4
5;--------------- Equates -----------------------------
6
7
8
9;-------------- Private global variables -------------
10; Section containing initialized data
11;SECTION .data
12
13g_strTimeout:   db  B_LL,BHL_TVR,"Selection Timeout %us",TVL_BHR,STOP
14
15
16;-------------- Public functions ---------------------
17; Section containing code
18SECTION .text
19
20
21;--------------------------------------------------------------------
22; Clears screen.
23;
24;   Parameters:
25;       Nothing
26;   Returns:
27;       Nothing
28;   Corrupts registers:
29;       AX, BX, CX, DX
30;--------------------------------------------------------------------
31ALIGN JUMP_ALIGN
32MenuDraw_ClrScr:
33    xor     dx, dx                      ; Cursor to (0,0)
34    call    MenuCrsr_SetCursor
35    mov     ah, 0Fh                     ; Get Current Video Mode
36    int     10h
37    mov     al, CNT_SCRN_ROW            ; Load row count
38    mul     ah                          ; AX=Column count * row count
39    mov     cx, 0920h                   ; Write Char and attr, space char
40    mov     bx, ATTR_MDA_NORMAL         ; Page zero, normal attribute
41    xchg    cx, ax                      ; CX=Char count AX=Space char and attr
42    int     10h
43    ret
44
45
46;--------------------------------------------------------------------
47; Changes line. When printing menu strings, this function must be
48; called instead of normal Print_Newline.
49;
50; MenuDraw_NewlineStrClrLn  Clear current line from cursor pos before newline
51; MenuDraw_NewlineStr
52;   Parameters:
53;       SS:BP:  Ptr to MENUVARS
54;   Returns:
55;       Nothing
56;   Corrupts registers:
57;       AX, BX, DX
58;--------------------------------------------------------------------
59ALIGN JUMP_ALIGN
60MenuDraw_NewlineStrClrLn:
61    push    cx
62    call    MenuCrsr_GetCursor              ; Get current cursor to DX
63    eMOVZX  cx, BYTE [bp+MENUVARS.bWidth]   ; Load menu width
64    add     cl, [bp+MENUVARS.bInitX]        ; Add menu start X coord
65    sub     cl, W_OFF_CRSR_STR & 0FFh       ; Subtract right borders
66    sub     cl, dl                          ; Subtract current X coord
67    mov     dl, ' '                         ; Clear with space
68    call    Print_Repeat                    ; Clear line to the end
69    pop     cx
70ALIGN JUMP_ALIGN
71MenuDraw_NewlineStr:
72    push    cx
73    call    MenuCrsr_GetCursor              ; Get current cursor to DX
74    mov     dl, [bp+MENUVARS.bInitX]        ; Load X offset to border
75    add     dx, W_OFF_CRSR_STR              ; Inc X and Y
76    call    MenuCrsr_SetCursor              ; Set new cursor
77    pop     cx
78    ret
79
80
81;--------------------------------------------------------------------
82; Draws multiline Title or Info string.
83;
84; MenuDraw_MultilineStr
85;   Parameters:
86;       CX:     Max Title or Info line count (menu initialization params)
87;       ES:DI:  Ptr to STOP terminated string to display
88;       SS:BP:  Ptr to MENUVARS
89;   Returns:
90;       Nothing
91;   Corrupts registers:
92;       AX, BX, CX, DX
93;--------------------------------------------------------------------
94%ifdef USE_MENU_DIALOGS
95ALIGN JUMP_ALIGN
96MenuDraw_MultilineStr:
97    push    si
98    xor     si, si
99ALIGN JUMP_ALIGN
100.LineLoop:
101    xchg    cx, si                          ; Idx to CX, count to SI
102    push    cx
103    call    MenuMsg_WriteLine               ; Write line
104    pop     cx
105    jc      .Return                         ;  Return if last token written
106    call    MenuDraw_NewlineStr             ; Cursor to next line
107    inc     cx                              ; Increment line index
108    xchg    cx, si                          ; Count to CX, idx to SI
109    loop    .LineLoop                       ; Loop while lines left
110ALIGN JUMP_ALIGN
111.Return:
112    pop     si
113    ret
114%endif ; USE_MENU_DIALOGS
115
116
117;--------------------------------------------------------------------
118; Draws menu component.
119;
120; MenuDraw_Title            Draws Title borders and user string
121; MenuDraw_Info             Draws Info borders and user string
122; MenuDraw_AllItems         Draws Item borders and all user menuitems
123; MenuDraw_TitleNoBord      MenuDraw_Title without clearing old chars
124; MenuDraw_InfoNoBord       MenuDraw_Info without clearing old chars
125; MenuDraw_AllItemsNoBord   MenuDraw_AllItems without clearing old chars
126;   Parameters:
127;       SS:BP:  Ptr to MENUVARS
128;   Returns:
129;       Nothing
130;   Corrupts registers:
131;       AX, BX, CX, DX
132;--------------------------------------------------------------------
133;ALIGN JUMP_ALIGN
134;MenuDraw_Title:
135;   call    MenuDraw_TitleBorders           ; Draw borders to clear old strings
136ALIGN JUMP_ALIGN
137MenuDraw_TitleNoBord:
138    cmp     BYTE [bp+MENUVARS.bTitleH], 0   ; Any title strings?
139    jz      MenuDraw_NothingToDraw          ;  If not, return
140    call    MenuCrsr_PointTitle             ; Set cursor position
141    mov     dl, MFL_UPD_TITLE               ; Update title string
142    jmp     MenuDraw_SendEvent
143
144;ALIGN JUMP_ALIGN
145;MenuDraw_Info:
146;   call    MenuDraw_InfoBorders            ; Draw borders to clear old strings
147ALIGN JUMP_ALIGN
148MenuDraw_InfoNoBord:
149    cmp     BYTE [bp+MENUVARS.bInfoH], 0    ; Any info strings?
150    jz      MenuDraw_NothingToDraw          ;  If not, return
151    test    BYTE [bp+MENUVARS.bFlags], FLG_MNU_HIDENFO
152    jnz     MenuDraw_NothingToDraw          ; Return if info is hidden
153    call    MenuCrsr_PointInfo              ; Set cursor position
154    mov     dl, MFL_UPD_NFO                 ; Update title string
155    jmp     MenuDraw_SendEvent
156
157;ALIGN JUMP_ALIGN
158;MenuDraw_AllItems:
159;   call    MenuDraw_ItemBorders            ; Draw borders to clear old strings
160ALIGN JUMP_ALIGN
161MenuDraw_AllItemsNoBord:
162    cmp     WORD [bp+MENUVARS.wItemCnt], 0  ; Any items to draw?
163    jz      MenuDraw_NothingToDraw          ;  If not, return
164    call    MenuCrsr_Point1stItem           ; Set cursor position
165    mov     cx, [bp+MENUVARS.wItemTop]      ; Load idx of first menuitem to draw
166    eMOVZX  dx, BYTE [bp+MENUVARS.bVisCnt]  ; Load number of visible menuitems
167    MIN_U   dx, [bp+MENUVARS.wItemCnt]      ; Limit to item count
168    add     dx, cx                          ; One past last menuitem to draw
169ALIGN JUMP_ALIGN
170.DrawLoop:
171    push    dx
172    call    MenuDraw_Item                   ; Draw menuitem
173    pop     dx
174    inc     cx                              ; Increment menuitem index
175    cmp     cx, dx                          ; More items left?
176    jb      .DrawLoop                       ;  If so, loop
177    jmp     MenuDraw_NothingToDraw
178
179ALIGN JUMP_ALIGN
180MenuDraw_SendEvent:
181    mov     bx, EVNT_MNU_UPD                ; Update string
182    call    MenuLoop_SendEvent
183ALIGN JUMP_ALIGN
184MenuDraw_NothingToDraw:
185    call    MenuCrsr_PointBelowBrdr         ; Cursor to safe location
186    ret
187
188
189;--------------------------------------------------------------------
190; Draws Menuitem without borders.
191; This function does not set initial cursor position but does
192; change line for next menuitem!
193;
194; MenuDraw_Item
195;   Parameters:
196;       CX:     Index of menuitem to draw
197;       SS:BP:  Ptr to MENUVARS
198;   Returns:
199;       AL:     1=Menuitem drawed by user event handler
200;               0=Menuitem not drawed by user event handler
201;   Corrupts registers:
202;       AH, BX, DX
203;--------------------------------------------------------------------
204ALIGN JUMP_ALIGN
205MenuDraw_Item:
206    push    cx
207    test    BYTE [bp+MENUVARS.bFlags], FLG_MNU_NOARRW
208    jnz     .DrawString                 ; Don't draw arrow unless wanted
209    mov     dl, RARROW                  ; Prepare to draw selection arrow
210    cmp     cx, [bp+MENUVARS.wItemSel]  ; Drawing selected item?
211    je      .DrawArrow                  ;  If so, jump to draw arrow
212    mov     dl, ' '                     ; Load space instead of arrow
213ALIGN JUMP_ALIGN
214.DrawArrow:
215    PRINT_CHAR
216    mov     dl, ' '                     ; Draw space before user str
217    PRINT_CHAR
218ALIGN JUMP_ALIGN
219.DrawString:
220    mov     dl, MFL_UPD_ITEM            ; Draw item string
221    mov     bx, EVNT_MNU_UPD            ; Update string
222    call    [bp+MENUVARS.fnEvent]       ; Send event
223    call    MenuDraw_NewlineStr         ; Move cursor to next menuitem
224    pop     cx
225    ret
226
227
228;-------------- Private functions --------------------
229
230;--------------------------------------------------------------------
231; Changes line. When printing menu borders, this function must be
232; called instead of normal Print_Newline.
233;   Parameters:
234;       SS:BP:  Ptr to MENUVARS
235;   Returns:
236;       Nothing
237;   Corrupts registers:
238;       AX, BX, CX, DX
239;--------------------------------------------------------------------
240ALIGN JUMP_ALIGN
241MenuDraw_NewlineBrdr:
242    call    MenuCrsr_GetCursor          ; Get current cursor to DX
243    mov     dl, [bp+MENUVARS.bInitX]    ; Load X offset to border
244    inc     dh                          ; Increment Y coordinate
245    jmp     MenuCrsr_SetCursor          ; Set new cursor
246
247
248;--------------------------------------------------------------------
249; Draws menu borders. User strings will be cleared.
250;
251; MenuDraw_TitleBorders     Draws Title borders
252; MenuDraw_InfoBorders      Draws Info borders
253; MenuDraw_ItemBorders      Draws Item borders
254; MenuDraw_Timeout          Draw timeout border (not whole InfoBorders)
255;   Parameters:
256;       SS:BP:  Ptr to MENUVARS
257;   Returns:
258;       Nothing
259;   Corrupts registers:
260;       AX, BX, CX, DX
261;--------------------------------------------------------------------
262ALIGN JUMP_ALIGN
263MenuDraw_TitleBorders:
264    xor     dx, dx                          ; Zero DX
265    call    MenuCrsr_PointTitleBrdr         ; Set cursor
266    call    MenuDraw_TopBorder              ; Draw top border
267    call    MenuDraw_NewlineBrdr            ; Change line
268    eMOVZX  cx, BYTE [bp+MENUVARS.bTitleH]  ; Load number of title strings
269    jcxz    .Return                         ; Return if no title strings
270ALIGN JUMP_ALIGN
271.LineLoop:
272    push    cx
273    call    MenuDraw_StringBorder
274    call    MenuDraw_NewlineBrdr
275    pop     cx
276    loop    .LineLoop
277    jmp     MenuDraw_MiddleBorder           ; Thin border before menuitems
278ALIGN JUMP_ALIGN
279.Return:
280    ret
281
282ALIGN JUMP_ALIGN
283MenuDraw_InfoBorders:
284    xor     dx, dx                          ; Zero DX
285    call    MenuCrsr_PointNfoBrdr           ; Set cursor
286    eMOVZX  cx, BYTE [bp+MENUVARS.bInfoH]   ; Load number of info strings
287    test    BYTE [bp+MENUVARS.bFlags], FLG_MNU_HIDENFO  ; Information hidden?
288    jnz     SHORT .JumpToBottomBorder
289    jcxz    MenuDraw_BottomBorder           ; Any info strings?
290    push    cx
291    call    MenuDraw_MiddleBorder           ; Draw middle border
292    call    MenuDraw_NewlineBrdr            ; Change line
293    pop     cx
294ALIGN JUMP_ALIGN
295.LineLoop:
296    push    cx
297    call    MenuDraw_StringBorder
298    call    MenuDraw_NewlineBrdr
299    pop     cx
300    loop    .LineLoop
301ALIGN JUMP_ALIGN
302.JumpToBottomBorder:
303    jmp     SHORT MenuDraw_BottomBorder
304
305ALIGN JUMP_ALIGN
306MenuDraw_Timeout:
307    xor     dx, dx                          ; Zero DX
308    call    MenuCrsr_PointNfoBrdr           ; Set cursor
309    mov     ch, [bp+MENUVARS.bInfoH]        ; Load info str count to CH
310    and     cx, 0FF00h                      ; Any info strings? (clears CL)
311    jz      SHORT MenuDraw_BottomBorder     ;  If not, draw bottom border
312    inc     ch                              ; Increment for info top border
313    call    MenuCrsr_Move                   ; Move cursor
314    jmp     SHORT MenuDraw_BottomBorder
315
316ALIGN JUMP_ALIGN
317MenuDraw_ItemBorders:
318    cmp     WORD [bp+MENUVARS.wItemCnt], BYTE 0 ; Any items?
319    jz      SHORT .Return                   ;  If not, return
320    xor     dx, dx                          ; Zero DX
321    call    MenuCrsr_PointItemBrdr          ; Set cursor
322    eMOVZX  cx, BYTE [bp+MENUVARS.bVisCnt]  ; Load max number of item strings
323ALIGN JUMP_ALIGN
324.LineLoop:
325    push    cx
326    call    MenuDraw_ScrollBorder
327    call    MenuDraw_NewlineBrdr
328    pop     cx
329    loop    .LineLoop
330.Return:
331    ret
332
333
334;--------------------------------------------------------------------
335; Draw horizontal border line to current cursor location.
336; MenuDraw_TopBorder    Draw thick top menu border
337; MenuDraw_StringBorder Draw thick user string border
338; MenuDraw_ScrollBorder Draw scrolling border for menuitems
339; MenuDraw_MiddleBorder Draw thin middle menu border
340; MenuDraw_BottomBorder Draw thick bottom menu border with timeout if set
341;   Parameters:
342;       CX:     Loop counter (Items left, MenuDraw_ScrollBorder only)
343;       SS:BP:  Ptr to MENUVARS
344;   Returns:
345;       Nothing
346;   Corrupts registers:
347;       AX, BX, CX, DX
348;--------------------------------------------------------------------
349ALIGN JUMP_ALIGN
350MenuDraw_TopBorder:
351    mov     bx, (B_TL << 8) + B_H
352    mov     dh, B_TR
353    jmp     SHORT MenuDraw_BorderChars
354
355ALIGN JUMP_ALIGN
356MenuDraw_StringBorder:
357    mov     bx, (B_V << 8) + ' '
358    mov     dh, B_V
359    jmp     SHORT MenuDraw_BorderChars
360
361ALIGN JUMP_ALIGN
362MenuDraw_ScrollBorder:
363    call    MenuDraw_GetScrollChar          ; Load scroll char to DH
364    mov     bx, (B_V << 8) + ' '
365    jmp     SHORT MenuDraw_BorderChars
366
367ALIGN JUMP_ALIGN
368MenuDraw_MiddleBorder:
369    mov     bx, (BVL_THR << 8) + T_H
370    mov     dh, THL_BVR
371
372ALIGN JUMP_ALIGN
373MenuDraw_BorderChars:
374    mov     dl, bh                          ; Leftmost
375    PRINT_CHAR
376    eMOVZX  cx, BYTE [bp+MENUVARS.bWidth]
377    times 2 dec cx                          ; Subtract borders
378    mov     dl, bl                          ; Middle
379    call    Print_Repeat
380    mov     dl, dh                          ; Rightmost
381    PRINT_CHAR
382    ret
383
384ALIGN JUMP_ALIGN
385MenuDraw_BottomBorder:
386    mov     bx, (B_LL << 8) + B_H
387    mov     dh, B_LR
388    cmp     WORD [bp+MENUVARS.wTimeInit], 0 ; Timeout enabled?
389    jz      MenuDraw_BorderChars            ;  If not, draw normal
390
391    ; Print timeout value
392    push    ds
393    push    si
394    push    cs
395    pop     ds                              ; Copy CS to DS
396    mov     si, g_strTimeout                ; Load ptr to timeout str (DS:SI)
397    mov     ax, 55                          ; 1 timer tick = 54.945ms
398    mul     WORD [bp+MENUVARS.wTimeout]     ; DX:AX = millisecs
399    eSHR_IM ax, 10                          ; ms to s (close enough to 1000)
400    push    ax                              ; Push seconds
401    call    Print_Format                    ; Print timeout
402    add     sp, 2                           ; Clean stack
403    pop     si
404    pop     ds
405
406    ; Print remaining border chars
407    call    MenuCrsr_GetCursor              ; Get cursor location to DX
408    sub     dl, [bp+MENUVARS.bInitX]        ; Compensate for start X...
409    inc     dx                              ; ...and lower right corner
410    mov     dh, [bp+MENUVARS.bWidth]        ; Load menu width to DH
411    sub     dh, dl                          ; Subtract current X coordinate
412    eMOVZX  cx, dh                          ; Number of border chars needed
413    mov     dl, B_H
414    call    Print_Repeat
415    mov     dl, B_LR
416    PRINT_CHAR
417    ret
418
419
420;--------------------------------------------------------------------
421; Returns character for scroll bars if needed.
422; If scroll bars are not needed, normal border character will be returned.
423;
424; Note! Current implementation doesn't always return thumb character
425;       if there are a lot of pages. Checking last char only is not enough.
426;
427; MenuDraw_GetScrollChar
428;   Parameters:
429;       CX:     Loop counter (Items left, MenuDraw_ScrollBorder only)
430;       SS:BP:  Ptr to MENUVARS
431;   Returns:
432;       DH:     Scroll bar character
433;   Corrupts registers:
434;       AX, BX, CX, DL
435;--------------------------------------------------------------------
436ALIGN JUMP_ALIGN
437MenuDraw_GetScrollChar:
438    mov     dh, B_V                     ; Assume no scroll bars needed
439    mov     ax, [bp+MENUVARS.wItemCnt]  ; Load menuitem count to AX
440    eMOVZX  bx, BYTE [bp+MENUVARS.bVisCnt]  ; Load visible menuitems to BX
441    cmp     ax, bx                      ; Need scroll bars?
442    jbe     .Return                     ;  If not, return
443
444    ; Calculate last menuitem index for thumb char on this line
445    push    bx                          ; Store number of visible menuitems
446    sub     bx, cx                      ; Calculate Line index
447    inc     bx                          ; Increment for next line index
448    mul     bx                          ; DX:AX=Total item count * Next line idx
449    pop     bx                          ; Pop number of visible menuitems
450    div     bx                          ; AX=First Menuitem for next string line
451    dec     ax                          ; AX=Last Menuitem for this string line
452
453    ; Draw thumb or track
454    mov     dh, FULL_BLCK               ; Assume thumb line
455    call    Menu_IsItemVisible          ; Is thumb menuitem visible?
456    jc      .Return                     ;  If so, draw thumb
457    mov     dh, T_V                     ; Load track character
458ALIGN JUMP_ALIGN, ret
459.Return:
460    ret
Note: See TracBrowser for help on using the repository browser.