source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Libraries/menu/menuloop.asm@ 15

Last change on this file since 15 was 10, checked in by Tomi Tilli, 15 years ago

Now assembles with Yasm

File size: 9.7 KB
Line 
1; File name : menuloop.asm
2; Project name : Menu library
3; Created date : 11.11.2009
4; Last update : 25.5.2010
5; Author : Tomi Tilli
6; Description : ASM library to menu system.
7; Contains event dispatching loop.
8
9;--------------- Equates -----------------------------
10
11; BIOS scan codes
12KEY_ENTER EQU 1Ch
13KEY_ESC EQU 01h
14KEY_UP EQU 48h
15KEY_DOWN EQU 50h
16KEY_PGUP EQU 49h
17KEY_PGDN EQU 51h
18KEY_HOME EQU 47h
19KEY_END EQU 4Fh
20CNT_MENU_KEYS EQU 8 ; Number of menukeys
21
22
23;-------------- Private global variables -------------
24; Section containing initialized data
25;SECTION .data
26
27
28;-------------- Public functions ---------------------
29; Section containing code
30SECTION .text
31
32
33;--------------------------------------------------------------------
34; Waits keyboard input, updates timeout and dispatch event for
35; user handler.
36; Parameters:
37; SS:BP: Ptr to MENUVARS
38; Returns:
39; Nothing
40; Corrupts registers:
41; AX, BX, CX, DX
42;--------------------------------------------------------------------
43ALIGN JUMP_ALIGN
44MenuLoop_Enter:
45 ; Get current time for timeout
46 call Menu_GetTime ; Get system time ticks to CX:DX
47 mov [bp+MENUVARS.wTimeLast], dx ; Store last read time
48
49 ; Check if menu operation should be continued
50ALIGN JUMP_ALIGN
51.CheckExit:
52 test BYTE [bp+MENUVARS.bFlags], FLG_MNU_EXIT
53 jnz .Return ; Return if exit flag set
54
55 ; Check if keystroke available
56 call Keys_GetStroke ; Get keystroke to AX
57 jz .CheckTimeout ; If no keystroke, jump to check timeout
58 call MenuLoop_ProcessKey ; Convert keystroke to events
59
60 ; Check if timeout needs updating
61ALIGN JUMP_ALIGN
62.CheckTimeout:
63 cmp WORD [bp+MENUVARS.wTimeInit], 0 ; Timeout enabled?
64 jz .CheckExit ; If not, loop
65 call Menu_GetTime ; Get system time ticks to CX:DX
66 mov cx, dx ; Copy time loword to CX
67 sub dx, [bp+MENUVARS.wTimeLast] ; Has time changed?
68 je .CheckExit ; If not, loop
69
70 ; Update timeout
71 mov [bp+MENUVARS.wTimeLast], cx ; Store last update time
72 sub [bp+MENUVARS.wTimeout], dx ; Update timeout
73 ja .PrintTimeout ; If time left, just print new value
74 call MenuLoop_SendSelEvent ; Send selection event
75
76 ; Print timeout value
77ALIGN JUMP_ALIGN
78.PrintTimeout:
79 call MenuDraw_Timeout
80 xor dx, dx
81 call MenuCrsr_PointBelowBrdr
82 jmp .CheckExit
83
84ALIGN JUMP_ALIGN
85.Return:
86 ret
87
88
89;--------------------------------------------------------------------
90; Sends Menu event to user handler (MENUVARS.fnEvent).
91; MenuLoop_SendSelEvent Sends Menuitem Selected event to user event handler
92; MenuLoop_SendEvent Sends any event to user event handler
93; Parameters:
94; BX: Event code (MenuLoop_SendEvent only)
95; DX: Event parameter (event specific)
96; SS:BP: Ptr to MENUVARS
97; Returns:
98; AH: Event specific or unused
99; AL: 1=Event processed
100; 0=Event not processed (default action if any)
101; Corrupts registers:
102; BX, CX, DX
103;--------------------------------------------------------------------
104ALIGN JUMP_ALIGN
105MenuLoop_SendSelEvent:
106 mov bx, EVNT_MNU_SELSET
107ALIGN JUMP_ALIGN
108MenuLoop_SendEvent:
109 mov cx, [bp+MENUVARS.wItemSel]
110 call [bp+MENUVARS.fnEvent]
111 ret
112
113
114;-------------- Private functions ---------------------
115
116
117;--------------------------------------------------------------------
118; Processed menu key input.
119; Menu keys will be handled and other keys dispatched as key events.
120; Parameters:
121; AH: BIOS Scan Code for key
122; AL: ASCII character
123; SS:BP: Ptr to MENUVARS
124; Returns:
125; Nothing
126; Corrupts registers:
127; AX, BX, CX, DX
128;--------------------------------------------------------------------
129ALIGN JUMP_ALIGN
130MenuLoop_ProcessKey:
131 push es
132 push di
133
134 ; Check if wanted key
135 push cs
136 pop es ; Copy CS to ES
137 mov cx, CNT_MENU_KEYS ; Load number of menu keys
138 mov di, .rgbKeyToIdx ; Load offset to translation table
139 xchg al, ah ; Scan code to AL
140 cld ; SCASB to increment DI
141 repne scasb ; Compare [ES:DI] to AL until match
142 jne .Dispatch ; If not menukey, jump to dispatch
143
144 ; Jump to process menu key
145 mov di, CNT_MENU_KEYS-1 ; Convert CX...
146 sub di, cx ; ...to lookup index
147 shl di, 1 ; Prepare for word lookup
148 jmp [cs:di+.rgwMenuKeyJmp]
149
150 ; Dispatch key event
151ALIGN JUMP_ALIGN
152.Dispatch:
153 xchg al, ah ; Restore AX
154 mov bx, EVNT_MNU_KEY
155 mov dx, ax ; Copy keys to DX
156 call MenuLoop_SendEvent
157ALIGN JUMP_ALIGN
158.Return:
159 pop di
160 pop es
161 ret
162
163 ;;;;;;;;;;;;;;;;;;;;;
164 ; Menu key handlers ;
165 ;;;;;;;;;;;;;;;;;;;;;
166
167 ; ENTER pressed
168ALIGN JUMP_ALIGN
169.KeyEnter:
170 call MenuLoop_SendSelEvent ; Send selection event
171 jmp .Return
172
173 ; ESC pressed
174ALIGN JUMP_ALIGN
175.KeyEsc:
176 call Menu_Exit
177 jc .Return ; User cancelled exit
178 mov WORD [bp+MENUVARS.wItemSel], -1
179 jmp .Return
180
181 ; UP pressed
182ALIGN JUMP_ALIGN
183.KeyUp:
184%ifdef USE_MENU_DIALOGS
185 test BYTE [bp+MENUVARS.bFlags], FLG_MNU_NOARRW ; Message dialog mode?
186 jnz .TextScrollUp ; If so, go to text scrolling
187%endif
188 mov ax, [bp+MENUVARS.wItemSel] ; Load selected index
189 test ax, ax ; Already at top?
190 jz .KeyEnd ; If so, go to end
191 mov dx, ax ; Copy selected index to DX
192 dec ax ; Decrement menuitem index
193 mov [bp+MENUVARS.wItemSel], ax ; Store new index
194 cmp ax, [bp+MENUVARS.wItemTop] ; Need to scroll?
195 jb SHORT .ScrollUp
196 jmp .DrawSelection ; If not, go to draw selection
197ALIGN JUMP_ALIGN
198.ScrollUp:
199 dec WORD [bp+MENUVARS.wItemTop] ; Scroll
200 jmp .ScrollMenu
201
202%ifdef USE_MENU_DIALOGS
203ALIGN JUMP_ALIGN
204.TextScrollUp:
205 cmp WORD [bp+MENUVARS.wItemTop], 0 ; Already at the top?
206 jz .Return ; If so, return
207 dec WORD [bp+MENUVARS.wItemTop]
208 jmp .ScrollMenu
209%endif
210
211 ; DOWN pressed
212ALIGN JUMP_ALIGN
213.KeyDown:
214%ifdef USE_MENU_DIALOGS
215 test BYTE [bp+MENUVARS.bFlags], FLG_MNU_NOARRW ; Message dialog mode?
216 jnz .TextScrollDown ; If so, go to text scrolling
217%endif
218 mov ax, [bp+MENUVARS.wItemSel] ; Load selected index
219 mov dx, ax ; Copy selected index to DX
220 inc ax ; Increment menuitem index
221 cmp ax, [bp+MENUVARS.wItemCnt] ; Already at bottom?
222 je .KeyHome ; If so, go to beginning
223 mov [bp+MENUVARS.wItemSel], ax ; Store new menuitem index
224 eMOVZX bx, BYTE [bp+MENUVARS.bVisCnt] ; Load number of visible items
225 add bx, [bp+MENUVARS.wItemTop] ; BX to one past last visible index
226 cmp ax, bx ; Need to scroll?
227 jae .ScrollDown
228 jmp .DrawSelection
229ALIGN JUMP_ALIGN
230.ScrollDown:
231 inc WORD [bp+MENUVARS.wItemTop] ; Scroll
232 jmp .ScrollMenu
233
234%ifdef USE_MENU_DIALOGS
235ALIGN JUMP_ALIGN
236.TextScrollDown:
237 eMOVZX ax, BYTE [bp+MENUVARS.bVisCnt] ; Load visible items
238 add ax, [bp+MENUVARS.wItemTop] ; Add topmost menuitem index
239 cmp ax, [bp+MENUVARS.wItemCnt] ; Already at the bottom?
240 jae .Return ; If so, return
241 inc WORD [bp+MENUVARS.wItemTop]
242 jmp .ScrollMenu
243%endif
244
245 ; HOME pressed
246ALIGN JUMP_ALIGN
247.KeyHome:
248 xor ax, ax
249 mov [bp+MENUVARS.wItemSel], ax
250 mov [bp+MENUVARS.wItemTop], ax
251 jmp .ScrollMenu
252
253 ; END pressed
254ALIGN JUMP_ALIGN
255.KeyEnd:
256 mov ax, [bp+MENUVARS.wItemCnt] ; Load number if menuitems
257 mov bx, ax ; Copy menuitem count to BX
258 dec ax ; Decrement for last index
259 mov [bp+MENUVARS.wItemSel], ax ; Store new selection
260 sub bl, [bp+MENUVARS.bVisCnt] ; BX to first menuitem to draw
261 sbb bh, 0
262 mov [bp+MENUVARS.wItemTop], bx ; Store first menuitem to draw
263 jnc .ScrollMenu
264 mov WORD [bp+MENUVARS.wItemTop], 0 ; Overflow, start with 0
265 jmp .ScrollMenu
266
267 ; PGUP pressed
268ALIGN JUMP_ALIGN
269.KeyPgUp:
270 mov ax, [bp+MENUVARS.wItemSel] ; Load selected index
271 div BYTE [bp+MENUVARS.bVisCnt] ; AL=Current page index
272 sub al, 1 ; Decrement page
273 jc .KeyHome ; Select first item if overflow
274 mul BYTE [bp+MENUVARS.bVisCnt] ; AX=Fist menuitem on page
275 mov [bp+MENUVARS.wItemSel], ax
276 mov [bp+MENUVARS.wItemTop], ax
277 jmp .ScrollMenu
278
279 ; PGDN pressed
280ALIGN JUMP_ALIGN
281.KeyPgDn:
282 mov ax, [bp+MENUVARS.wItemSel] ; Load selected index
283 div BYTE [bp+MENUVARS.bVisCnt] ; AL=Current page index
284 inc ax ; Increment page
285 mul BYTE [bp+MENUVARS.bVisCnt] ; AX=First menuitem on page
286 eMOVZX bx, BYTE [bp+MENUVARS.bVisCnt] ; Load number of visible items
287 add bx, ax ; BX now one past last visible
288 cmp bx, [bp+MENUVARS.wItemCnt] ; Went over last?
289 jae .KeyEnd ; If so, select last menuitem
290 mov [bp+MENUVARS.wItemSel], ax
291 mov [bp+MENUVARS.wItemTop], ax
292 ; Fall to .ScrollMenu
293
294 ; Menuitem selection changed, redraw all items
295ALIGN JUMP_ALIGN
296.ScrollMenu:
297 mov bx, EVNT_MMU_SELCHG
298 call MenuLoop_SendEvent
299 call Menu_RestartTimeout
300 xor cx, cx ; Invalidate...
301 dec cx ; ...all menuitems
302 mov dl, MFL_UPD_ITEM
303 call Menu_Invalidate
304 jmp .Return
305
306; Menuitem selection changed, only two items needs to be redrawn
307ALIGN JUMP_ALIGN
308.DrawSelection:
309 MINMAX_U ax, dx ; First menuitem to AX, next to DX
310 push dx ; Store second to draw
311 push ax ; Store first to draw
312 mov bx, EVNT_MMU_SELCHG
313 call MenuLoop_SendEvent
314 call Menu_RestartTimeout
315 pop cx ; First to draw to CX
316 call MenuCrsr_PointNthItem ; Set cursor position
317 call MenuDraw_Item ; Draw first menuitem
318 pop cx ; Second to draw to CX
319 call MenuDraw_Item ; Draw second menuitem
320 jmp .Return
321
322ALIGN WORD_ALIGN
323.rgwMenuKeyJmp:
324 dw .KeyEnter ; KEY_ENTER
325 dw .KeyEsc ; KEY_ESC
326 dw .KeyUp ; KEY_UP
327 dw .KeyDown ; KEY_DOWN
328 dw .KeyPgUp ; KEY_PGUP
329 dw .KeyPgDn ; KEY_PGDN
330 dw .KeyHome ; KEY_HOME
331 dw .KeyEnd ; KEY_END
332; Scan code to jump index translation table
333.rgbKeyToIdx:
334 db KEY_ENTER, KEY_ESC, KEY_UP, KEY_DOWN,
335 db KEY_PGUP, KEY_PGDN, KEY_HOME, KEY_END
Note: See TracBrowser for help on using the repository browser.