source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Libraries/menu/menudraw.asm @ 77

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

Minor size optimizations plus a bug fix in print.asm in Print_IntSW (DI was left hanging on the stack if the parameter in AX was positive). Also a very minor speed optimization in keys.asm in Keys_Backspace.

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