large refactor of ioe
This commit is contained in:
parent
21ce8d8014
commit
1722e218ef
10
am/am.h
10
am/am.h
|
@ -30,10 +30,10 @@ enum {
|
|||
_EVENT_SYSCALL,
|
||||
};
|
||||
|
||||
#define _PROT_NONE 1
|
||||
#define _PROT_READ 2
|
||||
#define _PROT_WRITE 4
|
||||
#define _PROT_EXEC 8
|
||||
#define _PROT_NONE 1 // no access
|
||||
#define _PROT_READ 2 // can read
|
||||
#define _PROT_WRITE 4 // can write
|
||||
#define _PROT_EXEC 8 // can execute
|
||||
|
||||
// A memory area of [@start, @end)
|
||||
typedef struct _Area {
|
||||
|
@ -91,7 +91,7 @@ void _prot_switch(_Protect *p);
|
|||
void _map(_Protect *p, void *va, void *pa);
|
||||
void _protect(_Protect *p, void *va, int len, int prot);
|
||||
_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack,
|
||||
void *entry, void *args);
|
||||
void (*entry)(void *), void *args);
|
||||
|
||||
// ================= Multi-Processor Extension (MPE) =================
|
||||
|
||||
|
|
127
am/amdev.h
127
am/amdev.h
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
// =========================== AM Devices ============================
|
||||
// ((_Device *)dev)->id
|
||||
|
||||
#define _DEV_PERFCNT 0x0000ac01
|
||||
#define _DEV_INPUT 0x0000ac02
|
||||
#define _DEV_TIMER 0x0000ac03
|
||||
|
@ -11,74 +14,74 @@
|
|||
#define _DEV_ATA0 0x00000dd0
|
||||
#define _DEV_ATA1 0x00000dd1
|
||||
|
||||
// Performance Counter (0000ac01)
|
||||
// ================= Device Register Specifications ==================
|
||||
|
||||
// Input (0000ac02)
|
||||
// ------------- _DEV_INPUT: AM Input Devices (0000ac02) -------------
|
||||
#define _DEVREG_INPUT_KBD 1
|
||||
#define _KEYS(_) \
|
||||
_(ESCAPE) \
|
||||
_(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \
|
||||
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) \
|
||||
_(MINUS) _(EQUALS) _(BACKSPACE) \
|
||||
_(TAB) _(Q) _(W) _(E) _(R) _(T) _(Y) _(U) _(I) _(O) _(P) \
|
||||
_(LEFTBRACKET) _(RIGHTBRACKET) _(BACKSLASH) \
|
||||
_(CAPSLOCK) _(A) _(S) _(D) _(F) _(G) _(H) _(J) _(K) _(L) \
|
||||
_(SEMICOLON) _(APOSTROPHE) _(RETURN) \
|
||||
_(LSHIFT) _(Z) _(X) _(C) _(V) _(B) _(N) _(M) \
|
||||
_(COMMA) _(PERIOD) _(SLASH) _(RSHIFT) \
|
||||
_(LCTRL) _(APPLICATION) _(LALT) _(SPACE) _(RALT) _(RCTRL) \
|
||||
_(UP) _(DOWN) _(LEFT) _(RIGHT) _(INSERT) _(DELETE) \
|
||||
_(HOME) _(END) _(PAGEUP) _(PAGEDOWN)
|
||||
#define _KEY_NAME(k) _KEY_##k,
|
||||
enum {
|
||||
_KEY_NONE = 0,
|
||||
_KEYS(_KEY_NAME)
|
||||
};
|
||||
typedef struct {
|
||||
int keydown; // is keydown ? 1 : 0
|
||||
int keycode; // key code _KEY_XXX
|
||||
} _KbdReg;
|
||||
|
||||
#define _DEV_INPUT_REG_KBD 1
|
||||
#define _KEYS(_) \
|
||||
_(ESCAPE) \
|
||||
_(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \
|
||||
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) \
|
||||
_(MINUS) _(EQUALS) _(BACKSPACE) \
|
||||
_(TAB) _(Q) _(W) _(E) _(R) _(T) _(Y) _(U) _(I) _(O) _(P) \
|
||||
_(LEFTBRACKET) _(RIGHTBRACKET) _(BACKSLASH) \
|
||||
_(CAPSLOCK) _(A) _(S) _(D) _(F) _(G) _(H) _(J) _(K) _(L) \
|
||||
_(SEMICOLON) _(APOSTROPHE) _(RETURN) \
|
||||
_(LSHIFT) _(Z) _(X) _(C) _(V) _(B) _(N) _(M) \
|
||||
_(COMMA) _(PERIOD) _(SLASH) _(RSHIFT) \
|
||||
_(LCTRL) _(APPLICATION) _(LALT) _(SPACE) _(RALT) _(RCTRL) \
|
||||
_(UP) _(DOWN) _(LEFT) _(RIGHT) _(INSERT) _(DELETE) \
|
||||
_(HOME) _(END) _(PAGEUP) _(PAGEDOWN)
|
||||
#define _KEY_NAME(k) _KEY_##k,
|
||||
enum {
|
||||
_KEY_NONE = 0,
|
||||
_KEYS(_KEY_NAME)
|
||||
};
|
||||
// ----------- _DEV_TIMER: AM Real Time Clock (0000ac03) -------------
|
||||
#define _DEVREG_TIMER_UPTIME 1
|
||||
typedef struct {
|
||||
uint32_t hi; // high 32bit of uptime (ms)
|
||||
uint32_t lo; // low 32bit of uptime (ms)
|
||||
} _UptimeReg;
|
||||
|
||||
// Timer (0000ac03)
|
||||
#define _DEVREG_TIMER_DATE 2
|
||||
typedef struct {
|
||||
int year, month, day; // date
|
||||
int hour, minute, second; // time
|
||||
} _RTCReg;
|
||||
|
||||
typedef struct _TimerUptime {
|
||||
uint32_t hi, lo;
|
||||
} _Dev_Timer_Uptime;
|
||||
#define _DEV_TIMER_REG_UPTIME 1
|
||||
typedef struct _TimerRTC {
|
||||
int year, month, day, hour, minute, second;
|
||||
} _Dev_Timer_RTC;
|
||||
#define _DEV_TIMER_REG_DATE 2
|
||||
// ----------- _DEV_VIDEO: AM Video Controller (0000ac04) ------------
|
||||
#define _DEVREG_VIDEO_INFO 1
|
||||
typedef struct {
|
||||
int32_t width, height; // screen size
|
||||
} _VideoInfoReg;
|
||||
|
||||
// Video (0000ac04)
|
||||
#define _DEVREG_VIDEO_FBCTL 2
|
||||
typedef struct {
|
||||
int x, y; // draw to (@x, @y)
|
||||
uint32_t *pixels; // @pixels: @w*@h pixels to draw
|
||||
int w, h; // @pixels[i * w + j] is 00RRGGBB
|
||||
int sync; // @sync ? sync screen : do nothing
|
||||
} _FBCtlReg;
|
||||
|
||||
typedef struct _VideoInfo {
|
||||
int32_t width, height;
|
||||
} _Dev_Video_Info;
|
||||
#define _DEV_VIDEO_REG_INFO 1
|
||||
typedef struct _Video_FBCtl {
|
||||
int x, y, w, h, sync;
|
||||
uint32_t *pixels;
|
||||
} _Dev_Video_FBCtl;
|
||||
#define _DEV_VIDEO_REG_FBCTL 2
|
||||
// -------- _DEV_PCICONF: PCI Configuration Space (00000080) ---------
|
||||
#define _DEVREG_PCICONF(bus, slot, func, offset) \
|
||||
((uint32_t)( 1) << 31) | ((uint32_t)( bus) << 16) | \
|
||||
((uint32_t)(slot) << 11) | ((uint32_t)(func) << 8) | (offset)
|
||||
|
||||
// PCI Configuration (00000080)
|
||||
|
||||
static inline uint32_t
|
||||
_DEV_PCICONF_REG(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
|
||||
return ((uint32_t)1 << 31)
|
||||
| ((uint32_t)bus << 16)
|
||||
| ((uint32_t)slot << 11)
|
||||
| ((uint32_t)func << 8)
|
||||
| offset;
|
||||
}
|
||||
|
||||
// ATA (00000dd0 -- 00000dd1)
|
||||
|
||||
#define _DEV_ATA_REG_DATA 0
|
||||
#define _DEV_ATA_REG_FEATURE 1
|
||||
#define _DEV_ATA_REG_NSECT 2
|
||||
#define _DEV_ATA_REG_SECT 3
|
||||
#define _DEV_ATA_REG_CYLOW 4
|
||||
#define _DEV_ATA_REG_CYHIGH 5
|
||||
#define _DEV_ATA_REG_DRIVE 6
|
||||
#define _DEV_ATA_REG_STATUS 7
|
||||
// ------ _DEV_ATAx: ATA Disk Controller (00000dd0 -- 00000dd1) ------
|
||||
#define _DEVREG_ATA_DATA 0
|
||||
#define _DEVREG_ATA_FEATURE 1
|
||||
#define _DEVREG_ATA_NSECT 2
|
||||
#define _DEVREG_ATA_SECT 3
|
||||
#define _DEVREG_ATA_CYLOW 4
|
||||
#define _DEVREG_ATA_CYHIGH 5
|
||||
#define _DEVREG_ATA_DRIVE 6
|
||||
#define _DEVREG_ATA_STATUS 7
|
||||
|
||||
#endif
|
||||
|
|
|
@ -223,7 +223,7 @@ _RegSet *_make(_Area stack, void *entry, void *arg) {
|
|||
regs->cs = KSEL(SEG_KCODE);
|
||||
regs->ds = regs->es = regs->ss = KSEL(SEG_KDATA);
|
||||
regs->eip = (uint32_t)entry;
|
||||
regs->eflags = FL_IF;
|
||||
regs->eflags = 0;
|
||||
regs->esp0 -= 4;
|
||||
*((void**)(regs->esp0)) = arg; // argument
|
||||
regs->esp0 -= 4;
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#include <am.h>
|
||||
#include <amdev.h>
|
||||
|
||||
struct VBEInfo {
|
||||
uint16_t attributes;
|
||||
uint8_t window_a;
|
||||
uint8_t window_b;
|
||||
uint16_t granularity;
|
||||
uint16_t window_size;
|
||||
uint16_t segment_a;
|
||||
uint16_t segment_b;
|
||||
uint32_t win_func_ptr;
|
||||
uint16_t pitch;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint8_t w_char;
|
||||
uint8_t y_char;
|
||||
uint8_t planes;
|
||||
uint8_t bpp;
|
||||
uint8_t banks;
|
||||
uint8_t memory_model;
|
||||
uint8_t bank_size;
|
||||
uint8_t image_pages;
|
||||
uint8_t reserved0;
|
||||
|
||||
uint8_t red_mask;
|
||||
uint8_t red_position;
|
||||
uint8_t green_mask;
|
||||
uint8_t green_position;
|
||||
uint8_t blue_mask;
|
||||
uint8_t blue_position;
|
||||
uint8_t reserved_mask;
|
||||
uint8_t reserved_position;
|
||||
uint8_t direct_color_attributes;
|
||||
|
||||
uint32_t framebuffer;
|
||||
uint32_t off_screen_mem_off;
|
||||
uint16_t off_screen_mem_size;
|
||||
uint8_t reserved1[206];
|
||||
} __attribute__ ((packed));
|
||||
typedef struct VBEInfo VBEInfo;
|
||||
|
||||
static inline uint32_t pixel(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
static uint8_t R(uint32_t p) { return p >> 16; }
|
||||
static uint8_t G(uint32_t p) { return p >> 8; }
|
||||
static uint8_t B(uint32_t p) { return p; }
|
||||
|
||||
static struct FBPixel {
|
||||
uint8_t b, g, r;
|
||||
} __attribute__ ((packed)) *fb;
|
||||
typedef struct FBPixel FBPixel;
|
||||
static int W, H;
|
||||
|
||||
void vga_init() {
|
||||
VBEInfo *info = (VBEInfo *)0x00004000;
|
||||
W = info->width;
|
||||
H = info->height;
|
||||
fb = (FBPixel*)(info->framebuffer);
|
||||
}
|
||||
|
||||
size_t video_read(uintptr_t reg, void *buf, size_t size) {
|
||||
switch(reg) {
|
||||
case _DEVREG_VIDEO_INFO: {
|
||||
_VideoInfoReg *info = (_VideoInfoReg *)buf;
|
||||
info->width = W;
|
||||
info->height = H;
|
||||
return sizeof(_VideoInfoReg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t video_write(uintptr_t reg, void *buf, size_t size) {
|
||||
switch(reg) {
|
||||
case _DEVREG_VIDEO_FBCTL: {
|
||||
_FBCtlReg *ctl = (_FBCtlReg *)buf;
|
||||
int x = ctl->x, y = ctl->y, w = ctl->w, h = ctl->h;
|
||||
uint32_t *pixels = ctl->pixels;
|
||||
int len = (x + w >= W) ? W - x : w;
|
||||
FBPixel *v;
|
||||
for (int j = 0; j < h; j ++) {
|
||||
if (y + j < H) {
|
||||
v = &fb[x + (j + y) * W];
|
||||
for (int i = 0; i < len; i ++, v ++) {
|
||||
uint32_t p = pixels[i];
|
||||
v->r = R(p); v->g = G(p); v->b = B(p);
|
||||
}
|
||||
}
|
||||
pixels += w;
|
||||
}
|
||||
if (ctl->sync) {
|
||||
// do nothing, hardware syncs.
|
||||
}
|
||||
return sizeof(size);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -14,64 +14,9 @@ static inline uint64_t rdtsc() {
|
|||
|
||||
extern "C" {
|
||||
|
||||
struct VBEInfo {
|
||||
uint16_t attributes;
|
||||
uint8_t window_a;
|
||||
uint8_t window_b;
|
||||
uint16_t granularity;
|
||||
uint16_t window_size;
|
||||
uint16_t segment_a;
|
||||
uint16_t segment_b;
|
||||
uint32_t win_func_ptr;
|
||||
uint16_t pitch;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint8_t w_char;
|
||||
uint8_t y_char;
|
||||
uint8_t planes;
|
||||
uint8_t bpp;
|
||||
uint8_t banks;
|
||||
uint8_t memory_model;
|
||||
uint8_t bank_size;
|
||||
uint8_t image_pages;
|
||||
uint8_t reserved0;
|
||||
|
||||
uint8_t red_mask;
|
||||
uint8_t red_position;
|
||||
uint8_t green_mask;
|
||||
uint8_t green_position;
|
||||
uint8_t blue_mask;
|
||||
uint8_t blue_position;
|
||||
uint8_t reserved_mask;
|
||||
uint8_t reserved_position;
|
||||
uint8_t direct_color_attributes;
|
||||
|
||||
uint32_t framebuffer;
|
||||
uint32_t off_screen_mem_off;
|
||||
uint16_t off_screen_mem_size;
|
||||
uint8_t reserved1[206];
|
||||
} __attribute__ ((packed));
|
||||
extern void vga_init();
|
||||
|
||||
static inline uint32_t pixel(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
static uint8_t R(uint32_t p) { return p >> 16; }
|
||||
static uint8_t G(uint32_t p) { return p >> 8; }
|
||||
static uint8_t B(uint32_t p) { return p; }
|
||||
|
||||
static struct FBPixel {
|
||||
uint8_t b, g, r;
|
||||
} __attribute__ ((packed)) *fb;
|
||||
static int W, H;
|
||||
|
||||
static void vga_init() {
|
||||
VBEInfo *info = reinterpret_cast<VBEInfo*>(0x00004000);
|
||||
W = info->width;
|
||||
H = info->height;
|
||||
fb = reinterpret_cast<FBPixel*>(info->framebuffer);
|
||||
}
|
||||
|
||||
static _Dev_Timer_RTC boot_date;
|
||||
static _RTCReg boot_date;
|
||||
static int read_rtc(int reg) {
|
||||
outb(0x70, reg);
|
||||
int ret = inb(0x71);
|
||||
|
@ -107,7 +52,7 @@ static uint32_t estimate_freq() {
|
|||
return freq;
|
||||
}
|
||||
|
||||
static void get_date(_Dev_Timer_RTC *rtc) {
|
||||
static void get_date(_RTCReg *rtc) {
|
||||
int tmp;
|
||||
do {
|
||||
rtc->second = read_rtc(0);
|
||||
|
@ -116,7 +61,7 @@ static void get_date(_Dev_Timer_RTC *rtc) {
|
|||
rtc->day = read_rtc(7);
|
||||
rtc->month = read_rtc(8);
|
||||
rtc->year = read_rtc(9) + 2000;
|
||||
tmp = read_rtc(0);
|
||||
tmp = read_rtc(0);
|
||||
} while (tmp != rtc->second);
|
||||
}
|
||||
|
||||
|
@ -190,7 +135,7 @@ static size_t input_read(uintptr_t reg, void *buf, size_t size) {
|
|||
ret = _KEY_NONE;
|
||||
} else {
|
||||
if (status & 0x20) { // mouse
|
||||
ret = upevent(_KEY_NONE);
|
||||
ret = _KEY_NONE;
|
||||
} else {
|
||||
int code = inb(0x60) & 0xff;
|
||||
|
||||
|
@ -212,57 +157,18 @@ static size_t input_read(uintptr_t reg, void *buf, size_t size) {
|
|||
|
||||
static size_t timer_read(uintptr_t reg, void *buf, size_t size) {
|
||||
switch (reg) {
|
||||
case _DEV_TIMER_REG_UPTIME: {
|
||||
case _DEVREG_TIMER_UPTIME: {
|
||||
uint64_t tsc = rdtsc() - uptsc;
|
||||
uint32_t mticks = (tsc >> 20);
|
||||
uint32_t ms = mticks * 1000 / freq_mhz;
|
||||
_Dev_Timer_Uptime *uptime = (_Dev_Timer_Uptime *)buf;
|
||||
_UptimeReg *uptime = (_UptimeReg *)buf;
|
||||
uptime->hi = 0;
|
||||
uptime->lo = ms;
|
||||
return sizeof(_Dev_Timer_Uptime);
|
||||
return sizeof(_UptimeReg);
|
||||
}
|
||||
case _DEV_TIMER_REG_DATE: {
|
||||
get_date((_Dev_Timer_RTC *)buf);
|
||||
return sizeof(_Dev_Timer_RTC);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t video_read(uintptr_t reg, void *buf, size_t size) {
|
||||
switch(reg) {
|
||||
case _DEV_VIDEO_REG_INFO: {
|
||||
_Dev_Video_Info *info = (_Dev_Video_Info *)buf;
|
||||
info->width = W;
|
||||
info->height = H;
|
||||
return sizeof(_Dev_Video_Info);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t video_write(uintptr_t reg, void *buf, size_t size) {
|
||||
switch(reg) {
|
||||
case _DEV_VIDEO_REG_FBCTL: {
|
||||
_Dev_Video_FBCtl *ctl = (_Dev_Video_FBCtl *)buf;
|
||||
int x = ctl->x, y = ctl->y, w = ctl->w, h = ctl->h;
|
||||
uint32_t *pixels = ctl->pixels;
|
||||
int len = (x + w >= W) ? W - x : w;
|
||||
FBPixel *v;
|
||||
for (int j = 0; j < h; j ++) {
|
||||
if (y + j < H) {
|
||||
v = &fb[x + (j + y) * W];
|
||||
for (int i = 0; i < len; i ++, v ++) {
|
||||
uint32_t p = pixels[i];
|
||||
v->r = R(p); v->g = G(p); v->b = B(p);
|
||||
}
|
||||
}
|
||||
pixels += w;
|
||||
}
|
||||
if (ctl->sync) {
|
||||
// do nothing, hardware syncs.
|
||||
}
|
||||
return sizeof(size);
|
||||
case _DEVREG_TIMER_DATE: {
|
||||
get_date((_RTCReg *)buf);
|
||||
return sizeof(_RTCReg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -279,6 +185,9 @@ static size_t hd_write(uintptr_t reg, void *buf, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t video_read(uintptr_t reg, void *buf, size_t size);
|
||||
size_t video_write(uintptr_t reg, void *buf, size_t size);
|
||||
|
||||
static _Device x86_dev[] = {
|
||||
{_DEV_INPUT, "8279 Keyboard Controller", input_read, nullptr},
|
||||
{_DEV_TIMER, "Dummy Timer", timer_read, nullptr},
|
||||
|
|
|
@ -102,7 +102,7 @@ void *_query(_Protect *p, void *va, int *prot) {
|
|||
void _unmap(_Protect *p, void *va) {
|
||||
}
|
||||
|
||||
_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) {
|
||||
_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, void (*entry)(void *), void *args) {
|
||||
_RegSet *regs = (_RegSet*)kstack.start;
|
||||
regs->cs = USEL(SEG_UCODE);
|
||||
regs->ds = regs->es = regs->ss = USEL(SEG_UDATA);
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#define __KLIB_H__
|
||||
|
||||
#include <am.h>
|
||||
#include <amdev.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -16,7 +15,7 @@ extern "C" {
|
|||
// am devices
|
||||
|
||||
uint32_t uptime();
|
||||
void gettimeofday(_Dev_Timer_RTC *rtc);
|
||||
void gettimeofday(void *rtc);
|
||||
int read_key();
|
||||
void draw_rect(uint32_t *pixels, int x, int y, int w, int h);
|
||||
void draw_sync();
|
||||
|
|
|
@ -20,56 +20,56 @@ static _Device *video_dev;
|
|||
static _Device *timer_dev;
|
||||
|
||||
uint32_t uptime() {
|
||||
_Dev_Timer_Uptime uptime;
|
||||
_UptimeReg uptime;
|
||||
_Device *dev = getdev(&timer_dev, _DEV_TIMER);
|
||||
dev->read(_DEV_TIMER_REG_UPTIME, &uptime, sizeof(uptime));
|
||||
dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime));
|
||||
return uptime.lo;
|
||||
}
|
||||
|
||||
void gettimeofday(_Dev_Timer_RTC *rtc) {
|
||||
void gettimeofday(void *rtc) {
|
||||
_Device *dev = getdev(&timer_dev, _DEV_TIMER);
|
||||
dev->read(_DEV_TIMER_REG_DATE, rtc, sizeof(_DEV_TIMER_REG_DATE));
|
||||
dev->read(_DEVREG_TIMER_DATE, rtc, sizeof(_RTCReg));
|
||||
}
|
||||
|
||||
int read_key() {
|
||||
_Device *dev = getdev(&input_dev, _DEV_INPUT);
|
||||
int32_t key;
|
||||
dev->read(_DEV_INPUT_REG_KBD, &key, sizeof(int32_t));
|
||||
dev->read(_DEVREG_INPUT_KBD, &key, sizeof(int32_t));
|
||||
return key;
|
||||
}
|
||||
|
||||
void draw_rect(uint32_t *pixels, int x, int y, int w, int h) {
|
||||
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
|
||||
_Dev_Video_FBCtl ctl;
|
||||
_FBCtlReg ctl;
|
||||
ctl.pixels = pixels;
|
||||
ctl.x = x;
|
||||
ctl.y = y;
|
||||
ctl.w = w;
|
||||
ctl.h = h;
|
||||
ctl.sync = 0;
|
||||
dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl));
|
||||
dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl));
|
||||
}
|
||||
|
||||
void draw_sync() {
|
||||
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
|
||||
_Dev_Video_FBCtl ctl;
|
||||
_FBCtlReg ctl;
|
||||
ctl.pixels = NULL;
|
||||
ctl.x = ctl.y = ctl.w = ctl.h = 0;
|
||||
ctl.sync = 1;
|
||||
dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl));
|
||||
dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl));
|
||||
}
|
||||
|
||||
int screen_width() {
|
||||
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
|
||||
_Dev_Video_Info info;
|
||||
dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info));
|
||||
_VideoInfoReg info;
|
||||
dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
|
||||
return info.width;
|
||||
}
|
||||
|
||||
int screen_height() {
|
||||
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
|
||||
_Dev_Video_Info info;
|
||||
dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info));
|
||||
_VideoInfoReg info;
|
||||
dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
|
||||
return info.height;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue