~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/openbios/libopenbios/video_common.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Creation Date: <2002/10/23 20:26:40 samuel>
 
3
 *   Time-stamp: <2004/01/07 19:39:15 samuel>
 
4
 *
 
5
 *     <video_common.c>
 
6
 *
 
7
 *     Shared video routines
 
8
 *
 
9
 *   Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se)
 
10
 *
 
11
 *   This program is free software; you can redistribute it and/or
 
12
 *   modify it under the terms of the GNU General Public License
 
13
 *   as published by the Free Software Foundation
 
14
 *
 
15
 */
 
16
 
 
17
#include "config.h"
 
18
#include "libc/vsprintf.h"
 
19
#include "libopenbios/bindings.h"
 
20
#include "libopenbios/fontdata.h"
 
21
#include "libopenbios/ofmem.h"
 
22
#include "libopenbios/video.h"
 
23
#include "packages/video.h"
 
24
#include "drivers/vga.h"
 
25
#define NO_QEMU_PROTOS
 
26
#include "arch/common/fw_cfg.h"
 
27
 
 
28
struct video_info video;
 
29
 
 
30
unsigned long
 
31
video_get_color( int col_ind )
 
32
{
 
33
        unsigned long col;
 
34
        if( !VIDEO_DICT_VALUE(video.ih) || col_ind < 0 || col_ind > 255 )
 
35
                return 0;
 
36
        if( VIDEO_DICT_VALUE(video.depth) == 8 )
 
37
                return col_ind;
 
38
        col = video.pal[col_ind];
 
39
        if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 )
 
40
                return col;
 
41
        if( VIDEO_DICT_VALUE(video.depth) == 15 )
 
42
                return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
 
43
        return 0;
 
44
}
 
45
 
 
46
/* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */
 
47
 
 
48
void
 
49
video_mask_blit(void)
 
50
{
 
51
        ucell bgcolor = POP();
 
52
        ucell fgcolor = POP();
 
53
        ucell height = POP();
 
54
        ucell width = POP();
 
55
        unsigned char *mask = (unsigned char *)POP();
 
56
        unsigned char *fbaddr = (unsigned char *)POP();
 
57
 
 
58
        ucell color;
 
59
        unsigned char *dst, *rowdst;
 
60
        int x, y, m, b, d, depthbytes;
 
61
 
 
62
        fgcolor = video_get_color(fgcolor);
 
63
        bgcolor = video_get_color(bgcolor);
 
64
        d = VIDEO_DICT_VALUE(video.depth);
 
65
        depthbytes = (d + 1) >> 3;
 
66
 
 
67
        dst = fbaddr;
 
68
        for( y = 0; y < height; y++) {
 
69
                rowdst = dst;
 
70
                for( x = 0; x < (width + 1) >> 3; x++ ) {
 
71
                        for (b = 0; b < 8; b++) {
 
72
                                m = (1 << (7 - b));
 
73
 
 
74
                                if (*mask & m) {
 
75
                                        color = fgcolor;
 
76
                                } else {
 
77
                                        color = bgcolor;
 
78
                                }
 
79
 
 
80
                                if( d >= 24 )
 
81
                                        *((uint32_t*)dst) = color;
 
82
                                else if( d >= 15 )
 
83
                                        *((uint16_t*)dst) = color;
 
84
                                else
 
85
                                        *dst = color;
 
86
 
 
87
                                dst += depthbytes;
 
88
                        }
 
89
                        mask++;
 
90
                }
 
91
                dst = rowdst;
 
92
                dst += VIDEO_DICT_VALUE(video.rb);
 
93
        }
 
94
}
 
95
 
 
96
/* ( x y w h fgcolor bgcolor -- ) */
 
97
 
 
98
void
 
99
video_invert_rect( void )
 
100
{
 
101
        ucell bgcolor = POP();
 
102
        ucell fgcolor = POP();
 
103
        int h = POP();
 
104
        int w = POP();
 
105
        int y = POP();
 
106
        int x = POP();
 
107
        char *pp;
 
108
 
 
109
        bgcolor = video_get_color(bgcolor);
 
110
        fgcolor = video_get_color(fgcolor);
 
111
 
 
112
        if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 ||
 
113
                x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h))
 
114
                return;
 
115
 
 
116
        pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y;
 
117
        for( ; h--; pp += *(video.rb) ) {
 
118
                int ww = w;
 
119
                if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) {
 
120
                        uint32_t *p = (uint32_t*)pp + x;
 
121
                        while( ww-- ) {
 
122
                                if (*p == fgcolor) {
 
123
                                        *p++ = bgcolor;
 
124
                                } else if (*p == bgcolor) {
 
125
                                        *p++ = fgcolor;
 
126
                                }
 
127
                        }
 
128
                } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) {
 
129
                        uint16_t *p = (uint16_t*)pp + x;
 
130
                        while( ww-- ) {
 
131
                                if (*p == (uint16_t)fgcolor) {
 
132
                                        *p++ = bgcolor;
 
133
                                } else if (*p == (uint16_t)bgcolor) {
 
134
                                        *p++ = fgcolor;
 
135
                                }
 
136
                        }
 
137
                } else {
 
138
                        char *p = (char *)(pp + x);
 
139
 
 
140
                        while( ww-- ) {
 
141
                                if (*p == (char)fgcolor) {
 
142
                                        *p++ = bgcolor;
 
143
                                } else if (*p == (char)bgcolor) {
 
144
                                        *p++ = fgcolor;
 
145
                                }
 
146
                        }
 
147
                }
 
