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

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