Annotation of Net2/arch/amiga/dev/grf_cc.c, revision 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.