Compare commits
13 Commits
decf62a4c4
...
9c313799ee
Author | SHA1 | Date |
---|---|---|
Potter360 | 9c313799ee | |
Potter360 | 1f3af360f8 | |
Potter360 | 3e6530fa13 | |
Potter360 | c9b36b8bbc | |
Potter360 | 4e9c1c89a9 | |
Potter360 | 9b5e28753b | |
Potter360 | 493bb4af21 | |
Potter360 | 032356bdb0 | |
Potter360 | 1900b4f54b | |
Potter360 | 40f052f93d | |
Potter360 | 532671fc32 | |
Potter360 | 8ab483d9a4 | |
Potter360 | fd0da205de |
|
@ -1,2 +1,2 @@
|
|||
omega.g3a
|
||||
.vscode/
|
||||
omega.g3a
|
||||
.vscode/
|
||||
|
|
6
Makefile
6
Makefile
|
@ -1,5 +1,5 @@
|
|||
CC=sh-elf-gcc
|
||||
CFLAGS= -Iinclude -ffreestanding -flto -nostdlib -O2 -Wall -Wextra
|
||||
CFLAGS= -Iinclude -ffreestanding -flto -nostdlib -O2 -Wall -Wextra -Xlinker
|
||||
NAME=
|
||||
FILENAME="omega"
|
||||
OBJCOPY = sh-elf-objcopy
|
||||
|
@ -8,8 +8,8 @@ CONV_DIR=oconv
|
|||
BUILD_DIR=build
|
||||
|
||||
|
||||
SRC := $(wildcard $(SRC_DIR)/*.c $(SRC_DIR)/*.S)
|
||||
SRC += $(wildcard $(SRC_DIR)/*/*.c $(SRC_DIR)/*/*.S)
|
||||
SRC := $(wildcard $(SRC_DIR)/*.c $(SRC_DIR)/*.s)
|
||||
SRC += $(wildcard $(SRC_DIR)/*/*.c $(SRC_DIR)/*/*.s)
|
||||
|
||||
all: mkdir convert compile clean
|
||||
no_clean : mkdir convert compile
|
||||
|
|
10
README.md
10
README.md
|
@ -1,6 +1,6 @@
|
|||
# omega
|
||||
|
||||
omega is a micro kernel for Casio FX-CG 50 (Graph 90+E in France). omega is in developpement and it will be very simple, but i will try to provides basic functions.
|
||||
omega is a micro kernel for Casio FX-CG 50 (Graph 90+E in France).
|
||||
|
||||
## build
|
||||
|
||||
|
@ -11,9 +11,9 @@ you can build sample program (provided in main.c) with
|
|||
|
||||
## project progress
|
||||
|
||||
You can do principal things with display, i.e :
|
||||
- set and reset pixels on VRAM
|
||||
- display .png images converted with oconv
|
||||
- print string and int
|
||||
Here are the features supported :
|
||||
- Display driver and display functions - interact with VRAM, display image with omega's converter oconv, print text in printf-like format...
|
||||
- Basic keyboard functions - only keydown() for the moment
|
||||
- An interrupt/exception/TLB handler, in order to provide a complete "OS-proof" kernel
|
||||
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
rick.png : image, rick
|
||||
rick.png : image, rick
|
||||
font.png : image, font
|
|
@ -1,3 +1,4 @@
|
|||
#include <stddef.h>
|
||||
|
||||
void coreinit(void);
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
void coreinit(void);
|
||||
uint32_t ramaddr(void);
|
|
@ -0,0 +1,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void cpu_set_vbr(uint32_t VBR);
|
||||
uint32_t cpu_get_vbr(void);
|
||||
void cpu_init(void);
|
||||
void cpu_exit();
|
|
@ -0,0 +1,4 @@
|
|||
#define ONORETURN __attribute__((noreturn))
|
||||
#define OIHANDLER __attribute__((interrupt_handler))
|
||||
#define OINTH __attribute__((section(".omega.inth")))
|
||||
#define OENTRY __attribute__((section(".text.entry")))
|
|
@ -1,7 +1,10 @@
|
|||
#include <stdint.h>
|
||||
#define rgb565(r, g, b) (((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F))
|
||||
|
||||
|
||||
#define C_BLACK rgb565(0,0,0)
|
||||
#define C_RED rgb565(255,0,0)
|
||||
#define C_WHITE rgb565(255,255,255)
|
||||
#define DWIDTH 396
|
||||
#define DHEIGHT 224
|
||||
|
||||
// image_t type for images
|
||||
typedef struct
|
||||
|
@ -12,7 +15,7 @@ typedef struct
|
|||
uint16_t pixels[];
|
||||
} image_t;
|
||||
|
||||
extern uint16_t vram[396*224];
|
||||
extern uint16_t vram[DWIDTH*DHEIGHT];
|
||||
// put pixel in VRAM at position (x,y) with color
|
||||
void dpixel(int x,int y,uint16_t color);
|
||||
// display vram
|
||||
|
@ -21,5 +24,6 @@ void dupdate(void);
|
|||
void dinit(void);
|
||||
void dimage(int x, int y, image_t *image);
|
||||
void dclear(void);
|
||||
void dtext(int x, int y, char *str);
|
||||
void dprintf(int x, int y, char *format, ...);
|
||||
void dtext(int x, int y, char *str, uint16_t color);
|
||||
void dprintf(int x, int y, uint16_t color, char *format, ...);
|
||||
void drect(int x1, int y1, int x2, int y2, uint16_t color);
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include <omega/utils.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern uint8_t scan[12];
|
||||
void keyboard_refresh();
|
||||
void keyboard_setup();
|
||||
uint8_t keyboard_get_line(int line);
|
||||
bool keydown(int key);
|
||||
|
||||
// Keycodes
|
||||
|
||||
enum {
|
||||
KEY_F1 = 0x91,
|
||||
KEY_F2 = 0x92,
|
||||
KEY_F3 = 0x93,
|
||||
KEY_F4 = 0x94,
|
||||
KEY_F5 = 0x95,
|
||||
KEY_F6 = 0x96,
|
||||
|
||||
KEY_SHIFT = 0x81,
|
||||
KEY_OPTN = 0x82,
|
||||
KEY_VARS = 0x83,
|
||||
KEY_MENU = 0x84,
|
||||
KEY_LEFT = 0x85,
|
||||
KEY_UP = 0x86,
|
||||
|
||||
KEY_ALPHA = 0x71,
|
||||
KEY_SQUARE = 0x72,
|
||||
KEY_POWER = 0x73,
|
||||
KEY_EXIT = 0x74,
|
||||
KEY_DOWN = 0x75,
|
||||
KEY_RIGHT = 0x76,
|
||||
|
||||
KEY_XOT = 0x61,
|
||||
KEY_LOG = 0x62,
|
||||
KEY_LN = 0x63,
|
||||
KEY_SIN = 0x64,
|
||||
KEY_COS = 0x65,
|
||||
KEY_TAN = 0x66,
|
||||
|
||||
KEY_FRAC = 0x51,
|
||||
KEY_FD = 0x52,
|
||||
KEY_LEFTP = 0x53,
|
||||
KEY_RIGHTP = 0x54,
|
||||
KEY_COMMA = 0x55,
|
||||
KEY_ARROW = 0x56,
|
||||
|
||||
KEY_7 = 0x41,
|
||||
KEY_8 = 0x42,
|
||||
KEY_9 = 0x43,
|
||||
KEY_DEL = 0x44,
|
||||
|
||||
KEY_4 = 0x31,
|
||||
KEY_5 = 0x32,
|
||||
KEY_6 = 0x33,
|
||||
KEY_MUL = 0x34,
|
||||
KEY_DIV = 0x35,
|
||||
|
||||
KEY_1 = 0x21,
|
||||
KEY_2 = 0x22,
|
||||
KEY_3 = 0x23,
|
||||
KEY_ADD = 0x24,
|
||||
KEY_SUB = 0x25,
|
||||
|
||||
KEY_0 = 0x11,
|
||||
KEY_DOT = 0x12,
|
||||
KEY_EXP = 0x13,
|
||||
KEY_NEG = 0x14,
|
||||
KEY_EXE = 0x15,
|
||||
|
||||
|
||||
KEY_ACON = 0x07,
|
||||
|
||||
|
||||
};
|
|
@ -1,10 +1,12 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void reverse(char str[], int length);
|
||||
char* itoa(int num, char* str, int base);
|
||||
int vsnprintf(char* str, size_t size, const char* format, va_list arg);
|
||||
char * strcpy(char *strDest, const char *strSrc);
|
||||
char * strcat(char *dest, const char *src);
|
||||
size_t strlen(const char *str);
|
||||
int vsprintf(char *buffer, char *format, va_list args);
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void reverse(char str[], int length);
|
||||
char* itoa(uint32_t num, char* str, int base);
|
||||
int vsnprintf(char* str, size_t size, const char* format, va_list arg);
|
||||
char * strcpy(char *strDest, const char *strSrc);
|
||||
char * strcat(char *dest, const char *src);
|
||||
size_t strlen(const char *str);
|
||||
int vsprintf(char *buffer, char *format, va_list args);
|
||||
void memcpy(uint32_t * l, uint32_t *r, int32_t s);
|
36
linker.ld
36
linker.ld
|
@ -1,41 +1,67 @@
|
|||
ENTRY(_start)
|
||||
MEMORY
|
||||
{
|
||||
|
||||
rom (rx): o = 0x00300000, l = 2M
|
||||
/*First 0x1400 bytes are reserved for VBR (starting at 0x08100000)*/
|
||||
ram (rw): o = 0x08101400, l = 491k
|
||||
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
_srom = SIZEOF(.pretext) + SIZEOF(.text) + SIZEOF(.rodata);
|
||||
|
||||
.pretext : {
|
||||
*(.text.entry)
|
||||
} > rom
|
||||
.text : {
|
||||
_exch_start = . ;
|
||||
*(.omega.exch)
|
||||
_exch_size = ABSOLUTE (. - _exch_start);
|
||||
|
||||
_inth_start = . ;
|
||||
*(.omega.inth)
|
||||
_inth_size = ABSOLUTE (. - _inth_start);
|
||||
|
||||
. = ALIGN(4);
|
||||
_tlbh_start = . ;
|
||||
*(.omega.tlbh)
|
||||
_tlbh_size = ABSOLUTE (. - _tlbh_start);
|
||||
|
||||
*(.text .text.*)
|
||||
|
||||
} > rom
|
||||
|
||||
|
||||
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} > rom
|
||||
|
||||
|
||||
. = ORIGIN(ram);
|
||||
|
||||
.data : {
|
||||
_rdata = .;
|
||||
*(.data .data.*)
|
||||
*(.omega.vram)
|
||||
_ldata = LOADADDR(.data);
|
||||
|
||||
|
||||
|
||||
} > ram AT > rom
|
||||
_sdata = SIZEOF(.data);
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_rbss = . ;
|
||||
|
||||
*(.bss .bss.* COMMON)
|
||||
|
||||
} > ram
|
||||
} > ram :NONE
|
||||
_sbss = SIZEOF(.bss);
|
||||
|
||||
_sbss = SIZEOF(.bss);
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} > rom
|
||||
|
||||
|
||||
|
||||
/* not important : comments */
|
||||
|
|
144
oconv/convert.py
144
oconv/convert.py
|
@ -1,72 +1,72 @@
|
|||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
def rgb_to_rgb565(rgb_tuple):
|
||||
r = rgb_tuple[0]
|
||||
g = rgb_tuple[1]
|
||||
b = rgb_tuple[2]
|
||||
return (int(r/255*31)<<11)|(int(g/255*63)<<5) | int(b/255*31)
|
||||
|
||||
class image:
|
||||
def __init__(self, path):
|
||||
self.image = Image.open(path)
|
||||
def getImage(self):
|
||||
return self.image
|
||||
def setImage(self,path):
|
||||
self.image = Image.open(path)
|
||||
def getpixels(self):
|
||||
width, height = self.image.size
|
||||
pixels = []
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
pixel = self.image.getpixel((x, y))
|
||||
pixels.append(rgb_to_rgb565(pixel))
|
||||
return pixels
|
||||
|
||||
class converter:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
def getFile(self):
|
||||
return self.file
|
||||
def setFile(self, file):
|
||||
self.file = file
|
||||
|
||||
def write_word(self, data):
|
||||
asm = ""
|
||||
asm += ".word " + hex(data)
|
||||
return asm
|
||||
|
||||
def convert_image(self, symbol, section=".rodata"):
|
||||
img = image(self.file)
|
||||
asmc = f".section {section} \n"
|
||||
asmc += f".global _{symbol}\n"
|
||||
asmc += f"_{symbol}:\n"
|
||||
width,height = img.getImage().size
|
||||
asmc += self.write_word(height) + "\n"
|
||||
asmc += self.write_word(width) + "\n"
|
||||
pixels = img.getpixels()
|
||||
for i in pixels:
|
||||
asmc += self.write_word(i) + "\n"
|
||||
f = open(symbol + ".S", "wb")
|
||||
f.write(asmc.encode('utf-8'))
|
||||
f.close()
|
||||
|
||||
|
||||
dir = sys.argv[1]
|
||||
ls = os.listdir(dir)
|
||||
if not "oconv.txt" in ls:
|
||||
print(" OConv ----- oconv.txt cannot be found")
|
||||
exit()
|
||||
print("\n")
|
||||
conf = open(f"{dir}oconv.txt", 'r').read().replace(" ","")
|
||||
files = conf.split("\n")
|
||||
for file in files:
|
||||
filename, metadatas = file.split(":")
|
||||
type, name = metadatas.split(",")
|
||||
print(f" OConv ----- Converting {filename}")
|
||||
conv = converter(dir+filename)
|
||||
if(type == "image"):
|
||||
conv.convert_image(name)
|
||||
print("\n")
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
def rgb_to_rgb565(rgb_tuple):
|
||||
r = rgb_tuple[0]
|
||||
g = rgb_tuple[1]
|
||||
b = rgb_tuple[2]
|
||||
return (int(r/255*31)<<11)|(int(g/255*63)<<5) | int(b/255*31)
|
||||
|
||||
class image:
|
||||
def __init__(self, path):
|
||||
self.image = Image.open(path)
|
||||
def getImage(self):
|
||||
return self.image
|
||||
def setImage(self,path):
|
||||
self.image = Image.open(path)
|
||||
def getpixels(self):
|
||||
width, height = self.image.size
|
||||
pixels = []
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
pixel = self.image.getpixel((x, y))
|
||||
pixels.append(rgb_to_rgb565(pixel))
|
||||
return pixels
|
||||
|
||||
class converter:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
def getFile(self):
|
||||
return self.file
|
||||
def setFile(self, file):
|
||||
self.file = file
|
||||
|
||||
def write_word(self, data):
|
||||
asm = ""
|
||||
asm += ".word " + hex(data)
|
||||
return asm
|
||||
|
||||
def convert_image(self, symbol, section=".rodata"):
|
||||
img = image(self.file)
|
||||
asmc = f".section {section} \n"
|
||||
asmc += f".global _{symbol}\n"
|
||||
asmc += f"_{symbol}:\n"
|
||||
width,height = img.getImage().size
|
||||
asmc += self.write_word(height) + "\n"
|
||||
asmc += self.write_word(width) + "\n"
|
||||
pixels = img.getpixels()
|
||||
for i in pixels:
|
||||
asmc += self.write_word(i) + "\n"
|
||||
f = open(symbol + ".S", "wb")
|
||||
f.write(asmc.encode('utf-8'))
|
||||
f.close()
|
||||
|
||||
|
||||
dir = sys.argv[1]
|
||||
ls = os.listdir(dir)
|
||||
if not "oconv.txt" in ls:
|
||||
print(" OConv ----- oconv.txt cannot be found")
|
||||
exit()
|
||||
print("\n")
|
||||
conf = open(f"{dir}oconv.txt", 'r').read().replace(" ","")
|
||||
files = conf.split("\n")
|
||||
for file in files:
|
||||
filename, metadatas = file.split(":")
|
||||
type, name = metadatas.split(",")
|
||||
print(f" OConv ----- Converting {filename}")
|
||||
conv = converter(dir+filename)
|
||||
if(type == "image"):
|
||||
conv.convert_image(name)
|
||||
print("\n")
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
//---
|
||||
// core.c - Initialize core of Omega kernel
|
||||
// core.c - Core of Omega kernel
|
||||
//---
|
||||
|
||||
#include <omega/core.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <omega/utils.h>
|
||||
#include <omega/display.h>
|
||||
|
||||
/* Symbols that came from linker script */
|
||||
extern uint32_t
|
||||
|
||||
ldata, sdata, rdata, /* .data section informations */
|
||||
sbss, rbss; /* .bss section informations */
|
||||
sbss, rbss; /* .bss section informations */
|
||||
|
||||
|
||||
/* Copy data of size s from one address l to another address r*/
|
||||
void copy(uint32_t * l, int32_t s, uint32_t *r)
|
||||
{
|
||||
while(s > 0)
|
||||
{
|
||||
*r++ = *l++;
|
||||
s -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean a section of size s beginning at adress a*/
|
||||
void clean(uint32_t * a, int32_t s)
|
||||
|
@ -36,12 +29,14 @@ void clean(uint32_t * a, int32_t s)
|
|||
/* Copy .data section from ROM to RAM - needed at start of kernel */
|
||||
void rcopy(void)
|
||||
{
|
||||
copy(&ldata,(int32_t)&sdata,&rdata);
|
||||
memcpy(&ldata,&rdata,(int32_t) sdata);
|
||||
|
||||
}
|
||||
/* Clean .bss section of the RAM */
|
||||
void rclean(void)
|
||||
{
|
||||
clean(&rbss,(int32_t)&sbss);
|
||||
|
||||
}
|
||||
/* Initialize kernel*/
|
||||
void coreinit(void)
|
||||
|
|
|
@ -4,20 +4,31 @@
|
|||
|
||||
#include <omega/core.h>
|
||||
#include <omega/display.h>
|
||||
|
||||
#include <omega/cpu.h>
|
||||
#include <omega/keyboard.h>
|
||||
#include <omega/defs/attributes.h>
|
||||
|
||||
int main();
|
||||
|
||||
extern uint32_t rbss;
|
||||
|
||||
// This function loads omega. It initialize drivers, do some stuff with memory...
|
||||
__attribute__((section(".text.entry")))
|
||||
void start()
|
||||
{
|
||||
|
||||
// Copy ROM to RAM for static and global variables and cleans .bss
|
||||
|
||||
OENTRY int start()
|
||||
{
|
||||
// Copy ROM to RAM for static and global variables and clean .bss
|
||||
coreinit();
|
||||
|
||||
// Init CPU (setup registers)
|
||||
cpu_init();
|
||||
|
||||
// Setup keyboard
|
||||
keyboard_setup();
|
||||
|
||||
|
||||
//call user's main() function
|
||||
main();
|
||||
|
||||
cpu_exit();
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
//---
|
||||
// cpu.c - CPU functions definitions for omega kernel
|
||||
//---
|
||||
#include <omega/cpu.h>
|
||||
#include <omega/core.h>
|
||||
#include <omega/display.h>
|
||||
#include <omega/utils.h>
|
||||
#include <omega/defs/attributes.h>
|
||||
|
||||
#include "tlbh.h"
|
||||
#include "exch.h"
|
||||
#include "inth.h"
|
||||
|
||||
extern uint32_t _bram;
|
||||
extern uint32_t exch_size, inth_size, tlbh_size;
|
||||
|
||||
static uint32_t VBR = 0x8c200000;
|
||||
|
||||
ONORETURN void cpu_panic(void)
|
||||
{
|
||||
// Read the EXPEVT register
|
||||
uint32_t code = *(uint32_t *)0xff000024;
|
||||
char const *name = "";
|
||||
if(code == 0x040) name = "TLB miss (read)";
|
||||
if(code == 0x060) name = "TLB miss (write)";
|
||||
if(code == 0x0e0) name = "Data address error (read)";
|
||||
if(code == 0x100) name = "Data address error (write)";
|
||||
if(code == 0x160) name = "Unconditional trap (TRAPA)";
|
||||
if(code == 0x180) name = "Illegal instruction";
|
||||
if(code == 0x1a0) name = "Illegal delay slot";
|
||||
|
||||
uint32_t PC;
|
||||
__asm__("stc spc, %0" : "=r"(PC));
|
||||
uint32_t TEA = *(volatile uint32_t *)0xff00000c;
|
||||
uint32_t TRA = *(volatile uint32_t *)0xff000020 >> 2;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
dclear();
|
||||
drect(0,0,DWIDTH,10,C_RED);
|
||||
dprintf(1,1,C_WHITE, "An exception occured !");
|
||||
dprintf(1,20,C_BLACK, "%x : %s", code, name);
|
||||
dprintf(1,50,C_BLACK, "PC = %x",PC);
|
||||
dprintf(200,50,C_BLACK,"(Error address)");
|
||||
dprintf(1,70,C_BLACK, "TEA = %x",TEA);
|
||||
dprintf(200,70,C_BLACK,"(Problematic address)");
|
||||
dprintf(1,90,C_BLACK, "TRA = %x",TRA);
|
||||
dprintf(200,90,C_BLACK,"(Trap number)");
|
||||
|
||||
dprintf(1,140,C_BLACK, "Please reset your calculator.");
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
uint8_t IMRSAV[13];
|
||||
uint8_t volatile *IMR = (void *)0xA4080080;
|
||||
uint8_t volatile *IMCR = (void *)0xa40800c0;
|
||||
void cpu_imr_save(void)
|
||||
{
|
||||
uint8_t volatile *CURIMR = IMR;
|
||||
for(int i=0;i<13;i++,CURIMR+=4)
|
||||
{
|
||||
IMRSAV[i] = *CURIMR;
|
||||
}
|
||||
|
||||
}
|
||||
void cpu_imr_restore(void)
|
||||
{
|
||||
uint8_t volatile *CURIMR = IMR;
|
||||
uint8_t volatile *CURIMCR = IMCR;
|
||||
for(int i=0;i<13;i++,CURIMR+=4,CURIMCR+=4)
|
||||
{
|
||||
*CURIMCR = 0xff;
|
||||
*CURIMR = IMRSAV[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t VBRSAV;
|
||||
|
||||
void cpu_vbr_save()
|
||||
{
|
||||
VBRSAV = cpu_get_vbr();
|
||||
}
|
||||
void cpu_vbr_restore()
|
||||
{
|
||||
cpu_set_vbr(VBRSAV);
|
||||
}
|
||||
void cpu_init(void)
|
||||
{
|
||||
|
||||
// Save IMR
|
||||
cpu_imr_save();
|
||||
cpu_vbr_save();
|
||||
// Disable interrupts that we don't handle
|
||||
uint8_t volatile *CURIMR = IMR;
|
||||
|
||||
for(int i=0;i<13;i++,CURIMR+=4)
|
||||
{
|
||||
|
||||
*CURIMR = 0xff;
|
||||
}
|
||||
|
||||
// We copy our handlers...
|
||||
memcpy((uint32_t *)&cpu_exch,(uint32_t *)(VBR+0x100),(int32_t)&exch_size);
|
||||
memcpy((uint32_t *)&cpu_tlbh,(uint32_t *)(VBR+0x400),(int32_t)&tlbh_size);
|
||||
memcpy((uint32_t *)&cpu_inth,(uint32_t *)(VBR+0x600),(int32_t)&inth_size);
|
||||
// ... and then we can change the VBR
|
||||
cpu_set_vbr(VBR);
|
||||
}
|
||||
void cpu_exit()
|
||||
{
|
||||
cpu_vbr_restore();
|
||||
cpu_imr_restore();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
void cpu_exch(void);
|
|
@ -0,0 +1,16 @@
|
|||
.global _cpu_exch
|
||||
.section .omega.exch, "ax"
|
||||
.balign 4
|
||||
|
||||
_cpu_exch:
|
||||
stc ssr, r0
|
||||
ldc r0, sr
|
||||
|
||||
mov.l .panic, r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
|
||||
.balign 4
|
||||
.panic:
|
||||
.long _cpu_panic
|
|
@ -0,0 +1 @@
|
|||
void cpu_inth(void);
|
|
@ -0,0 +1,7 @@
|
|||
.global _cpu_inth
|
||||
.section .omega.inth, "ax"
|
||||
.balign 4
|
||||
|
||||
_cpu_inth:
|
||||
rte
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# registers.s - Registers definition
|
||||
|
||||
.global _cpu_set_vbr
|
||||
.global _cpu_get_vbr
|
||||
.text
|
||||
|
||||
_cpu_set_vbr:
|
||||
ldc r4,vbr
|
||||
rts
|
||||
nop
|
||||
|
||||
_cpu_get_vbr:
|
||||
stc vbr, r0
|
||||
rts
|
||||
nop
|
|
@ -0,0 +1 @@
|
|||
void cpu_tlbh(void);
|
|
@ -0,0 +1,61 @@
|
|||
.global _cpu_tlbh
|
||||
.section .omega.tlbh, "ax"
|
||||
.balign 4
|
||||
|
||||
_cpu_tlbh:
|
||||
|
||||
|
||||
/* Save registers*/
|
||||
sts.l pr, @-r15
|
||||
stc.l gbr, @-r15
|
||||
sts.l mach, @-r15
|
||||
sts.l macl, @-r15
|
||||
|
||||
/* Is it possible to map TEA to TLB ? If not, well - panic*/
|
||||
mov.l .tea, r0
|
||||
mov.l @r0, r0
|
||||
mov.l .max_mapped_rom, r1
|
||||
cmp/ge r1, r0
|
||||
bt panic
|
||||
mov.l .min_mapped_rom, r1
|
||||
cmp/ge r1, r0
|
||||
bf panic
|
||||
|
||||
/* Okay it's possible to map so here we go */
|
||||
mov #12, r0
|
||||
mov.l .syscall, r2
|
||||
jsr @r2
|
||||
nop
|
||||
lds.l @r15+, macl
|
||||
lds.l @r15+, mach
|
||||
ldc.l @r15+, gbr
|
||||
lds.l @r15+, pr
|
||||
rte
|
||||
nop
|
||||
|
||||
/* Call VBR exception panic*/
|
||||
panic:
|
||||
lds.l @r15+, macl
|
||||
lds.l @r15+, mach
|
||||
ldc.l @r15+, gbr
|
||||
lds.l @r15+, pr
|
||||
|
||||
stc vbr, r0
|
||||
mov #1, r1
|
||||
shll8 r1
|
||||
add r1, r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
|
||||
|
||||
.align 4
|
||||
.tea:
|
||||
.long 0xff00000c
|
||||
.min_mapped_rom:
|
||||
.long 0x00300000
|
||||
.max_mapped_rom:
|
||||
.long 0x00300000 + _srom
|
||||
|
||||
.syscall:
|
||||
.long 0x80020070
|
|
@ -14,20 +14,32 @@ float floor(float x) {
|
|||
return (float)((int)x);
|
||||
}
|
||||
|
||||
uint16_t vram[396*224];
|
||||
extern image_t font;
|
||||
|
||||
|
||||
void dupdate(void)
|
||||
{
|
||||
rdisplay(vram);
|
||||
}
|
||||
void dpixel(int x,int y,uint16_t color)
|
||||
{
|
||||
vram[y * 397 + x] = color;
|
||||
if((x>=0 && x<DWIDTH) && (y>=0 && y<DHEIGHT)) vram[y * DWIDTH + x] = color;
|
||||
|
||||
}
|
||||
void drect(int x1, int y1, int x2, int y2, uint16_t color)
|
||||
{
|
||||
for(int x=x1;x<=x2;x++)
|
||||
{
|
||||
for(int y=y1;y<=y2;y++)
|
||||
{
|
||||
dpixel(x,y,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
void dclear(void)
|
||||
{
|
||||
for(int i = 0;i<395;i++){
|
||||
for(int j=0;j<223;j++){
|
||||
for(int i = 0;i<DWIDTH;i++){
|
||||
for(int j=0;j<DHEIGHT;j++){
|
||||
dpixel(i,j,0xffff);
|
||||
}
|
||||
|
||||
|
@ -43,35 +55,36 @@ void dimage(int x, int y, image_t *image)
|
|||
}
|
||||
}
|
||||
}
|
||||
void pchar(int x, int y, char ch)
|
||||
void pchar(int x, int y, char ch, uint16_t color)
|
||||
{
|
||||
int index = (int)ch;
|
||||
for(int i=0;i<8;i++){
|
||||
for (int j=0;j<8;j++){
|
||||
int offset_y = floor((8*index)/128);
|
||||
int index2 = index - offset_y*16;
|
||||
dpixel(x+j,y+i,font.pixels[j+(8*index2) +font.width*i+offset_y*font.width*8]);
|
||||
if(font.pixels[j+(8*index2) +font.width*i+offset_y*font.width*8]==0) dpixel(x+j,y+i,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dtext(int x, int y, char *str)
|
||||
void dtext(int x, int y, char *str, uint16_t color)
|
||||
{
|
||||
int i = 0;
|
||||
while(1)
|
||||
{
|
||||
pchar(x,y,str[i++]);
|
||||
pchar(x,y,str[i++], color);
|
||||
x+=8;
|
||||
if (str[i]=='\0'){break;}
|
||||
}
|
||||
}
|
||||
|
||||
void dprintf(int x, int y, char *format, ...)
|
||||
void dprintf(int x, int y, uint16_t color, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char str[512];
|
||||
vsprintf(str, format, args);
|
||||
dtext(x,y,str);
|
||||
dtext(x,y,str, color);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
uint16_t vram[DWIDTH*DHEIGHT];
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
#include <omega/utils.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
uint8_t scan[12];
|
||||
void keyboard_setup()
|
||||
{
|
||||
for(int i=0;i<12;i++)
|
||||
{
|
||||
scan[i] = 0;
|
||||
}
|
||||
}
|
||||
void keyboard_refresh()
|
||||
{
|
||||
uint16_t *KEYSC = (void *)0xa44b0000;
|
||||
for(int i=0; i<6;i++)
|
||||
{
|
||||
scan[i*2] = KEYSC[i]& 0xff;
|
||||
scan[i*2+1] = KEYSC[i] >> 8;
|
||||
}
|
||||
}
|
||||
uint8_t keyboard_get_line(int line)
|
||||
{
|
||||
return scan[line];
|
||||
}
|
||||
|
||||
bool keydown(int key)
|
||||
{
|
||||
keyboard_refresh();
|
||||
int row = (key >> 4);
|
||||
int col = 0x80 >> (key & 0x7);
|
||||
|
||||
return (scan[row] & col) != 0;
|
||||
}
|
20
src/main.c
20
src/main.c
|
@ -3,20 +3,22 @@
|
|||
#include <omega/core.h>
|
||||
#include <omega/display.h>
|
||||
#include <omega/utils.h>
|
||||
|
||||
#include <omega/keyboard.h>
|
||||
|
||||
extern image_t rick;
|
||||
|
||||
|
||||
|
||||
int main(){
|
||||
while(1){
|
||||
|
||||
int y = 65;
|
||||
int x = 88;
|
||||
while(!keydown(KEY_SHIFT)){
|
||||
dclear();
|
||||
dimage(88,55,&rick);
|
||||
int a = (12*60)/2;
|
||||
dprintf(10,20,"int : %i , hex : %x",a,a);
|
||||
dprintf(10,40,"str : %s", "~~ welcome to omega ~~");
|
||||
if(keydown(KEY_DOWN)) y+=1;
|
||||
if(keydown(KEY_UP)) y-=1;
|
||||
if(keydown(KEY_LEFT)) x-=1;
|
||||
if(keydown(KEY_RIGHT)) x+=1;
|
||||
dimage(x,y,&rick);
|
||||
dprintf(10,25,C_BLACK,"str : %s", "~~ welcome to omega ~~");
|
||||
dupdate();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -56,15 +56,10 @@ void rframe(uint16_t xmin, uint16_t xmax, uint16_t ymin, uint16_t ymax)
|
|||
rdirectwrite(ram_address_vertical,0);
|
||||
}
|
||||
|
||||
|
||||
void rsetup(void)
|
||||
{
|
||||
rframe(0,396,0,224);
|
||||
}
|
||||
void rdisplay(uint16_t *vram)
|
||||
{
|
||||
rsetup();
|
||||
rframe(0,DWIDTH-1,0,DHEIGHT-1);
|
||||
rselect(write_data);
|
||||
for(int i = 0; i < 396 * 224; i++)
|
||||
for(int i = 0; i < DWIDTH * DHEIGHT; i++)
|
||||
rwrite(vram[i]);
|
||||
}
|
|
@ -1,123 +1,133 @@
|
|||
#include <omega/utils.h>
|
||||
|
||||
void reverse(char str[], int length)
|
||||
{
|
||||
int start = 0;
|
||||
int end = length - 1;
|
||||
while (start < end) {
|
||||
char temp = str[start];
|
||||
str[start] = str[end];
|
||||
str[end] = temp;
|
||||
end--;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
// Implementation of citoa()
|
||||
char* itoa(int num, char* str, int base)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
int isNegative = 0;
|
||||
if (num == 0) {
|
||||
str[i++] = '0';
|
||||
str[i] = '\0';
|
||||
return str;
|
||||
}
|
||||
if (num < 0 && base == 10) {
|
||||
isNegative = 1;
|
||||
num = -num;
|
||||
}
|
||||
|
||||
while (num != 0) {
|
||||
int rem = num % base;
|
||||
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
|
||||
num = num / base;
|
||||
}
|
||||
if (isNegative)
|
||||
str[i++] = '-';
|
||||
|
||||
str[i] = '\0';
|
||||
reverse(str, i);
|
||||
|
||||
return str;
|
||||
}
|
||||
char * strcpy(char *strDest, const char *strSrc)
|
||||
{
|
||||
|
||||
char *temp = strDest;
|
||||
while((*strDest++=*strSrc++) != '\0');
|
||||
return temp;
|
||||
}
|
||||
char * strcat(char *dest, const char *src)
|
||||
{
|
||||
char *rdest = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++)!= '\0');
|
||||
return rdest;
|
||||
}
|
||||
size_t strlen(const char *str)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
int vsprintf(char *buffer, char *format, va_list args)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
while (*format != '\0') {
|
||||
if (*format == '%') {
|
||||
format++;
|
||||
char temp[20];
|
||||
|
||||
switch (*format) {
|
||||
case 'i': {
|
||||
int num = va_arg(args, int);
|
||||
itoa(num,temp,10);
|
||||
size_t len = strlen(temp);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = temp[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
int num = va_arg(args, int);
|
||||
itoa(num,temp,16);
|
||||
size_t len = strlen(temp);
|
||||
buffer[index++] = '0';
|
||||
buffer[index++] = 'x';
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = temp[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
char *str = va_arg(args, char *);
|
||||
size_t len = strlen(str);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = str[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// for unsupported format
|
||||
buffer[index++] = '%';
|
||||
buffer[index++] = *format;
|
||||
}
|
||||
} else {
|
||||
buffer[index++] = *format;
|
||||
}
|
||||
format++;
|
||||
}
|
||||
|
||||
|
||||
buffer[index] = '\0';
|
||||
|
||||
return index;
|
||||
#include <omega/utils.h>
|
||||
#include <stdint.h>
|
||||
#include <omega/display.h>
|
||||
void reverse(char str[], int length)
|
||||
{
|
||||
int start = 0;
|
||||
int end = length - 1;
|
||||
while (start < end) {
|
||||
char temp = str[start];
|
||||
str[start] = str[end];
|
||||
str[end] = temp;
|
||||
end--;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
// Implementation of citoa()
|
||||
char* itoa(uint32_t num, char* str, int base)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
int isNegative = 0;
|
||||
if (num == 0) {
|
||||
str[i++] = '0';
|
||||
str[i] = '\0';
|
||||
return str;
|
||||
}
|
||||
if (num < 0 && base == 10) {
|
||||
isNegative = 1;
|
||||
num = -num;
|
||||
}
|
||||
|
||||
while (num != 0) {
|
||||
int rem = num % base;
|
||||
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
|
||||
num = num / base;
|
||||
}
|
||||
if (isNegative)
|
||||
str[i++] = '-';
|
||||
|
||||
str[i] = '\0';
|
||||
reverse(str, i);
|
||||
|
||||
return str;
|
||||
}
|
||||
char * strcpy(char *strDest, const char *strSrc)
|
||||
{
|
||||
|
||||
char *temp = strDest;
|
||||
while((*strDest++=*strSrc++) != '\0');
|
||||
return temp;
|
||||
}
|
||||
char * strcat(char *dest, const char *src)
|
||||
{
|
||||
char *rdest = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++)!= '\0');
|
||||
return rdest;
|
||||
}
|
||||
size_t strlen(const char *str)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
int vsprintf(char *buffer, char *format, va_list args)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
while (*format != '\0') {
|
||||
if (*format == '%') {
|
||||
format++;
|
||||
char temp[20];
|
||||
|
||||
switch (*format) {
|
||||
case 'i': {
|
||||
uint32_t num = va_arg(args, uint32_t);
|
||||
itoa(num,temp,10);
|
||||
size_t len = strlen(temp);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = temp[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
int num = va_arg(args, int);
|
||||
itoa(num,temp,16);
|
||||
size_t len = strlen(temp);
|
||||
buffer[index++] = '0';
|
||||
buffer[index++] = 'x';
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = temp[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
char *str = va_arg(args, char *);
|
||||
size_t len = strlen(str);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buffer[index++] = str[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// for unsupported format
|
||||
buffer[index++] = '%';
|
||||
buffer[index++] = *format;
|
||||
}
|
||||
} else {
|
||||
buffer[index++] = *format;
|
||||
}
|
||||
format++;
|
||||
}
|
||||
|
||||
|
||||
buffer[index] = '\0';
|
||||
|
||||
return index;
|
||||
}
|
||||
/* Copy data of size s from one address l to another address r*/
|
||||
void memcpy(uint32_t * l, uint32_t * r, int32_t s)
|
||||
{
|
||||
while(s > 0)
|
||||
{
|
||||
*r++ = *l++;
|
||||
s -= 4;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue