Annotation of previous/src/dimension/nd_devs.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <limits.h>
                      3: #include <stdlib.h>
                      4: 
                      5: #include "main.h"
                      6: #include "configuration.h"
                      7: #include "m68000.h"
                      8: #include "sysdeps.h"
                      9: #include "dimension.h"
                     10: #include "nd_devs.h"
                     11: #include "nd_nbic.h"
                     12: #include "i860cfg.h"
                     13: #include "nd_sdl.h"
                     14: 
                     15: #if ENABLE_DIMENSION
                     16: 
                     17: /* --------- NEXTDIMENSION DEVICES ---------- */
                     18: 
                     19: /* Device registers */
                     20: 
                     21: /* Memory controller */
                     22: #define ND_MC_CSR0          0xFF800000
                     23: #define ND_MC_CSR1          0xFF800010
                     24: #define ND_MC_CSR2          0xFF800020
                     25: #define ND_MC_SID           0xFF800030
                     26: 
                     27: #define ND_MC_DMA_CSR       0xFF801000
                     28: 
                     29: #define ND_MC_VRAM_TIMING      0xFF802000
                     30: #define ND_MC_DRAM_SIZE                0xFF803000
                     31: 
                     32: /* CSR bits */
                     33: #define CSR0_i860PIN_RESET  0x00000001
                     34: #define CSR0_i860PIN_CS8    0x00000002
                     35: #define CSR0_i860_IMASK     0x00000004
                     36: #define CSR0_i860_INT       0x00000008
                     37: #define CSR0_BE_IMASK       0x00000010
                     38: #define CSR0_BE_INT         0x00000020
                     39: #define CSR0_VBL_IMASK      0x00000040
                     40: #define CSR0_VBL_INT        0x00000080
                     41: #define CSR0_VBLANK         0x00000100 /* ro */
                     42: #define CSR0_VIOVBL_IMASK   0x00000200
                     43: #define CSR0_VIOVBL_INT     0x00000400
                     44: #define CSR0_VIOBLANK       0x00000800 /* ro */
                     45: #define CSR0_i860_CACHE_EN  0x00001000
                     46: 
                     47: #define CSR1_CPU_INT        0x00000001
                     48: 
                     49: #define CSR2_GLOBAL_ACCESS  0x00000001
                     50: 
                     51: #define CSRDMA_VISIBLE_EN   0x00000001
                     52: #define CSRDMA_BLANKED_EN   0x00000002
                     53: #define CSRDMA_READ_EN      0x00000004
                     54: 
                     55: #define CSRVRAM_VBLANK      0x00000001
                     56: #define CSRVRAM_60HZ        0x00000002
                     57: #define CSRVRAM_EXT_SYNC    0x00000004
                     58: 
                     59: #define CSRDRAM_4MBIT       0x00000001
                     60: 
                     61: static
                     62: #if ENABLE_I860_THREAD
                     63: volatile
                     64: #endif
                     65: struct {
                     66:     uae_u32 csr0;
                     67:     uae_u32 csr1;
                     68:     uae_u32 csr2;
                     69:     uae_u32 sid;
                     70:     uae_u32 dma_csr;
                     71:     uae_u32 dma_start;
                     72:     uae_u32 dma_width;
                     73:     uae_u32 dma_pstart;
                     74:     uae_u32 dma_pwidth;
                     75:     uae_u32 dma_sstart;
                     76:     uae_u32 dma_swidth;
                     77:     uae_u32 dma_bsstart;
                     78:     uae_u32 dma_bswidth;
                     79:     uae_u32 dma_top;
                     80:     uae_u32 dma_bottom;
                     81:     uae_u32 dma_line_a;
                     82:     uae_u32 dma_curr_a;
                     83:     uae_u32 dma_scurr_a;
                     84:     uae_u32 dma_out_a;
                     85:     uae_u32 vram;
                     86:     uae_u32 dram;
                     87: } nd_mc;
                     88: static lock_t nd_mc_lock;
                     89: 
                     90: #define DP_IIC_MORE 0x20000000
                     91: #define DP_IIC_BUSY 0x80000000
                     92: 
                     93: static struct {
                     94:     uae_u8  iic_addr;
                     95:     uae_u8  iic_msg[4096];
                     96:     uae_u32 iic_msgsz;
                     97:     int     iic_busy;
                     98:     uae_u32 doff; // (SC) wild guess - vram offset in pixels?
                     99:     uae_u32 csr;
                    100:     uae_u32 alpha;
                    101:     uae_u32 dma;
                    102:     uae_u32 cpu_x;
                    103:     uae_u32 cpu_y;
                    104:     uae_u32 dma_x;
                    105:     uae_u32 dma_y;
                    106:     uae_u32 iic_stat_addr;
                    107:     uae_u32 iic_data;
                    108: } nd_dp;
                    109: 
                    110: /* nd_display_blank_start is called from SDL. See nd_sdl.c */
                    111: void nd_display_blank_start() {
                    112:     lock(&nd_mc_lock);
                    113:     Uint32 csr0 = nd_mc.csr0;
                    114:     csr0 |= CSR0_VBL_INT | CSR0_VBLANK;
                    115:     nd_mc.csr0 = csr0;
                    116:     unlock(&nd_mc_lock);
                    117:     i860_tick((csr0 & CSR0_VBL_IMASK) != 0);
                    118: }
                    119: 
                    120: /* nd_display_blank_start is called from SDL. See nd_sdl.c */
                    121: void nd_display_blank_end() {
                    122:     lock(&nd_mc_lock);
                    123:     nd_mc.csr0 &= ~CSR0_VBLANK;
                    124:     unlock(&nd_mc_lock);
                    125: }
                    126: 
                    127: /* nd_video_vbl is called from SDL. See nd_sdl.c */
                    128: Uint32 nd_video_vbl(Uint32 interval, void *param) {
                    129:     lock(&nd_mc_lock);
                    130:     Uint32 csr0 = nd_mc.csr0;
                    131:     if(csr0 & CSR0_VIOBLANK) {
                    132:         csr0 &= ~CSR0_VIOBLANK;
                    133:         interval = VIDEO_VBL_MS-BLANK_MS;
                    134:     } else {
                    135:         csr0 |= CSR0_VIOVBL_INT | CSR0_VIOBLANK;
                    136:         interval = BLANK_MS;
                    137:     }
                    138:     nd_mc.csr0 = csr0;
                    139:     unlock(&nd_mc_lock);
                    140:     i860_tick((csr0 & CSR0_VIOVBL_IMASK) != 0);
                    141:     return interval;
                    142: }
                    143: 
                    144: void nd_devs_init() {
                    145:     nd_set_speed_hack(0);
                    146: 
                    147:     nd_mc.csr0          = 0;
                    148:     nd_mc.csr1          = 0;
                    149:     nd_mc.csr2          = 0;
                    150:     nd_mc.sid           = ND_SLOT;
                    151:     nd_mc.dma_csr       = 0;
                    152:     nd_mc.dma_start     = 0;
                    153:     nd_mc.dma_width     = 0;
                    154:     nd_mc.dma_pstart    = 0;
                    155:     nd_mc.dma_pwidth    = 0;
                    156:     nd_mc.dma_sstart    = 0;
                    157:     nd_mc.dma_swidth    = 0;
                    158:     nd_mc.dma_bsstart   = 0;
                    159:     nd_mc.dma_bswidth   = 0;
                    160:     nd_mc.dma_top       = 0;
                    161:     nd_mc.dma_bottom    = 0;
                    162:     nd_mc.dma_line_a    = 0;
                    163:     nd_mc.dma_curr_a    = 0;
                    164:     nd_mc.dma_scurr_a   = 0;
                    165:     nd_mc.dma_out_a     = 0;
                    166:     nd_mc.vram          = 0;
                    167:     nd_mc.dram          = 0;
                    168:     nd_dp.iic_msgsz     = 0;
                    169:     nd_dp.iic_addr      = 0;
                    170:     nd_dp.csr           = 0;
                    171:     nd_dp.alpha         = 0;
                    172:     nd_dp.dma           = 0;
                    173:     nd_dp.cpu_x         = 0xc;
                    174:     nd_dp.cpu_y         = 0xc;
                    175:     nd_dp.dma_x         = 0xd;
                    176:     nd_dp.dma_y         = 0xd;
                    177:     nd_dp.iic_stat_addr = 0;
                    178:     nd_dp.iic_data      = 0;
                    179: }
                    180: 
                    181: 
                    182: static const char* ND_CSR0_BITS[] = {
                    183:     "i860PIN_RESET",   "i860PIN_CS8",     "i860_IMASK",  "i860_INT",
                    184:     "BE_IMASK",        "BE_INT",          "VBL_IMASK",   "VBL_INT",
                    185:     "VBLANK",          "VIOVBL_IMASK",    "VIOVBL_INT",  "VIOBLANK",
                    186:     "i860_CACHE_EN",   "00002000",        "00004000",    "00008000",
                    187:     "00010000",        "00020000",        "00040000",    "00080000",
                    188:     "00100000",        "00200000",        "00400000",    "00800000",
                    189:     "01000000",        "02000000",        "04000000",    "08000000",
                    190:     "10000000",        "20000000",        "40000000",    "80000000",
                    191: };
                    192: 
                    193: static const char* ND_CSR1_BITS[] = {
                    194:     "CPU_INT",         "00000002",        "00000004",    "00000008",
                    195:     "00000010",        "00000020",        "00000040",    "00000080",
                    196:     "00000100",        "00000200",        "00000400",    "00000800",
                    197:     "00001000",        "00002000",        "00004000",    "00008000",
                    198:     "00010000",        "00020000",        "00040000",    "00080000",
                    199:     "00100000",        "00200000",        "00400000",    "00800000",
                    200:     "01000000",        "02000000",        "04000000",    "08000000",
                    201:     "10000000",        "20000000",        "40000000",    "80000000",
                    202: };
                    203: 
                    204: static const char* ND_CSR2_BITS[] = {
                    205:     "GLOBAL_ACCESS",   "00000002",        "00000004",    "00000008",
                    206:     "00000010",        "00000020",        "00000040",    "00000080",
                    207:     "00000100",        "00000200",        "00000400",    "00000800",
                    208:     "00001000",        "00002000",        "00004000",    "00008000",
                    209:     "00010000",        "00020000",        "00040000",    "00080000",
                    210:     "00100000",        "00200000",        "00400000",    "00800000",
                    211:     "01000000",        "02000000",        "04000000",    "08000000",
                    212:     "10000000",        "20000000",        "40000000",    "80000000",
                    213: };
                    214: 
                    215: static const char* ND_DMA_CSR_BITS[] = {
                    216:     "VISIBLE_EN",      "BLANKED_EN",      "READ_EN",    "00000008",
                    217:     "00000010",        "00000020",        "00000040",    "00000080",
                    218:     "00000100",        "00000200",        "00000400",    "00000800",
                    219:     "00001000",        "00002000",        "00004000",    "00008000",
                    220:     "00010000",        "00020000",        "00040000",    "00080000",
                    221:     "00100000",        "00200000",        "00400000",    "00800000",
                    222:     "01000000",        "02000000",        "04000000",    "08000000",
                    223:     "10000000",        "20000000",        "40000000",    "80000000",
                    224: };
                    225: 
                    226: static const char* ND_VRAM_BITS[] = {
                    227:     "VBLANK",          "60HZ",            "EXT_SYNC",    "00000008",
                    228:     "00000010",        "00000020",        "00000040",    "00000080",
                    229:     "00000100",        "00000200",        "00000400",    "00000800",
                    230:     "00001000",        "00002000",        "00004000",    "00008000",
                    231:     "00010000",        "00020000",        "00040000",    "00080000",
                    232:     "00100000",        "00200000",        "00400000",    "00800000",
                    233:     "01000000",        "02000000",        "04000000",    "08000000",
                    234:     "10000000",        "20000000",        "40000000",    "80000000",
                    235: };
                    236: 
                    237: static const char* ND_DRAM_BITS[] = {
                    238:     "4MBIT",           "00000002",        "00000004",    "00000008",
                    239:     "00000010",        "00000020",        "00000040",    "00000080",
                    240:     "00000100",        "00000200",        "00000400",    "00000800",
                    241:     "00001000",        "00002000",        "00004000",    "00008000",
                    242:     "00010000",        "00020000",        "00040000",    "00080000",
                    243:     "00100000",        "00200000",        "00400000",    "00800000",
                    244:     "01000000",        "02000000",        "04000000",    "08000000",
                    245:     "10000000",        "20000000",        "40000000",    "80000000",
                    246: };
                    247: 
                    248: static const char* decodeBits(const char** bits, uae_u32 val) {
                    249:     static char buffer[512];
                    250:     char*       result = buffer;
                    251:     
                    252:     if(bits) {
                    253:         *result = 0;
                    254:         for(int i = 0; i < 32; i++) {
                    255:             if(val & (1 << i)) {
                    256:                 const char* str = bits[i];
                    257:                 while(*str) *result++ = *str++;
                    258:                 *result++ = '|';
                    259:             }
                    260:         }
                    261:         if(result != buffer)
                    262:             *--result = 0;
                    263:     }
                    264:     else
                    265:         sprintf(buffer, "%08X", val);
                    266:     return buffer;
                    267: }
                    268: 
                    269: static const char* MC_RD_FORMAT   = "[ND] Memory controller %s read %08X at %08X";
                    270: static const char* MC_RD_FORMAT_S = "[ND] Memory controller %s read (%s) at %08X";
                    271: 
                    272: uae_u32 nd_mc_read_register(uaecptr addr) {
                    273:        switch (addr&0x3FFF) {
                    274:                case 0x0000:
                    275:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"csr0", decodeBits(ND_CSR0_BITS, nd_mc.csr0),addr);
                    276:                        return nd_mc.csr0;
                    277:                case 0x0010:
                    278:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"csr1", decodeBits(ND_CSR1_BITS, nd_mc.csr1),addr);
                    279:                        return nd_mc.csr1;
                    280:                case 0x0020:
                    281:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"csr2", decodeBits(ND_CSR2_BITS, nd_mc.csr2),addr);
                    282:                        return nd_mc.csr2;
                    283:                case 0x0030:
                    284:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"sid", nd_mc.sid,addr);
                    285:                        return nd_mc.sid;
                    286:                case 0x1000:
                    287:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"dma_csr", decodeBits(ND_DMA_CSR_BITS, nd_mc.dma_csr),addr);
                    288:             return nd_mc.dma_csr;
                    289:         case 0x1010:
                    290:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_start", nd_mc.dma_start,addr);
                    291:             return nd_mc.dma_start;
                    292:         case 0x1020:
                    293:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_width", nd_mc.dma_width,addr);
                    294:             return nd_mc.dma_width;
                    295:         case 0x1030:
                    296:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_pstart", nd_mc.dma_pstart,addr);
                    297:             return nd_mc.dma_pstart;
                    298:         case 0x1040:
                    299:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_pwidth", nd_mc.dma_pwidth,addr);
                    300:             return nd_mc.dma_pwidth;
                    301:         case 0x1050:
                    302:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_sstart", nd_mc.dma_sstart,addr);
                    303:             return nd_mc.dma_sstart;
                    304:         case 0x1060:
                    305:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_swidth", nd_mc.dma_swidth,addr);
                    306:             return nd_mc.dma_swidth;
                    307:         case 0x1070:
                    308:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_bsstart", nd_mc.dma_bsstart,addr);
                    309:             return nd_mc.dma_bsstart;
                    310:         case 0x1080:
                    311:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_bswidth", nd_mc.dma_bswidth,addr);
                    312:             return nd_mc.dma_bswidth;
                    313:         case 0x1090:
                    314:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_top", nd_mc.dma_top,addr);
                    315:             return nd_mc.dma_top;
                    316:         case 0x10A0:
                    317:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_bottom", nd_mc.dma_bottom,addr);
                    318:             return nd_mc.dma_bottom;
                    319:         case 0x10B0:
                    320:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_line_a", nd_mc.dma_line_a,addr);
                    321:             return nd_mc.dma_line_a;
                    322:         case 0x10C0:
                    323:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_curr_a", nd_mc.dma_curr_a,addr);
                    324:             return nd_mc.dma_curr_a;
                    325:         case 0x10D0:
                    326:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_line_a", nd_mc.dma_line_a,addr);
                    327:             return nd_mc.dma_line_a;
                    328:         case 0x10E0:
                    329:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_scurr_a", nd_mc.dma_scurr_a,addr);
                    330:             return nd_mc.dma_scurr_a;
                    331:         case 0x10F0:
                    332:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT,"dma_out_a", nd_mc.dma_out_a,addr);
                    333:             return nd_mc.dma_out_a;
                    334:                case 0x2000:
                    335:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"vram", decodeBits(ND_VRAM_BITS, nd_mc.vram),addr);
                    336:             return nd_mc.vram;
                    337:                case 0x3000:
                    338:             Log_Printf(ND_LOG_IO_RD, MC_RD_FORMAT_S,"dram", decodeBits(ND_DRAM_BITS, nd_mc.dram),addr);
                    339:             return nd_mc.dram;
                    340:                default:
                    341:                        Log_Printf(LOG_WARN, "[ND] Memory controller UNKNOWN read at %08X",addr);
                    342:             break;
                    343:        }
                    344:        return 0;
                    345: }
                    346: 
                    347: static const char* MC_WR_FORMAT   = "[ND] Memory controller %s write %08X at %08X";
                    348: static const char* MC_WR_FORMAT_S = "[ND] Memory controller %s write (%s) at %08X";
                    349: 
                    350: void nd_mc_write_register(uaecptr addr, uae_u32 val) {
                    351:     lock(&nd_mc_lock);
                    352:     switch (addr&0x3FFF) {
                    353:         case 0x0000:
                    354:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"csr0", decodeBits(ND_CSR0_BITS, val), addr);
                    355:             if(val & CSR0_i860PIN_RESET) {
                    356:                 i860_reset();
                    357:                 val &= ~CSR0_i860PIN_RESET;
                    358:             }
                    359:             if ((nd_mc.csr0 & CSR0_i860_INT) && (nd_mc.csr0 & CSR0_i860_IMASK))
                    360:                 i860_tick(true);
                    361:             
                    362:             if((nd_mc.csr0 & CSR0_BE_INT) && (nd_mc.csr0 & CSR0_BE_IMASK))
                    363:                 i860_tick(true);
                    364:             
                    365:                        nd_set_speed_hack((val & 0x00008000) ? 0 : 1);
                    366:             nd_mc.csr0 = val;
                    367:             break;
                    368:         case 0x0010:
                    369:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"csr1", decodeBits(ND_CSR1_BITS, val),addr);
                    370:             nd_mc.csr1 = val;
                    371:                        if (nd_mc.csr1&CSR1_CPU_INT) {
                    372:                                nd_nbic_set_intstatus(true);
                    373:                        } else {
                    374:                 nd_nbic_set_intstatus(false);
                    375:                        }
                    376:             break;
                    377:         case 0x0020:
                    378:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"csr2", decodeBits(ND_CSR2_BITS, val),addr);
                    379:             nd_mc.csr2 = val;
                    380:             break;
                    381:         case 0x0030:
                    382:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"sid", val,addr);
                    383:             nd_mc.sid = val;
                    384:             break;
                    385:         case 0x1000:
                    386:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"dma_csr", decodeBits(ND_DMA_CSR_BITS, val),addr);
                    387:             nd_mc.dma_csr = val;
                    388:             break;
                    389:         case 0x1010:
                    390:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_start", val,addr);
                    391:             nd_mc.dma_start = val;
                    392:             break;
                    393:         case 0x1020:
                    394:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_width", val,addr);
                    395:             nd_mc.dma_width = val;
                    396:             break;
                    397:         case 0x1030:
                    398:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_pstart", val,addr);
                    399:             nd_mc.dma_pstart = val;
                    400:             break;
                    401:         case 0x1040:
                    402:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_pwidth", val,addr);
                    403:             nd_mc.dma_pwidth = val;
                    404:             break;
                    405:         case 0x1050:
                    406:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_sstart", val,addr);
                    407:             nd_mc.dma_sstart = val;
                    408:             break;
                    409:         case 0x1060:
                    410:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_swidth", val,addr);
                    411:             nd_mc.dma_swidth = val;
                    412:             break;
                    413:         case 0x1070:
                    414:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_bsstart", val,addr);
                    415:             nd_mc.dma_bsstart = val;
                    416:             break;
                    417:         case 0x1080:
                    418:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_bswidth", val,addr);
                    419:             nd_mc.dma_bswidth = val;
                    420:             break;
                    421:         case 0x1090:
                    422:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_top", val,addr);
                    423:             nd_mc.dma_top = val;
                    424:             break;
                    425:         case 0x10A0:
                    426:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_bottom", val,addr);
                    427:             nd_mc.dma_bottom = val;
                    428:             break;
                    429:         case 0x10B0:
                    430:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_line_a", val,addr);
                    431:             nd_mc.dma_line_a = val;
                    432:             break;
                    433:         case 0x10C0:
                    434:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_curr_a", val,addr);
                    435:             nd_mc.dma_curr_a = val;
                    436:             break;
                    437:         case 0x10D0:
                    438:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_line_a", val,addr);
                    439:             nd_mc.dma_line_a = val;
                    440:             break;
                    441:         case 0x10E0:
                    442:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_scurr_a", val,addr);
                    443:             nd_mc.dma_scurr_a = val;
                    444:             break;
                    445:         case 0x10F0:
                    446:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT,"dma_out_a", val,addr);
                    447:             nd_mc.dma_out_a = val;
                    448:             break;
                    449:         case 0x2000:
                    450:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"vram", decodeBits(ND_VRAM_BITS, val),addr);
                    451:             nd_mc.vram = val;
                    452:             break;
                    453:         case 0x3000:
                    454:             Log_Printf(ND_LOG_IO_WR, MC_WR_FORMAT_S,"dram", decodeBits(ND_DRAM_BITS, val),addr);
                    455:             nd_mc.dram = val;
                    456:             break;
                    457:         default:
                    458:             Log_Printf(LOG_WARN, "[ND] Memory controller UNKNOWN write at %08X",addr);
                    459:             break;
                    460:        }
                    461:     unlock(&nd_mc_lock);
                    462: }
                    463: 
                    464: /* NeXTdimension device space */
                    465: inline uae_u32 nd_io_lget(uaecptr addr) {
                    466:        return nd_mc_read_register(addr);
                    467: }
                    468: 
                    469: inline uae_u32 nd_io_wget(uaecptr addr) {
                    470:        return 0;
                    471: }
                    472: 
                    473: inline uae_u32 nd_io_bget(uaecptr addr) {
                    474:        return 0;
                    475: }
                    476: 
                    477: inline void nd_io_lput(uaecptr addr, uae_u32 l) {
                    478:        nd_mc_write_register(addr, l);
                    479: }
                    480: 
                    481: inline void nd_io_wput(uaecptr addr, uae_u32 w) {
                    482:     
                    483: }
                    484: 
                    485: inline void nd_io_bput(uaecptr addr, uae_u32 b) {
                    486:     
                    487: }
                    488: 
                    489: /* NeXTdimension RAMDAC */
                    490: 
                    491: static struct {
                    492:     int   addr;
                    493:     int   idx;
                    494:     Uint8 regs[0x1000];
                    495: } nd_ramdac;
                    496: 
                    497: static void nd_ramdac_autoinc() {
                    498:     nd_ramdac.idx++;
                    499:     if(nd_ramdac.idx == 3) {
                    500:         nd_ramdac.idx = 0;
                    501:         nd_ramdac.addr++;
                    502:     }
                    503: }
                    504: 
                    505: inline uae_u32 nd_ramdac_bget(uaecptr addr) {
                    506:     uae_u32 result = 0;
                    507:     switch(addr & 0xF) {
                    508:         case 0:
                    509:             return nd_ramdac.addr & 0xFF;
                    510:         case 0x4:
                    511:             return (nd_ramdac.addr >> 8) & 0xFF;
                    512:         case 0x8:
                    513:             result = nd_ramdac.regs[nd_ramdac.addr*3];
                    514:             if(nd_ramdac.addr == 0x100 || nd_ramdac.addr == 0x101)
                    515:                 nd_ramdac_autoinc();
                    516:             break;
                    517:         case 0xC:
                    518:             result = nd_ramdac.regs[nd_ramdac.addr*3+nd_ramdac.idx];
                    519:             nd_ramdac_autoinc();
                    520:             break;
                    521:     }
                    522:     return result;
                    523: }
                    524: 
                    525: inline void nd_ramdac_bput(uaecptr addr, uae_u32 b) {
                    526:     switch(addr & 0xF) {
                    527:         case 0x0:
                    528:             nd_ramdac.addr &= 0xFF00;
                    529:             nd_ramdac.addr |= b & 0xFF;
                    530:             nd_ramdac.idx = 0;
                    531:             break;
                    532:         case 0x4:
                    533:             nd_ramdac.addr &= 0x000F;
                    534:             nd_ramdac.addr |= (b & 0x0F) << 8;
                    535:             nd_ramdac.idx = 0;
                    536:             break;
                    537:         case 0x8:
                    538:             nd_ramdac.regs[nd_ramdac.addr*3] = b;
                    539:             if(nd_ramdac.addr == 0x100 || nd_ramdac.addr == 0x101)
                    540:                 nd_ramdac_autoinc();
                    541:             break;
                    542:         case 0xC:
                    543:             nd_ramdac.regs[nd_ramdac.addr*3+nd_ramdac.idx] = b;
                    544:             nd_ramdac_autoinc();
                    545:             break;
                    546:     }
                    547: }
                    548: 
                    549: /* NeXTdimension data path */
                    550: 
                    551: static void nd_dp_iicmsg() {
                    552:     Log_Printf(LOG_WARN, "[ND] data path IIC msg addr:%02X msg[%d]=%02X", nd_dp.iic_addr, nd_dp.iic_msgsz-1, nd_dp.iic_msg[nd_dp.iic_msgsz-1]);
                    553: }
                    554: 
                    555: inline uae_u32 nd_dp_lget(uaecptr addr) {
                    556:     switch(addr) {
                    557:         case 0x300: case 0x304: case 0x308: case 0x30C:
                    558:         case 0x310: case 0x314: case 0x318: case 0x31C:
                    559:         case 0x320: case 0x324: case 0x328: case 0x32C:
                    560:         case 0x330: case 0x334: case 0x338: case 0x33C:
                    561:             return nd_dp.doff;
                    562:         case 0x340:
                    563:             return nd_dp.csr;
                    564:         case 0x344:
                    565:             return nd_dp.alpha;
                    566:         case 0x348:
                    567:             return nd_dp.dma;
                    568:         case 0x350:
                    569:             return nd_dp.cpu_x;
                    570:         case 0x354:
                    571:             return nd_dp.cpu_y;
                    572:         case 0x358:
                    573:             return nd_dp.dma_x;
                    574:         case 0x35C:
                    575:             return nd_dp.dma_y;
                    576:         case 0x360:
                    577:             if(nd_dp.iic_busy <= 0)
                    578:                 nd_dp.iic_stat_addr &= ~DP_IIC_BUSY;
                    579:             else
                    580:                 nd_dp.iic_busy--;
                    581:             return nd_dp.iic_stat_addr;
                    582:         case 0x364:
                    583:             return 0;
                    584:         default:
                    585:             Log_Printf(LOG_WARN, "[ND] data path UNKNOWN read at %08X",addr);
                    586:     }
                    587:     return 0;
                    588: }
                    589: 
                    590: inline void nd_dp_lput(uaecptr addr, uae_u32 v) {
                    591:     switch(addr) {
                    592:         case 0x300: case 0x304: case 0x308: case 0x30C:
                    593:         case 0x310: case 0x314: case 0x318: case 0x31C:
                    594:         case 0x320: case 0x324: case 0x328: case 0x32C:
                    595:         case 0x330: case 0x334: case 0x338: case 0x33C:
                    596:             ND_vram_off = v * 4;
                    597:             nd_dp.doff  = v;
                    598:             break;
                    599:         case 0x340:
                    600:             nd_dp.csr = v;
                    601:             break;
                    602:         case 0x344:
                    603:             nd_dp.alpha = v;
                    604:             break;
                    605:         case 0x348:
                    606:             nd_dp.dma = v;
                    607:             break;
                    608:         case 0x350:
                    609:             nd_dp.cpu_x = v;
                    610:             break;
                    611:         case 0x354:
                    612:             nd_dp.cpu_y = v;
                    613:             break;
                    614:         case 0x358:
                    615:             nd_dp.dma_x = v;
                    616:             break;
                    617:         case 0x35C:
                    618:             nd_dp.dma_y = v;
                    619:             break;
                    620:         case 0x360:
                    621:             nd_dp.iic_msgsz = 0;
                    622:             nd_dp.iic_addr  = v >> 8;
                    623:             nd_dp.iic_msg[nd_dp.iic_msgsz++] = v;
                    624:             nd_dp.iic_stat_addr |= DP_IIC_BUSY;
                    625:             nd_dp.iic_busy       = 10;
                    626:             nd_dp_iicmsg();
                    627:             break;
                    628:         case 0x364:
                    629:             nd_dp.iic_msg[nd_dp.iic_msgsz++] = v;
                    630:             nd_dp.iic_stat_addr |= DP_IIC_BUSY;
                    631:             nd_dp.iic_busy       = 10;
                    632:             nd_dp_iicmsg();
                    633:             break;
                    634:         default:
                    635:             Log_Printf(LOG_WARN, "[ND] data path UNKNOWN write at %08X %08X",addr,v);
                    636:     }
                    637: }
                    638: 
                    639: static const char* nd_dump_path = "nd_memory.bin";
                    640: 
                    641: /* debugger stuff */
                    642: bool nd_dbg_cmd(const char* buf) {
                    643:     if(!(buf)) {
                    644:         fprintf(stderr,
                    645:                 "   w: write NeXTdimension DRAM to file '%s'\n"
                    646:                 "   n: dump NeXTdimension registers\n"
                    647:                 , nd_dump_path);
                    648:         return false;
                    649:     }
                    650:     
                    651:     switch(buf[0]) {
                    652:         case 'w': {
                    653:             char tmp[PATH_MAX];
                    654:             FILE* fp = fopen(nd_dump_path, "wb");
                    655:             size_t size  = ConfigureParams.Dimension.nMemoryBankSize[0];
                    656:             size        += ConfigureParams.Dimension.nMemoryBankSize[1];
                    657:             size        += ConfigureParams.Dimension.nMemoryBankSize[2];
                    658:             size        += ConfigureParams.Dimension.nMemoryBankSize[3];
                    659:             fprintf(stderr, "Writing %luMB to '%s'...", size, realpath(nd_dump_path, tmp));
                    660:             size <<= 20;
                    661:             fwrite(ND_ram, sizeof(Uint8), size, fp);
                    662:             fclose(fp);
                    663:             fprintf(stderr, "done.");
                    664:             return true;
                    665:         }
                    666:         case 'n': {
                    667:             fprintf(stderr, "csr0        (%s)\n", decodeBits(ND_CSR0_BITS,    nd_mc.csr0));
                    668:             fprintf(stderr, "csr1        (%s)\n", decodeBits(ND_CSR1_BITS,    nd_mc.csr1));
                    669:             fprintf(stderr, "csr2        (%s)\n", decodeBits(ND_CSR2_BITS,    nd_mc.csr2));
                    670:             fprintf(stderr, "sid         (%s)\n", decodeBits(0,               nd_mc.sid));
                    671:             fprintf(stderr, "dma_csr     (%s)\n", decodeBits(ND_DMA_CSR_BITS, nd_mc.dma_csr));
                    672:             fprintf(stderr, "dma_start   (%s)\n", decodeBits(0,               nd_mc.dma_start));
                    673:             fprintf(stderr, "dma_width   (%s)\n", decodeBits(0,               nd_mc.dma_width));
                    674:             fprintf(stderr, "dma_pstart  (%s)\n", decodeBits(0,               nd_mc.dma_pstart));
                    675:             fprintf(stderr, "dma_pwidth  (%s)\n", decodeBits(0,               nd_mc.dma_pwidth));
                    676:             fprintf(stderr, "dma_sstart  (%s)\n", decodeBits(0,               nd_mc.dma_sstart));
                    677:             fprintf(stderr, "dma_swidth  (%s)\n", decodeBits(0,               nd_mc.dma_swidth));
                    678:             fprintf(stderr, "dma_bsstart (%s)\n", decodeBits(0,               nd_mc.dma_bsstart));
                    679:             fprintf(stderr, "dma_bswidth (%s)\n", decodeBits(0,               nd_mc.dma_bswidth));
                    680:             fprintf(stderr, "dma_top     (%s)\n", decodeBits(0,               nd_mc.dma_top));
                    681:             fprintf(stderr, "dma_bottom  (%s)\n", decodeBits(0,               nd_mc.dma_bottom));
                    682:             fprintf(stderr, "dma_line_a  (%s)\n", decodeBits(0,               nd_mc.dma_line_a));
                    683:             fprintf(stderr, "dma_curr_a  (%s)\n", decodeBits(0,               nd_mc.dma_curr_a));
                    684:             fprintf(stderr, "dma_scurr_a (%s)\n", decodeBits(0,               nd_mc.dma_scurr_a));
                    685:             fprintf(stderr, "dma_out_a   (%s)\n", decodeBits(0,               nd_mc.dma_out_a));
                    686:             fprintf(stderr, "vram        (%s)\n", decodeBits(ND_VRAM_BITS,    nd_mc.vram));
                    687:             fprintf(stderr, "dram        (%s)\n", decodeBits(ND_DRAM_BITS,    nd_mc.dram));
                    688:             return true;
                    689:         }
                    690:         default:
                    691:             return false;
                    692:     }
                    693: }
                    694: 
                    695: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.