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

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