17 void ser_putchar(int c);
18 void ser_puts(const char *s);
19 void ser_printf(const char *fmt, ...);
21 static int setup_serial(int sdev);
23 static int logfd = -1, orig_fd1 = -1;
24 static int log_isfile;
26 int init_logger(const char *fname)
30 if(logfd != -1) return -1;
33 if(strcasecmp(fname, "CON") == 0) {
37 if((logfd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
38 fprintf(stderr, "init_logger: failed to open %s: %s\n", fname, strerror(errno));
42 if(sscanf(fname, "COM%d", &sdev) == 1) {
43 setup_serial(sdev - 1);
56 void stop_logger(void)
69 freopen("CON", "w", stdout);
70 freopen("CON", "w", stderr);
74 int print_tail(const char *fname)
81 if(!log_isfile) return 0;
83 printf("demo_abort called. see demo.log for details. Last lines:\n\n");
85 if(!(fp = fopen(fname, "rb"))) {
89 lineoffs[nlines++] = 0;
90 while(fgets(buf, sizeof buf, fp)) {
91 lineoffs[nlines & 0xf] = ftell(fp);
96 long offs = lineoffs[nlines & 0xf];
97 fseek(fp, offs, SEEK_SET);
99 while((c = fgetc(fp)) != -1) {
106 #define UART1_BASE 0x3f8
107 #define UART2_BASE 0x2f8
117 #define DIV_9600 (115200 / 9600)
118 #define DIV_38400 (115200 / 38400)
119 #define LCTL_8N1 0x03
120 #define LCTL_DLAB 0x80
121 #define FIFO_ENABLE_CLEAR 0x07
122 #define MCTL_DTR_RTS_OUT2 0x0b
123 #define LST_TRIG_EMPTY 0x20
125 static unsigned int iobase;
127 static int setup_serial(int sdev)
129 if(sdev < 0 || sdev > 1) {
132 iobase = sdev == 0 ? UART1_BASE : UART2_BASE;
134 /* set clock divisor */
135 outp(iobase | UART_LCTL, LCTL_DLAB);
136 outp(iobase | UART_DIVLO, DIV_9600 & 0xff);
137 outp(iobase | UART_DIVHI, DIV_9600 >> 8);
139 outp(iobase | UART_LCTL, LCTL_8N1);
140 /* assert RTS and DTR */
141 outp(iobase | UART_MCTL, MCTL_DTR_RTS_OUT2);
145 void ser_putchar(int c)
151 while((inp(iobase | UART_LSTAT) & LST_TRIG_EMPTY) == 0);
152 outp(iobase | UART_DATA, c);
155 void ser_puts(const char *s)
162 void ser_printf(const char *fmt, ...)
168 vsprintf(buf, fmt, ap);