Annotation of previous_trunk/src/scc.c, revision 1.1.1.1

1.1       root        1: /*  Previous - scc.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:  Serial Communication Controller (AMD AM8530H) Emulation.
                      7:  
                      8:  Incomplete. Hacked to pass power-on test --> see SCC_Reset()
                      9:  
                     10:  */
                     11: 
                     12: #include "ioMem.h"
                     13: #include "ioMemTables.h"
                     14: #include "m68000.h"
                     15: #include "configuration.h"
                     16: #include "scc.h"
                     17: #include "sysReg.h"
                     18: #include "dma.h"
                     19: 
                     20: #define IO_SEG_MASK    0x1FFFF
                     21: 
                     22: #define LOG_SCC_LEVEL          LOG_NONE
                     23: #define LOG_SCC_REG_LEVEL      LOG_NONE
                     24: 
                     25: 
                     26: /* Registers */
                     27: 
                     28: Uint8 scc_control_read(Uint8 channel);
                     29: void scc_control_write(Uint8 channel, Uint8 val);
                     30: Uint8 scc_data_read(Uint8 channel);
                     31: void scc_data_write(Uint8 channel, Uint8 val);
                     32: 
                     33: 
                     34: void SCC_ControlB_Read(void) { // 0x02018000
                     35:        IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = scc_control_read(1);
                     36:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel B control read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     37: }
                     38: 
                     39: void SCC_ControlB_Write(void) {
                     40:        scc_control_write(1, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]);
                     41:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel B control write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     42: }
                     43: 
                     44: void SCC_ControlA_Read(void) { // 0x02018001
                     45:        IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = scc_control_read(0);
                     46:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel A control read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     47: }
                     48: 
                     49: void SCC_ControlA_Write(void) {
                     50:        scc_control_write(0, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]);
                     51:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel A control write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     52: }
                     53: 
                     54: void SCC_DataB_Read(void) { // 0x02018002
                     55:        IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = scc_data_read(1);
                     56:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel B data read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     57: }
                     58: 
                     59: void SCC_DataB_Write(void) {
                     60:        scc_data_write(1, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]);
                     61:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel B data write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     62: }
                     63: 
                     64: void SCC_DataA_Read(void) { // 0x02018003
                     65:        IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = scc_data_read(0);
                     66:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel A data read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     67: }
                     68: 
                     69: void SCC_DataA_Write(void) {
                     70:        scc_data_write(0, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]);
                     71:        Log_Printf(LOG_SCC_REG_LEVEL,"[SCC] Channel A data write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
                     72: }
                     73: 
                     74: 
                     75: /* SCC Registers */
                     76: 
                     77: struct {
                     78:        Uint8 rreg[16];
                     79:        Uint8 wreg[16];
                     80: } scc[2];
                     81: 
                     82: Uint8 scc_register_pointer = 0;
                     83: 
                     84: /* Write function prototypes */
                     85: void scc_write_init_command(Uint8 ch, Uint8 val);
                     86: void scc_write_mode(Uint8 ch, Uint8 val);
                     87: void scc_write_master_intr_reset(Uint8 val);
                     88: 
                     89: 
                     90: Uint8 scc_control_read(Uint8 ch) {
                     91:        Uint8 val = 0;
                     92:        
                     93:        switch (scc_register_pointer) {
                     94:                case 0:
                     95:                case 1:
                     96:                case 3:
                     97:                case 10:
                     98:                        val = scc[ch].rreg[scc_register_pointer];
                     99:                        break;
                    100:                        
                    101:                case 12:
                    102:                case 13:
                    103:                case 15:
                    104:                        val = scc[ch].wreg[scc_register_pointer];
                    105:                        break;
                    106:                        
                    107:                case 2:
                    108:                        val = scc[0].wreg[2]; // FIXME: different for channel B
                    109:                        break;
                    110:                        
                    111:                case 8:
                    112:                        val = 0; // FIXME: Data Read
                    113:                        break;
                    114:                        
                    115:                default:
                    116:                        Log_Printf(LOG_WARN, "[SCC] Invalid register (%i) read\n",scc_register_pointer);
                    117:                        break;
                    118:        }
                    119: 
                    120:        Log_Printf(LOG_SCC_LEVEL,"[SCC] Channel %c: Register %i read %02X\n",
                    121:                           ch?'B':'A',scc_register_pointer,val);
                    122: 
                    123:        scc_register_pointer = 0;
                    124: 
                    125:        return val;
                    126: }
                    127: 
                    128: void scc_control_write(Uint8 ch, Uint8 val) {
                    129:        
                    130:        if (scc_register_pointer==0) {
                    131:                scc_register_pointer = val&7;
                    132:                if ((val&0x38)==8) {
                    133:                        scc_register_pointer |= 8;
                    134:                }
                    135:                if (val&0xF0) {
                    136:                        scc_write_init_command(ch, val);
                    137:                }
                    138:        } else {
                    139:                Log_Printf(LOG_SCC_LEVEL,"[SCC] Channel %c: Register %i write %02X\n",
                    140:                                   ch?'B':'A',scc_register_pointer,val);
                    141:                
                    142:                switch (scc_register_pointer) {
                    143:                        case 1:
                    144:                                scc_write_mode(ch, val);
                    145:                                break;
                    146:                        case 9:
                    147:                                scc_write_master_intr_reset(val);
                    148:                                break;
                    149:                        case 2:
                    150:                        case 3:
                    151:                        case 4:
                    152:                        case 5:
                    153:                        case 6:
                    154:                        case 7:
                    155:                        case 8:
                    156:                        case 10:
                    157:                        case 11:
                    158:                        case 12:
                    159:                        case 13:
                    160:                        case 14:
                    161:                        case 15:
                    162:                                break;
                    163:                        
                    164:                        default:
                    165:                                Log_Printf(LOG_WARN, "[SCC] Invalid register (%i) write\n",scc_register_pointer);
                    166:                                break;
                    167:                }
                    168:                
                    169:                scc_register_pointer = 0;
                    170:        }
                    171: }
                    172: 
                    173: Uint8 scc_data_read(Uint8 ch) {
                    174:        Uint8 val = 0;
                    175:        
                    176:        val = scc_buf[0];
                    177:        
                    178:        Log_Printf(LOG_SCC_LEVEL,"[SCC] Channel %c: Data read %02X\n",
                    179:                           ch?'B':'A',val);
                    180: 
                    181:        return val;
                    182: }
                    183: 
                    184: void scc_data_write(Uint8 ch, Uint8 val) {
                    185:        
                    186:        scc_buf[0] = val;
                    187:        
                    188:        scc[ch].rreg[R_STATUS] = RR0_TXEMPTY|RR0_RXAVAIL;
                    189: 
                    190:        Log_Printf(LOG_SCC_LEVEL,"[SCC] Channel %c: Data write %02X\n",
                    191:                           ch?'B':'A',val);
                    192: }
                    193: 
                    194: 
                    195: /* Reset functions */
                    196: static void scc_channel_reset(Uint8 ch, bool hard) {
                    197:        
                    198:        Log_Printf(LOG_SCC_LEVEL, "[SCC] Reset channel %c\n", ch?'B':'A');
                    199:        
                    200:        scc[ch].wreg[0] = 0x00;
                    201:        scc[ch].wreg[1] &= ~0xDB;
                    202:        scc[ch].wreg[3] &= ~0x01;
                    203:        scc[ch].wreg[4] |= 0x04;
                    204:        scc[ch].wreg[5] &= ~0x9E;
                    205:        scc[0].wreg[9] &= ~0x20;
                    206:        scc[1].wreg[9] &= ~0x20;
                    207:        scc[ch].wreg[10] &= ~0x9F;
                    208:        scc[ch].wreg[14] = (scc[ch].wreg[14]&~0x3C)|0x20;
                    209:        scc[ch].wreg[15] = 0xF8;
                    210:  
                    211:        scc[ch].rreg[0] = (scc[ch].rreg[0]&~0xC7)|0x44;
                    212:        scc[ch].rreg[1] = 0x06;
                    213:        scc[ch].rreg[3] = 0x00;
                    214:        scc[ch].rreg[10] = 0x00;
                    215:  
                    216:        if (hard) {
                    217:                scc[0].wreg[9] = (scc[0].wreg[9]&~0xFC)|0xC0;
                    218:                scc[1].wreg[9] = (scc[1].wreg[9]&~0xFC)|0xC0;
                    219:                scc[ch].wreg[10] = 0x00;
                    220:                scc[ch].wreg[11] = 0x08;
                    221:                scc[ch].wreg[14] = (scc[ch].wreg[14]&~0x3F)|0x20;
                    222:        }
                    223: }
                    224: 
                    225: void SCC_Reset(Uint8 ch) {
                    226:        if(ch==0 || ch==1) { // channel reset
                    227:                scc_channel_reset(ch, false);
                    228:        } else { // hard reset
                    229:                scc_channel_reset(0, true);
                    230:                scc_channel_reset(1, true);
                    231:        }
                    232: }
                    233: 
                    234: /* Register write functions */
                    235: 
                    236: void scc_write_init_command(Uint8 ch, Uint8 val) {
                    237:        
                    238: }
                    239: 
                    240: void scc_write_mode(Uint8 ch, Uint8 val) {
                    241:        if ((val&0xC0)==0xC0) {
                    242:                dma_scc_read_memory();
                    243:                scc[ch].rreg[R_STATUS] |= RR0_RXAVAIL;
                    244:        }
                    245: }
                    246: 
                    247: void scc_write_master_intr_reset(Uint8 val) {
                    248:        switch ((val>>6)&3) {
                    249:                case 1:
                    250:                        SCC_Reset(1);
                    251:                        break;
                    252:                case 2:
                    253:                        SCC_Reset(0);
                    254:                        break;
                    255:                case 3:
                    256:                        SCC_Reset(2);
                    257:                        break;
                    258:                        
                    259:                default:
                    260:                        break;
                    261:        }
                    262: }

unix.superglobalmegacorp.com

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