#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#define pstruct struct __attribute__((packed))

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;

static inline void INT(int n) { asm volatile("int %0" : : "i"(n)); }

static inline void outb(u16 port, u8 value) {
  asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}
static inline void outw(u16 port, u16 value) {
  asm volatile("outw %0, %1" : : "a"(value), "Nd"(port));
}
static inline void outd(u16 port, u32 value) {
  asm volatile("outl %0, %1" : : "a"(value), "Nd"(port));
}

static inline u8 inb(u16 port) {
  u8 value;
  asm volatile("inb %w1, %b0" : "=a"(value) : "Nd"(port) : "memory");
  return value;
}
static inline u16 inw(u16 port) {
  u16 value;
  asm volatile("inw %w1, %0" : "=a"(value) : "Nd"(port) : "memory");
  return value;
}
static inline u32 ind(u16 port) {
  u32 value;
  asm volatile("inl %w1, %0" : "=a"(value) : "Nd"(port) : "memory");
  return value;
}

void *memcpy(void *dst, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
void *memmove(void *dst, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void hang();
extern u64 hhdm_offset;
