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

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

Changes to Assembly Library:
File handle is now properly returned when opening file.
Added function for getting file size by using file handle.

File size: 6.7 KB
Line 
1; File name : Line Splitter.asm
2; Project name : Assembly Library
3; Created date : 8.8.2010
4; Last update : 1.10.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 .RemoveEmptyLinesAtTheEndIfAnyExists
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.RemoveEmptyLinesAtTheEndIfAnyExists:
150 cmp BYTE [si-2], SOH ; Character before NULL
151 je SHORT .RemoveEmptyLineAtTheEndOfString
152 ret
153ALIGN JUMP_ALIGN
154.RemoveEmptyLineAtTheEndOfString:
155 dec si
156 dec WORD [bp+LINE_SPLITTER.wLines]
157 mov BYTE [si-1], NULL
158 jmp SHORT .RemoveEmptyLinesAtTheEndIfAnyExists
159
160
161;--------------------------------------------------------------------
162; LineSplitter_PrintLineInCXfromStringInESDI
163; Parameters:
164; CX: Index of line to print
165; ES:DI: Ptr to string containing the line
166; Returns:
167; Nothing
168; Corrupts registers:
169; AX, BX, SI
170;--------------------------------------------------------------------
171ALIGN JUMP_ALIGN
172LineSplitter_PrintLineInCXfromStringInESDI:
173 push di
174 push cx
175
176 call LineSplitter_GetOffsetToSIforLineCXfromStringInESDI
177 jnc SHORT .LineNotFound
178 mov bx, es
179 CALL_DISPLAY_LIBRARY PrintCharBufferFromBXSIwithLengthInCX
180.LineNotFound:
181 pop cx
182 pop di
183 ret
184
185
186;--------------------------------------------------------------------
187; LineSplitter_GetOffsetToSIforLineCXfromStringInESDI
188; Parameters:
189; CX: Index of line to search for
190; ES:DI: Ptr to string
191; Returns:
192; CX: Line length
193; ES:SI: Ptr to beginning of line
194; CF: Set if wanted line was found
195; Corrupts registers:
196; AX, DI
197;--------------------------------------------------------------------
198ALIGN JUMP_ALIGN
199LineSplitter_GetOffsetToSIforLineCXfromStringInESDI:
200 mov si, di ; SI points to start of first line
201 mov al, STX ; Last control character to scan for
202 inc cx ; Increment CX to line count
203 cld
204ALIGN JUMP_ALIGN
205.LineScanLoop:
206 scasb ; cmp al, [es:di]. Increment DI
207 jb SHORT .LineScanLoop ; Ignore all above STX
208
209 ; NULL, SOH or STX
210 dec cx ; Decrement lines to scan through
211 jz SHORT .WantedLineFound
212 cmp BYTE [es:di-1], NULL
213 je SHORT .EndOfString ; Jump with CF cleared
214 mov si, di ; SI points to start of new line
215 jmp SHORT .LineScanLoop
216
217ALIGN JUMP_ALIGN
218.WantedLineFound:
219 stc ; Set CF since wanted line was found
220.EndOfString:
221 lahf ; Load FLAGS low to AH
222 lea cx, [di-1] ; CX = offset to NULL, SOH or STX
223 sub cx, si ; CX = string length
224 sahf ; Store AH to FLAGS low
225 ret
Note: See TracBrowser for help on using the repository browser.