Updated hello.c from putch() to printf().
[pdp11-modern-c] / pdp11 / pdp11_slu.c
CommitLineData
202004d5
AT
1// (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
2// See License.txt file for copyright and license details.
3
4#include <stdarg.h>
5#include <stdint.h>
6#include "pdp11.h"
7
8/*
9 * Polled console I/O
10 */
11
12void
13putch(uint16_t c)
14{
15 while(!(GET(CONSXCSR,SLUXCSR_XMTRDY))) continue;
16 CONSXBUF = c;
17}
18
19uint16_t
20getch(void)
21{
22 while(!(GET(CONSRCSR,SLURCSR_RCVRDY))) continue;
23 return CONSRBUF;
24}
25
26
27/*
28 * Helper functions for use with console IO
29 */
30
31void
32print_string(const char * string)
33{
34 while (*string != '\0') {
35 putch(*string);
36 string++;
37 }
38}
39
40char
41digit_to_ascii(uint16_t digit)
42{
43 if (digit > 15) {
44 print_string("ERROR: Out of range in digit_to_ascii()\r\n");
45 // TODO: How do I want to handle runtime errors?
46 return 0;
47 } else if (digit > 9) {
48 digit -= 10;
49 digit += 'a';
50 return digit;
51 } else {
52 digit += '0';
53 return digit;
54 }
55}
56
57void
58print_uint16_in_octal(uint16_t number)
59{
60 char output[7]; // +6 for digits; +1 for null-term
61 for (int i = 5; i >= 0; i--) {
62 output[i] = digit_to_ascii(number % 8);
63 number = number / 8;
64 }
65 output[6] = '\0';
66 putch('0');
67 print_string(output);
68}
69
70void
71printf(const char * format, ...)
72{
73 va_list ap;
74 va_start(ap, format);
75 while (*format) {
76 switch (*format) {
77 case '%':
78 format++;
79 switch (*format) {
80 case 's':
81 {
82 char * s = va_arg(ap, char *);
83 print_string(s);
84 break;
85 }
86 case 'o':
87 {
88 uint16_t u = va_arg(ap, unsigned int);
89 print_uint16_in_octal(u);
90 break;
91 }
92 default:
93 /* Put it back and look innocent. */
94 putch('%');
95 putch(*format);
96 break;
97 }
98 break;
99 case '\\':
100 format++;
101 switch (*format) {
102 case 'n':
103 print_string("\r\n");
104 break;
105 case 't':
106 putch('\t');
107 break;
108 case '%':
109 putch('%');
110 break;
111 case '\\':
112 putch('\\');
113 break;
114 default:
115 /* Maybe this escape wasn't meant for us. */
116 putch('\\');
117 putch(*format);
118 break;
119 }
120 break;
121 case '\n':
122 print_string("\r\n");
123 break;
124 default:
125 putch(*format);
126 break;
127 }
128 format++;
129 }
130 va_end(ap);
131}
132