148
        }
 
149
}
 
150
 
 
151
/* ( color_ind x y width height -- ) (?) */
 
152
void
 
153
video_fill_rect(void)
 
154
{
 
155
        int h = POP();
 
156
        int w = POP();
 
157
        int y = POP();
 
158
        int x = POP();
 
159
        int col_ind = POP();
 
160
 
 
161
        char *pp;
 
162
        unsigned long col = video_get_color(col_ind);
 
163
 
 
164
        if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 ||
 
165
            x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h))
 
166
                return;
 
167
 
 
168
        pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y;
 
169
        for( ; h--; pp += VIDEO_DICT_VALUE(video.rb) ) {
 
170
                int ww = w;
 
171
                if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) {
 
172
                        uint32_t *p = (uint32_t*)pp + x;
 
173
                        while( ww-- )
 
174
                                *p++ = col;
 
175
                } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) {
 
176
                        uint16_t *p = (uint16_t*)pp + x;
 
177
                        while( ww-- )
 
178
                                *p++ = col;
 
179
                } else {
 
180
                        char *p = (char *)(pp + x);
 
181
 
 
182
                        while( ww-- )
 
183
                                *p++ = col;
 
184
                }
 
185
        }
 
186
}
 
187
 
 
188
void setup_video()
 
189
{
 
190
        /* Make everything inside the video_info structure point to the
 
191
           values in the Forth dictionary. Hence everything is always in
 
192
           sync. */
 
193
        phandle_t options;
 
194
        char buf[6];
 
195
 
 
196
        feval("['] display-ih cell+");
 
197
        video.ih = cell2pointer(POP());
 
198
 
 
199
        feval("['] frame-buffer-adr cell+");
 
200
        video.mvirt = cell2pointer(POP());
 
201
        feval("['] openbios-video-width cell+");
 
202
        video.w = cell2pointer(POP());
 
203
        feval("['] openbios-video-height cell+");
 
204
        video.h = cell2pointer(POP());
 
205
        feval("['] depth-bits cell+");
 
206
        video.depth = cell2pointer(POP());
 
207
        feval("['] line-bytes cell+");
 
208
        video.rb = cell2pointer(POP());
 
209
        feval("['] color-palette cell+");
 
210
        video.pal = cell2pointer(POP());
 
211
 
 
212
        /* Set global variables ready for fb8-install */
 
213
        PUSH( pointer2cell(video_mask_blit) );
 
214
        fword("is-noname-cfunc");
 
215
        feval("to fb8-blitmask");
 
216
        PUSH( pointer2cell(video_fill_rect) );
 
217
        fword("is-noname-cfunc");
 
218
        feval("to fb8-fillrect");
 
219
        PUSH( pointer2cell(video_invert_rect) );
 
220
        fword("is-noname-cfunc");
 
221
        feval("to fb8-invertrect");
 
222
 
 
223
        /* Static information */
 
224
        PUSH((ucell)fontdata);
 
225
        feval("to (romfont)");
 
226
        PUSH(FONT_HEIGHT);
 
227
        feval("to (romfont-height)");
 
228
        PUSH(FONT_WIDTH);
 
229
        feval("to (romfont-width)");
 
230
 
 
231
        /* Initialise the structure */
 
232
        VIDEO_DICT_VALUE(video.w) = VGA_DEFAULT_WIDTH;
 
233
        VIDEO_DICT_VALUE(video.h) = VGA_DEFAULT_HEIGHT;
 
234
        VIDEO_DICT_VALUE(video.depth) = VGA_DEFAULT_DEPTH;
 
235
        VIDEO_DICT_VALUE(video.rb) = VGA_DEFAULT_LINEBYTES;
 
236
 
 
237
#if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64))
 
238
        /* If running from QEMU, grab the parameters from the firmware interface */
 
239
        int w, h, d;
 
240
 
 
241
        w = fw_cfg_read_i16(FW_CFG_ARCH_WIDTH);
 
242
        h = fw_cfg_read_i16(FW_CFG_ARCH_HEIGHT);
 
243
        d = fw_cfg_read_i16(FW_CFG_ARCH_DEPTH);
 
244
        if (w && h && d) {
 
245
                VIDEO_DICT_VALUE(video.w) = w;
 
246
                VIDEO_DICT_VALUE(video.h) = h;
 
247
                VIDEO_DICT_VALUE(video.depth) = d;
 
248
                VIDEO_DICT_VALUE(video.rb) = (w * ((d + 7) / 8));
 
249
        }
 
250
#endif
 
251
 
 
252
        /* Setup screen-#rows/screen-#columns */
 
253
        options = find_dev("/options");
 
254
        snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.w) / FONT_WIDTH);
 
255
        set_property(options, "screen-#columns", buf, strlen(buf) + 1);
 
256
        snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.h) / FONT_HEIGHT);
 
257
        set_property(options, "screen-#rows", buf, strlen(buf) + 1);
 
258
}