|
|
1.1 ! root 1: /* $Header: bitblt_apa16.h,v 10.1 86/11/19 10:51:47 jg Exp $ */ ! 2: /* ! 3: * Copyright (c) 1986 Brown University ! 4: * ! 5: * Permission to use, copy, modify and distribute this software and its ! 6: * documentation for any purpose and without fee is hereby granted, provided ! 7: * that the above copyright notice appear in all copies, and that both ! 8: * that copyright notice and this permission notice appear in supporting ! 9: * documentation, and that the name of Brown University not be used in ! 10: * advertising or publicity pertaining to distribution of the software without ! 11: * specific, written prior permission. Brown University makes no ! 12: * representations about the suitability of this software for any purpose. ! 13: * It is provided "as-is" without express or implied warranty. ! 14: * ! 15: * Written by Daniel Stone, Brown University/IRIS April 23, 1986. ! 16: * ! 17: * This file contains the defines to do hardware bit block transfers (bitblt's) ! 18: * on the APA-16. ! 19: */ ! 20: ! 21: /* $Header: bitblt_apa16.h,v 10.1 86/11/19 10:51:47 jg Exp $ */ ! 22: /* $Source: /u1/X/libibm/bitblt/RCS/bitblt_apa16.h,v $ */ ! 23: ! 24: /* ! 25: * Log 2 of the screen width. ! 26: */ ! 27: #define LOG2_BPSW 7 ! 28: ! 29: /* ! 30: * Divide and multiply by Bytes Per Screen Width. ! 31: */ ! 32: #define DIV_BPSW(value) ((value) >> LOG2_BPSW) ! 33: #define MUL_BPSW(value) ((value) << LOG2_BPSW) ! 34: ! 35: /* ! 36: * Screen dimensions in pixels. ! 37: */ ! 38: #define SCREEN_WD 1024 ! 39: #define HIDDEN_WD SCREEN_WD ! 40: ! 41: #define SCREEN_HT 768 ! 42: #define HIDDEN_HT 256 ! 43: ! 44: /* ! 45: * Screen dimensions in words. ! 46: */ ! 47: #define SCREEN_WORD_WD (SCREEN_WD/BPW) ! 48: #define HIDDEN_WORD_WD (HIDDEN_WD/BPW) ! 49: ! 50: #define SCREEN_WORD_HT (SCREEN_HT/BPW) ! 51: #define HIDDEN_WORD_HT (HIDDEN_HT/BPW) ! 52: ! 53: #define IO_ADDR 0xF0000000 ! 54: #define MODEL_IO_ADDR (IO_ADDR | 0x04000000) ! 55: ! 56: /* ! 57: * Hidden frame buffer address. ! 58: */ ! 59: #define HID_OFFSET 0x00018000 ! 60: #define HID_APA16BASE (APA16BASE + HID_OFFSET) ! 61: ! 62: /* ! 63: * Within the hidden screen area there is an area for 2 hardware locators. ! 64: */ ! 65: #define LOCATOR_OFFSET (HID_OFFSET + 0x800) ! 66: #define LOCATOR_APA16BASE (APA16BASE + LOCATOR_OFFSET) ! 67: ! 68: /* ! 69: * The bottom right corners of both locators. ! 70: */ ! 71: #define AND_LOCATOR_RT 48 ! 72: #define AND_LOCATOR_BM 848 ! 73: #define XOR_LOCATOR_RT (48*2) ! 74: #define XOR_LOCATOR_BM AND_LOCATOR_BM ! 75: ! 76: #define SAVE_AND_LOCATOR_RT (48*3) ! 77: #define SAVE_AND_LOCATOR_BM 848 ! 78: #define SAVE_XOR_LOCATOR_RT (48*4) ! 79: #define SAVE_XOR_LOCATOR_BM AND_LOCATOR_BM ! 80: ! 81: /* ! 82: * Dimensions of the locators found in the hidden screen area. ! 83: */ ! 84: #define HARD_LOCATOR_WD 48 ! 85: #define HARD_LOCATOR_HT 64 ! 86: ! 87: /* ! 88: * Spot on the APA-16's memory where the hardware cursor is located. ! 89: */ ! 90: #define AND_LOCATOR LOCATOR_APA16BASE ! 91: #define XOR_LOCATOR (LOCATOR_APA16BASE + BTOB(HARD_LOCATOR_WD)) ! 92: ! 93: /* ! 94: * Spot on the APA-16's memory where we will save the current locator. ! 95: */ ! 96: #define SAVE_AND_LOCATOR (LOCATOR_APA16BASE + BTOB(HARD_LOCATOR_WD*2)) ! 97: #define SAVE_XOR_LOCATOR (LOCATOR_APA16BASE + BTOB(HARD_LOCATOR_WD*3)) ! 98: ! 99: /* ! 100: * Within the hidden screen area there is an area for hidden fonts. ! 101: */ ! 102: #define FONT_Y_COORD 848 ! 103: #define FONT_OFFSET (HID_OFFSET + 0x2800) ! 104: #define FONT_APA16BASE (APA16BASE + FONT_OFFSET) ! 105: #define FONT_XBASE 1 ! 106: #define FONT_YBASE 848 ! 107: #define FONT_YBASE_BOTTOM 896 ! 108: ! 109: /* ! 110: * Within the hidden screen area there is an area for a rasterop queue. ! 111: */ ! 112: #define QUE_Y_COORD 896 ! 113: #define QUE_OFFSET (HID_OFFSET + 0x4000) ! 114: #define QUE_APA16BASE (APA16BASE + QUE_OFFSET) ! 115: ! 116: #define RESERVE_Y_COORD 1006 ! 117: #define RESERVE_OFFSET (HID_OFFSET + 0x7700) ! 118: #define LAST_QUE_OFFSET (RESERVE_OFFSET - 2) ! 119: #define LAST_QUE_APA16BASE (APA16BASE + LAST_QUE_OFFSET) ! 120: #define QUE_WD SCREEN_WD ! 121: #define QUE_HT 110 ! 122: ! 123: /* ! 124: * Macro that builds the queue pointer using the screen address which is a ! 125: * short pointer. ! 126: */ ! 127: #define SPTR_TO_QPTR(sptr) ((short)(DIV_2((long)sptr & 0x0000ffff) | \ ! 128: 0xE000)) ! 129: /* ! 130: * Macro that takes a queue pointer (an unsigned short) and builds a unsigned ! 131: * short pointer from it. ! 132: */ ! 133: #define QPTR_TO_SPTR(qptr) ((unsigned short *)(MUL_2(qptr)|QUE_APA16BASE)) ! 134: ! 135: /* ! 136: * Macros that take a short pointer to the bitmap and return the x value in bits ! 137: * and the y value in scanlines. ! 138: */ ! 139: #define SPTR_TO_X(sptr) (MUL_BPB((long)sptr & 0x007f)) ! 140: #define SPTR_TO_Y(sptr) (DIV_BPSW((long)sptr & 0x1ff80)) ! 141: ! 142: #define X_LOCATOR_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9F800)) ! 143: #define Y_LOCATOR_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9F802)) ! 144: #define QUE_COUNT_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9F804)) ! 145: #define QUE_PTR_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9f806)) ! 146: #define QUE_LINK_PTR_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9f814)) ! 147: #define QUE_MODE_R ((unsigned short *)(MODEL_IO_ADDR | 0xD9f816)) ! 148: ! 149: /* ! 150: * Macros and defines for the mode register. ! 151: */ ! 152: #define MODE_R (IO_ADDR | 0x0D10) ! 153: ! 154: #define ACCESS_BIT 0x8000 ! 155: #define SET_ACCESS_BIT(mode) (mode |= ACCESS_BIT) ! 156: #define CLR_ACCESS_BIT(mode) (mode &= ~ACCESS_BIT) ! 157: ! 158: #define PAGE_SELECT 0x4000 ! 159: ! 160: #define WR_MASK 0x0f00 ! 161: #define SET_WR_MASK(mode,msk) mode = ((mode & ~WR_MASK)|((msk<<8) & WR_MASK)) ! 162: #define CLR_WR_MASK(mode) mode &= ~WR_MASK ! 163: ! 164: #define LOGIC_FUNC 0x00f0 ! 165: #define SET_LOGIC_FUNC(mode,fc) mode = ((mode & ~LOGIC_FUNC)| \ ! 166: ((fc<<4) & LOGIC_FUNC)) ! 167: #define CLR_LOGIC_FUNC(mode) mode &= ~LOGIC_FUNC ! 168: ! 169: #define START_BIT 0x000f ! 170: #define SET_START_BIT(mode,sb) mode = ((mode & ~START_BIT)|(sb & START_BIT)) ! 171: #define CLR_START_BIT(mode) mode &= ~START_BIT ! 172: ! 173: /* ! 174: * More understandable names for access bit. ! 175: */ ! 176: #define HORZ_ACCESS(mode) SET_ACCESS_BIT(mode) ! 177: #define VERT_ACCESS(mode) CLR_ACCESS_BIT(mode) ! 178: ! 179: /* ! 180: * Control/Status register. ! 181: */ ! 182: #define CS_R (IO_ADDR | 0x0D12) ! 183: ! 184: #define BACKGRND_BIT 0x0400 ! 185: #define BLACK_ON_WHITE *(unsigned short *)(CS_R) |= BACKGRND_BIT ! 186: #define WHITE_ON_BLACK *(unsigned short *)(CS_R) &= ~BACKGRND_BIT ! 187: #define TOGGLE_BACKGRND *(unsigned short *)(CS_R) ^= BACKGRND_BIT ! 188: ! 189: /* ! 190: * Increment Queue register. NOTE: Reg is any register the data is ignored. ! 191: */ ! 192: #define INCR_QUE_R (IO_ADDR | 0x0D14) ! 193: #define INCR_QUE_COUNT(reg) *(unsigned short *)INCR_QUE_R = (unsigned short)reg ! 194: ! 195: /* ! 196: * Wait for the rasterop engine to stop. If it does not stop then kill it ! 197: * after a specified time. The way this works is this, we poll the queue ! 198: * counter register waiting for it to zero (which means the rasterop has ! 199: * stopped), if it doesn't zero by QUE_TIME_OUT then assume something drastic ! 200: * went wrong and initialize the APA-16. ! 201: * ! 202: * Later we will re-write this to receive an interrupt. ! 203: */ ! 204: #define QUE_TIME_OUT 500000 ! 205: ! 206: #define WAIT_QUE(c,num) { \ ! 207: if (*QUE_COUNT_R != 0) { \ ! 208: c = 0; \ ! 209: while (*QUE_COUNT_R != 0) { \ ! 210: if (c++ == QUE_TIME_OUT) { \ ! 211: c = *QUE_COUNT_R; \ ! 212: RESET_APA16(c); \ ! 213: printf("RESET APA-16! n:%d count:%d\r\n", \ ! 214: num,c); \ ! 215: break; \ ! 216: } \ ! 217: } \ ! 218: } \ ! 219: } ! 220: ! 221: /* ! 222: * Video data output. ! 223: */ ! 224: #define VD_OUT (IO_ADDR | 0xD1A) ! 225: ! 226: /* ! 227: * Disable video data output (pass it a temporary register). ! 228: */ ! 229: #define DISABLE_VD_OUT(reg) reg = *(unsigned short *)VD_OUT ! 230: ! 231: /* ! 232: * Enable video data output. NOTE: Reg is any register. The data in "reg" ! 233: * is ignored. ! 234: */ ! 235: #define ENABLE_VD_OUT(reg) *(unsigned short *)VD_OUT = (unsigned short)reg ! 236: ! 237: /* ! 238: * Reset adaptor register. ! 239: */ ! 240: #define RA_R (IO_ADDR | 0x0D20) ! 241: #define RESET_APA16(reg) *(unsigned short *)RA_R = (unsigned short)reg; ! 242: ! 243: /* ! 244: * Disable DMA processing. NOTE: Reg is any register the data is ignored. ! 245: */ ! 246: #define DISABLE_DMA (IO_ADDR | 0x0D26) ! 247: #define DISABLE_DMA_PROC(reg) *(unsigned short *)DISABLE_DMA=(unsigned short)reg ! 248: ! 249: #define ENABLE_DMA (IO_ADDR | 0x0D28) ! 250: #define ENABLE_DMA_PROC(reg) *(unsigned short *)ENABLE_DMA = (unsigned short)reg ! 251: ! 252: /* ! 253: * Default initial values for the APA-16 registers. ! 254: */ ! 255: #define MODER_DEFAULT 0x8090 ! 256: #define CSR_DEFAULT 0x0400 ! 257: ! 258: /* ! 259: * Defines and macros for the rasterop commands. ! 260: * ROT stands for Raster Operation Type. ! 261: * LF stands for logic function. ! 262: */ ! 263: #define DECR_QUE_COUNT 0x0800 ! 264: ! 265: #define ROT_WRDST 0x02F0 ! 266: #define ROT_RECTCP 0x0300 ! 267: #define ROT_TDDMA 0x0370 ! 268: ! 269: #define LF_CLEAR 0x0000 ! 270: #define LF_DSTandSRC 0x0001 ! 271: #define LF_NotDSTandSRC 0x0002 ! 272: #define LF_COPYDST 0x0003 ! 273: #define LF_DSTandNotSRC 0x0008 ! 274: #define LF_COPYSRC 0x0009 ! 275: #define LF_NotDST 0x0009 ! 276: #define LF_DSTxorSRC 0x000a ! 277: #define LF_DSTorSRC 0x000b ! 278: #define LF_NotDSTorNotSRC 0x000e ! 279: #define LF_SET 0x000f ! 280: ! 281: #define IS_ROT_WRDST(excmd) ((excmd & 0x03f0) == ROT_WRDST) ! 282: /* ! 283: * Rasterop execute command instruction. ! 284: */ ! 285: #define BUILD_EXCMD(decrflag,ROT_type,LF_type) \ ! 286: (0xD000 | decrflag | ROT_type | LF_type) ! 287: ! 288: #define Y_BRCH_BASE 896 ! 289: #define X_BRCH_BASE 0 ! 290: ! 291: /* ! 292: * Rasterop branch instruction. Both X and Y should be given in bits. ! 293: * Y must be between 896 and 1023. X must fall on a word boundrary. ! 294: */ ! 295: #define BUILD_BRCH(x,y) ((Y_BRCH_BASE << 6) | ((y) << 6) | DIV_BPW(x)) ! 296: ! 297: #define HIGH_BYTE(addr) (((unsigned long)addr & 0x1fe0000) >> 17) ! 298: #define MID_BYTE(addr) (((unsigned long)addr & 0x1fe00) >> 9) ! 299: #define LOW_BYTE(addr) (((unsigned long)addr & 0x1fe) >> 1) ! 300: ! 301: /* ! 302: * Queue command codes for the registers on the APA-16. ! 303: */ ! 304: #define REG_Y_LOOP 0x0000 ! 305: #define REG_X_LOOP 0x1000 ! 306: #define REG_GEN_A 0x2000 ! 307: #define REG_GEN_B 0x3000 ! 308: #define REG_Y_SRC 0x4000 ! 309: #define REG_X_SRC 0x5000 ! 310: #define REG_Y_DST 0x6000 ! 311: #define REG_X_DST 0x7000 ! 312: #define REG_Y_BACKUP 0x8000 ! 313: #define REG_X_BACKUP 0x9000 ! 314: #define REG_HIGHBYTE 0xa000 ! 315: #define REG_LOWBYTE 0xb000 ! 316: ! 317: /* ! 318: * Now that we've defined those names for hardware guru's lets have some ! 319: * real names. Notice how the HIGHBYTE register (whatever that is) is ! 320: * used as the Y destination register when dealing with rectangle copys ! 321: * also notice that the Y_LOOP register is used (as expected) as the height ! 322: * register during rectangle copies but that the Y_BACKUP register is used ! 323: * when only dealing with the destination. ! 324: */ ! 325: #define XDST_REG REG_X_DST ! 326: #define YDST_REG REG_Y_DST ! 327: #define XSRC_REG REG_X_SRC ! 328: #define YSRC_REG REG_Y_SRC ! 329: #define RECT_YDST_REG REG_HIGHBYTE ! 330: #define WIDTH_REG REG_X_BACKUP ! 331: #define HEIGHT_REG REG_Y_BACKUP ! 332: #define RECT_HEIGHT_REG REG_Y_LOOP ! 333: ! 334: #define MAXPARAM 1024 ! 335: #define VISPARAM 768 ! 336: #define MINPARAM 1 ! 337: ! 338: /* ! 339: * Register load command. ! 340: */ ! 341: #define BUILD_REGLOAD(REG_type,param) (REG_type | (param & (MAXPARAM-1))) ! 342: ! 343: /* ! 344: * Indicates a there is no bit image for this font. ! 345: */ ! 346: #define NULLIMAGE MAXPARAM+1 ! 347: ! 348: /* ! 349: * A nulls for pointers. ! 350: */ ! 351: #define US_NIL ((unsigned short *)0) ! 352: #define S_NIL ((short *)0) ! 353: ! 354: /* ! 355: * Execute the commands set up in the queue at Qaddr but first wait for ! 356: * the last command to finish, then set up the queue register pointer ! 357: * and increment the count nexec number of times. ! 358: */ ! 359: #define EXECUTE_QUE_CMDS(Qaddr,nexec,index) \ ! 360: { \ ! 361: register i,tmp; \ ! 362: WAIT_QUE(index); \ ! 363: *QUE_PTR_R = Qaddr; \ ! 364: for (i = nexec + 1; --i;) \ ! 365: INCR_QUE_COUNT(tmp); \ ! 366: } ! 367: ! 368: /* ! 369: * Take an index into one of the queue instructions, wait for the last command ! 370: * to finish, set up the queue register pointer and increment the count the ! 371: * right number of times. ! 372: */ ! 373: #define DO_QUE_CMD(index) EXECUTE_QUE_CMDS(QUEinstr[index].Qaddr, \ ! 374: QUEinstr[index].nexec,index) ! 375: ! 376: /* ! 377: * Number of words needed to do a destination only command is 5 and ! 378: * the number of words needed to do a rectangle copy is 7. ! 379: */ ! 380: #define DSTCMDWORDS 5 ! 381: #define RECTCMDWORDS 7
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.