|
|
1.1 ! root 1: /* ! 2: * Hatari SCC serial port test ! 3: * ! 4: * Partly based on the file serport.c and mfp.h from EmuTOS: ! 5: * Copyright (C) 2013-2018 The EmuTOS development team ! 6: * ! 7: * This file is distributed under the GPL, version 2 or at your ! 8: * option any later version. See doc/license.txt for details. ! 9: */ ! 10: ! 11: #include <tos.h> ! 12: ! 13: volatile int delay_cnt; ! 14: ! 15: static void delay_loop(int loops) ! 16: { ! 17: int i; ! 18: ! 19: for (i = 0; i < loops; i++) ! 20: delay_cnt++; ! 21: } ! 22: ! 23: /* ! 24: * defines ! 25: */ ! 26: #define RESET_RECOVERY_DELAY delay_loop(8) ! 27: #define RECOVERY_DELAY delay_loop(4) ! 28: ! 29: #define SCC_BASE 0xffff8c80UL ! 30: ! 31: #define HIBYTE(x) ((unsigned char)((unsigned short)(x) >> 8)) ! 32: #define LOBYTE(x) ((unsigned char)(unsigned short)(x)) ! 33: ! 34: /* ! 35: * structures ! 36: */ ! 37: typedef struct { ! 38: unsigned char dum1; ! 39: volatile unsigned char ctl; ! 40: unsigned char dum2; ! 41: volatile unsigned char data; ! 42: } PORT; ! 43: typedef struct { ! 44: PORT portA; ! 45: PORT portB; ! 46: } SCC; ! 47: ! 48: /* ! 49: * SCC port B i/o routines ! 50: */ ! 51: static long bcostatB(void) ! 52: { ! 53: SCC *scc = (SCC *)SCC_BASE; ! 54: long rc; ! 55: ! 56: rc = (scc->portB.ctl & 0x04) ? -1L : 0L; ! 57: RECOVERY_DELAY; ! 58: ! 59: return rc; ! 60: } ! 61: ! 62: long bconoutB(unsigned char b) ! 63: { ! 64: SCC *scc = (SCC *)SCC_BASE; ! 65: ! 66: while(!bcostatB()) ! 67: ; ! 68: scc->portB.data = b; ! 69: RECOVERY_DELAY; ! 70: ! 71: return 1L; ! 72: } ! 73: ! 74: static void write_scc(PORT *port, unsigned char reg, unsigned char data) ! 75: { ! 76: port->ctl = reg; ! 77: RECOVERY_DELAY; ! 78: port->ctl = data; ! 79: RECOVERY_DELAY; ! 80: } ! 81: ! 82: static const short SCC_init_string[] = { ! 83: 0x0444, /* x16 clock mode, 1 stop bit, no parity */ ! 84: 0x0104, /* 'parity is special condition' */ ! 85: 0x0260, /* interrupt vector #s start at 0x60 (lowmem 0x180) */ ! 86: 0x03c0, /* Rx 8 bits/char, disabled */ ! 87: 0x05e2, /* Tx 8 bits/char, disabled, DTR, RTS */ ! 88: 0x0600, /* SDLC (n/a) */ ! 89: 0x0700, /* SDLC (n/a) */ ! 90: 0x0901, /* status low, vector includes status */ ! 91: 0x0a00, /* misc flags */ ! 92: 0x0b50, /* Rx/Tx clocks from baudrate generator output */ ! 93: 0x0c18, /* time const low = 24 | so rate = (24+2)*2/BR clock period */ ! 94: 0x0d00, /* time const hi = 0 | = 52/(8053976/16) => 9680 bps */ ! 95: 0x0e02, /* baudrate generator source = PCLK (8MHz) */ ! 96: 0x0e03, /* ditto + enable baudrate generator */ ! 97: 0x03c1, /* Rx 8 bits/char, enabled */ ! 98: 0x05ea, /* Tx 8 bits/char, enabled, DTR, RTS */ ! 99: 0x0f20, /* CTS interrupt enable */ ! 100: 0x0010, /* reset external/status interrupts */ ! 101: 0x0010, /* reset again (necessary, see manual) */ ! 102: 0x0117, /* interrupts for Rx, Tx, special condition; parity is special */ ! 103: 0x0901, /* status low, master interrupt disable */ ! 104: /* NOTE: change above to 0x0909 to enable interrupts! */ ! 105: 0xffff /* end of table marker */ ! 106: }; ! 107: ! 108: /* ! 109: * initialise the SCC ! 110: */ ! 111: static void init_scc(void) ! 112: { ! 113: SCC *scc = (SCC *)SCC_BASE; ! 114: const short *p; ! 115: ! 116: /* issue hardware reset */ ! 117: scc->portA.ctl = 0x09; ! 118: RECOVERY_DELAY; ! 119: scc->portA.ctl = 0xC0; ! 120: RESET_RECOVERY_DELAY; ! 121: ! 122: /* initialise channel A */ ! 123: for (p = SCC_init_string; *p >= 0; p++) ! 124: write_scc(&scc->portA,HIBYTE(*p),LOBYTE(*p)); ! 125: ! 126: /* initialise channel B */ ! 127: for (p = SCC_init_string; *p >= 0; p++) ! 128: write_scc(&scc->portB,HIBYTE(*p),LOBYTE(*p)); ! 129: ! 130: /* ! 131: * Enable routing of the SCC interrupt through the SCU like TOS does. ! 132: * Even though interrupts are not used here, other programs might ! 133: * install their own interrupt vectors and expect the interrupt ! 134: * to be available to them. ! 135: */ ! 136: //if (HAS_VME) ! 137: // *(volatile BYTE *)VME_INT_MASK |= VME_INT_SCC; ! 138: } ! 139: ! 140: int main(int argc, char *argv[]) ! 141: { ! 142: char text[] = "The quick brown fox\njumps over the lazy dog\n"; ! 143: int i; ! 144: void *sp = (void*)Super(0); ! 145: ! 146: init_scc(); ! 147: ! 148: for (i = 0; text[i] != 0; i++) ! 149: bconoutB(text[i]); ! 150: ! 151: Super(sp); ! 152: ! 153: return 0; ! 154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.