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

Last change on this file since 194 was 194, checked in by gregli@…, 12 years ago

ifdef'd out more unused code. Also added a tool for looking through the listing and the output of the precompiler to aid in finding dead code. Some changes in the files are to add annotations for the tool to avoid false positives.

File size: 9.2 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 to DisplayFormat_ParseCharacters
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.