1/*	$NetBSD: grf_rtreg.h,v 1.15 2007/03/04 05:59:20 christos Exp $	*/
2
3/*
4 * Copyright (c) 1993 Markus Wild
5 * Copyright (c) 1993 Lutz Vieweg
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *      This product includes software developed by Lutz Vieweg.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33#ifndef _GRF_RTREG_H
34#define _GRF_RTREG_H
35
36/*
37 * This driver for the MacroSystem Retina board was only possible,
38 * because MacroSystem provided information about the pecularities
39 * of the board. THANKS! Competition in Europe among gfx board
40 * manufacturers is rather tough, so Lutz Vieweg, who wrote the
41 * initial driver, has made an agreement with MS not to document
42 * the driver source (see also his comment below).
43 * -> ALL comments and register defines after
44 * -> " -------------- START OF CODE -------------- "
45 * -> have been added by myself (mw) from studying the publically
46 * -> available "NCR 77C22E+" Data Manual
47 */
48/*
49 * This code offers low-level routines to access the Retina graphics-board
50 * manufactured by MS MacroSystem GmbH from within NetBSD for the Amiga.
51 *
52 * Thanks to MacroSystem for providing me with the necessary information
53 * to create theese routines. The sparse documentation of this code
54 * results from the agreements between MS and me.
55 */
56
57#if 0
58/* these are in dev/devices.h */
59
60/* definitions to find the autoconfig-board under
61   AmigaDOS */
62
63#define RETINA_MANUFACTURER     0x4754
64#define RETINA_PRODUCT          6
65#define RETINA_SERIALNUMBER     1
66#endif
67
68
69/*
70   For more information on the structure entries take a look at
71   grf_rt.cc and ite_rt.cc.
72*/
73
74struct MonDef {
75
76	/* first the general monitor characteristics */
77
78	unsigned long  FQ;
79	unsigned char  FLG;
80
81	unsigned short MW;  /* screen width in pixels */
82                            /* has to be at least a multiple of 8, */
83                            /* has to be a multiple of 64 in 256-color mode */
84                            /* if you want to use some great tricks */
85                            /* to speed up the vertical scrolling */
86	unsigned short MH;  /* screen height in pixels */
87
88	unsigned short HBS;
89	unsigned short HSS;
90	unsigned short HSE;
91	unsigned short HBE;
92	unsigned short HT;
93	unsigned short VBS;
94	unsigned short VSS;
95	unsigned short VSE;
96	unsigned short VBE;
97	unsigned short VT;
98
99	unsigned short DEP;  /* Color-depth, 4 for text-mode */
100                             /* 8 enables 256-color graphics-mode, */
101                             /* 16 and 24bit gfx not supported yet */
102
103	unsigned char * PAL; /* points to 16*3 byte RGB-palette data */
104                             /* use LoadPalette() to set colors 0..255 */
105                             /* in 256-color-gfx mode */
106
107	/* all following entries are font-specific in
108	   text mode. Make sure your monitor
109	   parameters are calculated for the
110	   appropriate font width and height!
111	*/
112
113       unsigned short  TX;     /* Text-mode (DEP=4):          */
114                               /* screen-width  in characters */
115                               /* currently, TX has to be a   */
116                               /* multiple of 16!             */
117
118                               /* Gfx-mode (DEP > 4)          */
119                               /* "logical" screen-width,     */
120                               /* use values > MW to allow    */
121                               /* hardware-panning            */
122                               /* has to be a multiple of 8   */
123
124       unsigned short  TY;     /* Text-mode:                  */
125                               /* screen-height in characters */
126
127                               /* Gfx-mode: "logical" screen  */
128                               /* height for panning          */
129
130       /* the following values are currently unused for gfx-mode */
131
132	unsigned short  XY;     /* TX*TY (speeds up some calcs.) */
133
134	unsigned short  FX;     /* font-width (valid values: 4,7-16) */
135	unsigned short  FY;     /* font-height (valid range: 1-32) */
136	unsigned char * FData;  /* pointer to the font-data */
137
138	/* The font data is simply an array of bytes defining
139	   the chars in ascending order, line by line. If your
140	   font is wider than 8 pixel, FData has to be an
141	   array of words. */
142
143	unsigned short  FLo;    /* lowest character defined */
144	unsigned short  FHi;    /* highest char. defined */
145
146};
147
148
149#if 0
150/* Some ready-made MonDef structures are available in grf_rt.cc */
151
152extern struct MonDef MON_640_512_60;
153extern struct MonDef MON_768_600_60;
154extern struct MonDef MON_768_600_80;
155
156/* text-screen resolutions wider than 1024 are currently damaged.
157   The VRAM access seems to become unstable at higher resolutions.
158   This may hopefully be subject of change.
159*/
160
161extern struct MonDef MON_1024_768_80;
162extern struct MonDef MON_1024_1024_59;
163
164/* WARNING: THE FOLLOWING MONITOR MODES EXCEED THE 90-MHz LIMIT THE PROCESSOR
165            HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
166            MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!     */
167extern struct MonDef MON_1280_1024_60;
168extern struct MonDef MON_1280_1024_69;
169
170/* Default monitor (change if this is too much for your monitor :-)) */
171#define DEFAULT_MONDEF	MON_768_600_80
172
173#else
174
175/* nothing exported for now... */
176
177#endif
178
179/* a standard 16-color palette is available in grf_rt.cc
180   and used by the standard monitor-definitions above */
181extern unsigned char NCRStdPalette[];
182
183/* The prototypes for C
184   with a little explanation
185
186	unsigned char * InitNCR(volatile void *BoardAddress, struct MonDef * md = &MON_640_512_60);
187
188   This routine initialises the Retina hardware, opens a
189   text- or gfx-mode screen, depending on the value of MonDef.DEP,
190   and sets the cursor to position 0.
191   It takes as arguments a pointer to the hardware-base
192   address as it is denoted in the DevConf structure
193   of the AmigaDOS, and a pointer to a struct MonDef
194   which describes the screen-mode parameters.
195
196   The routine returns 0 if it was unable to open the screen,
197   or an unsigned char * to the display/attribute memory
198   when it succeeded. The organisation of the display memory
199   is a little strange in text-mode (Intel-typically...) :
200
201   Byte  00    01    02    03    04     05    06   etc.
202       Char0  Attr0  --    --   Char1 Attr1   --   etc.
203
204   You may set a character and its associated attribute byte
205   with a single word-access, or you may perform to byte writes
206   for the char and attribute. Each 2. word has no meaning,
207   and writes to theese locations are ignored.
208
209   The attribute byte for each character has the following
210   structure:
211
212   Bit  7     6     5     4     3     2     1     0
213      BLINK BACK2 BACK1 BACK0 FORE3 FORE2 FORE1 FORE0
214
215   Were FORE is the foreground-color index (0-15) and
216   BACK is the background color index (0-7). BLINK
217   enables blinking for the associated character.
218   The higher 8 colors in the standard palette are
219   lighter than the lower 8, so you may see FORE3 as
220   an intensity bit. If FORE == 1 or FORE == 9 and
221   BACK == 0 the character is underlined. Since I don't
222   think this looks good, it will probably change in a
223   future release.
224
225   There's no routine "SetChar" or "SetAttr" provided,
226   because I think it's so trivial... a function call
227   would be pure overhead. As an example, a routine
228   to set the char code and attribute at position x,y:
229   (assumed the value returned by InitNCR was stored
230    into "DispMem", the actual MonDef struct * is hold
231    in "MDef")
232
233   void SetChar(unsigned char chr, unsigned char attr,
234                unsigned short x, unsigned short y) {
235
236      unsigned struct MonDef * md = MDef;
237      unsigned char * c = DispMem + x*4 + y*md->TX*4;
238
239      *c++ = chr;
240      *c   = attr;
241
242   }
243
244   In Gfx-mode, the memory organisation is rather simple,
245   1 byte per pixel in 256-color mode, one pixel after
246   each other, line by line.
247
248   Currently, InitNCR() disables the Retina VBLANK IRQ,
249   but beware: When running the Retina WB-Emu under
250   AmigaDOS, the VBLANK IRQ is ENABLED.
251
252	void SetCursorPos(unsigned short pos);
253
254   This routine sets the hardware-cursor position
255   to the screen location pos. pos can be calculated
256   as (x + y * md->TY).
257   Text-mode only!
258
259	void ScreenUp(void);
260
261   A somewhat optimized routine that scrolls the whole
262   screen up one row. A good idea to compile this piece
263   of code with optimization enabled.
264   Text-mode only!
265
266	void ScreenDown(void);
267
268   A somewhat optimized routine that scrolls the whole
269   screen down one row. A good idea to compile this piece
270   of code with optimization enabled.
271   Text-mode only!
272
273	unsigned char * SetSegmentPtr(unsigned long address);
274
275   Sets the beginning of the 64k-memory segment to the
276   address specified by the unsigned long. If address MOD 64
277   is != 0, the return value will point to the segments
278   start in the Amiga address space + (address MOD 64).
279   Don't use more than (65536-64) bytes in the segment
280   you set if you aren't sure that (address MOD 64) == 0.
281   See retina.doc from MS for further information.
282
283	void ClearScreen(unsigned char color);
284
285   Fills the whole screen with "color" - 256-color mode only!
286
287	void LoadPalette(unsigned char * pal, unsigned char firstcol,
288	                 unsigned char colors);
289
290   Loads the palette-registers. "pal" points to an array of unsigned char
291   triplets, for the red, green and blue component. "firstcol" determines the
292   number of the first palette-register to load (256 available). "colors"
293   is the number of colors you want to put in the palette registers.
294
295	void SetPalette(unsigned char colornum, unsigned char red,
296	                unsigned char green, unsigned char blue);
297
298   Allows you to set a single color in the palette, "colornum" is the number
299   of the palette entry (256 available), "red", "green" and "blue" are the
300   three components.
301
302	void SetPanning(unsigned short xoff, unsigned short yoff);
303
304   Moves the logical coordinate (xoff, yoff) to the upper left corner
305   of your screen. Of course, you shouldn't specify excess values that would
306   show garbage in the lower right area of your screen... SetPanning()
307   does NOT check for boundaries.
308*/
309
310/* -------------- START OF CODE -------------- */
311
312/* read VGA register */
313#define vgar(ba, reg) (*(((volatile unsigned char *)ba)+reg))
314
315/* write VGA register */
316#define vgaw(ba, reg, val) \
317	*(((volatile unsigned char *)ba)+reg) = val
318
319/* defines for the used register addresses (mw)
320
321   NOTE: there are some registers that have different addresses when
322         in mono or color mode. We only support color mode, and thus
323         some addresses won't work in mono-mode! */
324
325/* General Registers: */
326#define GREG_STATUS0_R		0x43C2
327#define GREG_STATUS1_R		0x43DA
328#define GREG_MISC_OUTPUT_R	0x43CC
329#define GREG_MISC_OUTPUT_W	0x43C2
330#define GREG_FEATURE_CONTROL_R	0x43CA
331#define GREG_FEATURE_CONTROL_W	0x43DA
332#define GREG_POS		0x4102
333
334/* Attribute Controller: */
335#define ACT_ADDRESS		0x43C0
336#define ACT_ADDRESS_R		0x03C0
337#define ACT_ADDRESS_W		0x43C0
338#define ACT_ID_PALETTE0		0x00
339#define ACT_ID_PALETTE1		0x01
340#define ACT_ID_PALETTE2		0x02
341#define ACT_ID_PALETTE3		0x03
342#define ACT_ID_PALETTE4		0x04
343#define ACT_ID_PALETTE5		0x05
344#define ACT_ID_PALETTE6		0x06
345#define ACT_ID_PALETTE7		0x07
346#define ACT_ID_PALETTE8		0x08
347#define ACT_ID_PALETTE9		0x09
348#define ACT_ID_PALETTE10	0x0A
349#define ACT_ID_PALETTE11	0x0B
350#define ACT_ID_PALETTE12	0x0C
351#define ACT_ID_PALETTE13	0x0D
352#define ACT_ID_PALETTE14	0x0E
353#define ACT_ID_PALETTE15	0x0F
354#define ACT_ID_ATTR_MODE_CNTL	0x10
355#define ACT_ID_OVERSCAN_COLOR	0x11
356#define ACT_ID_COLOR_PLANE_ENA	0x12
357#define ACT_ID_HOR_PEL_PANNING	0x13
358#define ACT_ID_COLOR_SELECT	0x14
359
360/* Graphics Controller: */
361#define GCT_ADDRESS		0x43CE
362#define GCT_ADDRESS_R		0x03CE
363#define GCT_ADDRESS_W		0x03CE
364#define GCT_ID_SET_RESET	0x00
365#define GCT_ID_ENABLE_SET_RESET	0x01
366#define GCT_ID_COLOR_COMPARE	0x02
367#define GCT_ID_DATA_ROTATE	0x03
368#define GCT_ID_READ_MAP_SELECT	0x04
369#define GCT_ID_GRAPHICS_MODE	0x05
370#define GCT_ID_MISC		0x06
371#define GCT_ID_COLOR_XCARE	0x07
372#define GCT_ID_BITMASK		0x08
373
374/* Sequencer: */
375#define SEQ_ADDRESS		0x43C4
376#define SEQ_ADDRESS_R		0x03C4
377#define SEQ_ADDRESS_W		0x03C4
378#define SEQ_ID_RESET		0x00
379#define SEQ_ID_CLOCKING_MODE	0x01
380#define SEQ_ID_MAP_MASK		0x02
381#define SEQ_ID_CHAR_MAP_SELECT	0x03
382#define SEQ_ID_MEMORY_MODE	0x04
383#define SEQ_ID_EXTENDED_ENABLE	0x05	/* down from here, all seq registers are NCR extensions */
384#define SEQ_ID_UNKNOWN1         0x06	/* it does exist so it's probably useful */
385#define SEQ_ID_UNKNOWN2         0x07	/* it does exist so it's probably useful */
386#define SEQ_ID_CHIP_ID		0x08
387#define SEQ_ID_UNKNOWN3         0x09	/* it does exist so it's probably useful */
388#define SEQ_ID_CURSOR_COLOR1	0x0A
389#define SEQ_ID_CURSOR_COLOR0	0x0B
390#define SEQ_ID_CURSOR_CONTROL	0x0C
391#define SEQ_ID_CURSOR_X_LOC_HI	0x0D
392#define SEQ_ID_CURSOR_X_LOC_LO	0x0E
393#define SEQ_ID_CURSOR_Y_LOC_HI	0x0F
394#define SEQ_ID_CURSOR_Y_LOC_LO	0x10
395#define SEQ_ID_CURSOR_X_INDEX	0x11
396#define SEQ_ID_CURSOR_Y_INDEX	0x12
397#define SEQ_ID_CURSOR_STORE_HI	0x13	/* printed manual is wrong about these.. */
398#define SEQ_ID_CURSOR_STORE_LO	0x14
399#define SEQ_ID_CURSOR_ST_OFF_HI	0x15
400#define SEQ_ID_CURSOR_ST_OFF_LO	0x16
401#define SEQ_ID_CURSOR_PIXELMASK	0x17
402#define SEQ_ID_PRIM_HOST_OFF_HI	0x18
403#define SEQ_ID_PRIM_HOST_OFF_LO	0x19
404#define SEQ_ID_DISP_OFF_HI	0x1A
405#define SEQ_ID_DISP_OFF_LO	0x1B
406#define SEQ_ID_SEC_HOST_OFF_HI	0x1C
407#define SEQ_ID_SEC_HOST_OFF_LO	0x1D
408#define SEQ_ID_EXTENDED_MEM_ENA	0x1E
409#define SEQ_ID_EXT_CLOCK_MODE	0x1F
410#define SEQ_ID_EXT_VIDEO_ADDR	0x20
411#define SEQ_ID_EXT_PIXEL_CNTL	0x21
412#define SEQ_ID_BUS_WIDTH_FEEDB	0x22
413#define SEQ_ID_PERF_SELECT	0x23
414#define SEQ_ID_COLOR_EXP_WFG	0x24
415#define SEQ_ID_COLOR_EXP_WBG	0x25
416#define SEQ_ID_EXT_RW_CONTROL	0x26
417#define SEQ_ID_MISC_FEATURE_SEL	0x27
418#define SEQ_ID_COLOR_KEY_CNTL	0x28
419#define SEQ_ID_COLOR_KEY_MATCH	0x29
420#define SEQ_ID_UNKNOWN4         0x2A
421#define SEQ_ID_UNKNOWN5         0x2B
422#define SEQ_ID_UNKNOWN6         0x2C
423#define SEQ_ID_CRC_CONTROL	0x2D
424#define SEQ_ID_CRC_DATA_LOW	0x2E
425#define SEQ_ID_CRC_DATA_HIGH	0x2F
426
427/* CRT Controller: */
428#define CRT_ADDRESS		0x43D4
429#define CRT_ADDRESS_R		0x03D4
430#define CRT_ADDRESS_W		0x03D4
431#define CRT_ID_HOR_TOTAL	0x00
432#define CRT_ID_HOR_DISP_ENA_END	0x01
433#define CRT_ID_START_HOR_BLANK	0x02
434#define CRT_ID_END_HOR_BLANK	0x03
435#define CRT_ID_START_HOR_RETR	0x04
436#define CRT_ID_END_HOR_RETR	0x05
437#define CRT_ID_VER_TOTAL	0x06
438#define CRT_ID_OVERFLOW		0x07
439#define CRT_ID_PRESET_ROW_SCAN	0x08
440#define CRT_ID_MAX_SCAN_LINE	0x09
441#define CRT_ID_CURSOR_START	0x0A
442#define CRT_ID_CURSOR_END	0x0B
443#define CRT_ID_START_ADDR_HIGH	0x0C
444#define CRT_ID_START_ADDR_LOW	0x0D
445#define CRT_ID_CURSOR_LOC_HIGH	0x0E
446#define CRT_ID_CURSOR_LOC_LOW	0x0F
447#define CRT_ID_START_VER_RETR	0x10
448#define CRT_ID_END_VER_RETR	0x11
449#define CRT_ID_VER_DISP_ENA_END	0x12
450#define CRT_ID_OFFSET		0x13
451#define CRT_ID_UNDERLINE_LOC	0x14
452#define CRT_ID_START_VER_BLANK	0x15
453#define CRT_ID_END_VER_BLANK	0x16
454#define CRT_ID_MODE_CONTROL	0x17
455#define CRT_ID_LINE_COMPARE	0x18
456#define CRT_ID_UNKNOWN1         0x19	/* are these register really void ? */
457#define CRT_ID_UNKNOWN2         0x1A
458#define CRT_ID_UNKNOWN3         0x1B
459#define CRT_ID_UNKNOWN4         0x1C
460#define CRT_ID_UNKNOWN5         0x1D
461#define CRT_ID_UNKNOWN6         0x1E
462#define CRT_ID_UNKNOWN7         0x1F
463#define CRT_ID_UNKNOWN8         0x20
464#define CRT_ID_UNKNOWN9         0x21
465#define CRT_ID_UNKNOWN10      	0x22
466#define CRT_ID_UNKNOWN11      	0x23
467#define CRT_ID_UNKNOWN12      	0x24
468#define CRT_ID_UNKNOWN13      	0x25
469#define CRT_ID_UNKNOWN14      	0x26
470#define CRT_ID_UNKNOWN15      	0x27
471#define CRT_ID_UNKNOWN16      	0x28
472#define CRT_ID_UNKNOWN17      	0x29
473#define CRT_ID_UNKNOWN18      	0x2A
474#define CRT_ID_UNKNOWN19      	0x2B
475#define CRT_ID_UNKNOWN20      	0x2C
476#define CRT_ID_UNKNOWN21      	0x2D
477#define CRT_ID_UNKNOWN22      	0x2E
478#define CRT_ID_UNKNOWN23      	0x2F
479#define CRT_ID_EXT_HOR_TIMING1	0x30	/* down from here, all crt registers are NCR extensions */
480#define CRT_ID_EXT_START_ADDR	0x31
481#define CRT_ID_EXT_HOR_TIMING2	0x32
482#define CRT_ID_EXT_VER_TIMING	0x33
483
484/* Video DAC (these are *pure* guesses from the usage of these registers,
485   I don't have a data sheet for this chip:-/) */
486#define VDAC_REG_D		0x800d	/* well.. */
487#define VDAC_REG_SELECT		0x8001	/* perhaps.. */
488#define VDAC_REG_DATA		0x8003	/* dito.. */
489
490#define WGfx(ba, idx, val) \
491	do { vgaw(ba, GCT_ADDRESS, idx); vgaw(ba, GCT_ADDRESS_W , val); } while (0)
492
493#define WSeq(ba, idx, val) \
494	do { vgaw(ba, SEQ_ADDRESS, idx); vgaw(ba, SEQ_ADDRESS_W , val); } while (0)
495
496#define WCrt(ba, idx, val) \
497	do { vgaw(ba, CRT_ADDRESS, idx); vgaw(ba, CRT_ADDRESS_W , val); } while (0)
498
499#define WAttr(ba, idx, val) \
500	do { vgaw(ba, ACT_ADDRESS, idx); vgaw(ba, ACT_ADDRESS_W, val); } while (0)
501
502#define Map(m) \
503	do { WGfx(ba, GCT_ID_READ_MAP_SELECT, m & 3 ); WSeq(ba, SEQ_ID_MAP_MASK, (1 << (m & 3))); } while (0)
504
505static inline unsigned char RAttr(volatile void *ba, short idx) {
506	vgaw (ba, ACT_ADDRESS, idx);
507	return vgar (ba, ACT_ADDRESS_R);
508}
509
510static inline unsigned char RSeq(volatile void *ba, short idx) {
511	vgaw (ba, SEQ_ADDRESS, idx);
512	return vgar (ba, SEQ_ADDRESS_R);
513}
514
515static inline unsigned char RCrt(volatile void *ba, short idx) {
516	vgaw (ba, CRT_ADDRESS, idx);
517	return vgar (ba, CRT_ADDRESS_R);
518}
519
520static inline unsigned char RGfx(volatile void *ba, short idx) {
521	vgaw(ba, GCT_ADDRESS, idx);
522	return vgar (ba, GCT_ADDRESS_R);
523}
524
525int grfrt_cnprobe(void);
526void grfrt_iteinit(struct grf_softc *);
527#endif /* _GRF_RTREG_H */
528