Annotation of Net2/arch/amiga/dev/grf_cc.c, revision 1.1.1.1

1.1       root        1: #include "grf.h"
                      2: #if NGRF > 0
                      3: 
                      4: /* Graphics routines for the AMIGA native custom chip set. */
                      5: 
                      6: #include "sys/param.h"
                      7: #include "sys/errno.h"
                      8: 
                      9: #include "grfioctl.h"
                     10: #include "grfvar.h"
                     11: #include "grf_ccreg.h"
                     12: 
                     13: #include "../include/cpu.h"
                     14: #include "../amiga/custom.h"
                     15: 
                     16: 
                     17: extern caddr_t CHIPMEMADDR;
                     18: extern caddr_t chipmem_steal ();
                     19: 
                     20: struct ccfb ccfb = {
                     21:        DEF_DISP_WIDTH, DEF_DISP_HEIGHT, DEF_DISP_X, DEF_DISP_Y, DEF_DISP_Z,
                     22:        0,
                     23:        DEF_FB_WIDTH, DEF_FB_HEIGHT, DEF_FB_X, DEF_FB_Y, DEF_FB_Z,
                     24:        DEF_COL0, DEF_COL1
                     25: };
                     26: 
                     27: /* Initialize one copper list.  We'll need two to make a nice interlaced display.  */
                     28: 
                     29: /* maximum size needed for a copper list (4 planes hires laced) */
                     30: #define COPENTS (4 * (2 * 4 + 2 + 1 + 2 + 2 + 2 + 16 * 1 + 1))
                     31: 
                     32: /* copper instructions */
                     33: #define MOVE(cl, reg, val)  \
                     34:        do { *cl++ = CUSTOM_OFS(reg); *cl++ = val; } while (0)
                     35: #define WAIT(cl, vp, hp, bfd, ve, he) \
                     36:        do { *cl++ = ((vp & 0xff)<<8)|(hp & 0xfe)|1; \
                     37:        *cl++ = (bfd<<15)|((ve & 0x7f)<<8)|(hp & 0xfe)|1; } while (0)
                     38: #define STOP(cl) \
                     39:        do { *cl++ = 0xffff; *cl++ = 0xffff; } while (0)
                     40: 
                     41: static void 
                     42: initcop (cop, othercop, shf, fb)
                     43:        u_short *cop;
                     44:        u_short *othercop;
                     45:        int     shf;
                     46:        struct ccfb *fb;
                     47: {
                     48:   long scrmem;
                     49:   int i;
                     50:   u_short c, strt, stop, *orig_cop = cop;
                     51: 
                     52:   /* get PA of display area */
                     53:   scrmem = (long) fb->fb - (long) CHIPMEMADDR;
                     54: 
                     55:   othercop = (u_short *) ((long)othercop - (long) CHIPMEMADDR);
                     56:   
                     57:   /* account for possible interlaced half-frame */
                     58:   if (shf)
                     59:     scrmem += fb->fb_width >> 3;
                     60:     
                     61:   /* account for oversized framebuffers */
                     62:   scrmem += (fb->fb_x >> 3) + (fb->fb_y * (fb->fb_width >> 3));  
                     63: 
                     64:   /* initialize bitplane pointers for all planes */
                     65:   /* remember offset in copperlist to patch later */
                     66:   if (! fb->bplstart_off)
                     67:     fb->bplstart_off = cop - orig_cop;
                     68:   for (i = 0; i < fb->disp_z; i++)
                     69:     {
                     70:       MOVE (cop, bplpth(i), scrmem >> 16);
                     71:       MOVE (cop, bplptl(i), scrmem & 0xffff);
                     72:       scrmem += (fb->fb_width >> 3) * fb->fb_height;
                     73:     }
                     74: 
                     75:   /* modulo is one line for interlaced displays, plus difference between
                     76:      virtual and effective framebuffer size */
                     77:   MOVE (cop, bpl1mod, (fb->fb_width + (fb->fb_width - fb->disp_width)) >> 3); 
                     78:   MOVE (cop, bpl2mod, (fb->fb_width + (fb->fb_width - fb->disp_width)) >> 3);
                     79:   
                     80:   c =   0x8000                                 /* HIRES */
                     81:       | ((fb->disp_z & 7) << 12)       /* bitplane use */
                     82:       | 0x0200                         /* composite COLOR enable (whatever this is..) */
                     83:       | 0x0004;                                /* LACE */
                     84:         
                     85:   MOVE (cop, bplcon0, c);
                     86:   
                     87:   /* these use pre-ECS register interpretation. Might want to go ECS ? */
                     88:   strt = (((fb->disp_y >> 1) & 0xff)<<8) | ((fb->disp_x >> 1) & 0xff);
                     89:   MOVE (cop, diwstrt, strt);
                     90:   stop = (((((fb->disp_y + fb->disp_height + 1-shf)>>1) & 0xff)<<8)
                     91:           | (((fb->disp_x + fb->disp_width)>>1) & 0xff));
                     92:   MOVE (cop, diwstop, stop);
                     93:   /* NOTE: default values for strt: 0x2c81, stop: 0xf4c1 */
                     94: 
                     95:   /* these are from from HW-manual.. */
                     96:   strt = ((strt & 0xff) - 9) >> 1;
                     97:   MOVE (cop, ddfstrt, strt);
                     98:   stop = strt + (((fb->disp_width >> 4) - 2) << 2);
                     99:   MOVE (cop, ddfstop, stop);
                    100: 
                    101:   /* setup interlaced display by constantly toggling between two copperlists */
                    102:   MOVE (cop, cop1lch, (long)othercop >> 16);
                    103:   MOVE (cop, cop1lcl, (long)othercop & 0xffff);
                    104: 
                    105:   for (i = 0; i < (1 << fb->disp_z); i++)
                    106:     MOVE (cop, color[i], fb->col[i]);
                    107: 
                    108:   /* wait forever */
                    109:   STOP (cop);
                    110: }
                    111: 
                    112: 
                    113: #ifdef DEBUG
                    114: void
                    115: dump_copperlist (cl)
                    116:     u_int *cl;
                    117: {
                    118:   while (*cl != 0xffffffff)
                    119:     {
                    120:       if (!(*cl & 0x00010000))
                    121:         printf ("MOVE (%x, %x)\t", *cl & 0xffff, *cl >> 16);
                    122:       else
                    123:         printf ("WAIT (%d, %d, %d, %d, %d)\t", *cl >> 24, (*cl & 0x00fe0000)>>16,
                    124:                (*cl & 0x8000)>> 15, (*cl & 0x7f00)>>8, (*cl & 0xfe));
                    125:       cl++;
                    126:     }
                    127:   printf ("STOP ()\n");
                    128: 
                    129: }
                    130: #endif
                    131: 
                    132: 
                    133: /*
                    134:  * Initialize hardware.
                    135:  * Must point g_display at a grfinfo structure describing the hardware.
                    136:  * Returns 0 if hardware not present, non-zero ow.
                    137:  */
                    138: cc_init(gp, ad)
                    139:        struct grf_softc *gp;
                    140:        struct amiga_device *ad;
                    141: {
                    142:   register struct ccfb *fb = &ccfb;
                    143:   struct grfinfo *gi = &gp->g_display;
                    144:   u_char *fbp, save;
                    145:   int fboff, fbsize;
                    146:   int s;
                    147: 
                    148:   /* if already initialized, fail */
                    149:   if (fb->fb)
                    150:     return 0;
                    151: 
                    152:   /* testing for the result is really redundant because chipmem_steal
                    153:      panics if it runs out of memory.. */
                    154:   fbsize = (fb->fb_width >> 3) * fb->fb_height * fb->fb_z;
                    155:   if (! (fb->fb = (u_char *) chipmem_steal (fbsize))
                    156:       || !(fb->cop1 = (u_short *) chipmem_steal (COPENTS))
                    157:       || !(fb->cop2 = (u_short *) chipmem_steal (COPENTS)))
                    158:     return 0;
                    159: 
                    160:   /* clear the display. bzero only likes regions up to 64k, so call multiple times */
                    161:   for (fboff = 0; fboff < fbsize; fboff += 64*1024)
                    162:     bzero (fb->fb + fboff, fbsize - fboff > 64*1024 ? 64*1024 : fbsize - fboff);
                    163: 
                    164:   initcop (fb->cop1, fb->cop2, 0, fb);
                    165:   initcop (fb->cop2, fb->cop1, 1, fb);
                    166: 
                    167:   /* Make sure no ex-sprites are streaking down the screen */
                    168:   {
                    169:     int i;
                    170:     for(i = 0;i < 8;i++)
                    171:       {
                    172:         custom.spr[i].data = 0;
                    173:         custom.spr[i].datb = 0;
                    174:       }
                    175:   }
                    176: 
                    177:   /* start the new display */
                    178:   /* disable these */
                    179:   custom.dmacon  = (DMAF_BLTDONE | DMAF_BLTNZERO | DMAF_BLITHOG | DMAF_BLITTER
                    180:                    | DMAF_SPRITE | DMAF_DISK
                    181:                    | DMAF_AUD3 | DMAF_AUD2 | DMAF_AUD1 | DMAF_AUD0);
                    182:   /* enable these */
                    183:   custom.dmacon  = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER;
                    184: 
                    185: #if 0
                    186:   /* ok, this is a bit rough.. */
                    187:   s = splhigh ();
                    188:   /* load a first guess copperlist, verify later whether we got the right
                    189:      one */
                    190:   custom.cop1lc  = (void *) ((long)fb->cop1 - (long) CHIPMEMADDR);
                    191:   custom.copjmp1 = 0;
                    192:   /* reset VBL */
                    193:   custom.intreq = INTF_VERTB;
                    194:   /* wait for VBL */
                    195:   while (! (custom.intreqr & INTF_VERTB)) ;
                    196:   /* reset VBL */
                    197:   custom.intreq = INTF_VERTB;
                    198:   /* now, in a safe location, set correct copperlist based on longframe/shortframe
                    199:      bit */
                    200:   if (custom.vposr & 0x8000)
                    201:     {
                    202:       custom.cop1lc = (void *) ((long)fb->cop1 - (long) CHIPMEMADDR);
                    203:       custom.copjmp1 = 0;      /* strobe it */
                    204:     }
                    205:   else
                    206:     {
                    207:       custom.cop1lc = (void *) ((long)fb->cop2 - (long) CHIPMEMADDR);
                    208:       custom.copjmp1 = 0;
                    209:     }
                    210:   /* wait for another VBL and reset int, then go back to previous int level */
                    211:   while (! (custom.intreqr & INTF_VERTB)) ;
                    212:   custom.intreq = INTF_VERTB;
                    213:   splx (s);
                    214: #else
                    215:   s = splhigh();
                    216:   /* set up copper */
                    217:   custom.cop1lc = (void *) ((long)fb->cop1 - (long) CHIPMEMADDR);
                    218:   custom.copjmp1 = 0;
                    219: 
                    220:   /* reset vertical blank interrupt */
                    221:   custom.intreq = INTF_VERTB;
                    222: 
                    223:   /* wait for vertical blank interrupt */
                    224:   while ((custom.intreqr & INTF_VERTB) != INTF_VERTB)
                    225:        ;
                    226: 
                    227:   /* set bitplane pointers based on LOF/SHF bit */
                    228:   if (custom.vposr & 0x8000)
                    229:     {
                    230:       custom.cop1lc = (void *) ((long)fb->cop1 - (long) CHIPMEMADDR);
                    231:       custom.copjmp1 = 0;
                    232:     }
                    233:   else
                    234:     {
                    235:       custom.cop1lc = (void *) ((long)fb->cop2 - (long) CHIPMEMADDR);
                    236:       custom.copjmp1 = 0;
                    237:     }
                    238:   splx (s);
                    239: #endif
                    240: 
                    241:   /* tame the blitter. Copying one word onto itself should put it into
                    242:      a consistent state. This is black magic... */
                    243:   custom.bltapt =
                    244:     custom.bltbpt =
                    245:       custom.bltcpt =
                    246:         custom.bltdpt = 0;
                    247:   custom.bltamod =
                    248:     custom.bltbmod =
                    249:       custom.bltcmod =
                    250:         custom.bltdmod = 0;
                    251:   custom.bltafwm =
                    252:     custom.bltalwn = 0xffff;
                    253:   custom.bltcon0 = 0x09f0;
                    254:   custom.bltcon1 = 0;
                    255:   custom.bltsize = 1;
                    256: 
                    257:   /* enable VBR interrupts. This is also done in the serial driver, but it
                    258:      really belongs here.. */
                    259:   custom.intena = INTF_SETCLR | INTF_VERTB;
                    260: 
                    261: #if 0
                    262: #ifdef DEBUG
                    263:   /* prove the display is up.. */
                    264:   for (fboff = 0; fboff < fbsize; fboff++)
                    265:     {
                    266:       fb->fb[fboff] = 0xff;
                    267:       DELAY(10);
                    268:     }
                    269:   for (fboff = 0; fboff < fbsize; fboff++)
                    270:     {
                    271:       fb->fb[fboff] = 0;
                    272:       DELAY(10);
                    273:     }
                    274: #endif
                    275: #endif
                    276: 
                    277:   gi->gd_regaddr = (caddr_t) fb;       /* XXX */
                    278:   gi->gd_regsize = 0;
                    279: 
                    280:   gi->gd_fbaddr  = fb->fb - (u_char *) CHIPMEMADDR;
                    281:   gi->gd_fbsize  = fbsize;
                    282:   
                    283:   gi->gd_colors  = 1 << fb->fb_z;
                    284:   gi->gd_planes  = fb->fb_z;
                    285:   
                    286:   gi->gd_fbwidth  = fb->fb_width;
                    287:   gi->gd_fbheight = fb->fb_height;
                    288:   gi->gd_fbx     = fb->fb_x;
                    289:   gi->gd_fby     = fb->fb_y;
                    290:   gi->gd_dwidth   = fb->disp_width;
                    291:   gi->gd_dheight  = fb->disp_height;
                    292:   gi->gd_dx      = fb->disp_x;
                    293:   gi->gd_dy      = fb->disp_y;
                    294:   
                    295:   gp->g_regkva = 0;    /* builtin */
                    296:   gp->g_fbkva  = fb->fb;
                    297:   
                    298:   return(1);
                    299: }
                    300: 
                    301: cc_config(gp, di)
                    302:        register struct grf_softc *gp;
                    303:        struct grfdyninfo *di;
                    304: {
                    305:   register struct ccfb *fb = &ccfb;
                    306:   struct grfinfo *gi = &gp->g_display;
                    307:   u_char *fbp, save;
                    308:   int fboff, fbsize;
                    309:   int s;
                    310: 
                    311:   /* bottom missing... */
                    312: 
                    313: }
                    314: 
                    315: /*
                    316:  * Change the mode of the display.
                    317:  * Right now all we can do is grfon/grfoff.
                    318:  * Return a UNIX error number or 0 for success.
                    319:  */
                    320: cc_mode(gp, cmd, arg)
                    321:        register struct grf_softc *gp;
                    322:        int cmd;
                    323:        void *arg;
                    324: {
                    325:   switch (cmd)
                    326:     {
                    327:     case GM_GRFON:
                    328:       custom.dmacon  = DMAF_SETCLR | DMAF_RASTER | DMAF_COPPER;
                    329:       return 0;
                    330:       
                    331:     case GM_GRFOFF:
                    332:       custom.dmacon  = DMAF_RASTER | DMAF_COPPER;
                    333:       return 0;
                    334:       
                    335:     case GM_GRFCONFIG:
                    336:       return cc_config (gp, (struct grfdyninfo *) arg);
                    337: 
                    338:     default:
                    339:       break;
                    340:     }
                    341:     
                    342:   return EINVAL;
                    343: }
                    344: 
                    345: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.