2 \ Fcode payload for QEMU TCX graphics card
4 \ This is the Forth source for an Fcode payload to initialise
5 \ the QEMU TCX graphics card.
7 \ (C) Copyright 2013 Mark Cave-Ayland
13 \ Instead of using fixed values for the framebuffer address and the width
14 \ and height, grab the ones passed in by QEMU/generated by OpenBIOS
17 : (find-xt) \ ( str len -- xt | -1 )
26 : (is-openbios) \ ( -- true | false )
27 " openbios-video-width" (find-xt) -1 <> if
34 " openbios-video-width" (find-xt) cell+ value openbios-video-width-xt
35 " openbios-video-height" (find-xt) cell+ value openbios-video-height-xt
36 " depth-bits" (find-xt) cell+ value depth-bits-xt
37 " line-bytes" (find-xt) cell+ value line-bytes-xt
39 : openbios-video-width
41 openbios-video-width-xt @
47 : openbios-video-height
49 openbios-video-height-xt @
75 h# 0 constant tcx-off-rom
76 h# 10000 constant /tcx-off-rom
78 h# 200000 constant tcx-off-cmap
79 h# 4000 constant /tcx-off-cmap-24
80 h# 4 constant /tcx-off-cmap-8
82 h# 240000 constant tcx-off-dhc
83 h# 4000 constant /tcx-off-dhc-24
84 h# 4 constant /tcx-off-dhc-8
86 h# 280000 constant tcx-off-alt
87 h# 8000 constant /tcx-off-alt-24
88 h# 1 constant /tcx-off-alt-8
90 h# 301000 constant tcx-off-thc-24
91 h# 300000 constant tcx-off-thc-8
92 h# 1000 constant /tcx-off-thc-24
93 h# 81c constant /tcx-off-thc-8
95 h# 701000 constant tcx-off-tec
96 h# 1000 constant /tcx-off-tec
98 h# 800000 constant tcx-off-dfb8
99 h# 100000 constant /tcx-off-dfb8
101 h# 2000000 constant tcx-off-dfb24
102 h# 400000 constant /tcx-off-dfb24-24
103 h# 1 constant /tcx-off-dfb24-8
105 h# 4000000 constant tcx-off-stip
106 h# 800000 constant /tcx-off-stip
108 h# 6000000 constant tcx-off-blit
109 h# 800000 constant /tcx-off-blit
111 h# a000000 constant tcx-off-rdfb32
112 h# 400000 constant /tcx-off-rdfb32-24
113 h# 1 constant /tcx-off-rdfb32-8
115 h# c000000 constant tcx-off-rstip
116 h# 800000 constant /tcx-off-rstip-24
117 h# 1 constant /tcx-off-rstip-8
119 h# e000000 constant tcx-off-rblit
120 h# 800000 constant /tcx-off-rblit-24
121 h# 1 constant /tcx-off-rblit-8
123 : >tcx-reg-spec ( offset size -- encoded-reg )
124 >r 0 my-address d+ my-space encode-phys r> encode-int encode+
128 \ WARNING: order is important (at least to Solaris)
129 tcx-off-dfb8 /tcx-off-dfb8 >tcx-reg-spec
130 tcx-off-dfb24 /tcx-off-dfb24-8 >tcx-reg-spec encode+
131 tcx-off-stip /tcx-off-stip >tcx-reg-spec encode+
132 tcx-off-blit /tcx-off-blit >tcx-reg-spec encode+
133 tcx-off-rdfb32 /tcx-off-rdfb32-8 >tcx-reg-spec encode+
134 tcx-off-rstip /tcx-off-rstip-8 >tcx-reg-spec encode+
135 tcx-off-rblit /tcx-off-rblit-8 >tcx-reg-spec encode+
136 tcx-off-tec /tcx-off-tec >tcx-reg-spec encode+
137 tcx-off-cmap /tcx-off-cmap-8 >tcx-reg-spec encode+
138 tcx-off-thc-8 /tcx-off-thc-8 >tcx-reg-spec encode+
139 tcx-off-rom /tcx-off-rom >tcx-reg-spec encode+
140 tcx-off-dhc /tcx-off-dhc-8 >tcx-reg-spec encode+
141 tcx-off-alt /tcx-off-alt-8 >tcx-reg-spec encode+
146 \ WARNING: order is important (at least to Solaris)
147 tcx-off-dfb8 /tcx-off-dfb8 >tcx-reg-spec
148 tcx-off-dfb24 /tcx-off-dfb24-24 >tcx-reg-spec encode+
149 tcx-off-stip /tcx-off-stip >tcx-reg-spec encode+
150 tcx-off-blit /tcx-off-blit >tcx-reg-spec encode+
151 tcx-off-rdfb32 /tcx-off-rdfb32-24 >tcx-reg-spec encode+
152 tcx-off-rstip /tcx-off-rstip-24 >tcx-reg-spec encode+
153 tcx-off-rblit /tcx-off-rblit-24 >tcx-reg-spec encode+
154 tcx-off-tec /tcx-off-tec >tcx-reg-spec encode+
155 tcx-off-cmap /tcx-off-cmap-24 >tcx-reg-spec encode+
156 tcx-off-thc-24 /tcx-off-thc-24 >tcx-reg-spec encode+
157 tcx-off-rom /tcx-off-rom >tcx-reg-spec encode+
158 tcx-off-dhc /tcx-off-dhc-24 >tcx-reg-spec encode+
159 tcx-off-alt /tcx-off-alt-24 >tcx-reg-spec encode+
163 : do-map-in ( offset size -- virt )
164 >r my-space r> " map-in" $call-parent
167 : do-map-out ( virt size )
168 " map-out" $call-parent
179 : dac! ( data reg# -- )
180 >r dup 2dup bljoin r> tcx-dac + l!
185 : color! ( r g b c# -- )
200 tcx-off-cmap /tcx-dac do-map-in to tcx-dac
204 tcx-off-dfb8 h# c0000 do-map-in to fb-addr
215 " SUNW,tcx" device-name
216 " display" device-type
218 : qemu-tcx-driver-install ( -- )
222 \ Initial pallette taken from Sun's "Writing FCode Programs"
223 h# ff h# ff h# ff h# 0 color! \ Background white
224 h# 0 h# 0 h# 0 h# ff color! \ Foreground black
225 h# 64 h# 41 h# b4 h# 1 color! \ SUN-blue logo
227 fb-addr to frame-buffer-adr
228 default-font set-font
230 \ Sun TCX adapters don't have an address property, but it is useful for
231 \ OpenBIOS developers. Unfortunately NetBSD SPARC32 has a bug that causes
232 \ it to fail initialising TCX if the address property is present; so work
233 \ around this by adding an underscore prefix
234 frame-buffer-adr encode-int " _address" property
236 openbios-video-width openbios-video-height over char-width / over char-height /
241 : qemu-tcx-driver-init
243 \ Handle differences between 8-bit/24-bit mode
246 /tcx-off-cmap-8 to /tcx-dac
247 " true" encode-string " tcx-8-bit" property
250 /tcx-off-cmap-24 to /tcx-dac
252 \ Even with a 24-bit enabled TCX card, the control plane is
253 \ used in 8-bit mode. So force the video subsystem into 8-bit
254 \ mode before initialisation.
256 openbios-video-width line-bytes-xt !
259 h# 1d encode-int " vbporch" property
260 h# a0 encode-int " hbporch" property
261 h# 06 encode-int " vsync" property
262 h# 88 encode-int " hsync" property
263 h# 03 encode-int " vfporch" property
264 h# 18 encode-int " hfporch" property
265 h# 03dfd240 encode-int " pixfreq" property
266 h# 3c encode-int " vfreq" property
268 openbios-video-height encode-int " height" property
269 openbios-video-width encode-int " width" property
270 line-bytes encode-int " linebytes" property
272 h# 39 encode-int 0 encode-int encode+ " intr" property
273 5 encode-int " interrupts" property
275 ['] qemu-tcx-driver-install is-install