Annotation of previous_trunk/src/scc.c, revision 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.