|
|
1.1 root 1: /* Previous - ramdac.c
2:
3: This file is distributed under the GNU Public License, version 2 or at
4: your option any later version. Read the file gpl.txt for details.
5:
6: Brooktree Bt463 RAMDAC emulation.
7:
1.1.1.2 ! root 8: This chip was is used in color NeXTstations and NeXTdimension.
1.1 root 9:
10: */
11:
12: #include "ioMem.h"
13: #include "ioMemTables.h"
14: #include "m68000.h"
15: #include "configuration.h"
16: #include "ramdac.h"
17: #include "sysReg.h"
18:
19: #define IO_SEG_MASK 0x1FFFF
20:
21: #define LOG_RAMDAC_LEVEL LOG_DEBUG
22:
23:
1.1.1.2 ! root 24: /* Bt 463 RAMDAC */
! 25:
! 26: #define BT_ADDR_MASK 0x0FFF
! 27: #define BT_ADDR_CCR 0x0100
! 28: #define BT_ADDR_REG 0x0200
! 29: #define BT_ADDR_WTT 0x0300
! 30:
! 31: #define BT463_ID 0x2A
! 32: #define BT463_REV 0x0A
! 33:
! 34: #define BT_REG_ID 0x0
! 35: #define BT_REG_CR0 0x1
! 36: #define BT_REG_CR1 0x2
! 37: #define BT_REG_CR2 0x3
! 38: #define BT_REG_RM0 0x5
! 39: #define BT_REG_RM1 0x6
! 40: #define BT_REG_RM2 0x7
! 41: #define BT_REG_RM3 0x8
! 42: #define BT_REG_BM0 0x9
! 43: #define BT_REG_BM1 0xa
! 44: #define BT_REG_BM2 0xb
! 45: #define BT_REG_BM3 0xc
! 46: #define BT_REG_TEST 0xd
! 47: #define BT_REG_ISR 0xe
! 48: #define BT_REG_OSR 0xf
! 49: #define BT_REG_REV 0x20
! 50:
! 51:
! 52:
! 53: static void bt463_autoinc(bt463* ramdac) {
! 54: ramdac->idx++;
! 55: if(ramdac->idx > 2) {
! 56: ramdac->idx = 0;
! 57: ramdac->addr++;
! 58: ramdac->addr &= 0x0FFF;
! 59: }
! 60: }
! 61:
! 62: static void bt463_autoinc_reg(bt463* ramdac) {
! 63: ramdac->idx = 0;
! 64: ramdac->addr++;
! 65: ramdac->addr &= 0x0FFF;
! 66: }
! 67:
! 68: /* BT463 Registers */
! 69: uae_u32 bt463_read_reg(bt463* ramdac) {
! 70: uae_u32 result = 0;
! 71:
! 72: if ((ramdac->addr&0xFF)<0x10) {
! 73: switch (ramdac->addr&0x0F) {
! 74: case BT_REG_ID:
! 75: result = BT463_ID;
! 76: bt463_autoinc_reg(ramdac);
! 77: break;
! 78: case BT_REG_ISR:
! 79: case BT_REG_OSR:
! 80: result = ramdac->reg[(ramdac->addr&0x0F)*3+ramdac->idx];
! 81: bt463_autoinc(ramdac);
! 82: break;
! 83: default:
! 84: result = ramdac->reg[(ramdac->addr&0x0F)*3];
! 85: bt463_autoinc_reg(ramdac);
! 86: break;
! 87: }
! 88: } else if ((ramdac->addr&0xFF)==BT_REG_REV){
! 89: result = BT463_REV;
! 90: bt463_autoinc_reg(ramdac);
! 91: }
! 92:
! 93: return result;
! 94: }
! 95:
! 96: void bt463_write_reg(bt463* ramdac, uae_u32 val) {
! 97:
! 98: if ((ramdac->addr&0xFF)<0x10) {
! 99: switch (ramdac->addr&0x0F) {
! 100: case BT_REG_ID:
! 101: bt463_autoinc_reg(ramdac);
! 102: break;
! 103: case BT_REG_ISR:
! 104: case BT_REG_OSR:
! 105: ramdac->reg[(ramdac->addr&0x0F)*3+ramdac->idx] = val & 0xFF;
! 106: bt463_autoinc(ramdac);
! 107: break;
! 108: default:
! 109: ramdac->reg[(ramdac->addr&0x0F)*3] = val & 0xFF;
! 110: bt463_autoinc_reg(ramdac);
! 111: break;
! 112: }
! 113: }
! 114: }
! 115:
! 116: /* BT463 Cursor Color */
! 117: uae_u32 bt463_read_ccr(bt463* ramdac) {
! 118: uae_u32 result = 0;
! 119:
! 120: if ((ramdac->addr&0xFF)<2) {
! 121: result = ramdac->ccr[(ramdac->addr&1)*3+ramdac->idx];
! 122: bt463_autoinc(ramdac);
! 123: }
! 124:
! 125: return result;
! 126: }
! 127:
! 128: void bt463_write_ccr(bt463* ramdac, uae_u32 val) {
! 129:
! 130: if ((ramdac->addr&0xFF)<4) {
! 131: ramdac->ccr[(ramdac->addr&3)*3+ramdac->idx] = val & 0xFF;
! 132: bt463_autoinc(ramdac);
! 133: }
! 134: }
! 135:
! 136: /* BT463 Window Type Table */
! 137: uae_u32 bt463_read_wtt(bt463* ramdac) {
! 138: uae_u32 result = 0;
! 139:
! 140: if ((ramdac->addr&0xFF)<0x10) {
! 141: switch (ramdac->idx) {
! 142: case 0:
! 143: ramdac->wtt_tmp = ramdac->wtt[ramdac->addr&0x0F];
! 144: result = ramdac->wtt_tmp & 0xFF;
! 145: break;
! 146: case 1:
! 147: result = (ramdac->wtt_tmp >> 8) & 0xFF;
! 148: break;
! 149: case 2:
! 150: result = (ramdac->wtt_tmp >> 16) & 0xFF;
! 151: break;
! 152: default:
! 153: break;
! 154: }
! 155: bt463_autoinc(ramdac);
! 156: }
! 157:
! 158: return result;
! 159: }
! 160:
! 161: void bt463_write_wtt(bt463* ramdac, uae_u32 val) {
! 162:
! 163: if ((ramdac->addr&0xFF)<0x10) {
! 164: switch (ramdac->idx) {
! 165: case 0:
! 166: ramdac->wtt_tmp = val & 0x0000FF;
! 167: break;
! 168: case 1:
! 169: ramdac->wtt_tmp |= (val << 8) & 0x00FF00;
! 170: break;
! 171: case 2:
! 172: ramdac->wtt_tmp |= (val << 16) & 0xFF0000;
! 173: ramdac->wtt[ramdac->addr&0x0F] = ramdac->wtt_tmp;
! 174: break;
! 175: default:
! 176: break;
! 177: }
! 178: bt463_autoinc(ramdac);
! 179: }
! 180: }
! 181:
! 182: /* BT463 Palette RAM */
! 183: uae_u32 bt463_read_palette(bt463* ramdac) {
! 184: uae_u32 result = 0;
! 185:
! 186: if (ramdac->addr<0x210) {
! 187: result = ramdac->ram[ramdac->addr*3+ramdac->idx];
! 188: }
! 189: bt463_autoinc(ramdac);
! 190:
! 191: return result;
! 192: }
! 193:
! 194: void bt463_write_palette(bt463* ramdac, uae_u32 val) {
! 195:
! 196: if (ramdac->addr<0x210) {
! 197: ramdac->ram[ramdac->addr*3+ramdac->idx] = val & 0xFF;
! 198: }
! 199: bt463_autoinc(ramdac);
! 200: }
! 201:
! 202:
! 203:
! 204: /* BT463 Host Interface */
! 205: uae_u32 bt463_bget(bt463* ramdac, uaecptr addr) {
! 206:
! 207: switch(addr & 0xF) {
! 208: case 0:
! 209: ramdac->idx = 0;
! 210: return ramdac->addr & 0xFF;
! 211: case 0x4:
! 212: ramdac->idx = 0;
! 213: return (ramdac->addr >> 8) & 0x0F;
! 214: case 0x8:
! 215: switch (ramdac->addr&0x0F00) {
! 216: case BT_ADDR_CCR:
! 217: return bt463_read_ccr(ramdac);
! 218: case BT_ADDR_REG:
! 219: return bt463_read_reg(ramdac);
! 220: case BT_ADDR_WTT:
! 221: return bt463_read_wtt(ramdac);
! 222:
! 223: default: break;
! 224: }
! 225: break;
! 226: case 0xC:
! 227: return bt463_read_palette(ramdac);
! 228: }
! 229: return 0;
! 230: }
! 231:
! 232: void bt463_bput(bt463* ramdac, uaecptr addr, uae_u32 b) {
! 233: switch(addr & 0xF) {
! 234: case 0x0:
! 235: ramdac->addr &= 0x0F00;
! 236: ramdac->addr |= b & 0xFF;
! 237: ramdac->idx = 0;
! 238: break;
! 239: case 0x4:
! 240: ramdac->addr &= 0x00FF;
! 241: ramdac->addr |= (b & 0x0F) << 8;
! 242: ramdac->idx = 0;
! 243: break;
! 244: case 0x8:
! 245: switch (ramdac->addr&0x0F00) {
! 246: case BT_ADDR_CCR:
! 247: bt463_write_ccr(ramdac, b);
! 248: break;
! 249: case BT_ADDR_REG:
! 250: bt463_write_reg(ramdac, b);
! 251: break;
! 252: case BT_ADDR_WTT:
! 253: bt463_write_wtt(ramdac, b);
! 254: break;
! 255:
! 256: default:
! 257: break;
! 258: }
! 259: break;
! 260: case 0xC:
! 261: bt463_write_palette(ramdac, b);
! 262: break;
! 263: }
! 264: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.