source: xtideuniversalbios/trunk/Assembly_Library/Src/Menu/Dialog/LineSplitter.asm@ 42

Last change on this file since 42 was 41, checked in by Tomi Tilli, 14 years ago

Initial commit for Assembly Library.

File size: 6.5 KB
Line 
1; File name : Line Splitter.asm
2; Project name : Assembly Library
3; Created date : 8.8.2010
4; Last update : 15.9.2010
5; Author : Tomi Tilli
6; Description : Splits long strings to multiple lines.
7
8struc LINE_SPLITTER
9 .pLastWord resb 2
10 .wMaxLineLength resb 2
11 .wLines resb 2
12endstruc
13
14
15; Section containing code
16SECTION .text
17
18;--------------------------------------------------------------------
19; LineSplitter_SplitStringFromDSSIwithMaxLineLengthInAXandGetLineCountToAX
20; Parameters:
21; AX: Maximum allowed length for a line
22; DS:SI: Ptr to string to split
23; Returns:
24; AX: Number of lines
25; Corrupts registers:
26; CX, SI
27;--------------------------------------------------------------------
28ALIGN JUMP_ALIGN
29LineSplitter_SplitStringFromDSSIwithMaxLineLengthInAXandGetLineCountToAX:
30 xor cx, cx
31 cmp [si], cl ; String length zero?
32 jne SHORT .PrepareToSplit
33 xchg ax, cx
34 ret
35
36ALIGN JUMP_ALIGN
37.PrepareToSplit:
38 eENTER_STRUCT LINE_SPLITTER_size ; SS:BP now points to LINE_SPLITTER
39
40 mov [bp+LINE_SPLITTER.wLines], cx
41 call Memory_SetZFifNullPointerInDSSI
42 jz SHORT .ReturnNumberOfLinesInAX
43 call SplitStringFromDSSIusingLineSplitterInSSBP
44
45.ReturnNumberOfLinesInAX:
46 mov ax, [bp+LINE_SPLITTER.wLines]
47 eLEAVE_STRUCT LINE_SPLITTER_size
48 ret
49
50;--------------------------------------------------------------------
51; SplitStringFromDSSIusingLineSplitterInSSBP
52; Parameters:
53; AX: Maximum allowed length for a line
54; DS:SI: Ptr to string to split
55; SS:BP: Ptr to LINE_SPLITTER
56; Returns:
57; SS:BP: Ptr to LINE_SPLITTER with number of lines
58; Corrupts registers:
59; AX, CX, SI
60;--------------------------------------------------------------------
61ALIGN JUMP_ALIGN
62SplitStringFromDSSIusingLineSplitterInSSBP:
63 mov [bp+LINE_SPLITTER.pLastWord], si
64 mov [bp+LINE_SPLITTER.wMaxLineLength], ax
65 inc WORD [bp+LINE_SPLITTER.wLines] ; Always at least one line
66 xor cx, cx ; Length of current line
67 cld
68ALIGN JUMP_ALIGN
69.ScanNextCharacter:
70 lodsb ; Load from [DS:SI] to AL, increment SI
71 cmp al, ' ' ; Control character or space?
72 je SHORT .ProcessSpace
73 jb SHORT .ProcessControlCharacter
74.IncrementCharacterCount:
75 inc cx ; Increment character count
76 cmp cx, [bp+LINE_SPLITTER.wMaxLineLength]
77 jbe SHORT .ScanNextCharacter
78
79 mov si, [bp+LINE_SPLITTER.pLastWord] ; Resume to beginning of last word
80 mov BYTE [si-1], STX ; STX marks start or new line
81 ; Fall to .StartNewLine
82
83;--------------------------------------------------------------------
84; .StartNewLine
85; Parameters:
86; CX: Line length so far
87; DS:SI: Ptr character that begins new line
88; SS:BP: Ptr to LINE_SPLITTER
89; Returns:
90; CX: Zero
91; SS:BP: LINE_SPLITTER updated for number of lines
92; Jumps to .ScanNextCharacter
93; Corrupts registers:
94; Nothing
95;--------------------------------------------------------------------
96.StartNewLine:
97 inc WORD [bp+LINE_SPLITTER.wLines] ; Increment number of lines
98 xor cx, cx ; Zero line length
99 jmp SHORT .ScanNextCharacter
100
101;--------------------------------------------------------------------
102; .ProcessSpace
103; Parameters:
104; CX: Line length so far
105; DS:SI: Ptr first character after space
106; SS:BP: Ptr to LINE_SPLITTER
107; Returns:
108; SS:BP: LINE_SPLITTER updated to beginning of next word
109; Jumps to .IncrementCharacterCount
110; Corrupts registers:
111; Nothing
112;--------------------------------------------------------------------
113ALIGN JUMP_ALIGN
114.ProcessSpace:
115 mov [bp+LINE_SPLITTER.pLastWord], si
116 jmp SHORT .IncrementCharacterCount
117
118;--------------------------------------------------------------------
119; .ProcessControlCharacter
120; Parameters:
121; AL: Control character
122; CX: Line length so far
123; DS:SI: Ptr inside string to split
124; SS:BP: Ptr to LINE_SPLITTER
125; Returns:
126; SS:BP: LINE_SPLITTER updated to beginning of next line (LF control character)
127; Corrupts registers:
128; Nothing
129;--------------------------------------------------------------------
130ALIGN JUMP_ALIGN
131.ProcessControlCharacter:
132 cmp al, NULL ; End of string?
133 je SHORT .EndOfString
134 cmp al, LF ; Line feed?
135 je SHORT .NewlineCharacter
136 cmp al, SOH ; Previous newline character?
137 je SHORT .NewlineCharacter
138
139 mov BYTE [si-1], ' ' ; Replace unhandled control characters with space
140 jmp SHORT .ProcessSpace
141
142ALIGN JUMP_ALIGN
143.NewlineCharacter:
144 mov BYTE [si-1], SOH ; SOH marks previous newline character
145 mov [bp+LINE_SPLITTER.pLastWord], si
146 jmp SHORT .StartNewLine
147
148ALIGN JUMP_ALIGN
149.EndOfString:
150 ret
151
152
153;--------------------------------------------------------------------
154; LineSplitter_PrintLineInCXfromStringInESDI
155; Parameters:
156; CX: Index of line to print
157; ES:DI: Ptr to string containing the line
158; Returns:
159; Nothing
160; Corrupts registers:
161; AX, BX, SI
162;--------------------------------------------------------------------
163ALIGN JUMP_ALIGN
164LineSplitter_PrintLineInCXfromStringInESDI:
165 push di
166 push cx
167
168 call LineSplitter_GetOffsetToSIforLineCXfromStringInESDI
169 jnc SHORT .LineNotFound
170 mov bx, es
171 CALL_DISPLAY_LIBRARY PrintCharBufferFromBXSIwithLengthInCX
172.LineNotFound:
173 pop cx
174 pop di
175 ret
176
177
178;--------------------------------------------------------------------
179; LineSplitter_GetOffsetToSIforLineCXfromStringInESDI
180; Parameters:
181; CX: Index of line to search for
182; ES:DI: Ptr to string
183; Returns:
184; CX: Line length
185; ES:SI: Ptr to beginning of line
186; CF: Set if wanted line was found
187; Corrupts registers:
188; AX, DI
189;--------------------------------------------------------------------
190ALIGN JUMP_ALIGN
191LineSplitter_GetOffsetToSIforLineCXfromStringInESDI:
192 mov si, di ; SI points to start of first line
193 mov al, STX ; Last control character to scan for
194 inc cx ; Increment CX to get length for first line
195 cld
196ALIGN JUMP_ALIGN
197.LineScanLoop:
198 scasb ; cmp al, [es:di]. Increment DI
199 jb SHORT .LineScanLoop ; Non control character
200
201 ; Our end of line characters or NULL character
202 dec cx ; Decrement lines to scan through
203 jz SHORT .WantedLineFound
204 cmp BYTE [es:di-1], NULL
205 je SHORT .EndOfString ; Jump with CF cleared
206 mov si, di ; SI points to start of new line
207 jmp SHORT .LineScanLoop
208
209ALIGN JUMP_ALIGN
210.WantedLineFound:
211 stc ; Set CF since wanted line was found
212.EndOfString:
213 lahf ; Load FLAGS low to AH
214 lea cx, [di-1] ; We don't want control character to be printed
215 sub cx, si ; String length to CX
216 sahf ; Store AH to FLAGS low
217 ret
Note: See TracBrowser for help on using the repository browser.