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

Last change on this file since 219 was 181, checked in by krille_n_@…, 13 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.