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

Last change on this file since 86 was 77, checked in by krille_n_@…, 14 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
RevLine 
[3]1; File name : menudraw.asm
2; Project name : Menu library
3; Created date : 9.11.2009
[77]4; Last update : 4.1.2011
5; Author : Tomi Tilli,
6; : Krister Nordvall (optimizations)
[3]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
[77]44 mov cx, 0920h ; Write Char and attr, space char
[3]45 mov bx, ATTR_MDA_NORMAL ; Page zero, normal attribute
[77]46 xchg cx, ax ; CX=Char count AX=Space char and attr
[3]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
[10]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
[3]297 call MenuDraw_MiddleBorder ; Draw middle border
298 call MenuDraw_NewlineBrdr ; Change line
[10]299 pop cx
[3]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
[10]308.JumpToBottomBorder:
309 jmp SHORT MenuDraw_BottomBorder
310
311ALIGN JUMP_ALIGN
[3]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
[10]316 and cx, 0FF00h ; Any info strings? (clears CL)
317 jz SHORT MenuDraw_BottomBorder ; If not, draw bottom border
[3]318 inc ch ; Increment for info top border
319 call MenuCrsr_Move ; Move cursor
[10]320 jmp SHORT MenuDraw_BottomBorder
[3]321
322ALIGN JUMP_ALIGN
323MenuDraw_ItemBorders:
[10]324 cmp WORD [bp+MENUVARS.wItemCnt], BYTE 0 ; Any items?
325 jz SHORT .Return ; If not, return
[3]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:
[77]357 mov bx, (B_TL << 8) + B_H
[3]358 mov dh, B_TR
[10]359 jmp SHORT MenuDraw_BorderChars
[3]360
361ALIGN JUMP_ALIGN
362MenuDraw_StringBorder:
[77]363 mov bx, (B_V << 8) + ' '
[3]364 mov dh, B_V
[10]365 jmp SHORT MenuDraw_BorderChars
[3]366
367ALIGN JUMP_ALIGN
368MenuDraw_ScrollBorder:
369 call MenuDraw_GetScrollChar ; Load scroll char to DH
[77]370 mov bx, (B_V << 8) + ' '
[10]371 jmp SHORT MenuDraw_BorderChars
[3]372
373ALIGN JUMP_ALIGN
374MenuDraw_MiddleBorder:
[77]375 mov bx, (BVL_THR << 8) + T_H
[3]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:
[77]392 mov bx, (B_LL << 8) + B_H
[3]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.