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

Last change on this file since 10 was 10, checked in by aitotat, 14 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.