aboutsummaryrefslogtreecommitdiff
path: root/dlog.h
blob: 3f853e71b33981ef7fb501fabbf11fd0d5ed2f46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * VBMouse - printf & logging routines
 * Copyright (C) 2022 Javier S. Pedro
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef DLOG_H
#define DLOG_H

#include <conio.h>

// Customizable defines
/** If 0, these routines become nops */
#define ENABLE_DLOG 0
/** 1 means target serial port, 0 means target IO port. */
#define DLOG_TARGET_SERIAL 1
/** IO port to target.
 *  VirtualBox uses 0x504, Bochs, DOSBox and descendants use 0xE9.
 *  When using DLOG_TARGET_SERIAL, use desired UART IO base port. (e.g. COM1 = 0x3F8). */
#define DLOG_TARGET_PORT 0x3f8

// End of customizable defines

#if ENABLE_DLOG

/** Initializes the debug log port. */
static void dlog_init();

/** Logs a single character to the debug message IO port. */
static inline void dlog_putc(char c);

#if DLOG_TARGET_SERIAL

static void dlog_init()
{
	// Comes straight from https://wiki.osdev.org/Serial_Ports#Initialization
	outp(DLOG_TARGET_PORT + 1, 0x00);    // Disable all interrupts
	outp(DLOG_TARGET_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
	outp(DLOG_TARGET_PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
	outp(DLOG_TARGET_PORT + 1, 0x00);    //                  (hi byte)
	outp(DLOG_TARGET_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
	outp(DLOG_TARGET_PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
	outp(DLOG_TARGET_PORT + 4, 0x03);    // RTS/DSR set, IRQs disabled
}

static inline void dlog_putc(char c)
{
	while (!(inp(DLOG_TARGET_PORT + 5) & 0x20));
	outp(DLOG_TARGET_PORT, c);
}

#else /* DLOG_TARGET_SERIAL */

static void dlog_init()
{
}

static inline void dlog_putc(char c)
{
	outp(DLOG_TARGET_PORT, c);
}



#endif /* DLOG_TARGET_SERIAL */

static void dlog_endline(void)
{
	dlog_putc('\n');
}

/** Print string to log */
static void dlog_print(const char *s)
{
	char c;
	while (c = *s++) {
		dlog_putc(c);
	}
}

/** Print + newline */
static void dlog_puts(const char *s)
{
	dlog_print(s);
	dlog_endline();
}

/** Print unsigned number with base */
static void dlog_printub(unsigned int num, int base)
{
	char buf[8];
	int i = 0;

	do {
		int digit = num % base;

		if (digit < 10) {
			buf[i] = '0' + digit;
		} else {
			buf[i] = 'a' + (digit - 10);
		}

		i++;
		num /= base;
	} while (num > 0 && i < sizeof(buf));

	while (i--) {
		dlog_putc(buf[i]);
	}
}

/** Print signed number with base */
static void dlog_printdb(int num, int base)
{
	unsigned int unum;

	// TODO
	if (num < 0) {
		dlog_putc('-');
		unum = -num;
	} else {
		unum = num;
	}

	dlog_printub(unum, base);
}

/** Print unsigned number in base 16. */
static void dlog_printu(unsigned int num)
{
	dlog_printub(num, 10);
}

/** Print unsigned number in base 10. */
static void dlog_printx(unsigned int num)
{
	dlog_printub(num, 16);
}

/** Print signed number in base 10. */
static void dlog_printd(int num)
{
	dlog_printdb(num, 10);
}

#else /* ENABLE_DLOG */

#define dlog_init()
#define dlog_putc(c)
#define dlog_endline()
#define dlog_print(s)
#define dlog_puts(s)
#define dlog_printub(n,b)
#define dlog_printdb(n,b)
#define dlog_printx(n)
#define dlog_printu(n)
#define dlog_printd(n)


#endif /* ENABLE_DLOG */

#endif /* DLOG_H */