source: xtideuniversalbios/trunk/Assembly_Library/Src/Display/DisplayFormatCompressed.asm@ 189

Last change on this file since 189 was 186, checked in by gregli@…, 13 years ago

Initial string compression checkin. All changes are under MODULE_STRINGS_COMPRESSED, and this can still be turned off. With this checkin, the serial and ebios code can both be turned on at the same time and still we remain below the 8K boundary (barely). I still need to chekin StringsCompress.pl after some more code cleanup. The output, in StringsCompressed.asm is checked in here, and should continue be to checkin when Strings.asm is changed, for those who do not have/want to run the Perl script to recreate it.

File size: 9.1 KB
Line 
1; Project name : Assembly Library
2; Description : Functions for displaying formatted strings.
3; ** Compressed Strings edition **
4;
5; Authors : Greg Lindhorst
6; : gregli@hotmail.com
7; :
8; : Tomi Tilli
9; : aitotat@gmail.com
10; :
11; Description : This is a plug replacement for DisplayFormat.asm,
12; working instead with precompiled and slightly compressed strings.
13;
14; Strings are compressed in a simple manner:
15; 1. The two most common characters, space and null, are removed
16; 2. Format specifiers are reduced to a single byte, including length information
17;
18; Format of bytes in the string are:
19; 01 xxxxxx Character in x plus StringsCompressed_NormalBase
20; 10 xxxxxx Character in x plus StringsCompressed_NormalBase, followed by a null (last character)
21; 11 xxxxxx Character in x plus StringsCompressed_NormalBase, followed by a space
22; 00 1 yyyyy Character/Format in lookup table StringsCopmressed_TranslatesAndFormats
23; 00 0 yyyyy Character/Format in lookup table StringsCompressed_TranslatesAndFormats, followed by a null
24;
25; StringsCompressed_NormalBase is defined by the compressor, but is usually around 0x40,
26; which gives a range of 0x40 to 0x7f, or roughly the upper and lower case letters.
27;
28; StringsCompressed_TranslatesAndFormats is a lookup table with the first few bytes being translation
29; characters, and the last few bytes being format jump offsets from DisplayFormatCompressed_BaseFormatOffset.
30; The dividing line is defined by StringsCompressed_FormatsBegin
31;
32; The assignments of the first two bits above is not by accident. The translates/format branch is 00
33; which is easy to test for. The '01' for "normal" (no null or space) and '001' for translates/format "normal"
34; match, allowing the translates/format codes to be shifted left by 1 and then tested with the same instructions.
35;
36; It is always possible to say that a null character follows the current character - thus there is
37; no way (nor need) to specify a zero character.
38;
39; Note that this code is optimized for size, not speed. Since this code is used only during initialization
40; and only for the user interface, small performance hits should not be noticed. It will seem odd to do so
41; much "preload", just in case a branch is taken, but that is cheaper (in size) than adding additional branches.
42;
43
44; Section containing code
45SECTION .text
46
47;--------------------------------------------------------------------
48; Format Handlers
49;
50; Names of format handlers are DisplayFormatCompressed_Format_* where * is
51; replaced with the format code after the '%' in the original string,
52; with '-' replaced with '_'.
53;
54; Parameters:
55; DS: BDA segment (zero)
56; AX: Parameter to Format
57; ES:DI: Ptr to cursor location in video RAM
58; Returns:
59; DI: Updated offset to video RAM
60; Corrupts registers:
61; AX, BX, CX, DX, SI
62;--------------------------------------------------------------------
63
64;
65; The following routines do not need any pre or post processing and can be jumped to directly.
66; Note that they need to be within 256 bytes of DisplayFormatCompressed_BaseFormatOffset
67;
68%define DisplayFormatCompressed_Format_c DisplayPrint_CharacterFromAL
69%define DisplayFormatCompressed_Format_nl DisplayPrint_Newline_FormatAdjustBP
70%define DisplayFormatCompressed_Format_s DisplayFormat_ParseCharacters_FromAX
71
72DisplayFormatCompressed_Format_A:
73 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
74DisplayFormatCompressed_ret: ; jump target for other routines who need a "ret"
75 ret
76
77DisplayFormatCompressed_Format_x:
78DisplayFormatCompressed_Format_5_x:
79 mov si,16 ; hex output, change base to 16
80 mov bx,(04<<8) + 'h' ; 4 bytes, with postfix character 'h' to emit
81 ; (note that the count includes the 'h')
82 jmp DisplayFormatCompressed_Format_u
83
84DisplayFormatCompressed_Format_2_I:
85 mov si,g_szDashForZero ; preload dash string in case we jump
86 test ax,ax ; if parameter equals zero, emit dash string instead
87 jz DisplayFormat_ParseCharacters
88;;; fall through
89
90DisplayFormatCompressed_Format_2_u:
91 mov bh,2 ; only two characters (instead of the default 5)
92;;; fall through
93
94DisplayFormatCompressed_Format_u:
95DisplayFormatCompressed_Format_5_u:
96 push bx ; push postfix character - either a zero (default) or a 'h'
97 mov bl,bh ; preserve character count for .PrintLoop
98
99.DivLoop:
100 xor dx, dx ; Zero DX for division
101 div si ; DX:AX / 10 => AX=quot, DX=rem
102 push dx ; Push digit
103
104 dec bh
105 jnz .DivLoop
106
107.PrintLoop:
108 pop ax ; Pop digit, postfix character on last iteration
109
110 dec bl ; on second to last iteration, emit digit whether it is zero or not
111 jz .PrintDigit
112
113 js short DisplayPrint_CharacterFromAL ; on last iteration, emit postfix character
114 ; if it is zero, DisplayPrint_CharacterFromAL will not emit
115
116 or dh, al ; skip leading zeros, dh keeps track if we have emitted anythng non-zero
117 jnz .PrintDigit ; note that dh starts at zero, from the div instruction in .DivLoop
118
119 test ch,2 ; are we padding with leading spaces?
120 jnz .PrintLoop ; test the even/odd of the format byte in the string
121
122 mov al,' '-'0' ; emit space, but let the following instuctions add '0'
123
124.PrintDigit:
125 add al,'0' ; Digit to character
126 cmp al,'9' ; for hex output, greater than '9'?
127 jle .NoHexAdjustment
128 add al,'A'-'9'-1 ; adjust for hex output ('A' to 'F')
129.NoHexAdjustment:
130
131 push dx ; preserve dh for future iterations
132 call DisplayPrint_CharacterFromAL
133 pop dx
134
135 jmp .PrintLoop
136
137
138;--------------------------------------------------------------------
139; DisplayFormat_ParseCharacters
140; Parameters:
141; DS: BDA segment (zero)
142; SS:BP: Pointer to first format parameter (-=2 updates to next parameter)
143; CS:SI: Pointer to string to format
144; ES:DI: Ptr to cursor location in video RAM
145; Returns:
146; CS:SI: Ptr to end of format string (ptr to one past NULL)
147; DI: Updated offset to video RAM
148; Corrupts registers:
149; AX, BX, CX, DX, BP
150;--------------------------------------------------------------------
151
152DisplayFormatCompressed_BaseFormatOffset:
153
154DisplayFormat_ParseCharacters_FromAX:
155 mov si,ax
156;;; Fall-through
157
158ALIGN JUMP_ALIGN
159DisplayFormat_ParseCharacters:
160;
161; This routine is used to outptu all strings from the ROM. The strings in ROMVARS are not compressed,
162; and must be handled differently.
163;
164 cmp si,byte 07fh ; well within the boundaries of ROMVARS_size
165 mov bx,cs ; preload bx with cs in case we take the following jump
166 jb short DisplayPrint_NullTerminatedStringFromBXSI
167
168.decode:
169 mov al,[cs:si] ; load next byte of the string
170 inc si
171
172 mov ch,al ; save a copy for later processing of high order bits
173
174 test al,0c0h ; check for translation/format character
175 jz DisplayFormatCompressed_TranslatesAndFormats
176
177 and al,03fh ; "Normal" character, mask off high order bits
178 add al,StringsCompressed_NormalBase ; and add character offset (usually around 0x40)
179
180.output:
181 call DisplayPrint_CharacterFromAL
182
183.process_after_output:
184 shl ch,1 ; check high order bits for end of string or space
185 jns short DisplayFormatCompressed_ret
186 jnc .decode
187 mov al,' '
188 call DisplayPrint_CharacterFromAL
189 jmp .decode
190
191
192ALIGN JUMP_ALIGN
193DisplayFormatCompressed_TranslatesAndFormats:
194;
195; This routine is here (above DisplayFormat_ParseCharacters) to reduce the amount of code between
196; DisplayFormatCompressed_BaseFormatOffset and jump targets (must fit in 256 bytes)
197;
198 shl ch,1 ; setup ch for later testing of null in .process_after_output
199 and ax,0001fh ; also clears AH for addition with BX and DX below
200
201 mov bx,StringsCompressed_TranslatesAndFormats ; calculate offset of translation/formats offset byte
202 add bx,ax
203
204 cmp al,StringsCompressed_FormatsBegin ; determine if this is a translation or a format
205
206 mov al,[cs:bx] ; fetch translation/formats byte
207
208 jb DisplayFormat_ParseCharacters.output ; check if this a translation or a format
209 ; if it is translation, output and postprocess for eos
210 ; note that the flags for this conditional jump were
211 ; set with the cmp al,StringsCompressed_FormatsBegin
212
213 mov dx,DisplayFormatCompressed_BaseFormatOffset ; calculate address to jump to for format handler
214 sub dx,ax
215
216 mov ax,[bp] ; preload ax with parameter
217 dec bp ; if no parameter is needed (format 'nl' for example),
218 dec bp ; the format handler can reincrement bp
219
220 mov bx,0500h ; preload bh with 5 decimal places for numeric output
221 ; bl is zero, indicating not to output a 'h' (default base 10)
222
223 push si ; preserve si and cx, in the case of outputing a string
224 push cx
225
226 mov si,10 ; preload si with 10 for numeric output (default base 10)
227
228 call dx ; call the format routine
229
230 pop cx ; restore cx and si
231 pop si
232
233 jmp DisplayFormat_ParseCharacters.process_after_output ; continue postprocessing, check for end of string
234
235
236
237
238
239
240
241
242
243
244
245
Note: See TracBrowser for help on using the repository browser.