source: xtideuniversalbios/trunk/Configurator/Src/Libraries/menu/menumsg.asm @ 2

Last change on this file since 2 was 2, checked in by aitotat, 14 years ago
File size: 8.8 KB
Line 
1; File name     :   menumsg.asm
2; Project name  :   Menu library
3; Created date  :   13.11.2009
4; Last update   :   10.1.2010
5; Author        :   Tomi Tilli
6; Description   :   ASM library to menu system.
7;                   Contains functions for displaying messages.
8
9;--------------- Equates -----------------------------
10
11; Control characters for Menu Message string.
12; Normal control characters cannot be used since message string
13; will be tokenized and converted to menuitems.
14%define MNU_NL          " |n "  ; Menu newline defined as token string
15W_MNU_NL            EQU "|n"    ; Menu newline defined as WORD
16
17; Total border chars on left and right side of string menuitem
18SIZE_MSG_HBRDR      EQU     4   ; Horizontal border size
19
20; Message variables. This is an expanded MENUVARS struct.
21struc MSGVARS
22    .menuVars   resb    MENUVARS_size
23    .dwStrPtr:                  ; Far pointer to string to display
24    .wStrOff:   resb    2       ; Offset to string to display
25    .wStrSeg:   resb    2       ; Segment to string to display
26endstruc
27
28
29;-------------- Private global variables -------------
30; Section containing initialized data
31;SECTION .data
32
33
34;-------------- Public functions ---------------------
35; Section containing code
36SECTION .text
37
38;--------------------------------------------------------------------
39; Displays message string.
40;
41; MenuMsg_ShowMessage
42;   Parameters:
43;       BL:     Dialog width with borders included
44;       SS:BP:  Ptr to MENUVARS
45;       ES:DI:  Ptr to STOP terminated string to display
46;   Returns:
47;       Nothing
48;   Corrupts registers:
49;       AX, BX, CX, DX
50;--------------------------------------------------------------------
51ALIGN JUMP_ALIGN
52MenuMsg_ShowMessage:
53    ; Create stack frame
54    eENTER  MSGVARS_size, 0
55    sub     bp, MSGVARS_size                ; Point to MSGVARS
56
57    ; Initialize menu variables
58    mov     [bp+MENUVARS.bWidth], bl        ; Menu size
59    mov     WORD [bp+MENUVARS.wTopDwnH], 0  ; Title and Info size
60    mov     WORD [bp+MENUVARS.fnEvent], MenuMsg_MsgEvent
61    mov     [bp+MSGVARS.wStrOff], di        ; Store far ptr...
62    mov     [bp+MSGVARS.wStrSeg], es        ; ...to string to display
63
64    ; Enter menu
65    call    MenuMsg_GetLineCnt              ; Get message line count to CX
66    mov     ax, CNT_SCRN_ROW-2              ; Load max line rows to AX
67    MIN_U   ax, cx                          ; String lines to display to AX
68    times 2 inc ax                          ; Include borders for dlg height
69    mov     [bp+MENUVARS.bHeight], al       ; Store dialog height
70    call    MenuCrsr_GetCenter              ; Get X and Y coordinates to DX
71    xor     ax, ax                          ; Selection timeout (disable)
72    mov     bl, FLG_MNU_NOARRW              ; Menu flags
73    call    Menu_Init                       ; Returns only after dlg closed
74
75    ; Return
76    add     bp, MSGVARS_size                ; Point to old BP
77    eLEAVE                                  ; Destroy stack frame
78    ret
79
80
81;-------------- Private functions ---------------------
82
83;--------------------------------------------------------------------
84; Calculates number of string lines needed by string to display.
85;
86; MenuMsg_GetLineCnt
87;   Parameters:
88;       SS:BP:  Ptr to MSGVARS
89;       ES:DI:  Ptr to STOP terminated string to display
90;   Returns:
91;       CX:     Number of lines needed
92;   Corrupts registers:
93;       AX, BX, DX
94;--------------------------------------------------------------------
95ALIGN JUMP_ALIGN
96MenuMsg_GetLineCnt:
97    push    di
98
99    ; Get index for last line
100    mov     cx, -1                  ; Get last possible line
101    call    MenuMsg_GetTokenForLine
102    inc     cx                      ; Last index to line count
103
104    ; Return
105    pop     di
106    ret
107
108
109;--------------------------------------------------------------------
110; Check if line has space for token.
111;
112; MenuMsg_HasLineSpace
113;   Parameters:
114;       AX:     Token length in characters
115;       DX:     Characters left on line
116;       ES:DI:  Ptr to token string (not terminated!)
117;   Returns:
118;       DX:     Chars left after token + space at the end
119;       CF:     Set if space left for token
120;               Cleared if not enough space
121;   Corrupts registers:
122;       Nothing
123;--------------------------------------------------------------------
124ALIGN JUMP_ALIGN
125MenuMsg_HasLineSpace:
126    sub     dx, ax
127    jl      .NoSpace
128    cmp     WORD [es:di], W_MNU_NL  ; Newline token?
129    je      .NoSpace                ;  If so, end line
130    dec     dx                      ; Decrement for space after token
131    stc                             ; Set CF since space left
132    ret
133ALIGN JUMP_ALIGN
134.NoSpace:
135    xor     dx, dx                  ; Clear space left and CF
136    ret
137
138
139;--------------------------------------------------------------------
140; Return pointer to first token for wanted message line.
141;
142; MenuMsg_GetTokenForLine
143;   Parameters:
144;       CX:     Line index
145;       ES:DI:  Ptr to STOP terminated string to display
146;       SS:BP:  Ptr to MSGVARS
147;   Returns:
148;       AX:     Length of first token in characters
149;       CX:     Index of last line found (if wanted line not found)
150;       ES:DI:  Ptr to token
151;       CF:     Set if message line found
152;               Cleared if message line not found
153;   Corrupts registers:
154;       BX, DX
155;--------------------------------------------------------------------
156ALIGN JUMP_ALIGN
157MenuMsg_GetTokenForLine:
158    test    cx, cx              ; Line 0 wanted?
159    jz      .GetFirst           ;  If so, just get token length
160    push    bp
161    push    si
162
163    ; Prepare to scan tokens
164    eMOVZX  si, [bp+MENUVARS.bWidth]
165    sub     si, SIZE_MSG_HBRDR  ; Max number of chars per line
166    mov     dx, si              ; Initialize chars left on line
167    mov     bp, cx              ; Copy line index to BP
168    xor     bx, bx              ; Zero line index counter
169    xor     ax, ax              ; Zero token length
170
171    ; Scan all tokens to calculate lines needed
172ALIGN JUMP_ALIGN
173.TokenLoop:
174    ; Get token and length
175    xor     cx, cx              ; Always read token at index 0
176    add     di, ax              ; Increment offset for next token
177    call    String_StrToken     ; Get token length to AX, ptr to ES:DI
178    jnc     .Return             ; Return if no more tokens (CF cleared)
179    ; Check does line have space left for token
180    call    MenuMsg_HasLineSpace
181    jc      .TokenLoop          ; Space left, check next token
182    ; Change to next line
183    mov     dx, si              ; Copy max chars on line
184    call    MenuMsg_HasLineSpace; Update chars left
185    inc     bx                  ; Increment line index
186    cmp     bx, bp              ; Correct line found?
187    jne     .TokenLoop          ;  If not, check more tokens
188    stc                         ; Set CF since line found
189ALIGN JUMP_ALIGN
190.Return:
191    mov     cx, bx              ; Copy idx of last line found to CX
192    pop     si
193    pop     bp
194    ret
195ALIGN JUMP_ALIGN
196.GetFirst:
197    jmp     String_StrToken     ; Get token length to AX, ptr to ES:DI
198
199
200;--------------------------------------------------------------------
201; Message dialog menu event handler.
202;
203; MenuMsg_WriteLine
204;   Parameters:
205;       CX:     Index of line to display
206;       ES:DI:  Ptr to STOP terminated string to display
207;       SS:BP:  Ptr to MSGVARS
208;   Returns:
209;       CF:     Set if end of string
210;               Cleared if string has unwritten tokens
211;   Corrupts registers:
212;       AX, BX, CX, DX
213;--------------------------------------------------------------------
214ALIGN JUMP_ALIGN
215MenuMsg_WriteLine:
216    push    di
217    call    MenuMsg_GetTokenForLine         ; Get ptr to first token, length to AX
218    jnc     .EndOfString                    ; Return if no tokens
219    eMOVZX  dx, BYTE [bp+MENUVARS.bWidth]   ; Menu width
220    sub     dl, SIZE_MSG_HBRDR              ; To line length 
221    mov     bl, ' '                         ; Space character
222ALIGN JUMP_ALIGN
223.PrintToken:
224    ; Check if space for token
225    call    MenuMsg_HasLineSpace    ; Space left on line?
226    jnc     .PrintDone              ;  If not, all done
227    ; Print token
228    push    ax                      ; Store token length
229    mov     cx, ax                  ; Copy token length to CX
230    call    Print_CharBuffer        ; Print token
231    xchg    dx, bx                  ; Space char to DL
232    PRINT_CHAR
233    xchg    dx, bx                  ; Restore DX
234    pop     ax                      ; Pop token length
235    ; Get next token
236    add     di, ax                  ; Point to next token
237    xor     cx, cx                  ; Get token at index 0
238    call    String_StrToken         ; Get next token to ES:DI, len to AX
239    jc      .PrintToken             ; Print while tokens left
240ALIGN JUMP_ALIGN
241.EndOfString:   ; Last token written
242    stc
243ALIGN JUMP_ALIGN
244.PrintDone:     ; End of line but tokens left
245    pop     di
246    ret
247
248
249;--------------------------------------------------------------------
250; Message dialog menu event handler.
251;
252; MenuMsg_MsgEvent
253;   Parameters:
254;       BX:     Callback event
255;       CX:     Selected menuitem index
256;       DX:     Event parameter (event specific)
257;       SS:BP:  Ptr to MSGVARS
258;   Returns:
259;       AH:     Event specific or unused
260;       AL:     1=Event processed
261;               0=Event not processed (default action if any)
262;   Corrupts registers:
263;       BX, CX, DX
264;--------------------------------------------------------------------
265ALIGN JUMP_ALIGN
266MenuMsg_MsgEvent:
267    cmp     bx, EVNT_MMU_SELCHG     ; Selection changed?
268    je      .RetProcessed           ;  If so, return
269    cmp     bx, EVNT_MNU_SELSET     ; Enter to close dialog?
270    je      .CloseDialog            ;  If so, jump to close dialog
271    cmp     bx, EVNT_MNU_UPD        ; Draw menuitem string?
272    je      .DrawLine               ;  If so, jump to draw
273    cmp     bx, EVNT_MNU_KEY        ; Any key pressed to close dialog?
274    jne     .RetUnhandled           ;  If not, ignore message
275
276    ; Close dialog since key pressed
277ALIGN JUMP_ALIGN
278.CloseDialog:
279    or      BYTE [bp+MENUVARS.bFlags], FLG_MNU_EXIT ; Any key, exit
280ALIGN JUMP_ALIGN
281.RetUnhandled:
282    xor     ax, ax
283    ret
284
285ALIGN JUMP_ALIGN
286.DrawLine:
287    push    es
288    push    di
289
290    ; Print string line
291    mov     di, [bp+MSGVARS.wStrOff]; Load string offset
292    mov     es, [bp+MSGVARS.wStrSeg]; Load string segment
293    call    MenuMsg_WriteLine
294    pop     di
295    pop     es
296ALIGN JUMP_ALIGN
297.RetProcessed:
298    mov     ax, 1                   ; Event processed
299    ret
Note: See TracBrowser for help on using the repository browser.