libws libws
WSwan hardware library for the Wonderful toolchain
Loading...
Searching...
No Matches
ia16.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022, 2023 Adrian "asie" Siekierka
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 *
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 *
20 * 3. This notice may not be removed or altered from any source distribution.
21 */
22
26
27#ifndef IA16_H_
28#define IA16_H_
29
34
38#define IA16_INT_DIV 0
42#define IA16_INT_STEP 1
46#define IA16_INT_NMI 2
50#define IA16_INT_BREAK 3
54#define IA16_INT_INTO 4
58#define IA16_INT_BOUNDS 5
59
63#define IA16_FLAG_CF 0x0001
67#define IA16_FLAG_PF 0x0004
71#define IA16_FLAG_AF 0x0010
75#define IA16_FLAG_ZF 0x0040
79#define IA16_FLAG_SF 0x0080
83#define IA16_FLAG_TF 0x0100
87#define IA16_FLAG_IF 0x0200
91#define IA16_FLAG_DF 0x0400
95#define IA16_FLAG_OF 0x0800
99#define IA16_FLAG_MD 0x8000
100
101#ifdef __ASSEMBLER__
102
103#ifdef __IA16_CMODEL_IS_FAR_TEXT
107#define IA16_RET retf
108#define IA16_CALL_STACK_OFFSET(n) ((n)+4)
109
113.macro IA16_CALL tgt:req
114 .reloc .+3, R_386_SEG16, "\tgt\‍()!"
115 call 0:\tgt
116.endm
122.macro IA16_CALL_LOCAL tgt:req
123 push cs
124 call \tgt
125.endm
129.macro IA16_JMP tgt:req
130 .reloc .+3, R_386_SEG16, "\tgt\‍()!"
131 jmp 0:\tgt
132.endm
133#else
137#define IA16_RET ret
138#define IA16_CALL_STACK_OFFSET(n) ((n)+2)
139
143.macro IA16_CALL tgt:req
144 call \tgt
145.endm
151.macro IA16_CALL_LOCAL tgt:req
152 call \tgt
153.endm
157.macro IA16_JMP tgt:req
158 jmp \tgt
159.endm
160#endif
161
162#else
163
164#include <stdbool.h>
165#include <stdint.h>
166
170#define FP_SEG(x) __builtin_ia16_selector ((uint16_t) (((uint32_t) ((void __far*) (x))) >> 16))
171
175#define FP_OFF(x) __builtin_ia16_FP_OFF ((x))
176
180#define MK_FP(seg, ofs) ((void __far*) (((uint16_t) ofs) | (((uint32_t) ((uint16_t) seg)) << 16)))
181#define _CS ia16_get_cs()
182#define _DS ia16_get_ds()
183#define _ES ia16_get_es()
184#define _SS ia16_get_ss()
185
189static inline __segment ia16_get_cs() {
190 __segment result;
191 __asm (
192 "mov %%cs, %0"
193 : "=r" (result)
194 );
195 return result;
196}
197
201#define ia16_get_ds __builtin_ia16_near_data_segment
202
206static inline __segment ia16_get_es() {
207 __segment result;
208 __asm (
209 "mov %%es, %0"
210 : "=r" (result)
211 );
212 return result;
213}
214
218#define ia16_get_ss __builtin_ia16_ss
219
223static inline uint16_t ia16_get_sp() {
224 uint16_t result;
225 __asm (
226 "mov %%sp, %0"
227 : "=r" (result)
228 );
229 return result;
230}
231
235static inline uint16_t ia16_get_flags() {
236 uint16_t result;
237 __asm volatile (
238 "pushf\npop %0"
239 : "=r" (result)
240 );
241 return result;
242}
243
247static inline void ia16_set_flags(uint16_t flags) {
248 __asm volatile (
249 "push %0\npopf"
250 : : "r" (flags)
251 : "cc"
252 );
253}
254
261static inline uint8_t inportb(uint8_t port) {
262 uint8_t result;
263 __asm volatile (
264 "inb %1, %0"
265 : "=Ral" (result)
266 : "Nd" ((uint16_t) port)
267 );
268 return result;
269}
270
277static inline uint16_t inportw(uint8_t port) {
278 uint16_t result;
279 __asm volatile (
280 "inw %1, %0"
281 : "=a" (result)
282 : "Nd" ((uint16_t) port)
283 );
284 return result;
285}
286
293static inline void outportb(uint8_t port, uint8_t value) {
294 __asm volatile (
295 "outb %0, %1"
296 :
297 : "Ral" (value), "Nd" ((uint16_t) port)
298 );
299}
300
307static inline void outportw(uint8_t port, uint16_t value) {
308 __asm volatile (
309 "outw %0, %1"
310 :
311 : "a" (value), "Nd" ((uint16_t) port)
312 );
313}
314
315#define ia16_port_inb(port) inportb(port)
316#define ia16_port_inw(port) inportw(port)
317#define ia16_port_outb(value, port) outportb(port, value)
318#define ia16_port_outw(value, port) outportw(port, value)
319
323static inline void ia16_halt(void) {
324 __asm volatile ("hlt");
325}
326
330static inline void ia16_enable_irq(void) {
331 __asm volatile ("sti");
332}
333
337static inline void ia16_disable_irq(void) {
338 __asm volatile ("cli");
339}
340
346#define ia16_critical(...) \
347 do { \
348 ia16_disable_irq(); \
349 __VA_ARGS__; \
350 ia16_enable_irq(); \
351 } while(0)
352
353typedef __attribute__((interrupt)) void __far (*ia16_int_handler_t)(void);
354
361void ia16_int_set_handler(uint8_t idx, ia16_int_handler_t handler);
362
363#endif
364
366
367#endif /* IA16_H_ */
static void outportw(uint8_t port, uint16_t value)
Write a word to the given port.
Definition ia16.h:307
static void outportb(uint8_t port, uint8_t value)
Write a byte to the given port.
Definition ia16.h:293
static void ia16_disable_irq(void)
Disable jumping to interrupt vectors on an interrupt being received by the CPU.
Definition ia16.h:337
static uint8_t inportb(uint8_t port)
Read a byte from the given port.
Definition ia16.h:261
static uint16_t ia16_get_flags()
Retrieve the current value of the CPU flag register.
Definition ia16.h:235
static void ia16_enable_irq(void)
Enable jumping to interrupt vectors on an interrupt being received by the CPU.
Definition ia16.h:330
static __segment ia16_get_cs()
Retrieve the current value of the code segment CS.
Definition ia16.h:189
static uint16_t ia16_get_sp()
Retrieve the current value of the stack pointer SP.
Definition ia16.h:223
void ia16_int_set_handler(uint8_t idx, ia16_int_handler_t handler)
Register a CPU interrupt handler.
static uint16_t inportw(uint8_t port)
Read a word from the given port.
Definition ia16.h:277
static __segment ia16_get_es()
Retrieve the current value of the data segment ES.
Definition ia16.h:206
void __far(* ia16_int_handler_t)(void)
Definition ia16.h:353
static void ia16_halt(void)
Halt the CPU until an interrupt is received.
Definition ia16.h:323
static void ia16_set_flags(uint16_t flags)
Set the CPU flag register to a new value.
Definition ia16.h:247