|
|
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.