From d863472196ebd94a245aaf34cc1cbe6d2465bb9c Mon Sep 17 00:00:00 2001 From: ChengLong Zou Date: Thu, 27 Sep 2012 11:36:45 +0200 Subject: [PATCH] master: ficheros iniciales fase 1 --- .gitignore | 6 + GARLIC_API/GARLIC_API.h | 45 ++++ GARLIC_API/GARLIC_API.pnproj | 1 + GARLIC_API/GARLIC_API.s | 44 ++++ GARLIC_API/Makefile | 21 ++ GARLIC_OS/GARLIC_OS.pnproj | 1 + GARLIC_OS/Makefile | 156 +++++++++++++ GARLIC_OS/data/garlic_font.gif | Bin 0 -> 1769 bytes GARLIC_OS/data/garlic_font.grit | 20 ++ GARLIC_OS/include/garlic_font.h | 28 +++ GARLIC_OS/include/garlic_system.h | 139 +++++++++++ GARLIC_OS/nitrofiles/LEAME.txt | 13 ++ GARLIC_OS/source/garlic_dtcm.s | 35 +++ GARLIC_OS/source/garlic_font.s | 349 ++++++++++++++++++++++++++++ GARLIC_OS/source/garlic_graf.c | 32 +++ GARLIC_OS/source/garlic_itcm_api.s | 170 ++++++++++++++ GARLIC_OS/source/garlic_itcm_proc.s | 148 ++++++++++++ GARLIC_OS/source/garlic_mem.c | 40 ++++ GARLIC_OS/source/garlic_vectors.s | 74 ++++++ GARLIC_OS/source/main.c | 88 +++++++ GARLIC_Progs/HOLA/Makefile | 61 +++++ GARLIC_Progs/HOLA/hola.c | 28 +++ GARLIC_Progs/HOLA/hola.pnproj | 1 + GARLIC_Progs/HOLA/hola.s | 72 ++++++ 24 files changed, 1572 insertions(+) create mode 100644 .gitignore create mode 100644 GARLIC_API/GARLIC_API.h create mode 100644 GARLIC_API/GARLIC_API.pnproj create mode 100644 GARLIC_API/GARLIC_API.s create mode 100644 GARLIC_API/Makefile create mode 100644 GARLIC_OS/GARLIC_OS.pnproj create mode 100644 GARLIC_OS/Makefile create mode 100644 GARLIC_OS/data/garlic_font.gif create mode 100644 GARLIC_OS/data/garlic_font.grit create mode 100644 GARLIC_OS/include/garlic_font.h create mode 100644 GARLIC_OS/include/garlic_system.h create mode 100644 GARLIC_OS/nitrofiles/LEAME.txt create mode 100644 GARLIC_OS/source/garlic_dtcm.s create mode 100644 GARLIC_OS/source/garlic_font.s create mode 100644 GARLIC_OS/source/garlic_graf.c create mode 100644 GARLIC_OS/source/garlic_itcm_api.s create mode 100644 GARLIC_OS/source/garlic_itcm_proc.s create mode 100644 GARLIC_OS/source/garlic_mem.c create mode 100644 GARLIC_OS/source/garlic_vectors.s create mode 100644 GARLIC_OS/source/main.c create mode 100644 GARLIC_Progs/HOLA/Makefile create mode 100644 GARLIC_Progs/HOLA/hola.c create mode 100644 GARLIC_Progs/HOLA/hola.pnproj create mode 100644 GARLIC_Progs/HOLA/hola.s diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85c8a7b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.d +*.o +*.elf +*.nds +*.pnps +*.DS_Store diff --git a/GARLIC_API/GARLIC_API.h b/GARLIC_API/GARLIC_API.h new file mode 100644 index 0000000..2f4801c --- /dev/null +++ b/GARLIC_API/GARLIC_API.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------------ + + "GARLIC_API.h" : cabeceras de funciones del API (Application Program + Interface) del sistema operativo GARLIC (código fuente + disponible en "GARLIC_API.s") + +------------------------------------------------------------------------------*/ +#ifndef _GARLIC_API_h_ +#define _GARLIC_API_h_ + + + /* GARLIC_random: devuelve un número aleatorio de 32 bits */ +extern int GARLIC_random(); + + /* GARLIC_divmod: calcula la división num / den (numerador / denominador), + almacenando el cociente y el resto en las posiciones de memoria indica- + das por *quo y *mod, respectivamente (pasa resultados por referencia); + la función devuelve 0 si la división és correcta, o diferente de 0 + si hay algún problema (división por cero). + ATENCIóN: sólo procesa números naturales de 32 bits SIN signo. */ +extern int GARLIC_divmod(unsigned int num, unsigned int den, + unsigned int * quo, unsigned int * mod); + + /* GARLIC_num2str: convertir el número pasado por valor en el parámetro num + a una representación en códigos ASCII de los dígitos decimales corres- + pondientes, que se escribirán dentro del vector de caracteres numstr, + que se pasa por referencia; el parámetro length indicará la longitud del + vector; esta función coloca un caracter centinela (cero) en la última + posición del vector (numstr[length-1]) y, a partir de la penúltima + posición, empieza a colocar los códigos ASCII correspondientes a las + unidades, decenas, centenas, etc.; en el caso que después de trancribir + todo el número todavía queden posiciones libres en el vector, la función + rellenará dichas posiciones con espacios en blanco, y devolverá un cero; + en el caso que NO hayan suficientes posiciones para transcribir todo el + número, la función abandonará el proceso y devolverá un valor diferente + de cero. + ATENCIóN: sólo procesa números naturales de 32 bits SIN signo. */ +extern int GARLIC_num2str(char * numstr, unsigned int length, unsigned int num); + + /* GARLIC_print: escribir string en la ventana del proceso actual */ +extern void GARLIC_print(char * string); + + + +#endif // _GARLIC_API_h_ diff --git a/GARLIC_API/GARLIC_API.pnproj b/GARLIC_API/GARLIC_API.pnproj new file mode 100644 index 0000000..aa0694b --- /dev/null +++ b/GARLIC_API/GARLIC_API.pnproj @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GARLIC_API/GARLIC_API.s b/GARLIC_API/GARLIC_API.s new file mode 100644 index 0000000..9a4e102 --- /dev/null +++ b/GARLIC_API/GARLIC_API.s @@ -0,0 +1,44 @@ +@;============================================================================== +@; +@; "GARLIC_API.s": implementación de funciones del API del sistema operativo +@; GARLIC (descripción de funciones en "GARLIC_API.h") +@; +@;============================================================================== + +.text + .arm + .align 2 + + .global GARLIC_random +GARLIC_random: + push {r4, lr} + mov r4, #0 @; vector base de funciones GARLIC + mov lr, pc @; guardar dirección de retorno + ldr pc, [r4] @; llamada indirecta a la función 0x00 de GARLIC + pop {r4, pc} + + .global GARLIC_divmod +GARLIC_divmod: + push {r4, lr} + mov r4, #0 + mov lr, pc + ldr pc, [r4, #4] @; llamada indirecta a la función 0x01 + pop {r4, pc} + + .global GARLIC_num2str +GARLIC_num2str: + push {r4, lr} + mov r4, #0 + mov lr, pc + ldr pc, [r4, #8] @; llamada indirecta a la función 0x02 + pop {r4, pc} + + .global GARLIC_print +GARLIC_print: + push {r4, lr} + mov r4, #0 + mov lr, pc + ldr pc, [r4, #12] @; llamada indirecta a la función 0x03 + pop {r4, pc} + +.end diff --git a/GARLIC_API/Makefile b/GARLIC_API/Makefile new file mode 100644 index 0000000..975b360 --- /dev/null +++ b/GARLIC_API/Makefile @@ -0,0 +1,21 @@ +#------------------------------------------------------------------------------- +# Makefile for GARLIC API's Object (interface routines) +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# options for Object code generation +#------------------------------------------------------------------------------- +ARCH := -march=armv5te -mlittle-endian + +ASFLAGS := -g0 $(ARCH) -mcpu=arm946e-s + # -g0 : disable debug info generation + # $(ARCH) -mcpu=arm946e-s : define architecture and machine + +#------------------------------------------------------------------------------- +# make commands +#------------------------------------------------------------------------------- + +GARLIC_API.o : GARLIC_API.s + @echo "assembling GARLIC_API.s into GARLIC_API.o" + @arm-eabi-as $(ASFLAGS) GARLIC_API.s -o GARLIC_API.o + diff --git a/GARLIC_OS/GARLIC_OS.pnproj b/GARLIC_OS/GARLIC_OS.pnproj new file mode 100644 index 0000000..9dd5bf5 --- /dev/null +++ b/GARLIC_OS/GARLIC_OS.pnproj @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GARLIC_OS/Makefile b/GARLIC_OS/Makefile new file mode 100644 index 0000000..336ec9c --- /dev/null +++ b/GARLIC_OS/Makefile @@ -0,0 +1,156 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif + +ifeq ($(strip $(DESMUME)),) +$(error "Please set DESMUME in your environment. export DESMUME=DeSmuME") +endif + +include $(DEVKITARM)/base_rules + +#------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +# DATA contains .bin files with extra data for the project (e.g. graphic tiles) +# NITRODATA contains the "virtual" file system accessed through filesystem lib +#------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +INCLUDES := include +DATA := data +NITRODATA := nitrofiles + +#------------------------------------------------------------------------------- +# options for code generation +#------------------------------------------------------------------------------- +ARCH := -march=armv5te -mlittle-endian + +CFLAGS := -Wall -g -O2 \ + $(ARCH) -mtune=arm946e-s -fomit-frame-pointer -ffast-math + # -Wall : enable all warnings + # -g : enable debug info generation + # -O2 : code optimization level 2 + # $(ARCH) -mtune=arm946e-s : tune code generation for specific machine + # -fomit-frame-pointer : avoid to use a 'frame-pointer' register in functions that do not need it + # -ffast-math : optimize math operations + +CFLAGS += $(INCLUDE) -DARM9 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=ds_arm9.specs $(ARCH) -mno-fpu + +#------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project (order is important) +#------------------------------------------------------------------------------- +LIBS := -lfilesystem -lfat -lnds9 + +#------------------------------------------------------------------------------- +# list of directories containing libNDS libraries, this must be the top level +# containing include and lib +#------------------------------------------------------------------------------- +LIBNDS := $(DEVKITPRO)/libnds + +#--------------------------------------------------------------------------------- +# check if the build directory is not created yet +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +AFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin))) + +export OFILES := $(BINFILES:.bin=.o) $(CFILES:.c=.o) +export SFILES := $(AFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBNDS),-I$(dir)/include) + +export LIBPATHS := $(foreach dir,$(LIBNDS),-L$(dir)/lib) + + +#--------------------------------------------------------------------------------- +# use CC for linking standard C projects +#--------------------------------------------------------------------------------- +export LD := $(CC) + +export GAME_TITLE := GARLIC_OS_v1 +export GAME_SUBTITLE1 := Practica de Estructura de Sistemas Operativos +export GAME_SUBTITLE2 := Departamento de Ingenieria Informatica y Matematicas (URV) +export GAME_ICON := $(DEVKITPRO)/libnds/icon.bmp + +export _ADDFILES := -d $(CURDIR)/$(NITRODATA) + + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds + +#--------------------------------------------------------------------------------- +run : $(TARGET).nds + @echo "runing $(TARGET).nds with DesmuME" + @$(DESMUME)/DeSmuME.exe $(TARGET).nds & + +#--------------------------------------------------------------------------------- +debug : $(TARGET).nds $(TARGET).elf + @echo "testing $(TARGET).nds/.elf with DeSmuME_dev/Insight (gdb) through TCP port=1000" + @$(DESMUME)/DeSmuME_dev.exe --arm9gdb=1000 $(TARGET).nds & + @$(DEVKITPRO)/insight/bin/arm-eabi-insight $(TARGET).elf & + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) $(SFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) $(SFILES) + +#--------------------------------------------------------------------------------- +%.nds: %.elf + @ndstool -c $@ -9 $< -b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1);$(GAME_SUBTITLE2)" $(_ADDFILES) + @echo built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +%.elf: + @echo linking $(notdir $@) + $(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) $(SFILES) -o $@ + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPSDIR)/*.d + + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/GARLIC_OS/data/garlic_font.gif b/GARLIC_OS/data/garlic_font.gif new file mode 100644 index 0000000000000000000000000000000000000000..6aaedfb316f4099224f791ee14ab6213721d0bb3 GIT binary patch literal 1769 zcmchY{a*_R9LGPNim;GwuXAaKY$Wm=prB>VJpg;4FW?9`0ZiZrfCY>IIKUXd6PN^e z0W$z!U=F|q0s$Tn1n_}XfB;wv2!R+t48#EvAQ6xP$@q#%1LVK~Kmi;Al)y1S1)KuZ zKq;UBE(2QN2A~7 zU?EruMD|v4v=GxwEE92zh9LZ`=-v&VBNW>&!5pjq-iM)t>iMT{OB0iCTNJu0m zk`PIWWJGcz1(A|SMWiOu5NU~YLCp@$T&S)18YL zeW|CuyrfRE>G`96(SzIdh4Gco`WH#mg5#T`n<$ITNZbGx!S&A5VN#vt@)UJ5W>ly7)-AHY`2lys+wwSm9E+YHCI8*`-bl z*Dvm|b-B?aQdU2X-dG+#sdQ!H=c&&s9ymwf~yCb9mv= zjUmyhSjP0@r&MpU*Tk^jIkc94=)N_oyf9xMy01Aup}4FixWwUo$l0^HA$4t8q4$jgZ#%DT8>>j}@DD!M7$H=jxZ3Mv{co)q z{Tg=f>s~L)8s_6Nz9{5Qp1RW4x_V=EGkf>s%l%oZxY)qbz*py;7LWbq<~VJgxW-A| z_U1}a$gW|9xdYQCZ3qZ#^>}C%c~34cZLS?&!9G?NTsFw*DyMu$g1+yE?8btbG4(^$ zw=@@IJ$!N=a&LH#Pm?<^-1hDZTGjk?&JFM4y>YhNZ*}W8Gq&DiJ dirección de memoria de entrada al código del proceso + zocalo -> identificador del zócalo (0 - 15) + nombre -> nombre en clave del programa (4 caracteres ASCII) + Resultado: 0 si no hay problema, >0 si no se puede crear el proceso +*/ +extern int _gp_crearProc(intFunc funcion, int zocalo, char *nombre); + + + +//------------------------------------------------------------------------------ +// Funciones de memoria (garlic_mem.c) +//------------------------------------------------------------------------------ + +/* _gm_cargarPrograma: busca un fichero de nombre "(keyName).elf" dentro del + directorio "/Programas/" del sistema de ficheros Nitro, y + carga los segmentos de programa en una zona libre de memoria + del sistema, efectuando la relocatación de las referencias a + los símbolos del programa; + Parámetors: + keyName -> string de 4 caracteres con el nombre en clave del progrma + Resultado: + != 0 -> dirección de inicio del programa (intFunc) + == 0 -> no se ha podido cargar el programa +*/ +extern intFunc _gm_cargarPrograma(char *keyName); + + + +//------------------------------------------------------------------------------ +// Funciones de gráficos (garlic_graf.c) +//------------------------------------------------------------------------------ + +/* _gg_iniGraf: inicializa el entorno gráfico para GARLIC */ +extern void _gg_iniGraf(); + +/* _gg_escribir: escribe una cadena de caracteres en el zócalo indicado; + Parámetros: + mensaje -> cadena de códigos ASCII, terminada con centinela '\0'; + admite '\n' (salto de línea), '\t' (tabulador, 4 espacios) + y códigos ASCII entre 32 y 159 (los códigos mayores de 126 + corresponden a caracteres gráficos) + zócalo -> número de zócalo (de 0 a 15) +*/ +extern void _gg_escribir(char *mensaje, int zocalo); + + + +#endif // _GARLIC_SYSTEM_h_ diff --git a/GARLIC_OS/nitrofiles/LEAME.txt b/GARLIC_OS/nitrofiles/LEAME.txt new file mode 100644 index 0000000..8967374 --- /dev/null +++ b/GARLIC_OS/nitrofiles/LEAME.txt @@ -0,0 +1,13 @@ +Este fichero describe el proposito del directorio donde se encuentra. + +Se trata del contenido de un disco "virtual" que genera en la memoria ROM +(definida por el fichero NDS) que contiene el proyecto ejecutable. + +Desde el código del proyecto se puede acceder al contenido de los ficheros y +directorios almacenados en el directorio "nitrofiles", usando las funciones de +la librería "libfilesystem.a", que implementa las funciones de acceso a ficheros +definidas por el sistema NITRO. + +Para más información, consultar los ficheros siguientes: +- "devkitPro/libnds/include/filesystem.h" +- "devkitPro/examples/nds/filesystem/nitrofs/nitrodir/source/directory.c" \ No newline at end of file diff --git a/GARLIC_OS/source/garlic_dtcm.s b/GARLIC_OS/source/garlic_dtcm.s new file mode 100644 index 0000000..a64088e --- /dev/null +++ b/GARLIC_OS/source/garlic_dtcm.s @@ -0,0 +1,35 @@ +@;============================================================================== +@; +@; "garlic_dtcm.s": zona de datos básicos del sistema GARLIC +@; (ver "garlic_system.h" para descripción de variables) +@; +@;============================================================================== + +.section .dtcm,"wa",%progbits + + .global _gd_pidz @; Identificador de proceso + zócalo actual +_gd_pidz: .word 0 + + .global _gd_pidCount @; Contador global de PIDs +_gd_pidCount: .word 0 + + .global _gd_tickCount @; Contador global de tics +_gd_tickCount: .word 0 + + .global _gd_seed @; Semilla para generación de números aleatorios +_gd_seed: .word 0xFFFFFFFF + + .global _gd_nReady @; Número de procesos en la cola de READY +_gd_nReady: .word 0 + + .global _gd_qReady @; Cola de READY (procesos preparados) +_gd_qReady: .space 16 + + .global _gd_psv @; Vector de estado de los procesos +_gd_psv: .space 16 * 16 * 4 + + .global _gd_stacks @; Vector de pilas de los procesos +_gd_stacks: .space 15 * 128 * 4 + +.end + diff --git a/GARLIC_OS/source/garlic_font.s b/GARLIC_OS/source/garlic_font.s new file mode 100644 index 0000000..ffe31d3 --- /dev/null +++ b/GARLIC_OS/source/garlic_font.s @@ -0,0 +1,349 @@ + +@{{BLOCK(garlic_font) + +@======================================================================= +@ +@ garlic_font, 1024x8@8, +@ + palette 256 entries, not compressed +@ + 128 tiles not compressed +@ Total size: 512 + 8192 = 8704 +@ +@ Time-stamp: 2012-08-27, 12:04:15 +@ Exported by Cearn's GBA Image Transmogrifier, v0.8.8 +@ ( http://www.coranac.com/projects/#grit ) +@ +@======================================================================= + + .section .rodata + .align 2 + .global garlic_fontTiles @ 8192 unsigned chars +garlic_fontTiles: + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0xFFFFFF00,0xFFFFFFFF,0xFF000000,0x0000FF00 + .word 0xFFFFFF00,0xFFFFFFFF,0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0x00000000,0x00000000 + + .word 0x00000000,0x000000FF,0xFF000000,0x00FFFFFF,0x00FF0000,0x000000FF,0xFF000000,0x0000FFFF + .word 0x00000000,0x00FF00FF,0xFFFF0000,0x0000FFFF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFF0000,0x00FF0000,0xFFFF0000,0x0000FF00,0x00000000,0x000000FF + .word 0xFF000000,0x00FFFF00,0x00FF0000,0x00FFFF00,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFF000000,0x000000FF,0x00FF0000,0x000000FF,0xFF000000,0x00000000,0x00FF0000,0x000000FF + .word 0x0000FF00,0x00FFFF00,0x0000FF00,0x0000FF00,0xFFFF0000,0x00FF00FF,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + + .word 0x00000000,0x0000FF00,0x00000000,0x000000FF,0xFF000000,0x00000000,0xFF000000,0x00000000 + .word 0xFF000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x0000FF00,0x00000000,0x00000000 + .word 0xFF000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x0000FF00,0x00000000,0x0000FF00 + .word 0x00000000,0x0000FF00,0x00000000,0x000000FF,0xFF000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x0000FF00,0xFF0000FF,0x00FF0000,0x00FF00FF,0xFF000000,0x0000FFFF + .word 0x00FF0000,0x00FF00FF,0x0000FF00,0xFF0000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0xFFFFFF00,0xFFFFFFFF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x0000FF00,0x00000000,0x000000FF + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFF00,0xFFFFFFFF + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0xFF000000,0x00000000,0x00FF0000,0x00000000,0x0000FF00,0x00000000,0x000000FF + .word 0xFF000000,0x00000000,0x00FF0000,0x00000000,0x0000FF00,0x00000000,0x00000000,0x00000000 + + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF00FF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0xFF000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x0000FF00 + .word 0x00000000,0x000000FF,0xFF000000,0x00000000,0xFFFF0000,0x00FFFFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x0000FFFF + .word 0x00000000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x00000000,0x0000FFFF,0xFF000000,0x0000FF00,0x00FF0000,0x0000FF00,0xFFFF0000,0x00FFFFFF + .word 0x00000000,0x0000FF00,0x00000000,0x0000FF00,0x00000000,0x00FFFFFF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00FFFFFF,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0xFFFF0000,0x0000FFFF + .word 0x00000000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0xFFFF0000,0x0000FFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00FFFFFF,0x00000000,0x00FF0000,0x00000000,0x0000FF00,0x00000000,0x000000FF + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0x00000000,0x00000000 + + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x00FFFFFF + .word 0x00000000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0x0000FF00,0x00000000,0x000000FF + + .word 0x00000000,0x0000FF00,0x00000000,0x000000FF,0xFF000000,0x00000000,0x00FF0000,0x00000000 + .word 0xFF000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x0000FF00,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFF00,0xFFFFFFFF,0x00000000,0x00000000 + .word 0xFFFFFF00,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00FF0000,0x00000000,0xFF000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x0000FF00 + .word 0x00000000,0x000000FF,0xFF000000,0x00000000,0x00FF0000,0x00000000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x0000FF00 + .word 0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x00000000 + + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FFFFFF,0x00FF0000,0x00FF00FF + .word 0x00FF0000,0x00FFFFFF,0x00FF0000,0x00000000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x00FFFFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0xFFFF0000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x0000FFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00FF0000,0x00000000 + .word 0x00FF0000,0x00000000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0xFFFF0000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x0000FFFF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00FFFFFF,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0xFFFF0000,0x0000FFFF + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0xFFFF0000,0x00FFFFFF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00FFFFFF,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0xFFFF0000,0x00FFFFFF + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00FF0000,0x00FFFFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x00FFFFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x00FFFFFF,0x00000000,0x0000FF00,0x00000000,0x0000FF00,0x00000000,0x0000FF00 + .word 0x00FF0000,0x0000FF00,0x00FF0000,0x0000FF00,0xFF000000,0x000000FF,0x00000000,0x00000000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x0000FF00,0xFFFF0000,0x000000FF + .word 0x00FF0000,0x0000FF00,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000 + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00FFFFFF,0x00000000,0x00000000 + .word 0x0000FF00,0xFF000000,0x00FFFF00,0xFFFF0000,0xFF00FF00,0xFF00FF00,0x0000FF00,0xFF0000FF + .word 0x0000FF00,0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0xFF000000,0x00000000,0x00000000 + .word 0x00FF0000,0x00FF0000,0xFFFF0000,0x00FF0000,0x00FF0000,0x00FF00FF,0x00FF0000,0x00FF00FF + .word 0x00FF0000,0x00FFFF00,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0xFF000000,0x0000FFFF,0xFF000000,0x00FF0000,0xFF000000,0x00FF0000,0xFF000000,0x0000FFFF + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00FFFF00 + .word 0xFFFF0000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFFFF0000,0x0000FFFF + .word 0x00FF0000,0x000000FF,0x00FF0000,0x0000FF00,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0xFF000000,0x0000FFFF + .word 0x00000000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0xFFFF0000,0x00FFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FF00 + .word 0xFF000000,0x0000FF00,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x0000FF00,0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0xFF000000,0x00FF0000,0x00FF00FF + .word 0x00FF0000,0x00FF00FF,0xFF000000,0x0000FF00,0xFF000000,0x0000FF00,0x00000000,0x00000000 + + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FF00,0x00000000,0x000000FF + .word 0xFF000000,0x0000FF00,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FF00,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00FFFFFF,0x00000000,0x00FF0000,0x00000000,0x0000FF00,0x00000000,0x000000FF + .word 0xFF000000,0x00000000,0x00FF0000,0x00000000,0xFFFF0000,0x00FFFFFF,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000 + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x0000FF00,0x00000000,0x00FF0000,0x00000000,0xFF000000,0x00000000,0x00000000,0x000000FF + .word 0x00000000,0x0000FF00,0x00000000,0x00FF0000,0x00000000,0xFF000000,0x00000000,0x00000000 + .word 0xFF000000,0x0000FFFF,0x00000000,0x0000FF00,0x00000000,0x0000FF00,0x00000000,0x0000FF00 + .word 0x00000000,0x0000FF00,0x00000000,0x0000FF00,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0xFF000000,0x0000FF00,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFF00,0xFFFFFFFF + + .word 0xFF000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFF000000,0x0000FFFF,0x00000000,0x00FF0000,0xFF000000,0x00FFFFFF + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0xFF00FFFF,0x00000000,0x00000000 + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x0000FFFF,0xFF000000,0x00FF0000 + .word 0xFF000000,0x00FF0000,0xFF000000,0x00FF0000,0x00FF0000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x0000FFFF,0x00FF0000,0x00000000 + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x00000000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00FFFFFF,0xFF000000,0x00FF0000 + .word 0xFF000000,0x00FF0000,0xFF000000,0x00FF0000,0x00000000,0xFF00FFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000 + .word 0xFFFF0000,0x00FFFFFF,0x00FF0000,0x00000000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x0000FFFF,0xFF000000,0x00FF0000,0xFF000000,0x00000000,0xFFFF0000,0x000000FF + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0xFF00FFFF,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0xFF000000,0x00FFFFFF,0x00000000,0x00FF0000,0xFF000000,0x0000FFFF + + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00FF0000,0x0000FFFF,0xFFFF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x000000FF,0x00000000,0x00000000,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0xFFFF0000,0x00000000 + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00FF0000,0x0000FF00,0x00FF0000,0x000000FF + .word 0xFFFF0000,0x00000000,0x00FF0000,0x000000FF,0x00FF0000,0x0000FF00,0x00000000,0x00000000 + + .word 0xFF000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFF00FF,0x00FFFF00,0x0000FF00,0xFF0000FF + .word 0x0000FF00,0xFF0000FF,0x0000FF00,0xFF000000,0x0000FF00,0xFF000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x0000FFFF,0xFF000000,0x00FF0000 + .word 0xFF000000,0x00FF0000,0xFF000000,0x00FF0000,0xFF000000,0x00FF0000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x0000FFFF,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x0000FFFF,0xFF000000,0x00FF0000 + .word 0xFF000000,0x00FF0000,0xFF000000,0x0000FFFF,0xFF000000,0x00000000,0xFF000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x00FF00FF,0x00FF0000,0x0000FF00 + .word 0x00FF0000,0x0000FF00,0xFF000000,0x0000FFFF,0x00000000,0x0000FF00,0x00000000,0x0000FF00 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x0000FFFF,0xFFFF0000,0x00000000 + .word 0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00FF0000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x0000FFFF,0x00FF0000,0x00000000 + .word 0xFF000000,0x000000FF,0x00000000,0x0000FF00,0xFFFF0000,0x000000FF,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0x00000000,0x000000FF,0xFF000000,0x0000FFFF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x0000FF00,0x00FF0000,0x0000FF00 + .word 0x00FF0000,0x0000FF00,0x00FF0000,0x0000FF00,0xFF000000,0x00FF00FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000 + .word 0x00FF0000,0x00FF0000,0xFF000000,0x0000FF00,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x0000FF00,0xFF000000,0x0000FF00,0xFF000000 + .word 0x0000FF00,0xFF0000FF,0xFF00FF00,0xFF00FF00,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00FF0000,0x00FF0000,0xFF000000,0x0000FF00 + .word 0x00000000,0x000000FF,0xFF000000,0x0000FF00,0x00FF0000,0x00FF0000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFF000000,0x00FF0000,0xFF000000,0x00FF0000 + .word 0xFF000000,0x00FF0000,0x00000000,0x00FFFFFF,0x00000000,0x00FF0000,0xFF000000,0x0000FFFF + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFF0000,0x0000FFFF,0x00000000,0x0000FF00 + .word 0x00000000,0x000000FF,0xFF000000,0x00000000,0xFFFF0000,0x0000FFFF,0x00000000,0x00000000 + .word 0x00000000,0x0000FFFF,0xFF000000,0x00000000,0xFF000000,0x00000000,0x00FF0000,0x00000000 + .word 0xFF000000,0x00000000,0xFF000000,0x00000000,0x00000000,0x0000FFFF,0x00000000,0x00000000 + + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x00000000 + .word 0xFFFF0000,0x00000000,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x0000FF00 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0xFFFF0000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFF0000,0x00000000,0x0000FF00,0xFF0000FF + .word 0x00000000,0x00FFFF00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF + .word 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF + + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000 + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF + .word 0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000 + .word 0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000 + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0xFFFFFFFF,0xFFFFFFFF + .word 0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000 + .word 0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0xFFFFFFFF,0xFFFFFFFF + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000 + .word 0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000,0x00000000,0xFF000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000 + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000 + + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0x000000FF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0xFFFFFFFF,0x00000000,0x000000FF + .word 0x00000000,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x000000FF,0x00000000,0x000000FF,0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF + .word 0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF,0x00000000,0x000000FF + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x000000FF,0x00000000,0x000000FF,0x00000000 + .word 0x000000FF,0x00000000,0x000000FF,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x0000FFFF,0x00000000,0x0000FFFF,0x00000000 + .word 0x0000FFFF,0x00000000,0x0000FFFF,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00FFFFFF,0x00000000,0x00FFFFFF,0x00000000 + .word 0x00FFFFFF,0x00000000,0x00FFFFFF,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000 + .word 0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x000000FF,0xFFFFFFFF,0x000000FF + .word 0xFFFFFFFF,0x000000FF,0xFFFFFFFF,0x000000FF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x0000FFFF,0xFFFFFFFF,0x0000FFFF + .word 0xFFFFFFFF,0x0000FFFF,0xFFFFFFFF,0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00FFFFFF,0xFFFFFFFF,0x00FFFFFF + .word 0xFFFFFFFF,0x00FFFFFF,0xFFFFFFFF,0x00FFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + .word 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF + .word 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 + + .section .rodata + .align 2 + .global garlic_fontPal @ 512 unsigned chars +garlic_fontPal: + .hword 0x0000,0x0000,0x0000,0x0001,0x0001,0x0002,0x0002,0x0003 + .hword 0x0003,0x0004,0x0004,0x0005,0x0005,0x0006,0x0006,0x0007 + .hword 0x0007,0x0008,0x0008,0x0009,0x0009,0x000A,0x000A,0x000B + .hword 0x000B,0x000C,0x000C,0x000D,0x000D,0x000E,0x000E,0x000F + .hword 0x000F,0x0010,0x0010,0x0011,0x0011,0x0012,0x0012,0x0013 + .hword 0x0013,0x0014,0x0014,0x0015,0x0015,0x0016,0x0016,0x0017 + .hword 0x0017,0x0018,0x0018,0x0019,0x0019,0x001A,0x001A,0x001B + .hword 0x001B,0x001C,0x001C,0x001D,0x001D,0x001E,0x001E,0x001F + + .hword 0x001F,0x001E,0x003D,0x005C,0x007B,0x009A,0x00B9,0x00D8 + .hword 0x00F7,0x0116,0x0135,0x0154,0x0173,0x0192,0x01B1,0x01D0 + .hword 0x01EF,0x020E,0x022D,0x024C,0x026B,0x028A,0x02A9,0x02C8 + .hword 0x02E7,0x0306,0x0325,0x0344,0x0363,0x0382,0x03A1,0x03C0 + .hword 0x03E0,0x03C0,0x07A0,0x0B80,0x0F60,0x1340,0x1720,0x1B00 + .hword 0x1EE0,0x22C0,0x26A0,0x2A80,0x2E60,0x3240,0x3620,0x3A00 + .hword 0x3DE0,0x41C0,0x45A0,0x4980,0x4D60,0x5140,0x5520,0x5900 + .hword 0x5CE0,0x60C0,0x64A0,0x6880,0x6C60,0x7040,0x7420,0x7800 + + .hword 0x7C00,0x7C00,0x7C20,0x7C40,0x7C60,0x7C80,0x7CA0,0x7CC0 + .hword 0x7CE0,0x7D00,0x7D20,0x7D40,0x7D60,0x7D80,0x7DA0,0x7DC0 + .hword 0x7DE0,0x7E00,0x7E20,0x7E40,0x7E60,0x7E80,0x7EA0,0x7EC0 + .hword 0x7EE0,0x7F00,0x7F20,0x7F40,0x7F60,0x7F80,0x7FA0,0x7FC0 + .hword 0x7FE0,0x7FC0,0x7FA1,0x7F82,0x7F63,0x7F44,0x7F25,0x7F06 + .hword 0x7EE7,0x7EC8,0x7EA9,0x7E8A,0x7E6B,0x7E4C,0x7E2D,0x7E0E + .hword 0x7DEF,0x7DD0,0x7DB1,0x7D92,0x7D73,0x7D54,0x7D35,0x7D16 + .hword 0x7CF7,0x7CD8,0x7CB9,0x7C9A,0x7C7B,0x7C5C,0x7C3D,0x7C1E + + .hword 0x7C1F,0x781F,0x743F,0x705F,0x6C7F,0x689F,0x64BF,0x60DF + .hword 0x5CFF,0x591F,0x553F,0x515F,0x4D7F,0x499F,0x45BF,0x41DF + .hword 0x3DFF,0x3A1F,0x363F,0x325F,0x2E7F,0x2A9F,0x26BF,0x22DF + .hword 0x1EFF,0x1B1F,0x173F,0x135F,0x0F7F,0x0B9F,0x07BF,0x03DF + .hword 0x03FF,0x03FF,0x07FF,0x0BFF,0x0FFF,0x13FF,0x17FF,0x1BFF + .hword 0x1FFF,0x23FF,0x27FF,0x2BFF,0x2FFF,0x33FF,0x37FF,0x3BFF + .hword 0x3FFF,0x43FF,0x47FF,0x4BFF,0x4FFF,0x53FF,0x57FF,0x5BFF + .hword 0x5FFF,0x63FF,0x67FF,0x6BFF,0x6FFF,0x73FF,0x77FF,0x7BFF + +@}}BLOCK(garlic_font) diff --git a/GARLIC_OS/source/garlic_graf.c b/GARLIC_OS/source/garlic_graf.c new file mode 100644 index 0000000..fa2f8fa --- /dev/null +++ b/GARLIC_OS/source/garlic_graf.c @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------------ + + "garlic_graf.c" : fase 1 / programador G + + Rutinas de gestión del entorno gráfico (ventanas de texto), para el sistema + GARLIC 0.5 + +------------------------------------------------------------------------------*/ +#include + +#include // definición de funciones y variables de sistema +#include // definición gráfica de caracteres + + +/* Inicializaciones gráficas del sistema Garlic */ +//------------------------------------------------------------------------------ +void _gg_iniGraf() +//------------------------------------------------------------------------------ +{ + +} + + +/* Escribir un mensaje de texto, como vector de caracteres terminado por cero, + en la ventana correspondiente al zócalo indicado por parámetro */ +//------------------------------------------------------------------------------ +void _gg_escribir(char *mensaje, int zocalo) +//------------------------------------------------------------------------------ +{ + +} + diff --git a/GARLIC_OS/source/garlic_itcm_api.s b/GARLIC_OS/source/garlic_itcm_api.s new file mode 100644 index 0000000..b394ffb --- /dev/null +++ b/GARLIC_OS/source/garlic_itcm_api.s @@ -0,0 +1,170 @@ +@;============================================================================== +@; +@; "garlic_itcm_api.s": código de las funciones del API de GARLIC (ver +@; "GARLIC_API.h" para descripción de las funciones) +@; +@;============================================================================== + +.section .itcm,"ax",%progbits + + .arm + .align 2 + + .global _gi_random + @;Resultado: + @; R0 = valor aleatorio de 32 bits +_gi_random: + push {r1-r5, lr} + ldr r0, =_gd_seed + ldr r1, [r0] @; R1 = valor de semilla de números aleatorios + ldr r2, =0x0019660D + ldr r3, =0x3C6EF35F + umull r4, r5, r1, r2 @; R5:R4 = _gd_seed * 0x19660D + add r4, r3 @; R4 += 0x3C6EF35F + str r4, [r0] @; guarda la nueva semilla (R4) + mov r0, r5 @; devuelve por R0 el valor aleatorio (R5) + pop {r1-r5, pc} + + + .global _gi_divmod + @;Parámetros + @; R0: unsigned int num, + @; R1: unsigned int den, + @; R2: unsigned int * quo, + @; R3: unsigned int * mod + @;Resultado + @; R0: 0 si no hay problema, !=0 si hay error en la división +_gi_divmod: + @;Código para realizar la división con el hardware matemático de la NDS + @;ATENCIÓN: ¡NO funciona en un entorno emulado (DeSmuME)! + @;Por este motivo, el siguiente código está comentado: +@; push {r4, r5, lr} +@; mov r4, #0x04000000 +@; add r4, #0x280 @; R4 = dir. base registro DIVCNT (0x04000280) +@; mov r5, #0 +@; strh r5, [r4] @; fijar modo 0 (división 32 bits) +@; str r0, [r4, #0x10] @; guardar numerador en DIV_NUMER (0x04000290) +@; str r1, [r4, #0x18] @; guardar denominador en DIV_DENOM (0x04000298) +@; str r5, [r4, #0x1c] @; guardar cero en parte alta DIV_NUMER (0x0400029C) +@;.Ldiv_wait: +@; ldrh r5, [r4] @; bucle para esperar a que el hardware de división +@; tst r5, #0x8000 @; termine el cálculo (¡espera ACTIVA!) +@; bne .Ldiv_wait +@; tst r5, #0x4000 @; test del bit de error +@; beq .Ldiv_noerr +@; mov r0, r5 @; código de error +@; b .Ldiv_fin +@;.Ldiv_noerr: +@; ldr r5, [r4, #0x20] @; R5 = cociente, desde DIV_RESULT (0x040002A0) +@; str r5, [r2] @; guardar resultado en dirección (*quo); +@; ldr r5, [r4, #0x28] @; R5 = resto, desde DIVREM_RESULT (0x040002A8) +@; str r5, [r2] @; guardar resultado en dirección (*mod); +@; mov r0, #0 @; código de retorno OK +@;.Ldiv_fin: +@; pop {r4, r5, pc} + @;¡FIN del código comentado! + @;ATENCIÓN: en caso de descomentar el código anterior, la división pasaría + @;a realizarse CON signo. + push {r4-r7, lr} + cmp r1, #0 @; verificar si se está intentando dividir por cero + bne .Ldiv_ini + mov r0, #1 @; código de error + b .Ldiv_fin2 +.Ldiv_ini: + mov r4, #0 @; R4 es el cociente (q) + mov r5, #0 @; R5 es el resto (r) + mov r6, #31 @; R6 es índice del bucle (de 31 a 0) + mov r7, #0xff000000 +.Ldiv_for1: + tst r0, r7 @; comprobar si hay bits activos en una zona de 8 + bne .Ldiv_for2 @; bits del numerador, para evitar rastreo 32 bits + mov r7, r7, lsr #8 + sub r6, #8 @; 8 bits menos a buscar + cmp r7, #0 + bne .Ldiv_for1 + b .Ldiv_fin1 @; caso especial (numerador = 0 -> q=0 y r=0) +.Ldiv_for2: + mov r7, r0, lsr r6 @; R7 es variable de trabajo j; + and r7, #1 @; j = bit i-ésimo del numerador; + mov r5, r5, lsl #1 @; r = r << 1; + orr r5, r7 @; r = r | j; + mov r4, r4, lsl #1 @; q = q << 1; + cmp r5, r1 + blo .Ldiv_cont @; si (r >= divisor), activar bit en cociente + sub r5, r1 @; r = r - divisor; + orr r4, #1 @; q = q | 1; + .Ldiv_cont: + sub r6, #1 @; decrementar índice del bucle + cmp r6, #0 + bge .Ldiv_for2 @; bucle for-2, mientras i >= 0 +.Ldiv_fin1: + str r4, [r2] + str r5, [r3] @; guardar resultados en memoria (por referencia) + mov r0, #0 @; código de OK +.Ldiv_fin2: + pop {r4-r7, pc} + + + .global _gi_num2str + @;Parámetros + @; R0: char * numstr, + @; R1: unsigned int length, + @; R2: unsigned int num + @;Resultado + @; R0: 0 si no hay problema, !=0 si el número no cabe en el string +_gi_num2str: + push {r3-r8, lr} + cmp r1, #1 + bhi .Ln2s_cont1 @; verificar si hay espacio para centinela + 1 dígito + mov r0, #-1 + b .Ln2s_fin @; retornar con código de error en R0 +.Ln2s_cont1: + mov r6, r0 @; R6 = puntero a string de resultado + mov r7, r1 @; R7 = índice carácter (inicialmente es la longitud del string) + mov r8, r2 @; R8 = número a transcribir + mov r3, #0 + sub r7, #1 + strb r3, [r6, r7] @; guardar final de string (0) en última posición +.Ln2s_while: + cmp r7, #0 @; repetir mientras quede espacio en el string + beq .Ln2s_cont2 + sub sp, #8 @; reservar espacio en la pila para resultados + mov r0, r8 @; pasar numerador por valor + mov r1, #10 @; pasar denominador por valor + mov r2, sp @; pasar dirección para albergar el cociente + add r3, sp, #4 @; pasar dirección para albergar el resto + bl _gi_divmod + pop {r4-r5} @; R4 = cociente, R5 = resto + add r5, #48 @; añadir base de códigos ASCII para dígitos numéricos + sub r7, #1 + strb r5, [r6, r7] @; almacenar código ASCII en vector + mov r8, r4 @; actualizar valor del número a convertir + cmp r8, #0 @; repetir mientras el número sea diferente de 0 + bne .Ln2s_while +.Ln2s_pad: + cmp r7, #0 @; bucle para llenar de espacios en blanco la + beq .Ln2s_cont2 @; parte restante del inicio del string + mov r3, #' ' + sub r7, #1 + strb r3, [r6, r7] @; almacenar código de espacio en blanco en vector + b .Ln2s_pad +.Ln2s_cont2: + mov r0, r8 @; esto indica si el numero se ha podido codificar +.Ln2s_fin: @; completamente en el string (si R0 = 0) + pop {r3-r8, pc} + + + .global _gi_print + @;Parámetros + @; R0: char * message +_gi_print: + push {r1-r2, lr} + ldr r2, =_gd_pidz @; R2 = dirección _gd_pidz + ldr r1, [r2] + and r1, #0xf @; R1 = zócalo actual + bl _gg_escribir + pop {r1-r2, pc} + + +.end + diff --git a/GARLIC_OS/source/garlic_itcm_proc.s b/GARLIC_OS/source/garlic_itcm_proc.s new file mode 100644 index 0000000..efb4216 --- /dev/null +++ b/GARLIC_OS/source/garlic_itcm_proc.s @@ -0,0 +1,148 @@ +@;============================================================================== +@; +@; "garlic_itcm_proc.s": código de las funciones de control de procesos. +@; (ver "garlic_system.h" para descripción de funciones) +@; +@;============================================================================== + +.section .itcm,"ax",%progbits + + .arm + .align 2 + + .global _gp_WaitForVBlank + @; rutina para pausar el procesador mientras no se produzca una interrupción + @; de retrazado vertical (IRQ_VBL); es un sustituto de la "swi #5", que + @; evita la necesidad de cambiar a modo supervisor en los procesos GARLIC +_gp_WaitForVBlank: + push {r0-r1, lr} + ldr r0, =__irq_flags +.Lwait_espera: + mcr p15, 0, lr, c7, c0, 4 @; HALT (suspender hasta nueva interrupción) + nop @; instrucción de relleno, para asegurar que se + ldr r1, [r0] @; ejecuta la "ldr r1, [r0]" al salir de HALT + tst r1, #1 @; comprobar flag IRQ_VBL + beq .Lwait_espera @; repetir bucle mientras no exista IRQ_VBL + bic r1, #1 + str r1, [r0] @; poner a cero el flag IRQ_VBL + pop {r0-r1, pc} + + + .global _gp_IntrMain + @; Manejador principal de interrupciones del sistema Garlic +_gp_IntrMain: + mov r12, #0x4000000 + add r12, r12, #0x208 @; R12 = base registros de control de interrupciones + ldr r2, [r12, #0x08] @; R2 = REG_IE (máscara de bits con int. permitidas) + ldr r1, [r12, #0x0C] @; R1 = REG_IF (máscara de bits con int. activas) + and r1, r1, r2 @; filtrar int. activas con int. permitidas + ldr r2, =irqTable +.Lintr_find: @; buscar manejadores de interrupciones específicos + ldr r0, [r2, #4] @; R0 = máscara de int. del manejador indexado + cmp r0, #0 @; si máscara = cero, fin de vector de manejadores + beq .Lintr_setflags @; (abandonar bucle de búsqueda de manejador) + ands r0, r0, r1 @; determinar si el manejador indexado atiende a una + beq .Lintr_cont1 @; de las interrupciones activas + ldr r3, [r2] @; R3 = dirección de salto del manejador indexado + cmp r3, #0 + beq .Lintr_ret @; abandonar si dirección = 0 + mov r2, lr @; guardar dirección de retorno + blx r3 @; invocar el manejador indexado + mov lr, r2 @; recuperar dirección de retorno + b .Lintr_ret @; salir del bucle de búsqueda +.Lintr_cont1: + add r2, r2, #8 @; pasar al siguiente índice del vector de + b .Lintr_find @; manejadores de interrupciones específicas +.Lintr_ret: + mov r1, r0 @; indica qué interrupción se ha servido +.Lintr_setflags: + str r1, [r12, #0x0C] @; REG_IF = R1 (comunica interrupción servida) + ldr r0, =__irq_flags @; R0 = dirección flags IRQ para gestión IntrWait + ldr r3, [r0] + orr r3, r3, r1 @; activar el flag correspondiente a la interrupción + str r3, [r0] @; servida (todas si no se ha encontrado el maneja- + @; dor correspondiente) + mov pc,lr @; retornar al gestor de la excepción IRQ de la BIOS + + + .global _gp_rsiVBL + @; Manejador de interrupciones VBL (Vertical BLank) de Garlic: + @; se encarga de actualizar los tics, intercambiar procesos, etc. +_gp_rsiVBL: + push {r4-r7, lr} + + pop {r4-r7, pc} + + + @; Rutina para salvar el estado del proceso interrumpido en la entrada + @; del vector _gd_psv correspondiente al zócalo actual + @;Parámetros + @; R4: dirección _gd_nReady + @; R5: número de procesos en READY + @; R6: dirección _gd_pidz + @; R7: PIDz + @;Resultado + @; R5: nuevo número de procesos en READY (+1) +_gp_salvarProc: + push {r8-r11, lr} + + pop {r8-r11, pc} + + + @; Rutina para restaurar el estado del siguiente proceso en la cola de READY + @;Parámetros + @; R4: dirección _gd_nReady + @; R5: número de procesos en READY + @; R6: dirección _gd_pidz +_gp_restaurarProc: + push {r8-r11, lr} + + pop {r8-r11, pc} + + + .global _gp_numProc + @;Resultado + @; R0: número total de procesos cargados en el sistema +_gp_numProc: + push {r1-r2, lr} + mov r0, #1 @; contar siempre 1 proceso en RUN + ldr r1, =_gd_nReady + ldr r2, [r1] @; R2 = número de procesos en cola de READY + add r0, r2 @; añadir procesos en READY + pop {r1-r2, pc} + + + .global _gp_crearProc + @; prepara un proceso para ser ejecutado, creando su entorno de ejecución y + @; colocándolo en la cola de READY + @;Parámetros + @; R0: intFunc funcion, + @; R1: int zocalo, + @; R2: char *nombre + @;Resultado + @; R0: 0 si no hay problema, >0 si no se puede crear el proceso +_gp_crearProc: + push {r1-r8, lr} + + pop {r1-r8, pc} + + + @; Función para terminar un proceso de usuario: + @; borra el PID del PSB del zócalo actual, para indicar que esa entrada + @; del vector _gd_psv está libre; también elimina el PID de la variable + @; _gd_pidz (sin modificar el número de zócalo), para que el procedimiento + @; de intercambio de procesos NO salve el estado del proceso terminado. +_gp_terminarProc: + ldr r0, =_gd_pidz + ldr r1, [r0] @; R1 = valor actual de PID + zócalo + and r1, r1, #0xf @; R1 = zócalo del proceso desbancado + str r1, [r0] @; guardar zócalo con PID = 0, para no salvar estado + ldr r2, =_gd_psv + add r2, r1, lsl #6 @; R2 = dirección base _gd_psv[zocalo] + mov r3, #0 + str r3, [r2] @; borrar PID del bloque de estado del proceso + bl _gp_WaitForVBlank @; pausar procesador + + +.end + diff --git a/GARLIC_OS/source/garlic_mem.c b/GARLIC_OS/source/garlic_mem.c new file mode 100644 index 0000000..70e76ab --- /dev/null +++ b/GARLIC_OS/source/garlic_mem.c @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ + + "garlic_mem.c" : fase 1 / programador M + + Rutinas de carga de un fichero ejecutable en formato ELF, para el sistema + GARLIC 0.5 + +------------------------------------------------------------------------------*/ +#include +#include +#include +#include + +#include // definición de funciones y variables de sistema + + + +/* _gm_relocatar: a partir de una dirección de memoria (destino), de un vector + que contiene todo el fichero ELF (file) y de una dirección 'virtual' + de inicio de un segmento (pAddr), esta función interpretará los + 'relocs' del fichero ELF y ajustará las direcciones de memoria + correspondientes a relocs de tipo R_ARM_ABS32, restando la dirección + virtual y sumando la dirección destino */ +void _gm_relocatar(unsigned int *destino, char *file, unsigned int pAddr) +{ + +} + +/* _gm_cargarPrograma: cargar el programa "(keyName).elf" en una zona de memoria + libre y relocatar las referencias a los símbolos del programa; */ +//--------------------------------------------------------------------------------- +intFunc _gm_cargarPrograma(char *keyName) { +//--------------------------------------------------------------------------------- + unsigned int result = 0; + + return ((intFunc) result); +} + + + diff --git a/GARLIC_OS/source/garlic_vectors.s b/GARLIC_OS/source/garlic_vectors.s new file mode 100644 index 0000000..c4c2c8c --- /dev/null +++ b/GARLIC_OS/source/garlic_vectors.s @@ -0,0 +1,74 @@ +@;============================================================================== +@; +@; "garlic_vector.s": vector de direcciones de funciones del API de GARLIC +@; +@;============================================================================== + +.section .vectors,"a",%progbits + +@;Vector de manejadores de excepciones ARM +@;ATENCIÓN: ¡NO funciona en un entorno emulado (DeSmuME)! +@;Por este motivo, el siguiente código está comentado: +@; +@; .arm +@;SystemVectors: @; Vector de excepciones ARM +@; ldr pc, bios_reset +@; ldr pc, bios_undefined +@; b garlic_SWI @; en vez de 'ldr pc, =bios_swi' +@; ldr pc, bios_prefetch_abort +@; ldr pc, bios_data_abort +@;dummy: b dummy +@; ldr pc, bios_irq +@; ldr pc, bios_fiq +@; +@; @; Direcciones de manejadores de excepciones de la BIOS +@;bios_reset: +@; .word 0xFFFF0000 +@;bios_undefined: +@; .word 0xFFFF0004 +@;bios_swi: +@; .word 0xFFFF0008 +@;bios_prefetch_abort: +@; .word 0xFFFF000C +@;bios_data_abort: +@; .word 0xFFFF0010 +@;bios_irq: +@; .word 0xFFFF0018 +@;bios_fiq: +@; .word 0xFFFF001C +@; +@; +@; Nueva rutina de tratamiento de excepciones SWI, para llamadas al sistema +@; GARLIC (con identificador de SWI mayor o igual a 0x20) +@;garlic_SWI: +@; push {r4, r5} @; guardar registros modificados en pila de SVC +@; +@; mov r4, lr +@; sub r4, #2 +@; ldrb r5, [r4] @; R5 = código identificador de SWI (byte) +@; cmp r5, #0x20 +@; bhs .LGarlicFunc @; si >= 0x20, se trata de una llamada GARLIC +@; @; sinó, transferir el control a la BIOS +@; pop {r4, r5} @; restaurar registros +@; ldr pc, =bios_swi @; saltar al tratamiento de SWI de la BIOS +@; +@; .LGarlicFunc: @; tratamiento de funciones del API de GARLIC +@; sub r5, #0x20 @; restar el desplazamiento al número de func. +@; ldr r4, =APIVector @; R4 = base de vector de direcciones de func. +@; bl [r4, r5, lsl #2] @; salto indirecto a través del vector +@; +@; pop {r4, r5} @; recuperar registros modificados +@; movs pc, lr @; retorno de la excepción SWI +@; +@; .pool @; posición para guardar valores de 32 bits +@; +@;¡FIN del código comentado! + + +APIVector: @; Vector de direcciones de funciones + .word _gi_random @; (código de funciones en "garlic_itcm_api.s") + .word _gi_divmod + .word _gi_num2str + .word _gi_print + +.end \ No newline at end of file diff --git a/GARLIC_OS/source/main.c b/GARLIC_OS/source/main.c new file mode 100644 index 0000000..642ae00 --- /dev/null +++ b/GARLIC_OS/source/main.c @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------------ + + "main.c" : fase 1 / master + + Programa de control del sistema operativo GARLIC, versión 0.5 + +------------------------------------------------------------------------------*/ +#include +#include +#include + +#include // definición de funciones y variables de sistema + +extern int * punixTime; // puntero a zona de memoria con el tiempo real + + +/* Inicializaciones generales del sistema Garlic */ +//------------------------------------------------------------------------------ +void inicializarSistema() { +//------------------------------------------------------------------------------ + + _gg_iniGraf(); // inicializar gráficos + + _gd_seed = *punixTime; // inicializar semilla para números aleatorios con + _gd_seed <<= 16; // el valor de tiempo real UNIX, desplazado 16 bits + + irqInitHandler(_gp_IntrMain); // inicializar IRQs + irqSet(IRQ_VBLANK, _gp_rsiVBL); + irqEnable(IRQ_VBLANK); + + _gd_psv[0].keyName = 0x4C524147; // "GARL" + + if (!nitroFSInit()) { + _gg_escribir("ERROR: ¡no se puede utilizar NitroFS!", 0); + exit(0); + } +} + + +//------------------------------------------------------------------------------ +int main(int argc, char **argv) { +//------------------------------------------------------------------------------ + intFunc start; + char string[8]; + + inicializarSistema(); + + _gg_escribir("********************************", 0); + _gg_escribir("* *", 0); + _gg_escribir("* Sistema Operativo GARLIC 0.5 *", 0); + _gg_escribir("* *", 0); + _gg_escribir("********************************", 0); + _gg_escribir("*** Inicio fase 1\n", 0); + + _gg_escribir("*** Carga de programa HOLA.elf\n", 0); + start = _gm_cargarPrograma("HOLA"); + if (start) + { + _gg_escribir("*** Pusle \'START\' ::\n\n", 0); + while(1) { + _gp_WaitForVBlank(); + scanKeys(); + if (keysDown() & KEY_START) break; + } + + _gp_crearProc(start, 3, "HOLA"); + + while (_gp_numProc() > 1) + { // esperar a que termine el proceso pendiente + _gg_escribir("*** Test \t", 0); + _gi_num2str(string, 5, _gd_tickCount); + string[4] = '\t'; + _gi_num2str(&string[5], 2, _gp_numProc()); + string[6] = '\n'; string[7] = 0; + _gg_escribir(string, 0); + } + } else + _gg_escribir("*** Programa NO cargado\n", 0); + + _gg_escribir("*** Final fase 1\n", 0); + + while(1) { + _gp_WaitForVBlank(); + } // parar el procesador en un bucle infinito + return 0; +} + + diff --git a/GARLIC_Progs/HOLA/Makefile b/GARLIC_Progs/HOLA/Makefile new file mode 100644 index 0000000..9316716 --- /dev/null +++ b/GARLIC_Progs/HOLA/Makefile @@ -0,0 +1,61 @@ +#------------------------------------------------------------------------------- +# Makefile for a GARLIC program (Executable) +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# Current directory for GARLIC's API content +#------------------------------------------------------------------------------- +GARLICAPI := ../../GARLIC_API + # assume a relative structure of the GARLIC project directories + +#--------------------------------------------------------------------------------- +# TARGET is the name of the project's directory +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) + +#------------------------------------------------------------------------------- +# options for Executable code generation +#------------------------------------------------------------------------------- +ARCH := -march=armv5te -mlittle-endian + +CFLAGS := -Wall -g0 $(ARCH) -mtune=arm946e-s -fomit-frame-pointer -ffast-math + # -Wall : enable all warnings + # -g0 : disable debug info generation + # $(ARCH) -mtune=arm946e-s : tune code generation for specific machine + # -fomit-frame-pointer : avoid to use a 'frame-pointer' register in functions that do not need it + # -ffast-math : optimize math operations + +ASFLAGS := -g0 $(ARCH) -mcpu=arm946e-s + # -g0 : disable debug info generation + # $(ARCH) -mcpu=arm946e-s : define architecture and machine + +LDFLAGS := --oformat elf32-littlearm \ + --emit-relocs --gc-sections --strip-debug + # --oformat elf32-littlearm : define output code target + # --emit-relocs : generate relocations in final output + # --gc-sections : remove unused sections + # --strip-debug : strip debugging symbols + +#------------------------------------------------------------------------------- +# make commands +#------------------------------------------------------------------------------- + +$(TARGET).elf : $(TARGET).o + @echo "linking $(TARGET).o into $(TARGET).elf" + @arm-eabi-ld $(LDFLAGS) $(TARGET).o $(GARLICAPI)/GARLIC_API.o -o $(TARGET).elf + +$(TARGET).o : $(TARGET).s + @echo "assembling $(TARGET).s into $(TARGET).o" + @arm-eabi-as $(ASFLAGS) $(TARGET).s -o $(TARGET).o + +$(TARGET).s : $(TARGET).c + @echo "compiling $(TARGET).c into $(TARGET).s" + @arm-eabi-gcc $(CFLAGS) -S $(TARGET).c -I$(GARLICAPI) -o $(TARGET).s + +#--------------------------------------------------------------------------------- +# clean commands +#--------------------------------------------------------------------------------- +clean : + @rm -fv $(TARGET).s + @rm -fv $(TARGET).o + @rm -fv $(TARGET).elf diff --git a/GARLIC_Progs/HOLA/hola.c b/GARLIC_Progs/HOLA/hola.c new file mode 100644 index 0000000..75cdd32 --- /dev/null +++ b/GARLIC_Progs/HOLA/hola.c @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------------ + + "HOLA.c" : primer programa de prueba para el sistema operativo GARLIC; + + Imprime el típico mensaje "Hello world!" por una ventana de GARLIC, un + número aleatorio de veces. + +------------------------------------------------------------------------------*/ + +#include /* definición de las funciones API de GARLIC */ + +int _start(void) /* función de inicio : no se usa 'main' */ +{ + unsigned int i, iter; + char num[5]; + + GARLIC_print("-- Programa HOLA (Garlic 0.5) --"); + // cálculo del número aleatorio de iteraciones + GARLIC_divmod((unsigned) GARLIC_random(), 100, &i, &iter); + iter++; // asegurar que hay al menos una iteración + for (i = 0; i < iter; i++) + { + GARLIC_num2str(num, 5, i); + GARLIC_print(num); + GARLIC_print("\tHello world!\n"); + } + return 0; +} diff --git a/GARLIC_Progs/HOLA/hola.pnproj b/GARLIC_Progs/HOLA/hola.pnproj new file mode 100644 index 0000000..d7d9a4a --- /dev/null +++ b/GARLIC_Progs/HOLA/hola.pnproj @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GARLIC_Progs/HOLA/hola.s b/GARLIC_Progs/HOLA/hola.s new file mode 100644 index 0000000..37b54b5 --- /dev/null +++ b/GARLIC_Progs/HOLA/hola.s @@ -0,0 +1,72 @@ + .arch armv5te + .fpu softvfp + .eabi_attribute 23, 1 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 1 + .eabi_attribute 30, 6 + .eabi_attribute 18, 4 + .file "hola.c" + .section .rodata + .align 2 +.LC0: + .ascii "-- Programa HOLA (Garlic 0.5) --\000" + .align 2 +.LC1: + .ascii "\011Hello world!\012\000" + .text + .align 2 + .global _start + .type _start, %function +_start: + @ args = 0, pretend = 0, frame = 16 + @ frame_needed = 0, uses_anonymous_args = 0 + str lr, [sp, #-4]! + sub sp, sp, #20 + ldr r0, .L4 + bl GARLIC_print + bl GARLIC_random + mov r3, r0 + mov r1, r3 + add r2, sp, #12 + add r3, sp, #8 + mov r0, r1 + mov r1, #100 + bl GARLIC_divmod + ldr r3, [sp, #8] + add r3, r3, #1 + str r3, [sp, #8] + mov r3, #0 + str r3, [sp, #12] + b .L2 +.L3: + ldr r3, [sp, #12] + mov r2, sp + mov r0, r2 + mov r1, #5 + mov r2, r3 + bl GARLIC_num2str + mov r3, sp + mov r0, r3 + bl GARLIC_print + ldr r0, .L4+4 + bl GARLIC_print + ldr r3, [sp, #12] + add r3, r3, #1 + str r3, [sp, #12] +.L2: + ldr r2, [sp, #12] + ldr r3, [sp, #8] + cmp r2, r3 + bcc .L3 + mov r3, #0 + mov r0, r3 + add sp, sp, #20 + ldmfd sp!, {pc} +.L5: + .align 2 +.L4: + .word .LC0 + .word .LC1 + .size _start, .-_start + .ident "GCC: (devkitARM release 34) 4.6.1"