diff --git a/README.md b/README.md index 65e6796..1ba40a4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # libMicrofx -Make very small add-ins. \ No newline at end of file +Make very small add-ins. + +With this library you can easly make very small add-ins, but they are not as fast as add-ins made using gint, so you should use gint to write more complex add-ins. This library only provides support of the fx98xx series of CASIO monochrome calculators that support add-ins. + +## Getting started + +An example add-in is in template. Start your project with this folder. Requires sh-elf-* of the fxsdk. + +The library is in microfx_src. If the library was updated, update you project by replacing lib with a new version compiled by typing `make` in microfx_src. + +You can read the header files in lib/include/microfx to see the available functions. + +Thanks to Lephenixnoir and Yatis for their help ! \ No newline at end of file diff --git a/microfx_src/Makefile b/microfx_src/Makefile new file mode 100644 index 0000000..482b46c --- /dev/null +++ b/microfx_src/Makefile @@ -0,0 +1,27 @@ +CC = sh-elf-gcc +AR = sh-elf-ar + +OUT = libMicrofx.a +OUT_DIR = lib + +SRC = src/start.c src/syscall.S src/microfx.c src/img.c +OBJ = $(SRC:src/%=build/%.o) + +BUILD = build + +all: $(OBJ) | $(OUT_DIR)/ + $(AR) rsv $(OUT_DIR)/$(OUT) $(OBJ) + cp --recursive include $(OUT_DIR)/ + cp src/fx98xx.ld $(OUT_DIR)/ + +$(BUILD)/%.o: src/% | $(BUILD)/ + $(CC) -c $< -o $@ -Os + +.PRECIOUS: %/ + +%/: + @ mkdir -p $@ + +clean: $(BUILD)/ | $(OUT_DIR)/ + rm $(OUT_DIR) --recursive + rm $(BUILD) --recursive diff --git a/microfx_src/include/microfx/config.h.in b/microfx_src/include/microfx/config.h.in new file mode 100644 index 0000000..a660533 --- /dev/null +++ b/microfx_src/include/microfx/config.h.in @@ -0,0 +1,6 @@ +#ifndef MICROFX_CONFIG_H +#define MICROFX_CONFIG_H + +#define EX_VERSION "@libMicrofx_VERSION@" + +#endif diff --git a/microfx_src/include/microfx/ext/img.h b/microfx_src/include/microfx/ext/img.h new file mode 100644 index 0000000..32be80d --- /dev/null +++ b/microfx_src/include/microfx/ext/img.h @@ -0,0 +1,20 @@ +#ifndef IMG_H +#define IMG_H + +enum {SNORMAL = 0, SINVERTED, STRANSP, SNOWHITE, SNOBLACK}; + +/* void simage(int sx, int sy, int w, int h, unsigned char *img, int mode); + +Draws an image from a Sprite Coder string that is in img, +where the top left corner is at (sx, sy). +w is the width and h the height of the image. +mode can be : +SNORMAL : Draws the image normally. +SINVERTED : Draws the image with inverted colors. +STRANSP : Black is white and white is not drawn. Useful for +transparency in sprites. +*/ + +void simage(int sx, int sy, int w, int h, unsigned char *img, int mode); + +#endif diff --git a/microfx_src/include/microfx/keycodes.h b/microfx_src/include/microfx/keycodes.h new file mode 100644 index 0000000..80fc942 --- /dev/null +++ b/microfx_src/include/microfx/keycodes.h @@ -0,0 +1,63 @@ +#ifndef KEYCODES_H +#define KEYCODES_H + +#define KCF1 79 +#define KCF2 69 +#define KCF3 59 +#define KCF4 49 +#define KCF5 39 +#define KCF6 29 + +#define KCSHIFT 78 +#define KCOPTN 68 +#define KCVARS 58 +#define KCMENU 48 +#define KCLEFT 38 +#define KCUP 28 + +#define KCALPHA 77 +#define KCX2 67 +#define KCPOW 57 +#define KCEXIT 47 +#define KCDOWN 37 +#define KCRIGHT 27 + +#define KCXOT 76 +#define KCLOG 66 +#define KCLN 56 +#define KCSIN 46 +#define KCCOS 36 +#define KCTAN 26 + +#define KCFRAC 75 +#define KCSD 65 +#define KCLPAR 55 +#define KCRPAR 45 +#define KCCOMMA 35 +#define KCARROW 25 + +#define KC7 74 +#define KC8 64 +#define KC9 54 +#define KCDEL 44 +#define KCAC 10 + +#define KC4 73 +#define KC5 63 +#define KC6 53 +#define KCMULTI 43 +#define KCDIV 33 + +#define KC1 72 +#define KC2 62 +#define KC3 52 +#define KCPLUS 42 +#define KCMIN 32 + +#define KC0 71 +#define KCDOT 61 +#define KCEXP 51 +#define KCNEGA 41 +#define KCEXE 31 + +#endif diff --git a/microfx_src/include/microfx/microfx.h b/microfx_src/include/microfx/microfx.h new file mode 100644 index 0000000..7dbb9bf --- /dev/null +++ b/microfx_src/include/microfx/microfx.h @@ -0,0 +1,132 @@ +#ifndef MICROFX_H +#define MICROFX_H + +#include "keycodes.h" + +/******* DISPLAY *******/ + +enum {SWHITE = 0, SBLACK}; + +/* void sclear(void); + +Clears the VRAM in white. +*/ + +void sclear(void); + +/* void supdate(void); + +Put the VRAM on the screen. +*/ + +void supdate(void); + +/* void srect(int x1, int y1, int x2, int y2); + +Draws a white rectangle with a black border of one pixel from (x1, y1) to (x2, y2) +in the VRAM. +*/ + +void srect(int x1, int y1, int x2, int y2); + +/* void sline(int x1, int y1, int x2, int y2, int color); + +Draws a line with a width of one pixel from (x1, y1) to (x2, y2) in the VRAM of +color color. +The available colors are SWHITE or SBLACK. +*/ + +void sline(int x1, int y1, int x2, int y2, int color); + +/* void spixel(int x, int y, int color); + +Set the pixel at (x, y) in the color color in the VRAM. +The available colors are SWHITE or SBLACK. +*/ + +void spixel(int x, int y, int color); + +/* void stext(int x, int y, char *text); + +Puts the text text at (x, y) on the screen using casio +default font. +*/ + +void stext(int x, int y, char *text); + +/* void slocate(int x, int y, char *text); + +Works like the Locate function of CASIO Basic. +*/ + +void slocate(int x, int y, char *text); + +/******* KEYBOARD *******/ + +/* int kisdown(void); + +Returns a positive int if a key is down. +Returns 0 if there is no key down. +*/ +int kisdown(void); + +/* int kcheck(int key, int type); + +/!\ Not working /!\ + +Checks if the key key is down or not : returns a positive +int if the key is down, or 0 if he's not down. +*/ +int kcheck(int key); + +/* int kgetkey(void); + +Works like the Getkey function of CASIO Basic. +Returns the pressed key. +*/ +int kgetkey(void); + +/******* TOOLS *******/ + +/* void itoa(int n, char *buffer); + +Put a string of the int n in buffer. +*/ + +void itoa(int n, char *buffer); + +/******* TIME *******/ + +/* void tsleep_ms(int ms); + +Wait ms miliseconds. +*/ +void tsleep_ms(int ms); + +/* void tgetticks(void); + +Get 1/128 seconds ticks since midnight. +*/ + +int tgetticks(void); + +/* int tiselapsed(int start, int ms); + +Check if ms where elapsed since start (ticks that you can +get with tgetticks). +Returns 1 if ms is elapsed and 0 if it is not. +*/ + +int tiselapsed(int start, int ms); + +/******* CPU *******/ + +/* void csleep(void); + +Uses asm sleep instruction. +Can be used to reduce battery usage of some loops. +*/ + +void csleep(void); + +#endif diff --git a/microfx_src/src/fx98xx.ld b/microfx_src/src/fx98xx.ld new file mode 100644 index 0000000..8a5279b --- /dev/null +++ b/microfx_src/src/fx98xx.ld @@ -0,0 +1,33 @@ +ENTRY(_start) + +MEMORY +{ + rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K + ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K +} + +SECTIONS +{ + .text : { + *(.pretext) + *(.text) + } > rom + .rodata : { + *(.rodata) + *(.rodata.str1.4) + _romdata_start = . ; + } > rom + .bss : { + _start_bss = . ; + _bssdatasize = . ; + LONG(0); + *(.bss) + *(COMMON) + _end_bss = . ; + } > ram + .data : AT(_romdata_start) { + _start_data = . ; + *(.data) + _end_data = . ; + } > ram +} diff --git a/microfx_src/src/img.c b/microfx_src/src/img.c new file mode 100644 index 0000000..befb6f2 --- /dev/null +++ b/microfx_src/src/img.c @@ -0,0 +1,29 @@ +#include "../include/microfx/ext/img.h" +#include + +void simage(int sx, int sy, int w, int h, unsigned char *img, int mode) { + /* Draws an image from a sprite coder string */ + int x, y, rpos, gpos, bpos, color; + for(y=0;y> column_pos) & 1; +} + +int kgetkey(void){ + unsigned char buffer[12]; + _Keyboard_PRGM_GetKey(buffer); + return (buffer[1] & 0x0F) * 10 + ((buffer[2] & 0xF0 ) >> 4); +} + +/******* Time *******/ + +/* Syscalls */ + +void _Sleep(int delay_ms); +int _RTC_GetTicks(void); +int _RTC_Elapsed_ms(int start_value, int duration_in_ms); + +/* Microfx */ + +void tsleep_ms(int ms) { + _Sleep(ms); +} + +int tgetticks(void) { + return _RTC_GetTicks(); +} + +int tiselapsed(int start, int ms) { + return _RTC_Elapsed_ms(start, ms); +} + +/******* CPU *******/ + +void csleep(void) { + __asm__("sleep"); +} diff --git a/microfx_src/src/start.c b/microfx_src/src/start.c new file mode 100644 index 0000000..665955d --- /dev/null +++ b/microfx_src/src/start.c @@ -0,0 +1,21 @@ +extern char start_bss, end_bss; +extern char start_data, end_data; +extern char romdata_start; +extern int main(void); + +__attribute__((section(".pretext"))) + +int start(int isappli, int optnum) { + int i; + char *bss_startptr = &start_bss; + for(i=0;i<&end_bss - &start_bss;i++){ + bss_startptr[i] = 0; + } + char *data_startptr = &start_data; + char *romdataptr = &romdata_start; + for(i=0;i<&end_data - &start_data;i++){ + data_startptr[i] = romdataptr[i]; + } + return main(); +} + diff --git a/microfx_src/src/syscall.S b/microfx_src/src/syscall.S new file mode 100644 index 0000000..cd620d4 --- /dev/null +++ b/microfx_src/src/syscall.S @@ -0,0 +1,82 @@ +.text + +.global __Bdisp_PutDisp_DD +.global __Bdisp_DrawRectangle +.global __Bdisp_AllClr_VRAM +.global __Bdisp_SetPoint_VRAM +.global __Bdisp_GetPoint_VRAM +.global __PrintXY +.global __locate +.global __Print +.global __Bdisp_DrawLineVRAM +.global __Bdisp_ClearLineVRAM +/* Keyboard */ +.global __Keyboard_GetPressedTime +.global __Keyboard_IsKeyPressed +.global __Keyboard_IsKeyPressed_fast +.global __Keyboard_KeyDown +.global __Keyboard_PRGM_GetKey +/* Time */ +.global __Sleep +.global __RTC_GetTicks +.global __RTC_Elapsed_ms +/* Files */ +/* Tools */ +.global _itoa + +#define syscall(syscall_number) \ + mov.l 1f, r0 ;\ + mov.l do_syscall, r2 ;\ + jmp @r2 ;\ + nop ;\ +.align 4 ;\ +1: .long syscall_number + +/* Display */ +__Bdisp_PutDisp_DD: + syscall(0x028) +__Bdisp_DrawRectangle: + syscall(0x0763) +__Bdisp_AllClr_VRAM: + syscall(0x143) +__Bdisp_SetPoint_VRAM: + syscall(0x146) +__Bdisp_GetPoint_VRAM: + syscall(0x149) +__PrintXY: + syscall(0x150) +__locate: + syscall(0x807) +__Print: + syscall(0x808) +__Bdisp_DrawLineVRAM: + syscall(0x030) +__Bdisp_ClearLineVRAM: + syscall(0x031) +/* Keyboard */ +__Keyboard_GetPressedTime: + syscall(0x249) +__Keyboard_IsKeyPressed: + syscall(0x24C) +__Keyboard_IsKeyPressed_fast: + syscall(0x24B) +__Keyboard_KeyDown: + syscall(0x24D) +__Keyboard_PRGM_GetKey: + syscall(0x6C4) +/* Time */ +__Sleep: + syscall(0x0420) +__RTC_GetTicks: + syscall(0x03B) +__RTC_Elapsed_ms: + syscall(0x03C) +/* Files */ +/* Nothing here ... */ +/* Tools */ +_itoa: + syscall(0x541) +/* Menu */ +/* Nothing here ... */ + +do_syscall: .long 0x80010070 diff --git a/template/Makefile b/template/Makefile new file mode 100644 index 0000000..5aaecbf --- /dev/null +++ b/template/Makefile @@ -0,0 +1,40 @@ +NAME = Template + +ELF = $(NAME).elf +BIN = $(NAME).bin + +CC = sh-elf-gcc + +SRC = src/main.c +OBJ = $(SRC:src/%=build/%.o) + +ICON = icon.png + +LIB = lib + +BUILD = build + +VERSION = v.1.0 + +all: $(BIN) + fxgxa --g1a -n $(NAME) -i $(ICON) --version="$(VERSION)" -o $(NAME).g1a build/$(BIN) + sh-elf-objdump -h $(BUILD)/$(ELF) + +$(BIN): $(ELF) + sh-elf-objcopy -O binary build/$(ELF) build/$(BIN) -R .bss + +$(ELF): $(OBJ) | $(LIB)/ + $(CC) $(OBJ) $(LIB)/libMicrofx.a -o $(BUILD)/$@ -nostdlib -T lib/fx98xx.ld -ffreestanding -mb -m3 -Os -Wa,--dsp + +$(BUILD)/%.o: src/% | $(BUILD)/ + $(CC) -c $< -o $@ -Os -Ilib/include/ + +.PRECIOUS: %/ + +%/: + @ mkdir -p $@ + +clean: $(BUILD) + rm $(BUILD) --recursive + rm $(NAME).g1a + diff --git a/template/icon.png b/template/icon.png new file mode 100644 index 0000000..d15353b Binary files /dev/null and b/template/icon.png differ diff --git a/template/lib/fx98xx.ld b/template/lib/fx98xx.ld new file mode 100644 index 0000000..8a5279b --- /dev/null +++ b/template/lib/fx98xx.ld @@ -0,0 +1,33 @@ +ENTRY(_start) + +MEMORY +{ + rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K + ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K +} + +SECTIONS +{ + .text : { + *(.pretext) + *(.text) + } > rom + .rodata : { + *(.rodata) + *(.rodata.str1.4) + _romdata_start = . ; + } > rom + .bss : { + _start_bss = . ; + _bssdatasize = . ; + LONG(0); + *(.bss) + *(COMMON) + _end_bss = . ; + } > ram + .data : AT(_romdata_start) { + _start_data = . ; + *(.data) + _end_data = . ; + } > ram +} diff --git a/template/lib/include/microfx/config.h.in b/template/lib/include/microfx/config.h.in new file mode 100644 index 0000000..a660533 --- /dev/null +++ b/template/lib/include/microfx/config.h.in @@ -0,0 +1,6 @@ +#ifndef MICROFX_CONFIG_H +#define MICROFX_CONFIG_H + +#define EX_VERSION "@libMicrofx_VERSION@" + +#endif diff --git a/template/lib/include/microfx/ext/img.h b/template/lib/include/microfx/ext/img.h new file mode 100644 index 0000000..32be80d --- /dev/null +++ b/template/lib/include/microfx/ext/img.h @@ -0,0 +1,20 @@ +#ifndef IMG_H +#define IMG_H + +enum {SNORMAL = 0, SINVERTED, STRANSP, SNOWHITE, SNOBLACK}; + +/* void simage(int sx, int sy, int w, int h, unsigned char *img, int mode); + +Draws an image from a Sprite Coder string that is in img, +where the top left corner is at (sx, sy). +w is the width and h the height of the image. +mode can be : +SNORMAL : Draws the image normally. +SINVERTED : Draws the image with inverted colors. +STRANSP : Black is white and white is not drawn. Useful for +transparency in sprites. +*/ + +void simage(int sx, int sy, int w, int h, unsigned char *img, int mode); + +#endif diff --git a/template/lib/include/microfx/keycodes.h b/template/lib/include/microfx/keycodes.h new file mode 100644 index 0000000..80fc942 --- /dev/null +++ b/template/lib/include/microfx/keycodes.h @@ -0,0 +1,63 @@ +#ifndef KEYCODES_H +#define KEYCODES_H + +#define KCF1 79 +#define KCF2 69 +#define KCF3 59 +#define KCF4 49 +#define KCF5 39 +#define KCF6 29 + +#define KCSHIFT 78 +#define KCOPTN 68 +#define KCVARS 58 +#define KCMENU 48 +#define KCLEFT 38 +#define KCUP 28 + +#define KCALPHA 77 +#define KCX2 67 +#define KCPOW 57 +#define KCEXIT 47 +#define KCDOWN 37 +#define KCRIGHT 27 + +#define KCXOT 76 +#define KCLOG 66 +#define KCLN 56 +#define KCSIN 46 +#define KCCOS 36 +#define KCTAN 26 + +#define KCFRAC 75 +#define KCSD 65 +#define KCLPAR 55 +#define KCRPAR 45 +#define KCCOMMA 35 +#define KCARROW 25 + +#define KC7 74 +#define KC8 64 +#define KC9 54 +#define KCDEL 44 +#define KCAC 10 + +#define KC4 73 +#define KC5 63 +#define KC6 53 +#define KCMULTI 43 +#define KCDIV 33 + +#define KC1 72 +#define KC2 62 +#define KC3 52 +#define KCPLUS 42 +#define KCMIN 32 + +#define KC0 71 +#define KCDOT 61 +#define KCEXP 51 +#define KCNEGA 41 +#define KCEXE 31 + +#endif diff --git a/template/lib/include/microfx/microfx.h b/template/lib/include/microfx/microfx.h new file mode 100644 index 0000000..7dbb9bf --- /dev/null +++ b/template/lib/include/microfx/microfx.h @@ -0,0 +1,132 @@ +#ifndef MICROFX_H +#define MICROFX_H + +#include "keycodes.h" + +/******* DISPLAY *******/ + +enum {SWHITE = 0, SBLACK}; + +/* void sclear(void); + +Clears the VRAM in white. +*/ + +void sclear(void); + +/* void supdate(void); + +Put the VRAM on the screen. +*/ + +void supdate(void); + +/* void srect(int x1, int y1, int x2, int y2); + +Draws a white rectangle with a black border of one pixel from (x1, y1) to (x2, y2) +in the VRAM. +*/ + +void srect(int x1, int y1, int x2, int y2); + +/* void sline(int x1, int y1, int x2, int y2, int color); + +Draws a line with a width of one pixel from (x1, y1) to (x2, y2) in the VRAM of +color color. +The available colors are SWHITE or SBLACK. +*/ + +void sline(int x1, int y1, int x2, int y2, int color); + +/* void spixel(int x, int y, int color); + +Set the pixel at (x, y) in the color color in the VRAM. +The available colors are SWHITE or SBLACK. +*/ + +void spixel(int x, int y, int color); + +/* void stext(int x, int y, char *text); + +Puts the text text at (x, y) on the screen using casio +default font. +*/ + +void stext(int x, int y, char *text); + +/* void slocate(int x, int y, char *text); + +Works like the Locate function of CASIO Basic. +*/ + +void slocate(int x, int y, char *text); + +/******* KEYBOARD *******/ + +/* int kisdown(void); + +Returns a positive int if a key is down. +Returns 0 if there is no key down. +*/ +int kisdown(void); + +/* int kcheck(int key, int type); + +/!\ Not working /!\ + +Checks if the key key is down or not : returns a positive +int if the key is down, or 0 if he's not down. +*/ +int kcheck(int key); + +/* int kgetkey(void); + +Works like the Getkey function of CASIO Basic. +Returns the pressed key. +*/ +int kgetkey(void); + +/******* TOOLS *******/ + +/* void itoa(int n, char *buffer); + +Put a string of the int n in buffer. +*/ + +void itoa(int n, char *buffer); + +/******* TIME *******/ + +/* void tsleep_ms(int ms); + +Wait ms miliseconds. +*/ +void tsleep_ms(int ms); + +/* void tgetticks(void); + +Get 1/128 seconds ticks since midnight. +*/ + +int tgetticks(void); + +/* int tiselapsed(int start, int ms); + +Check if ms where elapsed since start (ticks that you can +get with tgetticks). +Returns 1 if ms is elapsed and 0 if it is not. +*/ + +int tiselapsed(int start, int ms); + +/******* CPU *******/ + +/* void csleep(void); + +Uses asm sleep instruction. +Can be used to reduce battery usage of some loops. +*/ + +void csleep(void); + +#endif diff --git a/template/lib/libMicrofx.a b/template/lib/libMicrofx.a new file mode 100644 index 0000000..c67cacc Binary files /dev/null and b/template/lib/libMicrofx.a differ diff --git a/template/src/main.c b/template/src/main.c new file mode 100644 index 0000000..5c1912b --- /dev/null +++ b/template/src/main.c @@ -0,0 +1,6 @@ +#include + +int main(void) { + stext(1, 1, "A Microfx Add-in !"); + return 1; +}