2 #include "../port/lib.h"
7 #include "../port/error.h"
16 * #9 Ticket to Ride IV.
27 enum { /* index registers */
54 CursorMode32x32 = 0x23,
55 CursorMode64x64 = 0x27,
56 CursorMode = CursorMode32x32,
60 t2r4enable(VGAscr* scr)
71 mmio = vmap(p->mem[4].bar & ~0x0F, p->mem[4].size);
74 addvgaseg("t2r4mmio", p->mem[4].bar & ~0x0F, p->mem[4].size);
79 addvgaseg("t2r4screen", scr->paddr, scr->apsize);
83 t2r4xi(VGAscr* scr, int index)
88 mmio[IndexLo] = index & 0xFF;
89 mmio[IndexHi] = (index>>8) & 0xFF;
95 t2r4xo(VGAscr* scr, int index, uchar data)
100 mmio[IndexLo] = index & 0xFF;
101 mmio[IndexHi] = (index>>8) & 0xFF;
107 t2r4curdisable(VGAscr* scr)
111 t2r4xo(scr, CursorCtl, 0x00);
115 t2r4curload(VGAscr* scr, Cursor* curs)
118 int size, x, y, zoom;
119 ulong clr, *mmio, pixels, set;
126 * Make sure cursor is off by initialising the cursor
127 * control to defaults.
129 t2r4xo(scr, CursorCtl, 0x00);
132 * Set auto-increment mode for index-register addressing
133 * and initialise the cursor array index.
135 mmio[IndexCtl] = 0x01;
136 mmio[IndexLo] = CursorArray & 0xFF;
137 mmio[IndexHi] = (CursorArray>>8) & 0xFF;
140 * Initialise the cursor RAM array. There are 2 planes,
141 * p0 and p1. Data is written 4 pixels per byte, with p1 the
142 * MS bit of each pixel.
143 * The cursor is set in X-Windows mode which gives the following
146 * 0 0 underlying pixel colour
147 * 0 1 underlying pixel colour
148 * 1 0 cursor colour 1
149 * 1 1 cursor colour 2
150 * Put the cursor into the top-left of the array.
152 * Although this looks a lot like the IBM RGB524 cursor, the
153 * scanlines appear to be twice as long as they should be and
154 * some of the other features are missing.
156 if(mmio[Zoom] & 0x0F)
160 data = (uchar*)&mmio[Data];
161 for(y = 0; y < zoom; y++){
162 clr = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];
163 set = (curs->set[2*y]<<8)|curs->set[y*2 + 1];
165 for(x = 0; x < 16; x++){
167 pixels |= 0x03<<(x*2);
168 else if(clr & (1<<x))
169 pixels |= 0x02<<(x*2);
182 if(CursorMode == CursorMode32x32 && zoom == 16)
194 if(CursorMode == CursorMode32x32)
199 for(x = 0; x < size/8; x++){
205 mmio[IndexCtl] = 0x00;
208 * Initialise the hotpoint and enable the cursor.
210 t2r4xo(scr, CursorHotX, -curs->offset.x);
211 zoom = (scr->mmio[Zoom] & 0x0F)+1;
212 t2r4xo(scr, CursorHotY, -curs->offset.y*zoom);
214 t2r4xo(scr, CursorCtl, CursorMode);
218 t2r4curmove(VGAscr* scr, Point p)
225 t2r4xo(scr, CursorXLo, p.x & 0xFF);
226 t2r4xo(scr, CursorXHi, (p.x>>8) & 0x0F);
228 zoom = (scr->mmio[Zoom] & 0x0F)+1;
230 t2r4xo(scr, CursorYLo, y & 0xFF);
231 t2r4xo(scr, CursorYHi, (y>>8) & 0x0F);
237 t2r4curenable(VGAscr* scr)
244 * Make sure cursor is off by initialising the cursor
245 * control to defaults.
247 t2r4xo(scr, CursorCtl, 0x00);
250 * Cursor colour 1 (white),
251 * cursor colour 2 (black).
253 t2r4xo(scr, CursorR1, Pwhite);
254 t2r4xo(scr, CursorG1, Pwhite);
255 t2r4xo(scr, CursorB1, Pwhite);
257 t2r4xo(scr, CursorR2, Pblack);
258 t2r4xo(scr, CursorG2, Pblack);
259 t2r4xo(scr, CursorB2, Pblack);
262 * Load, locate and enable the cursor, 64x64, mode 2.
264 t2r4curload(scr, &arrow);
265 t2r4curmove(scr, ZP);
266 t2r4xo(scr, CursorCtl, CursorMode);
302 /* wait until pipeline ready for new command */
304 waitforfifo(VGAscr *scr)
310 d = scr->mmio + RBaseD;
311 while((d[Busy]&1) && x++ < 1000000)
313 if(x >= 1000000) /* shouldn't happen */
314 iprint("busy %8lux\n", d[Busy]);
317 /* wait until command has finished executing */
319 waitforcmd(VGAscr *scr)
325 d = scr->mmio + RBaseD;
326 while((d[Flow]&0x1B) && x++ < 1000000)
328 if(x >= 1000000) /* shouldn't happen */
329 iprint("flow %8lux\n", d[Flow]);
332 /* wait until memory controller not busy (i.e. wait for writes to flush) */
334 waitformem(VGAscr *scr)
340 d = scr->mmio + RBaseD;
341 while((d[Flow]&2)&& x++ < 1000000)
343 if(x >= 1000000) /* shouldn't happen */
344 iprint("mem %8lux\n", d[Busy]);
348 t2r4hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
355 if(r.min.y == sr.min.y){ /* a purely horizontal scroll */
356 depth = scr->gscreen->depth;
360 * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
361 * 32-bit scrolls don't work perfectly on rectangles of width <= 24.
362 * we bail on a bigger bound for padding.
369 * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
370 * 16-bit scrolls don't work perfectly on rectangles of width <= 96.
371 * we bail on a bigger bound for padding.
380 d = scr->mmio + RBaseD;
382 if(r.min.x <= sr.min.x){
391 if(r.min.y < sr.min.y){
400 d[CmdOpc] = 0x1; /* bitblt */
401 d[CmdRop] = 0xC; /* copy source */
407 /* writing XY1 executes cmd */
409 d[XY0] = (sp.x<<16)|sp.y;
410 d[XY2] = (Dx(r)<<16)|Dy(r);
412 d[XY1] = (dp.x<<16)|dp.y;
419 t2r4hwfill(VGAscr *scr, Rectangle r, ulong sval)
423 d = scr->mmio + RBaseD;
427 d[CmdOpc] = 0x1; /* bitblt */
428 d[CmdRop] = 0xC; /* copy source */
429 d[CmdStyle] = 1; /* use source from Fore register */
430 d[CmdPatrn] = 0; /* no stipple */
434 /* writing XY1 executes cmd */
436 d[XY0] = (r.min.x<<16)|r.min.y;
437 d[XY2] = (Dx(r)<<16)|Dy(r);
439 d[XY1] = (r.min.x<<16)|r.min.y;
446 t2r4blank(VGAscr *scr, int blank)
450 x = t2r4xi(scr, CursorSyncCtl);
453 x |= HsyncLo | VsyncLo;
454 t2r4xo(scr, CursorSyncCtl, x);
458 t2r4drawinit(VGAscr *scr)
465 pitch = Dx(scr->gscreen->r);
466 depth = scr->gscreen->depth;
468 switch(scr->gscreen->chan){
484 d = scr->mmio + RBaseD;
489 d[DeSptch] = (pitch*depth)/8;
490 d[DeDptch] = (pitch*depth)/8;
491 d[CmdClp] = 0; /* 2 = inside rectangle */
495 d[Clpbr] = 0xFFF0FFF0;
499 scr->fill = t2r4hwfill;
500 scr->scroll = t2r4hwscroll;
501 scr->blank = t2r4blank;
504 VGAdev vgat2r4dev = {
514 VGAcur vgat2r4cur = {