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

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