--- /dev/null
+
+ARM_CPUNAME = gerneric-armv6
+CC = arm-armv6-eabi-gcc -mcpu=$(ARM_CPUNAME)
+AS = arm-armv6-eabi-gcc -mcpu=$(ARM_CPUNAME) -c
+LD = arm-armv6-eabi-ld
+OBJDUMP = arm-armv6-eabi-objdump
+DISASM = $(OBJDUMP) -d -S
+ARCHDIR = armv6
+STRIP = arm-elf-strip
+
+ASSUFFIX = S
+
+# Default Configuration
+ifeq ($(PLATFORM),)
+ PLATFORM=raspberrypi
+$(warning Defaulting to "PLATFORM=$(PLATFORM)")
+endif
+
--- /dev/null
+
+ifeq ($(PLATFORM),default)
+ $(error Please select a platform)
+endif
+
+#MODULES += armv7/GIC
+MODULES += Filesystems/InitRD
--- /dev/null
+
+include $(ACESSDIR)/BuildConf/armv6/default.mk
+ARM_CPUNAME = arm1176jzf-s
# - Does whatever architecture defined rules
$(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile ../../BuildConf/$(ARCH)/Makefile.cfg ../../BuildConf/$(ARCH)/$(PLATFORM).mk
@echo --- LD -o $(BIN)
- @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
+ @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) $(LIBGCC_PATH) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
@$(DISASM) -S $(BIN) > $(BIN).dsm
@echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum.$(ARCH)
$(POSTBUILD)
--- /dev/null
+#
+# Acess2 Kernel
+# arm7 Architecture Makefile
+# arch/arm7/Makefile
+
+CPPFLAGS =
+CFLAGS =
+ASFLAGS =
+
+CPPFLAGS += -DMMU_PRESENT=1
+LDFLAGS +=
+LIBGCC_PATH = $(shell $(CC) --print-libgcc-file-name)
+
+A_OBJ = start.ao main.o lib.o lib.ao time.o pci.o debug.o
+A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao
+
+#main.c: Makefile.BuildNum.$(ARCH)
+
+ifeq ($(PLATFORM),tegra2)
+ POSTBUILD = arm-elf-objcopy $(BIN) -O binary $(BIN)
+endif
--- /dev/null
+/**
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/debug.c
+ * - ARM7 Debug output
+ * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu
+ */
+#include <acess.h>
+
+// === CONSTANTS ===
+//#define UART0_BASE 0x10009000
+#define UART0_BASE 0xF1000000 // Boot time mapped
+
+// === PROTOTYPES ===
+void KernelPanic_SetMode(void);
+void KernelPanic_PutChar(char Ch);
+void StartupPrint(const char *str);
+
+// === GLOBALS ===
+ int giDebug_SerialInitialised = 0;
+
+// === CODE ===
+void Debug_PutCharDebug(char ch)
+{
+ if(ch == '\n')
+ Debug_PutCharDebug('\r');
+
+ #if PLATFORM_is_tegra2
+ // Tegra2
+ while( !(*(volatile Uint32*)(UART0_BASE + 0x14) & (1 << 5)) )
+ ;
+ #endif
+
+// *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_DATA) = ch;
+ *(volatile Uint32*)(UART0_BASE) = ch;
+}
+
+void Debug_PutStringDebug(const char *str)
+{
+ for( ; *str; str++ )
+ Debug_PutCharDebug( *str );
+}
+
+void KernelPanic_SetMode(void)
+{
+}
+
+void KernelPanic_PutChar(char ch)
+{
+// Debug_PutCharDebug(ch);
+}
+
+void StartupPrint(const char *str)
+{
+}
+
--- /dev/null
+/*
+ * Acess2
+ * ARM7 Architecture Header
+ */
+#ifndef _ARCH_H_
+#define _ARCH_H_
+
+// === CONSTANTS ===
+#define INVLPTR ((void*)-1)
+#define BITS 32
+#define PAGE_SIZE 0x1000
+#define KERNEL_BASE 0x80000000 // 2GiB
+
+// === TYPES ===
+typedef unsigned int Uint;
+typedef unsigned char Uint8;
+typedef unsigned short Uint16;
+typedef unsigned long Uint32;
+typedef unsigned long long Uint64;
+typedef signed int Sint;
+typedef signed char Sint8;
+typedef signed short Sint16;
+typedef signed long Sint32;
+typedef signed long long Sint64;
+
+typedef int size_t;
+typedef char BOOL;
+
+typedef Uint32 tVAddr;
+typedef Uint32 tPAddr;
+
+#include "lock.h"
+
+// --- Debug
+extern void Debug_PutCharDebug(char Ch);
+extern void Debug_PutStringDebug(const char *String);
+
+// This should be elsewhere, but CBF
+extern void MM_SetupPhys(void);
+extern int MM_InitialiseVirtual(void);
+
+#define NO_IO_BUS 1
+
+#endif
--- /dev/null
+/*
+ * Acess2 ARMv7
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/include/assembly.h
+ * - Assembly specific macros
+ */
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+#define PUSH_GPRS \
+ str r0, [sp,#-1*4];\
+ str r1, [sp,#-2*4];\
+ str r2, [sp,#-3*4];\
+ str r3, [sp,#-4*4];\
+ str r4, [sp,#-5*4];\
+ str r5, [sp,#-6*4];\
+ str r6, [sp,#-7*4];\
+ str r7, [sp,#-8*4];\
+ str r8, [sp,#-9*4];\
+ str r9, [sp,#-10*4];\
+ str r10, [sp,#-11*4];\
+ str r11, [sp,#-12*4];\
+ str r12, [sp,#-13*4];\
+ str sp, [sp,#-14*4];\
+ str lr, [sp,#-15*4];\
+ sub sp, #16*4
+
+#define POP_GPRS add sp, #16*4; \
+ ldr r0, [sp,#-1*4]; \
+ ldr r1, [sp,#-2*4]; \
+ ldr r2, [sp,#-3*4]; \
+ ldr r3, [sp,#-4*4]; \
+ ldr r4, [sp,#-5*4]; \
+ ldr r5, [sp,#-6*4]; \
+ ldr r6, [sp,#-7*4]; \
+ ldr r7, [sp,#-8*4]; \
+ ldr r8, [sp,#-9*4]; \
+ ldr r9, [sp,#-10*4]; \
+ ldr r10, [sp,#-11*4]; \
+ ldr r11, [sp,#-12*4]; \
+ ldr r12, [sp,#-13*4]; \
+ ldr lr, [sp,#-15*4];
+
+#endif
+
--- /dev/null
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * lock.h - Hardware level spinlocks
+ */
+#ifndef _LOCK_H_
+#define _LOCK_H_
+
+// === CODE ===
+struct sShortSpinlock {
+ int Lock;
+};
+
+// --- Spinlocks ---
+static inline int IS_LOCKED(struct sShortSpinlock *Lock)
+{
+ return !!Lock->Lock;
+}
+
+static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock)
+{
+ // TODO: Handle multiple CPUs
+ return !!Lock->Lock;
+}
+
+static inline int SHORTLOCK(struct sShortSpinlock *Lock)
+{
+ #if 0
+ // Coped from linux, yes, but I know what it does now :)
+ Uint tmp;
+ __asm__ __volatile__ (
+ "1: ldrex %0, [%1]\n" // Exclusive LOAD
+ " teq %0, #0\n" // Check if zero
+ " strexeq %0, %2, [%1]\n" // Set to one if it is zero (releasing lock on the memory)
+ " teqeq %0, #0\n" // If the lock was avaliable, check if the write succeeded
+ " bne 1b" // If the lock was unavaliable, or the write failed, loop
+ : "=&r" (tmp) // Temp
+ : "r" (&Lock->Lock), "r" (1)
+ : "cc" // Condition codes clobbered
+ );
+ #elif 1
+ while( *(volatile int*)&Lock->Lock ) ;
+ Lock->Lock = 1;
+ #else
+ int v = 1;
+ while( v )
+ __asm__ __volatile__ (
+ "swp %0, %0, [%1]"
+ : "=r" (v) : "r" (&Lock->Lock)
+ : "cc"
+ );
+ #endif
+ return 1;
+}
+
+static inline void SHORTREL(struct sShortSpinlock *Lock)
+{
+ Lock->Lock = 0;
+}
+
+#endif
+
--- /dev/null
+/*
+ * Acess2
+ * ARM7 Virtual Memory Manager Header
+ */
+#ifndef _MM_VIRT_H_
+#define _MM_VIRT_H_
+
+#include "options.h"
+
+#define USER_STACK_COMM 0x04000 // Pages to allocate up front
+#define USER_STACK_SIZE 0x10000 // Stack space
+#define USER_STACK_TOP 0x78000000
+
+#define MM_USER_MIN 0x00001000
+#define USER_LIB_MAX 0x70000000
+#define MM_PPD_HANDLES 0x7F800000
+#define MM_TABLE1USER 0x7FC00000 // 2 GiB - 4 MiB
+#define MM_TABLE0USER 0x7FE00000 // 2 GiB - 2 MiB
+#define MM_KSTACK_BASE 0x7FE00000
+#define MM_KSTACK_END 0x80000000
+
+// Page Blocks are 12-bits wide (12 address bits used)
+// Hence, the table is 16KiB large (and must be so aligned)
+// and each block addresses 1MiB of data
+
+// First level table is aligned to 16KiB (restriction of TTBR reg)
+// - VMSAv6 uses two TTBR regs, determined by bit 31
+
+//#define KERNEL_BASE 0x80000000 // 2GiB
+
+#define MM_KHEAP_BASE 0x80800000 // 8MiB of kernel code
+#define MM_KHEAP_MAX 0xC0000000 // ~1GiB of kernel heap
+
+#define MM_MODULE_MIN 0xC0000000 // - 0xD0000000
+#define MM_MODULE_MAX 0xCF000000
+
+#define MM_GLOBALSTACKS 0xCF000000 // Global stacks
+#define MM_GLOBALSTACKS_END 0xD0000000
+
+// PMM Data, giving it 256MiB is overkill, but it's unused atm
+#define MM_MAXPHYSPAGE (1024*1024)
+// 2^(32-12) max pages
+// 8.125 bytes per page (for bitmap allocation)
+// = 8.125 MiB
+#define MM_PMM_BASE 0xE0000000
+#define MM_PMM_END 0xF0000000
+
+#define MM_HWMAP_BASE 0xF0000000 // Ent 0xF00
+#define MM_HWMAP_END 0xFE000000
+#define MM_TMPMAP_BASE 0xFE000000
+#define MM_TMPMAP_END 0xFF000000
+
+#define MM_KERNEL_VFS 0xFF000000 //
+#define MM_TABLE1KERN 0xFF800000 // - 0x???????? 4MiB
+//#define MM_TABLE0KERN 0xFFC00000 // - 0xFFE04000 16KiB
+
+#endif
--- /dev/null
+/*
+ * Acess2 ARMv6 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * options.h
+ * - C/ASM Shared constants
+ */
+#ifndef _ARMV7_OPTIONS_H_
+#define _ARMV7_OPTIONS_H_
+
+#define KERNEL_BASE 0x80000000
+
+#if PLATFORM_is_raspberrypi
+# define UART0_PADDR 0x7E215040 // Realview
+#else
+# error Unknown platform
+#endif
+
+#define MM_KSTACK_SIZE 0x2000 // 2 Pages
+
+#endif
+
--- /dev/null
+/*
+ * Acess2
+ * ARM7 Architecture
+ *
+ * proc.h - Arch-Dependent Process Management
+ */
+#ifndef _PROC_H_
+#define _PROC_H_
+
+#define MAX_CPUS 4
+#define USER_MAX 0x80000000
+
+// === STRUCTURES ===
+typedef struct {
+ Uint32 IP, SP;
+ Uint32 UserIP, UserSP;
+} tTaskState;
+
+typedef struct {
+ Uint32 Base;
+} tMemoryState;
+
+typedef struct {
+ union {
+ Uint32 Num;
+ Uint32 Error;
+ };
+ union {
+ Uint32 Arg1;
+ Uint32 Return;
+ };
+ union {
+ Uint32 Arg2;
+ Uint32 RetHi;
+ };
+ Uint32 Arg3;
+ Uint32 Arg4;
+ Uint32 Arg5;
+ Uint32 Arg6; // R6
+} tSyscallRegs;
+
+// === MACROS ===
+#define HALT() do{}while(0)
+
+// === PROTOTYPES ===
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 ARM
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/lib.S
+ * - Assembly editions of library functions
+ */
+#include "include/assembly.h"
+
+.globl __memcpy_byte
+__memcpy_byte:
+1:
+ tst r2, r2 @ Check counter
+ moveq pc, lr @ Return if zero
+ ldrb r3, [r1],#1 @ Read
+ strb r3, [r0],#1 @ Write
+ sub r2, #1
+ b 1b
+
+@
+@ Pre-aligned memcpy (32-bit blocks)
+@
+.globl __memcpy_align4
+__memcpy_align4:
+ push {r4}
+ mvn r3, #3 @ Mask for checking length
+
+ @ 4 byte chunk copies
+1: tst r2, r3
+ ldrne r4, [r1],#4
+ strne r4, [r0],#4
+ subne r2, #4
+ bne 1b
+
+ @ single byte copies to finish off
+2: tst r2, #3
+ beq 3f
+ ldrb r4, [r1],#1
+ strb r4, [r0],#1
+ sub r2, #1
+ b 2b
+
+3: pop {r4}
+ mov pc, lr
+
+@
+@ Division
+@
+.globl __divmod32_asm
+__divmod32_asm:
+ push {r4}
+ mov r4, #0 @ Return value
+ mov r3, #1 @ add value
+
+ @ Scan up for first larger multiple of 2
+1: cmp r0, r1 @ N < D
+ bmi 2f @ ^^
+ lsl r1, r1, #1 @ D <<= 1
+ lsls r3, r3, #1 @ add <<= 1
+ beq .err @ result is zero
+ b 1b
+
+ @ Go back down
+2: lsrs r3, r3, #1 @ add >>= 1
+ beq 3f @ Done (value is zero)
+ lsr r1, r1, #1 @ D >>= 1
+ cmp r0, r1 @ N < D
+ bmi 2b
+ sub r0, r1 @ N -= D
+ add r4, r3 @ ret += add
+ b 2b
+3:
+ tst r2, r2 @ Remainder (if wanted)
+ strne r0,[r2]
+ mov r0, r4 @ Return value
+ pop {r4}
+ mov pc, lr
+.err:
+ mov r0, #0
+ tst r2, r2
+ strne r0, [r2]
+ pop {r4}
+ mov pc, lr
+
--- /dev/null
+/*
+ * Acess2 ARM7 Port
+ *
+ * lib.c - Library Functions
+ */
+#include <acess.h>
+#include "../helpers.h"
+
+// === IMPORTS ===
+extern void __memcpy_align4(void *_dest, const void *_src, size_t _length);
+extern void __memcpy_byte(void *_dest, const void *_src, size_t _length);
+extern Uint32 __divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
+
+// === PROTOTYPES ===
+Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
+Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
+#if 0
+Uint64 __udivdi3(Uint64 Num, Uint64 Den);
+Uint64 __umoddi3(Uint64 Num, Uint64 Den);
+Uint32 __udivsi3(Uint32 Num, Uint32 Den);
+Uint32 __umodsi3(Uint32 Num, Uint32 Den);
+Sint32 __divsi3(Sint32 Num, Sint32 Den);
+Sint32 __modsi3(Sint32 Num, Sint32 Den);
+#endif
+
+// === CODE ===
+void *memcpy(void *_dest, const void *_src, size_t _length)
+{
+ Uint8 *dst8 = _dest;
+ const Uint8 *src8 = _src;
+
+ if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
+ {
+ __memcpy_align4(_dest, _src, _length);
+ return _dest;
+ }
+
+ // Handle small copies / Non-aligned
+ if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
+ {
+ __memcpy_byte(_dest, _src, _length);
+ return _dest;
+ }
+
+ // Force alignment
+ while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
+
+ __memcpy_align4(dst8, src8, _length);
+
+ return _dest;
+}
+
+int memcmp(const void *_m1, const void *_m2, size_t _length)
+{
+ const Uint32 *m1, *m2;
+ const Uint8 *m1_8 = _m1, *m2_8 = _m2;
+
+ // Handle small copies / Non-aligned
+ if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
+ {
+ for( ; _length--; m1_8++,m2_8++ ) {
+ if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
+ }
+ return 0;
+ }
+
+ // Force alignment
+ for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
+ if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
+ }
+ m1 = (void *)m1_8; m2 = (void *)m2_8;
+
+ // DWORD copies
+ for( ; _length > 3; _length -= 4, m1++, m2++)
+ if(*m1 != *m2) return *m1 - *m2;
+
+ // Trailing bytes
+ m1_8 = (void*)m1; m2_8 = (void*)m2;
+ for( ; _length; _length --, m1_8++, m2_8++ )
+ if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
+
+ return 0;
+}
+
+void *memset(void *_dest, int _value, size_t _length)
+{
+ Uint32 *dst, val32;
+ Uint8 *dst8 = _dest;
+
+ _value = (Uint8)_value;
+
+ // Handle small copies
+ if( _length < 4 )
+ {
+ for( ; _length--; dst8++ )
+ *dst8 = _value;
+ return _dest;
+ }
+
+ val32 = _value;
+ val32 |= val32 << 8;
+ val32 |= val32 << 16;
+
+ // Force alignment
+ while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
+ dst = (void *)dst8;
+
+ // DWORD copies
+ for( ; _length > 3; _length -= 4)
+ *dst++ = val32;
+
+ // Trailing bytes
+ dst8 = (void*)dst;
+ for( ; _length; _length -- )
+ *dst8 ++ = _value;
+
+ return _dest;
+}
+
+DEF_DIVMOD(64)
+DEF_DIVMOD(32)
+
+Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
+{
+ Uint64 ret;
+ if(Den == 0) return 0; // TODO: #div0
+ if(Num < Den) {
+ if(Rem) *Rem = Num;
+ return 0;
+ }
+ if(Num == 0) {
+ if(Rem) *Rem = 0;
+ return 0;
+ }
+ if(Den == 1) {
+ if(Rem) *Rem = 0;
+ return Num;
+ }
+ if(Den == 2) {
+ if(Rem) *Rem = Num & 1;
+ return Num >> 1;
+ }
+ if(Den == 16) {
+ if(Rem) *Rem = Num & 0xF;
+ return Num >> 4;
+ }
+ if(Den == 32) {
+ if(Rem) *Rem = Num & 0x1F;
+ return Num >> 5;
+ }
+ if(Den == 0x1000) {
+ if(Rem) *Rem = Num & 0xFFF;
+ return Num >> 12;
+ }
+
+ if( !(Den >> 32) && !(Num >> 32) ) {
+ if(Rem) *Rem = 0; // Clear high bits
+ return __divmod32_asm(Num, Den, (Uint32*)Rem);
+ }
+
+ ret = __divmod64(Num, Den, Rem);
+ return ret;
+}
+
+#if 0
+// Unsigned Divide 64-bit Integer
+Uint64 __udivdi3(Uint64 Num, Uint64 Den)
+{
+ return DivMod64U(Num, Den, NULL);
+}
+
+// Unsigned Modulus 64-bit Integer
+Uint64 __umoddi3(Uint64 Num, Uint64 Den)
+{
+ Uint64 ret = 0;
+ DivMod64U(Num, Den, &ret);
+ return ret;
+}
+
+Uint32 __udivsi3(Uint32 Num, Uint32 Den)
+{
+ return __divmod32_asm(Num, Den, NULL);
+}
+
+Uint32 __umodsi3(Uint32 Num, Uint32 Den)
+{
+ Uint32 rem;
+ __divmod32_asm(Num, Den, &rem);
+ return rem;
+}
+#endif
+
+static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
+{
+ Sint32 ret = 1;
+ if( Num < 0 ) {
+ ret = -ret;
+ Num = -Num;
+ }
+ if( Den < 0 ) {
+ ret = -ret;
+ Den = -Den;
+ }
+ if(ret < 0)
+ ret = -__divmod32(Num, Den, (Uint32*)Rem);
+ else
+ ret = __divmod32(Num, Den, (Uint32*)Rem);
+ return ret;
+}
+
+#if 0
+Sint32 __divsi3(Sint32 Num, Sint32 Den)
+{
+ return DivMod32S(Num, Den, NULL);
+}
+
+Sint32 __modsi3(Sint32 Num, Sint32 Den)
+{
+ Sint32 rem;
+ DivMod32S(Num, Den, &rem);
+ return rem;
+}
+#endif
+
--- /dev/null
+ENTRY (_start)
+
+_kernel_base = 0x80000000;
+_usertext_vbase = 0xFFFFE000;
+
+SECTIONS
+{
+ . = 0;
+ .init :
+ {
+ *(.init)
+ }
+ . += _kernel_base;
+ .text : AT( ADDR(.text) - _kernel_base )
+ {
+ *(.text*)
+ *(.rodata*)
+ }
+ __exidx_start = .;
+ .ARM.exidx : { *(.ARM.exidx*) }
+ __exidx_end = .;
+ .ARM.extab : { *(.ARM.extab*) }
+
+
+ /* HACKS: User accesible .text section */
+ . = ALIGN(0x1000);
+ gUsertextPhysStart = . - _kernel_base;
+ . = _usertext_vbase;
+ .usertext : AT( gUsertextPhysStart )
+ {
+ *(.usertext)
+ }
+ . += gUsertextPhysStart + _kernel_base - _usertext_vbase;
+
+ /* 0x4000 (4 pages) alignment needed for root table */
+ .data ALIGN(0x4000) : AT( ADDR(.data) - _kernel_base )
+ {
+ *(.padata)
+ *(.data*)
+
+ gKernelSymbols = .;
+ *(KEXPORT)
+ gKernelSymbolsEnd = .;
+
+ gKernelModules = .;
+ *(KMODULES)
+ gKernelModulesEnd = .;
+ }
+ .bss : AT( ADDR(.bss) - _kernel_base )
+ {
+ bss_start = .;
+ *(.bss*)
+ *(COMMON*)
+ . = ALIGN(0x1000);
+ *(.pabss)
+ bss_end = .;
+ }
+ gKernelEnd = .;
+}
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Entrypoint
+ * arch/arm7/main.c
+ */
+#define DEBUG 0
+
+#include <acess.h>
+#include <modules.h>
+
+// === IMPORTS ===
+extern void Interrupts_Setup(void);
+extern void Arch_LoadBootModules(void);
+extern void Heap_Install(void);
+extern void Threads_Init(void);
+extern void System_Init(const char *Commandline);
+
+// === PROTOTYPES ===
+ int kmain(void);
+Uint32 ARMv7_int_HandleSyscalls(Uint32 Num, Uint32 *Args);
+
+// === CODE ===
+int kmain(void)
+{
+ LogF("Acess2 ARMv7 v"EXPAND_STR(KERNEL_VERSION)"\n");
+ LogF(" Git Hash %s\n", gsGitHash);
+ LogF(" Build %i\n", BUILD_NUM);
+
+ MM_SetupPhys();
+
+ LogF("Heap Setup...\n");
+ Heap_Install();
+
+ LogF("Threads Init...\n");
+ Threads_Init();
+
+ LogF("VFS Init...\n");
+ VFS_Init();
+
+ // Boot modules?
+ Module_EnsureLoaded("armv7_GIC");
+
+ //
+ LogF("Moving to arch-independent init\n");
+ #if PLATFORM_is_tegra2
+ System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid");
+ #else
+ System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=PL110");
+ #endif
+// System_Init("Acess2.armv7.bin /Acess=initrd:");
+ //TODO:
+ LogF("End of kmain(), for(;;) Threads_Sleep();\n");
+ for(;;)
+ Threads_Sleep();
+}
+
+void Arch_LoadBootModules(void)
+{
+}
+
+Uint32 ARMv7_int_HandleSyscalls(Uint32 Num, Uint32 *Args)
+{
+ Uint32 ret = -1, err = 0;
+ Uint32 addr;
+ ENTER("iNum xArgs[0] xArgs[1] xArgs[2] xArgs[3]",
+ Num, Args[0], Args[1], Args[2], Args[3]
+ );
+ switch(Num)
+ {
+ case 1:
+// Log_Debug("ARMv7", "__clear_cache(%p, %p)", Args[0], Args[1]);
+ // Align
+ Args[0] &= ~0xFFF;
+ Args[1] += 0xFFF; Args[1] &= ~0xFFF;
+ // Invalidate!
+ for( addr = Args[0]; addr < Args[1]; addr += 0x1000 )
+ {
+ LOG("addr = %p", addr);
+ __asm__ __volatile__ (
+ "mcrlt p15, 0, %0, c7, c5, 1;\n\t"
+ "mcrlt p15, 0, %0, c7, c6, 1;\n\t"
+ :
+ : "r" (addr)
+ );
+ }
+ ret = 0;
+ break;
+ }
+ Args[0] = ret; // RetLow
+ Args[1] = 0; // RetHi
+ Args[2] = err; // Errno
+ LEAVE('x', ret);
+ return ret;
+}
+
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Physical Memory Manager
+ * arch/arm7/mm_phys.c
+ */
+#define DEBUG 0
+
+#include <acess.h>
+#include <mm_virt.h>
+
+#define MM_NUM_RANGES 1 // Single range
+#define MM_RANGE_MAX 0
+#define TRACE_ALLOCS 0
+
+#define NUM_STATIC_ALLOC 4
+
+char gStaticAllocPages[NUM_STATIC_ALLOC][PAGE_SIZE] __attribute__ ((section(".padata")));
+tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = {
+ (tPAddr)(&gStaticAllocPages[0]) - KERNEL_BASE,
+ (tPAddr)(&gStaticAllocPages[1]) - KERNEL_BASE,
+ (tPAddr)(&gStaticAllocPages[2]) - KERNEL_BASE,
+ (tPAddr)(&gStaticAllocPages[3]) - KERNEL_BASE
+};
+extern char gKernelEnd[];
+
+
+#include <tpl_mm_phys_bitmap.h>
+
+//#define REALVIEW_LOWRAM_SIZE 0x10000000
+#define REALVIEW_LOWRAM_SIZE (32*1024*1024)
+
+void MM_SetupPhys(void)
+{
+ LogF("MM_SetupPhys: ()\n");
+ MM_Tpl_InitPhys( REALVIEW_LOWRAM_SIZE/0x1000, NULL );
+}
+
+int MM_int_GetMapEntry( void *Data, int Index, tPAddr *Start, tPAddr *Length )
+{
+ switch(Index)
+ {
+ case 0:
+ *Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF;
+ *Length = REALVIEW_LOWRAM_SIZE - *Start;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * \brief Takes a physical address and returns the ID of its range
+ * \param Addr Physical address of page
+ * \return Range ID from eMMPhys_Ranges
+ */
+int MM_int_GetRangeID( tPAddr Addr )
+{
+ return MM_RANGE_MAX; // ARM doesn't need ranges
+}
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Virtual Memory Manager
+ * - arch/arm7/mm_virt.c
+ */
+#define DEBUG 0
+#include <acess.h>
+#include <mm_virt.h>
+#include <hal_proc.h>
+
+#define TRACE_MAPS 0
+
+#define AP_KRW_ONLY 1 // Kernel page
+#define AP_KRO_ONLY 5 // Kernel RO page
+#define AP_RW_BOTH 3 // Standard RW
+#define AP_RO_BOTH 7 // COW Page
+#define AP_RO_USER 2 // User RO Page
+#define PADDR_MASK_LVL1 0xFFFFFC00
+
+// === IMPORTS ===
+extern Uint32 kernel_table0[];
+
+// === TYPES ===
+typedef struct
+{
+ tPAddr PhysAddr;
+ Uint8 Size;
+ Uint8 Domain;
+ BOOL bExecutable;
+ BOOL bGlobal;
+ BOOL bShared;
+ int AP;
+} tMM_PageInfo;
+
+//#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>20)])
+#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>22)])
+#define USRFRACTAL(addr) (*((Uint32*)(0x7FDFF000) + ((addr)>>22)))
+#define TLBIALL() __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0))
+#define TLBIMVA(addr) __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r" (((addr)&~0xFFF)|1):"memory")
+#define DCCMVAC(addr) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" ((addr)&~0xFFF))
+
+// === PROTOTYPES ===
+void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1);
+ int MM_int_AllocateCoarse(tVAddr VAddr, int Domain);
+ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
+ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi);
+tVAddr MM_NewUserStack(void);
+tPAddr MM_AllocateZero(tVAddr VAddr);
+tPAddr MM_AllocateRootTable(void);
+void MM_int_CloneTable(Uint32 *DestEnt, int Table);
+tPAddr MM_Clone(void);
+tVAddr MM_NewKStack(int bGlobal);
+void MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info);
+//void MM_DumpTables(tVAddr Start, tVAddr End);
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch);
+
+// === GLOBALS ===
+tPAddr giMM_ZeroPage;
+
+// === CODE ===
+int MM_InitialiseVirtual(void)
+{
+ return 0;
+}
+
+void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1)
+{
+ if(VAddr & 0x80000000) {
+ *Table0 = (void*)&kernel_table0; // Level 0
+ *Table1 = (void*)MM_TABLE1KERN; // Level 1
+ }
+ else {
+ *Table0 = (void*)MM_TABLE0USER;
+ *Table1 = (void*)MM_TABLE1USER;
+ }
+}
+
+int MM_int_AllocateCoarse(tVAddr VAddr, int Domain)
+{
+ Uint32 *table0, *table1;
+ Uint32 *desc;
+ tPAddr paddr;
+
+ ENTER("xVAddr iDomain", VAddr, Domain);
+
+ MM_int_GetTables(VAddr, &table0, &table1);
+
+ VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page
+
+ desc = &table0[ VAddr>>20];
+ LOG("desc = %p", desc);
+
+ // table0: 4 bytes = 1 MiB
+
+ LOG("desc[0] = %x", desc[0]);
+ LOG("desc[1] = %x", desc[1]);
+ LOG("desc[2] = %x", desc[2]);
+ LOG("desc[3] = %x", desc[3]);
+
+ if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0
+ || (desc[2] & 3) != 0 || (desc[3] & 3) != 0 )
+ {
+ // Error?
+ LEAVE('i', 1);
+ return 1;
+ }
+
+ paddr = MM_AllocPhys();
+ if( !paddr )
+ {
+ // Error
+ LEAVE('i', 2);
+ return 2;
+ }
+
+ *desc = paddr | (Domain << 5) | 1;
+ desc[1] = desc[0] + 0x400;
+ desc[2] = desc[0] + 0x800;
+ desc[3] = desc[0] + 0xC00;
+
+ if( VAddr < 0x80000000 ) {
+ USRFRACTAL(VAddr) = paddr | 0x13;
+ }
+ else {
+ FRACTAL(table1, VAddr) = paddr | 0x13;
+ }
+
+ // TLBIALL
+ TLBIALL();
+
+ memset( (void*)&table1[ (VAddr >> 12) & ~(1024-1) ], 0, 0x1000 );
+
+ LEAVE('i', 0);
+ return 0;
+}
+
+int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+ Uint32 *table0, *table1;
+ Uint32 *desc;
+
+ ENTER("pVAddr ppi", VAddr, pi);
+
+ MM_int_GetTables(VAddr, &table0, &table1);
+
+ desc = &table0[ VAddr >> 20 ];
+ LOG("desc = %p", desc);
+
+ switch(pi->Size)
+ {
+ case 12: // Small Page
+ case 16: // Large Page
+ LOG("Page");
+ if( (*desc & 3) == 0 ) {
+ MM_int_AllocateCoarse( VAddr, pi->Domain );
+ }
+ desc = &table1[ VAddr >> 12 ];
+ LOG("desc (2) = %p", desc);
+ if( pi->Size == 12 )
+ {
+ // Small page
+ // - Error if overwriting a large page
+ if( (*desc & 3) == 1 ) LEAVE_RET('i', 1);
+ if( pi->PhysAddr == 0 ) {
+ *desc = 0;
+ TLBIMVA( VAddr );
+ DCCMVAC( (tVAddr) desc );
+// #warning "HACK: TLBIALL"
+// TLBIALL();
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ *desc = (pi->PhysAddr & 0xFFFFF000) | 2;
+ if(!pi->bExecutable) *desc |= 1; // XN
+ if(!pi->bGlobal) *desc |= 1 << 11; // nG
+ if( pi->bShared) *desc |= 1 << 10; // S
+ *desc |= (pi->AP & 3) << 4; // AP
+ *desc |= ((pi->AP >> 2) & 1) << 9; // APX
+ TLBIMVA( VAddr );
+// #warning "HACK: TLBIALL"
+// TLBIALL();
+ DCCMVAC( (tVAddr) desc );
+ LEAVE('i', 0);
+ return 0;
+ }
+ else
+ {
+ // Large page
+ Log_Warning("MMVirt", "TODO: Implement large pages in MM_int_SetPageInfo");
+ }
+ break;
+ case 20: // Section or unmapped
+ Log_Warning("MMVirt", "TODO: Implement sections in MM_int_SetPageInfo");
+ break;
+ case 24: // Supersection
+ // Error if not aligned
+ if( VAddr & 0xFFFFFF ) {
+ LEAVE('i', 1);
+ return 1;
+ }
+ if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18))) )
+ {
+ if( pi->PhysAddr == 0 ) {
+ *desc = 0;
+ }
+ else {
+ // Apply
+ *desc = pi->PhysAddr & 0xFF000000;
+// *desc |= ((pi->PhysAddr >> 32) & 0xF) << 20;
+// *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5;
+ *desc |= 2 | (1 << 18);
+ }
+ // TODO: Apply to all entries
+ Log_Warning("MMVirt", "TODO: Apply changes to all entries of supersections");
+ LEAVE('i', 0);
+ return 0;
+ }
+ // TODO: What here?
+ Log_Warning("MMVirt", "TODO: 24-bit not on supersection?");
+ LEAVE('i', 1);
+ return 1;
+ }
+
+ LEAVE('i', 1);
+ return 1;
+}
+
+int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+ Uint32 *table0, *table1;
+ Uint32 desc;
+
+// LogF("MM_int_GetPageInfo: VAddr=%p, pi=%p\n", VAddr, pi);
+
+ MM_int_GetTables(VAddr, &table0, &table1);
+
+ desc = table0[ VAddr >> 20 ];
+
+// if( VAddr > 0x90000000)
+// LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc);
+
+ pi->bExecutable = 1;
+ pi->bGlobal = 0;
+ pi->bShared = 0;
+ pi->AP = 0;
+
+ switch( (desc & 3) )
+ {
+ // 0: Unmapped
+ case 0:
+ pi->PhysAddr = 0;
+ pi->Size = 20;
+ pi->Domain = 0;
+ return 1;
+
+ // 1: Coarse page table
+ case 1:
+ // Domain from top level table
+ pi->Domain = (desc >> 5) & 7;
+ // Get next level
+ desc = table1[ VAddr >> 12 ];
+// LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc);
+ switch( desc & 3 )
+ {
+ // 0: Unmapped
+ case 0:
+ pi->Size = 12;
+ return 1;
+ // 1: Large Page (64KiB)
+ case 1:
+ pi->Size = 16;
+ pi->PhysAddr = desc & 0xFFFF0000;
+ pi->AP = ((desc >> 4) & 3) | (((desc >> 9) & 1) << 2);
+ pi->bExecutable = !(desc & 0x8000);
+ pi->bShared = (desc >> 10) & 1;
+ return 0;
+ // 2/3: Small page
+ case 2:
+ case 3:
+ pi->Size = 12;
+ pi->PhysAddr = desc & 0xFFFFF000;
+ pi->bExecutable = !(desc & 1);
+ pi->bGlobal = !(desc >> 11);
+ pi->bShared = (desc >> 10) & 1;
+ pi->AP = ((desc >> 4) & 3) | (((desc >> 9) & 1) << 2);
+ return 0;
+ }
+ return 1;
+
+ // 2: Section (or Supersection)
+ case 2:
+ if( desc & (1 << 18) ) {
+ // Supersection
+ pi->PhysAddr = desc & 0xFF000000;
+ pi->PhysAddr |= (Uint64)((desc >> 20) & 0xF) << 32;
+ pi->PhysAddr |= (Uint64)((desc >> 5) & 0x7) << 36;
+ pi->Size = 24;
+ pi->Domain = 0; // Supersections default to zero
+ pi->AP = ((desc >> 10) & 3) | (((desc >> 15) & 1) << 2);
+ return 0;
+ }
+
+ // Section
+ pi->PhysAddr = desc & 0xFFF80000;
+ pi->Size = 20;
+ pi->Domain = (desc >> 5) & 7;
+ pi->AP = ((desc >> 10) & 3) | (((desc >> 15) & 1) << 2);
+ return 0;
+
+ // 3: Reserved (invalid)
+ case 3:
+ pi->PhysAddr = 0;
+ pi->Size = 20;
+ pi->Domain = 0;
+ return 2;
+ }
+ return 2;
+}
+
+// --- Exports ---
+tPAddr MM_GetPhysAddr(const void *Ptr)
+{
+ tVAddr VAddr = (tPAddr)Ptr;
+ tMM_PageInfo pi;
+ if( MM_int_GetPageInfo(VAddr, &pi) )
+ return 0;
+ return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
+}
+
+Uint MM_GetFlags(tVAddr VAddr)
+{
+ tMM_PageInfo pi;
+ int ret;
+
+ if( MM_int_GetPageInfo(VAddr, &pi) )
+ return 0;
+
+ ret = 0;
+
+ switch(pi.AP)
+ {
+ case 0:
+ break;
+ case AP_KRW_ONLY:
+ ret |= MM_PFLAG_KERNEL;
+ break;
+ case AP_KRO_ONLY:
+ ret |= MM_PFLAG_KERNEL|MM_PFLAG_RO;
+ break;
+ case AP_RW_BOTH:
+ break;
+ case AP_RO_BOTH:
+ ret |= MM_PFLAG_COW;
+ break;
+ case AP_RO_USER:
+ ret |= MM_PFLAG_RO;
+ break;
+ }
+
+ if( pi.bExecutable ) ret |= MM_PFLAG_EXEC;
+ return ret;
+}
+
+void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
+{
+ tMM_PageInfo pi;
+ Uint curFlags;
+
+ if( MM_int_GetPageInfo(VAddr, &pi) )
+ return ;
+
+ curFlags = MM_GetFlags(VAddr);
+ if( (curFlags & Mask) == Flags )
+ return ;
+ curFlags &= ~Mask;
+ curFlags |= Flags;
+
+ if( curFlags & MM_PFLAG_COW )
+ pi.AP = AP_RO_BOTH;
+ else
+ {
+ switch(curFlags & (MM_PFLAG_KERNEL|MM_PFLAG_RO) )
+ {
+ case 0:
+ pi.AP = AP_RW_BOTH; break;
+ case MM_PFLAG_KERNEL:
+ pi.AP = AP_KRW_ONLY; break;
+ case MM_PFLAG_RO:
+ pi.AP = AP_RO_USER; break;
+ case MM_PFLAG_KERNEL|MM_PFLAG_RO:
+ pi.AP = AP_KRO_ONLY; break;
+ }
+ }
+
+ pi.bExecutable = !!(curFlags & MM_PFLAG_EXEC);
+
+ MM_int_SetPageInfo(VAddr, &pi);
+}
+
+int MM_IsValidBuffer(tVAddr Addr, size_t Size)
+{
+ tMM_PageInfo pi;
+ int bUser = 0;
+
+ Size += Addr & (PAGE_SIZE-1);
+ Addr &= ~(PAGE_SIZE-1);
+
+ if( MM_int_GetPageInfo(Addr, &pi) ) return 0;
+ Addr += PAGE_SIZE;
+
+ if(pi.AP != AP_KRW_ONLY && pi.AP != AP_KRO_ONLY)
+ bUser = 1;
+
+ while( Size >= PAGE_SIZE )
+ {
+ if( MM_int_GetPageInfo(Addr, &pi) )
+ return 0;
+ if(bUser && (pi.AP == AP_KRW_ONLY || pi.AP == AP_KRO_ONLY))
+ return 0;
+ Addr += PAGE_SIZE;
+ Size -= PAGE_SIZE;
+ }
+
+ return 1;
+}
+
+int MM_Map(tVAddr VAddr, tPAddr PAddr)
+{
+ tMM_PageInfo pi = {0};
+ #if TRACE_MAPS
+ Log("MM_Map %P=>%p", PAddr, VAddr);
+ #endif
+
+ pi.PhysAddr = PAddr;
+ pi.Size = 12;
+ if(VAddr < USER_STACK_TOP)
+ pi.AP = AP_RW_BOTH;
+ else
+ pi.AP = AP_KRW_ONLY; // Kernel Read/Write
+ pi.bExecutable = 1;
+ if( MM_int_SetPageInfo(VAddr, &pi) ) {
+// MM_DerefPhys(pi.PhysAddr);
+ return 0;
+ }
+ return pi.PhysAddr;
+}
+
+tPAddr MM_Allocate(tVAddr VAddr)
+{
+ tMM_PageInfo pi = {0};
+
+ ENTER("pVAddr", VAddr);
+
+ pi.PhysAddr = MM_AllocPhys();
+ if( pi.PhysAddr == 0 ) LEAVE_RET('i', 0);
+ pi.Size = 12;
+ if(VAddr < USER_STACK_TOP)
+ pi.AP = AP_RW_BOTH;
+ else
+ pi.AP = AP_KRW_ONLY;
+ pi.bExecutable = 0;
+ if( MM_int_SetPageInfo(VAddr, &pi) ) {
+ MM_DerefPhys(pi.PhysAddr);
+ LEAVE('i', 0);
+ return 0;
+ }
+ LEAVE('x', pi.PhysAddr);
+ return pi.PhysAddr;
+}
+
+tPAddr MM_AllocateZero(tVAddr VAddr)
+{
+ if( !giMM_ZeroPage ) {
+ giMM_ZeroPage = MM_Allocate(VAddr);
+ MM_RefPhys(giMM_ZeroPage);
+ memset((void*)VAddr, 0, PAGE_SIZE);
+ }
+ else {
+ MM_RefPhys(giMM_ZeroPage);
+ MM_Map(VAddr, giMM_ZeroPage);
+ }
+ MM_SetFlags(VAddr, MM_PFLAG_COW, MM_PFLAG_COW);
+ return giMM_ZeroPage;
+}
+
+void MM_Deallocate(tVAddr VAddr)
+{
+ tMM_PageInfo pi;
+
+ if( MM_int_GetPageInfo(VAddr, &pi) ) return ;
+ if( pi.PhysAddr == 0 ) return;
+ MM_DerefPhys(pi.PhysAddr);
+
+ pi.PhysAddr = 0;
+ pi.AP = 0;
+ pi.bExecutable = 0;
+ MM_int_SetPageInfo(VAddr, &pi);
+}
+
+tPAddr MM_AllocateRootTable(void)
+{
+ tPAddr ret;
+
+ ret = MM_AllocPhysRange(2, -1);
+ if( ret & 0x1000 ) {
+ MM_DerefPhys(ret);
+ MM_DerefPhys(ret+0x1000);
+ ret = MM_AllocPhysRange(3, -1);
+ if( ret & 0x1000 ) {
+ MM_DerefPhys(ret);
+ ret += 0x1000;
+// Log("MM_AllocateRootTable: Second try not aligned, %P", ret);
+ }
+ else {
+ MM_DerefPhys(ret + 0x2000);
+// Log("MM_AllocateRootTable: Second try aligned, %P", ret);
+ }
+ }
+// else
+// Log("MM_AllocateRootTable: Got it in one, %P", ret);
+ return ret;
+}
+
+void MM_int_CloneTable(Uint32 *DestEnt, int Table)
+{
+ tPAddr table;
+ Uint32 *tmp_map;
+ Uint32 *cur = (void*)MM_TABLE1USER;
+// Uint32 *cur = &FRACTAL(MM_TABLE1USER,0);
+ int i;
+
+ table = MM_AllocPhys();
+ if(!table) return ;
+
+ cur += 256*Table;
+
+ tmp_map = MM_MapTemp(table);
+
+ for( i = 0; i < 1024; i ++ )
+ {
+// Log_Debug("MMVirt", "cur[%i] (%p) = %x", Table*256+i, &cur[Table*256+i], cur[Table*256+i]);
+ switch(cur[i] & 3)
+ {
+ case 0: tmp_map[i] = 0; break;
+ case 1:
+ tmp_map[i] = 0;
+ Log_Error("MMVirt", "TODO: Support large pages in MM_int_CloneTable (%p)", (Table*256+i)*0x1000);
+ // Large page?
+ break;
+ case 2:
+ case 3:
+ // Small page
+ // - If full RW
+// Debug("%p cur[%i] & 0x230 = 0x%x", Table*256*0x1000, i, cur[i] & 0x230);
+ if( (cur[i] & 0x230) == 0x010 )
+ {
+ void *dst, *src;
+ tPAddr newpage;
+ newpage = MM_AllocPhys();
+ src = (void*)( (Table*256+i)*0x1000 );
+ dst = MM_MapTemp(newpage);
+// Debug("Taking a copy of kernel page %p (%P)", src, cur[i] & ~0xFFF);
+ memcpy(dst, src, PAGE_SIZE);
+ MM_FreeTemp( dst );
+ tmp_map[i] = newpage | (cur[i] & 0xFFF);
+ }
+ else
+ {
+ if( (cur[i] & 0x230) == 0x030 )
+ cur[i] |= 0x200; // Set to full RO (Full RO=COW, User RO = RO)
+ tmp_map[i] = cur[i];
+ MM_RefPhys( tmp_map[i] & ~0xFFF );
+ }
+ break;
+ }
+ }
+ MM_FreeTemp( tmp_map );
+
+ DestEnt[0] = table + 0*0x400 + 1;
+ DestEnt[1] = table + 1*0x400 + 1;
+ DestEnt[2] = table + 2*0x400 + 1;
+ DestEnt[3] = table + 3*0x400 + 1;
+}
+
+tPAddr MM_Clone(void)
+{
+ tPAddr ret;
+ Uint32 *new_lvl1_1, *new_lvl1_2, *cur;
+ Uint32 *tmp_map;
+ int i;
+
+// MM_DumpTables(0, KERNEL_BASE);
+
+ ret = MM_AllocateRootTable();
+
+ cur = (void*)MM_TABLE0USER;
+ new_lvl1_1 = MM_MapTemp(ret);
+ new_lvl1_2 = MM_MapTemp(ret+0x1000);
+ tmp_map = new_lvl1_1;
+ for( i = 0; i < 0x800-4; i ++ )
+ {
+ // HACK! Ignore the original identity mapping
+ if( i == 0 && Threads_GetTID() == 0 ) {
+ tmp_map[0] = 0;
+ continue;
+ }
+ if( i == 0x400 )
+ tmp_map = &new_lvl1_2[-0x400];
+ switch( cur[i] & 3 )
+ {
+ case 0: tmp_map[i] = 0; break;
+ case 1:
+ MM_int_CloneTable(&tmp_map[i], i);
+ i += 3; // Tables are alocated in blocks of 4
+ break;
+ case 2:
+ case 3:
+ Log_Error("MMVirt", "TODO: Support Sections/Supersections in MM_Clone (i=%i)", i);
+ tmp_map[i] = 0;
+ break;
+ }
+ }
+
+ // Allocate Fractal table
+ {
+ int j, num;
+ tPAddr tmp = MM_AllocPhys();
+ Uint32 *table = MM_MapTemp(tmp);
+ Uint32 sp;
+ register Uint32 __SP asm("sp");
+
+ // Map table to last 4MiB of user space
+ new_lvl1_2[0x3FC] = tmp + 0*0x400 + 1;
+ new_lvl1_2[0x3FD] = tmp + 1*0x400 + 1;
+ new_lvl1_2[0x3FE] = tmp + 2*0x400 + 1;
+ new_lvl1_2[0x3FF] = tmp + 3*0x400 + 1;
+
+ tmp_map = new_lvl1_1;
+ for( j = 0; j < 512; j ++ )
+ {
+ if( j == 256 )
+ tmp_map = &new_lvl1_2[-0x400];
+ if( (tmp_map[j*4] & 3) == 1 )
+ {
+ table[j] = tmp_map[j*4] & PADDR_MASK_LVL1;// 0xFFFFFC00;
+ table[j] |= 0x813; // nG, Kernel Only, Small page, XN
+ }
+ else
+ table[j] = 0;
+ }
+ // Fractal
+ table[j++] = (ret + 0x0000) | 0x813;
+ table[j++] = (ret + 0x1000) | 0x813;
+ // Nuke the rest
+ for( ; j < 1024; j ++ )
+ table[j] = 0;
+
+ // Get kernel stack bottom
+ sp = __SP & ~(MM_KSTACK_SIZE-1);
+ j = (sp / 0x1000) % 1024;
+ num = MM_KSTACK_SIZE/0x1000;
+
+// Log("num = %i, sp = %p, j = %i", num, sp, j);
+
+ // Copy stack pages
+ for(; num--; j ++, sp += 0x1000)
+ {
+ tVAddr page;
+ void *tmp_page;
+
+ page = MM_AllocPhys();
+// Log("page = %P", page);
+ table[j] = page | 0x813;
+
+ tmp_page = MM_MapTemp(page);
+ memcpy(tmp_page, (void*)sp, 0x1000);
+ MM_FreeTemp( tmp_page );
+ }
+
+ MM_FreeTemp( table );
+ }
+
+ MM_FreeTemp( new_lvl1_1 );
+ MM_FreeTemp( new_lvl1_2 );
+
+// Log("MM_Clone: ret = %P", ret);
+
+ return ret;
+}
+
+void MM_ClearUser(void)
+{
+ int i, j;
+ const int user_table_count = USER_STACK_TOP / (256*0x1000);
+ Uint32 *cur = (void*)MM_TABLE0USER;
+ Uint32 *tab;
+
+// MM_DumpTables(0, 0x80000000);
+
+// Log("user_table_count = %i (as opposed to %i)", user_table_count, 0x800-4);
+
+ for( i = 0; i < user_table_count; i ++ )
+ {
+ switch( cur[i] & 3 )
+ {
+ case 0: break; // Already unmapped
+ case 1: // Sub pages
+ tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+ for( j = 0; j < 1024; j ++ )
+ {
+ switch( tab[j] & 3 )
+ {
+ case 0: break; // Unmapped
+ case 1:
+ Log_Error("MMVirt", "TODO: Support large pages in MM_ClearUser");
+ break;
+ case 2:
+ case 3:
+ MM_DerefPhys( tab[j] & ~(PAGE_SIZE-1) );
+ break;
+ }
+ }
+ MM_DerefPhys( cur[i] & ~(PAGE_SIZE-1) );
+ cur[i+0] = 0;
+ cur[i+1] = 0;
+ cur[i+2] = 0;
+ i += 3;
+ break;
+ case 2:
+ case 3:
+ Log_Error("MMVirt", "TODO: Implement sections/supersections in MM_ClearUser");
+ break;
+ }
+ cur[i] = 0;
+ }
+
+ // Final block of 4 tables are KStack
+ i = 0x800 - 4;
+
+ // Clear out unused stacks
+ {
+ register Uint32 __SP asm("sp");
+ int cur_stack_base = ((__SP & ~(MM_KSTACK_SIZE-1)) / PAGE_SIZE) % 1024;
+
+ tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+
+ // First 512 is the Table1 mapping + 2 for Table0 mapping
+ for( j = 512+2; j < 1024; j ++ )
+ {
+ // Skip current stack
+ if( j == cur_stack_base ) {
+ j += (MM_KSTACK_SIZE / PAGE_SIZE) - 1;
+ continue ;
+ }
+ if( !(tab[j] & 3) ) continue;
+ ASSERT( (tab[j] & 3) == 2 );
+ MM_DerefPhys( tab[j] & ~(PAGE_SIZE) );
+ tab[j] = 0;
+ }
+ }
+
+
+// MM_DumpTables(0, 0x80000000);
+}
+
+void *MM_MapTemp(tPAddr PAddr)
+{
+ tVAddr ret;
+ tMM_PageInfo pi;
+
+ for( ret = MM_TMPMAP_BASE; ret < MM_TMPMAP_END - PAGE_SIZE; ret += PAGE_SIZE )
+ {
+ if( MM_int_GetPageInfo(ret, &pi) == 0 )
+ continue;
+
+// Log("MapTemp %P at %p by %p", PAddr, ret, __builtin_return_address(0));
+ MM_RefPhys(PAddr); // Counter the MM_Deallocate in FreeTemp
+ MM_Map(ret, PAddr);
+
+ return (void*)ret;
+ }
+ Log_Warning("MMVirt", "MM_MapTemp: All slots taken");
+ return 0;
+}
+
+void MM_FreeTemp(void *Ptr)
+{
+ tVAddr VAddr = (tVAddr)Ptr;
+ if( VAddr < MM_TMPMAP_BASE || VAddr >= MM_TMPMAP_END ) {
+ Log_Warning("MMVirt", "MM_FreeTemp: Passed an addr not from MM_MapTemp (%p)", VAddr);
+ return ;
+ }
+
+ MM_Deallocate(VAddr);
+}
+
+tVAddr MM_MapHWPages(tPAddr PAddr, Uint NPages)
+{
+ tVAddr ret;
+ int i;
+ tMM_PageInfo pi;
+
+ ENTER("xPAddr iNPages", PAddr, NPages);
+
+ // Scan for a location
+ for( ret = MM_HWMAP_BASE; ret < MM_HWMAP_END - NPages * PAGE_SIZE; ret += PAGE_SIZE )
+ {
+// LOG("checking %p", ret);
+ // Check if there is `NPages` free pages
+ for( i = 0; i < NPages; i ++ )
+ {
+ if( MM_int_GetPageInfo(ret + i*PAGE_SIZE, &pi) == 0 )
+ break;
+ }
+ // Nope, jump to after the used page found and try again
+// LOG("i = %i, ==? %i", i, NPages);
+ if( i != NPages ) {
+ ret += i * PAGE_SIZE;
+ continue ;
+ }
+
+ // Map the pages
+ for( i = 0; i < NPages; i ++ )
+ MM_Map(ret+i*PAGE_SIZE, PAddr+i*PAGE_SIZE);
+ // and return
+ LEAVE('p', ret);
+ return ret;
+ }
+ Log_Warning("MMVirt", "MM_MapHWPages: No space for a %i page block", NPages);
+ LEAVE('p', 0);
+ return 0;
+}
+
+tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PAddr)
+{
+ tPAddr phys;
+ tVAddr ret;
+
+ phys = MM_AllocPhysRange(Pages, MaxBits);
+ if(!phys) {
+ Log_Warning("MMVirt", "No space left for a %i page block (MM_AllocDMA)", Pages);
+ return 0;
+ }
+
+ ret = MM_MapHWPages(phys, Pages);
+ *PAddr = phys;
+
+ return ret;
+}
+
+void MM_UnmapHWPages(tVAddr Vaddr, Uint Number)
+{
+ Log_Error("MMVirt", "TODO: Implement MM_UnmapHWPages");
+}
+
+tVAddr MM_NewKStack(int bShared)
+{
+ tVAddr min_addr, max_addr;
+ tVAddr addr, ofs;
+
+ if( bShared ) {
+ min_addr = MM_GLOBALSTACKS;
+ max_addr = MM_GLOBALSTACKS_END;
+ }
+ else {
+ min_addr = MM_KSTACK_BASE;
+ max_addr = MM_KSTACK_END;
+ }
+
+ // Locate a free slot
+ for( addr = min_addr; addr < max_addr; addr += MM_KSTACK_SIZE )
+ {
+ tMM_PageInfo pi;
+ if( MM_int_GetPageInfo(addr+MM_KSTACK_SIZE-PAGE_SIZE, &pi) ) break;
+ }
+
+ // Check for an error
+ if(addr >= max_addr) {
+ return 0;
+ }
+
+ // 1 guard page
+ for( ofs = PAGE_SIZE; ofs < MM_KSTACK_SIZE; ofs += PAGE_SIZE )
+ {
+ if( MM_Allocate(addr + ofs) == 0 )
+ {
+ while(ofs)
+ {
+ ofs -= PAGE_SIZE;
+ MM_Deallocate(addr + ofs);
+ }
+ Log_Warning("MMVirt", "MM_NewKStack: Unable to allocate");
+ return 0;
+ }
+ }
+ return addr + ofs;
+}
+
+tVAddr MM_NewUserStack(void)
+{
+ tVAddr addr, ofs;
+
+ addr = USER_STACK_TOP - USER_STACK_SIZE;
+ if( MM_GetPhysAddr( (void*)(addr + PAGE_SIZE) ) ) {
+ Log_Error("MMVirt", "Unable to create initial user stack, addr %p taken",
+ addr + PAGE_SIZE
+ );
+ return 0;
+ }
+
+ // 1 guard page
+ for( ofs = PAGE_SIZE; ofs < USER_STACK_SIZE; ofs += PAGE_SIZE )
+ {
+ tPAddr rv;
+ if(ofs >= USER_STACK_SIZE - USER_STACK_COMM)
+ rv = MM_Allocate(addr + ofs);
+ else
+ rv = MM_AllocateZero(addr + ofs);
+ if(rv == 0)
+ {
+ while(ofs)
+ {
+ ofs -= PAGE_SIZE;
+ MM_Deallocate(addr + ofs);
+ }
+ Log_Warning("MMVirt", "MM_NewUserStack: Unable to allocate");
+ return 0;
+ }
+ MM_SetFlags(addr+ofs, 0, MM_PFLAG_KERNEL);
+ }
+// Log("Return %p", addr + ofs);
+// MM_DumpTables(0, 0x80000000);
+ return addr + ofs;
+}
+
+void MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info)
+{
+ if( giMM_ZeroPage && Info->PhysAddr == giMM_ZeroPage )
+ {
+ Debug("%p => %8s - 0x%7x %i %x %s",
+ Start, "ZERO", Len,
+ Info->Domain, Info->AP,
+ Info->bGlobal ? "G" : "nG"
+ );
+ }
+ else
+ {
+ Debug("%p => %8x - 0x%7x %i %x %s",
+ Start, Info->PhysAddr-Len, Len,
+ Info->Domain, Info->AP,
+ Info->bGlobal ? "G" : "nG"
+ );
+ }
+}
+
+void MM_DumpTables(tVAddr Start, tVAddr End)
+{
+ tVAddr range_start = 0, addr;
+ tMM_PageInfo pi, pi_old;
+ int i = 0, inRange=0;
+
+ memset(&pi_old, 0, sizeof(pi_old));
+
+ Debug("Page Table Dump (%p to %p):", Start, End);
+ range_start = Start;
+ for( addr = Start; i == 0 || (addr && addr < End); i = 1 )
+ {
+ int rv;
+// Log("addr = %p", addr);
+ rv = MM_int_GetPageInfo(addr, &pi);
+ if( rv
+ || pi.Size != pi_old.Size
+ || pi.Domain != pi_old.Domain
+ || pi.AP != pi_old.AP
+ || pi.bGlobal != pi_old.bGlobal
+ || pi_old.PhysAddr != pi.PhysAddr )
+ {
+ if(inRange) {
+ MM_int_DumpTableEnt(range_start, addr - range_start, &pi_old);
+ }
+ addr &= ~((1 << pi.Size)-1);
+ range_start = addr;
+ }
+
+ pi_old = pi;
+ // Handle the zero page
+ if( !giMM_ZeroPage || pi_old.Size != 12 || pi_old.PhysAddr != giMM_ZeroPage )
+ pi_old.PhysAddr += 1 << pi_old.Size;
+ addr += 1 << pi_old.Size;
+ inRange = (rv == 0);
+ }
+ if(inRange)
+ MM_int_DumpTableEnt(range_start, addr - range_start, &pi);
+ Debug("Done");
+}
+
+// NOTE: Runs in abort context, not much difference, just a smaller stack
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
+{
+ int rv;
+ tMM_PageInfo pi;
+
+ rv = MM_int_GetPageInfo(Addr, &pi);
+
+ // Check for COW
+ if( rv == 0 && pi.AP == AP_RO_BOTH )
+ {
+ pi.AP = AP_RW_BOTH;
+ if( giMM_ZeroPage && pi.PhysAddr == giMM_ZeroPage )
+ {
+ tPAddr newpage;
+ newpage = MM_AllocPhys();
+ if( !newpage ) {
+ Log_Error("MMVirt", "Unable to allocate new page for COW of ZERO");
+ for(;;);
+ }
+
+ #if TRACE_COW
+ Log_Notice("MMVirt", "COW %p caused by %p, ZERO duped to %P (RefCnt(%i)--)", Addr, PC,
+ newpage, MM_GetRefCount(pi.PhysAddr));
+ #endif
+
+ MM_DerefPhys(pi.PhysAddr);
+ pi.PhysAddr = newpage;
+ pi.AP = AP_RW_BOTH;
+ MM_int_SetPageInfo(Addr, &pi);
+
+ memset( (void*)(Addr & ~(PAGE_SIZE-1)), 0, PAGE_SIZE );
+
+ return ;
+ }
+ else if( MM_GetRefCount(pi.PhysAddr) > 1 )
+ {
+ // Duplicate the page
+ tPAddr newpage;
+ void *dst, *src;
+
+ newpage = MM_AllocPhys();
+ if(!newpage) {
+ Log_Error("MMVirt", "Unable to allocate new page for COW");
+ for(;;);
+ }
+ dst = MM_MapTemp(newpage);
+ src = (void*)(Addr & ~(PAGE_SIZE-1));
+ memcpy( dst, src, PAGE_SIZE );
+ MM_FreeTemp( dst );
+
+ #if TRACE_COW
+ Log_Notice("MMVirt", "COW %p caused by %p, %P duped to %P (RefCnt(%i)--)", Addr, PC,
+ pi.PhysAddr, newpage, MM_GetRefCount(pi.PhysAddr));
+ #endif
+
+ MM_DerefPhys(pi.PhysAddr);
+ pi.PhysAddr = newpage;
+ }
+ #if TRACE_COW
+ else {
+ Log_Notice("MMVirt", "COW %p caused by %p, took last reference to %P",
+ Addr, PC, pi.PhysAddr);
+ }
+ #endif
+ // Unset COW
+ pi.AP = AP_RW_BOTH;
+ MM_int_SetPageInfo(Addr, &pi);
+ return ;
+ }
+
+
+ Log_Error("MMVirt", "Code at %p accessed %p (DFSR = 0x%x)%s", PC, Addr, DFSR,
+ (bPrefetch ? " - Prefetch" : "")
+ );
+ if( Addr < 0x80000000 )
+ MM_DumpTables(0, 0x80000000);
+ else
+ MM_DumpTables(0x80000000, -1);
+ for(;;);
+}
+
--- /dev/null
+/*
+ *
+ */
+#include <acess.h>
+#include <drv_pci_int.h>
+
+// Realview
+//#define PCI_BASE 0x60000000
+
+//#define PCI_BASE 0xF0400000 // VMM Mapping
+#define PCI_BASE 0
+
+// === CODE ===
+void PCI_CfgWriteDWord(Uint32 Addr, Uint32 Data)
+{
+ #if PCI_BASE
+ Uint32 address = PCI_BASE | Addr;
+ *(Uint32*)(address) = Data;
+ #else
+ #endif
+}
+
+Uint32 PCI_CfgReadDWord(Uint32 Addr)
+{
+ #if PCI_BASE
+ Uint32 address = PCI_BASE | Addr;
+ return *(Uint32*)address;
+ #else
+ return 0xFFFFFFFF;
+ #endif
+}
+
--- /dev/null
+/*
+ * Acess2 ARM
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/proc.S
+ * - Process management assembly
+ */
+
+#include "include/assembly.h"
+
+.globl KernelThreadHeader
+@ SP+12: Argument 1
+@ SP+8: Argument Count
+@ SP+4: Function
+@ SP+0: Thread Pointer
+KernelThreadHeader:
+ ldr r0, [sp],#4
+ @ TODO: Do something with the thread pointer
+
+ ldr r4, [sp],#4 @ Function
+ @ Get argument
+ ldr r0, [sp],#4
+
+ blx r4
+
+ ldr r0, =0
+ bl Threads_Exit
+ b .
+
+.globl SwitchTask
+@ R0: New stack
+@ R1: Pointer to where to save old stack
+@ R2: New IP
+@ R3: Pointer to save old IP
+@ SP+0: New address space
+SwitchTask:
+ push {r4-r12,lr}
+
+ @ Save IP
+ ldr r4, =.return
+ str r4, [r3]
+ @ Save SP
+ str sp, [r1]
+
+ @ Only update TTBR0 if the task has an explicit address space
+ ldr r1, [sp,#4*10]
+ tst r1, r1
+ mcrne p15, 0, r1, c2, c0, 0 @ Set TTBR0 to r0
+# mov r1, #1
+ mcrne p15, 0, r1, c8, c7, 0 @ TLBIALL - Invalid user space
+
+ @ Restore state
+ mov sp, r0
+ bx r2
+
+.return:
+ pop {r4-r12,pc}
+
+.extern MM_Clone
+.extern MM_DumpTables
+.globl Proc_CloneInt
+Proc_CloneInt:
+ @ R0: SP Destination
+ @ R1: Mem Destination
+ push {r4-r12,lr}
+ mov r4, r1 @ Save mem destination
+ str sp, [r0] @ Save SP to SP dest
+
+ bl MM_Clone
+ str r0, [r4] @ Save clone return to Mem Dest
+
+ ldr r0, =Proc_CloneInt_new
+ pop {r4-r12,pc}
+Proc_CloneInt_new:
+ mov r0, #0
+ pop {r4-r12,pc}
+
+@ R0: New user SP
+@ Return: Old user SP
+.globl Proc_int_SwapUserSP
+Proc_int_SwapUserSP:
+ cps #31 @ Go to system mode
+ mov r1, sp
+ tst r0, r0 @ Only update if non-zero
+ movne sp, r0
+ mov r0, r1
+ cps #19
+ mov pc, lr
+
+.section .usertext, "ax"
+.globl Proc_int_DropToUser
+@ R0: User IP
+@ R1: User SP
+Proc_int_DropToUser:
+ cps #16
+ mov sp, r1
+ mov pc, r0
+
+.section .rodata
+csProc_CloneInt_NewTaskMessage:
+ .asciz "New task PC=%p, R4=%p, sp=%p"
+csProc_CloneInt_OldTaskMessage:
+ .asciz "Parent task PC=%p, R4=%p, SP=%p"
+
+@ vim: ft=armv7
--- /dev/null
+/*
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/proc.c
+ * - ARM7 Process Switching
+ */
+#include <acess.h>
+#include <threads_int.h>
+#include <hal_proc.h>
+
+// === IMPORTS ===
+extern tThread gThreadZero;
+extern tProcess gProcessZero;
+extern void SwitchTask(Uint32 NewSP, Uint32 *OldSP, Uint32 NewIP, Uint32 *OldIP, Uint32 MemPtr);
+extern void KernelThreadHeader(void); // Actually takes args on stack
+extern void Proc_int_DropToUser(Uint32 IP, Uint32 SP) NORETURN __attribute__((long_call));
+extern Uint32 Proc_int_SwapUserSP(Uint32 NewSP);
+extern Uint32 Proc_CloneInt(Uint32 *SP, Uint32 *MemPtr);
+extern tVAddr MM_NewKStack(int bGlobal); // TODO: Move out into a header
+extern tVAddr MM_NewUserStack(void);
+extern char kernel_table0[];
+
+// === PROTOTYPES ===
+void Proc_IdleThread(void *unused);
+
+// === GLOBALS ===
+tThread *gpCurrentThread = &gThreadZero;
+tThread *gpIdleThread = NULL;
+
+// === CODE ===
+void ArchThreads_Init(void)
+{
+ gProcessZero.MemState.Base = (tPAddr)&kernel_table0 - KERNEL_BASE;
+}
+
+void Proc_IdleThread(void *unused)
+{
+ Threads_SetPriority(gpIdleThread, -1);
+ for(;;) {
+ Proc_Reschedule();
+ __asm__ __volatile__ ("wfi");
+ }
+}
+
+void Proc_Start(void)
+{
+ tTID tid;
+
+ tid = Proc_NewKThread( Proc_IdleThread, NULL );
+ gpIdleThread = Threads_GetThread(tid);
+ gpIdleThread->ThreadName = (char*)"Idle Thread";
+}
+
+int GetCPUNum(void)
+{
+ return 0;
+}
+
+tThread *Proc_GetCurThread(void)
+{
+ return gpCurrentThread;
+}
+
+void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, const char **ArgV, int DataSize)
+{
+ Uint32 *usr_sp;
+ int i;
+ const char **envp;
+ tVAddr delta;
+
+// Log_Debug("Proc", "Proc_StartUser: (Entrypoint=%p, Base=%p, ArgC=%i, ArgV=%p, DataSize=0x%x)",
+// Entrypoint, Base, ArgC, ArgV, DataSize);
+
+ // Write data to the user's stack
+ usr_sp = (void*)MM_NewUserStack();
+ usr_sp -= (DataSize+3)/4;
+ memcpy(usr_sp, ArgV, DataSize);
+ free(ArgV);
+
+ // Adjust user's copy of the arguments
+ delta = (tVAddr)usr_sp - (tVAddr)ArgV;
+ ArgV = (void*)usr_sp;
+ for(i = 0; ArgV[i]; i ++) ArgV[i] += delta;
+ envp = &ArgV[i+1];
+ for(i = 0; envp[i]; i ++) envp[i] += delta;
+
+ *--usr_sp = (Uint32)envp;
+ *--usr_sp = (Uint32)ArgV;
+ *--usr_sp = (Uint32)ArgC;
+ *--usr_sp = Base;
+
+ // Drop to user code
+ Log_Debug("Proc", "Proc_int_DropToUser(%p, %p)", Entrypoint, usr_sp);
+ Proc_int_DropToUser(Entrypoint, (Uint32)usr_sp);
+}
+
+void Proc_ClearProcess(tProcess *Process)
+{
+ Log_Warning("Proc", "TODO: Nuke address space etc");
+}
+
+void Proc_ClearThread(tThread *Thread)
+{
+}
+
+tTID Proc_Clone(Uint Flags)
+{
+ tThread *new;
+ Uint32 pc, sp, mem;
+
+ new = Threads_CloneTCB(Flags);
+ if(!new) return -1;
+
+ // Actual clone magic
+ pc = Proc_CloneInt(&sp, &mem);
+ if(pc == 0) {
+ Log("Proc_Clone: In child");
+ return 0;
+ }
+
+ new->SavedState.IP = pc;
+ new->SavedState.SP = sp;
+ new->SavedState.UserSP = Proc_int_SwapUserSP(0);
+ new->SavedState.UserIP = Proc_GetCurThread()->SavedState.UserIP;
+ new->Process->MemState.Base = mem;
+
+ Threads_AddActive(new);
+
+ return new->TID;
+}
+
+int Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
+{
+ tThread *new;
+ Uint32 sp;
+
+ new = Threads_CloneThreadZero();
+ if(!new) return -1;
+ if(new->ThreadName) free(new->ThreadName);
+ new->ThreadName = NULL;
+
+ new->KernelStack = MM_NewKStack(1);
+ if(!new->KernelStack) {
+ // TODO: Delete thread
+ Log_Error("Proc", "Unable to allocate kernel stack");
+ return -1;
+ }
+
+ sp = new->KernelStack;
+
+ *(Uint32*)(sp -= 4) = (Uint)Ptr;
+ *(Uint32*)(sp -= 4) = (Uint)Fnc;
+ *(Uint32*)(sp -= 4) = (Uint)new;
+
+ new->SavedState.SP = sp;
+ new->SavedState.IP = (Uint)KernelThreadHeader;
+
+ Threads_AddActive(new);
+
+ return new->TID;
+}
+
+tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr )
+{
+ tThread *new;
+ Uint32 sp;
+
+ new = Threads_CloneTCB(0);
+ if(!new) return -1;
+ free(new->ThreadName);
+ new->ThreadName = NULL;
+
+ // TODO: Non-shared stack
+ new->KernelStack = MM_NewKStack(1);
+ if(!new->KernelStack) {
+ // TODO: Delete thread
+ Log_Error("Proc", "Unable to allocate kernel stack");
+ return -1;
+ }
+
+ sp = new->KernelStack;
+
+ *(Uint32*)(sp -= 4) = (Uint)Ptr;
+ *(Uint32*)(sp -= 4) = (Uint)Fnc;
+ *(Uint32*)(sp -= 4) = (Uint)new;
+
+ new->SavedState.SP = sp;
+ new->SavedState.IP = (Uint)KernelThreadHeader;
+
+ Threads_AddActive(new);
+
+ return new->TID;
+}
+
+void Proc_CallFaultHandler(tThread *Thread)
+{
+
+}
+
+void Proc_Reschedule(void)
+{
+ tThread *cur, *next;
+
+ cur = gpCurrentThread;
+
+ next = Threads_GetNextToRun(0, cur);
+ if(!next) next = gpIdleThread;
+ if(!next || next == cur) return;
+
+ Log("Switching to %p (%i %s) IP=%p SP=%p TTBR0=%p UsrSP=%p",
+ next, next->TID, next->ThreadName,
+ next->SavedState.IP, next->SavedState.SP, next->Process->MemState.Base,
+ next->SavedState.UserSP
+ );
+
+ Log("Requested by %p", __builtin_return_address(0));
+
+ gpCurrentThread = next;
+
+ cur->SavedState.UserSP = Proc_int_SwapUserSP( next->SavedState.UserSP );
+
+ SwitchTask(
+ next->SavedState.SP, &cur->SavedState.SP,
+ next->SavedState.IP, &cur->SavedState.IP,
+ next->Process->MemState.Base
+ );
+
+}
+
+void Proc_DumpThreadCPUState(tThread *Thread)
+{
+
+}
+
--- /dev/null
+
+#include "include/assembly.h"
+#include "include/options.h"
+
+@
+@ Exception defs taken from ARM DDI 0406B
+@
+.section .init
+interrupt_vector_table:
+ivt_reset: b _start @ 0x00 Reset
+ivt_undef: b Undef_Handler @ 0x04 #UD
+ivt_svc: b SVC_Handler @ 0x08 SVC (used to be called SWI)
+ivt_prefetch: b PrefetchAbort @ 0x0C Prefetch abort
+ivt_data: b DataAbort @ 0x10 Data abort
+ivt_unused: b . @ 0x14 Not Used
+ivt_irq: b IRQHandler @ 0x18 IRQ
+ivt_fiq: b . @ 0x1C FIQ (Fast interrupt)
+
+.globl _start
+_start:
+ ldr r2, =UART0_PADDR
+ mov r1, #'A'
+ str r1, [r2]
+
+ ldr r0, =kernel_table0-KERNEL_BASE
+ mcr p15, 0, r0, c2, c0, 1 @ Set TTBR1 to r0
+ mcr p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 too (for identity)
+
+ mov r1, #'c'
+ str r1, [r2]
+
+ mov r0, #1
+ mcr p15, 0, r0, c2, c0, 2 @ Set TTCR to 1 (50/50 split)
+
+ mov r1, #'e'
+ str r1, [r2]
+
+ mov r0, #3
+ mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager
+
+ mov r1, #'s'
+ str r1, [r2]
+
+ @ Enable VMSA
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #1
+ orr r0, r0, #1 << 23
+ mcr p15, 0, r0, c1, c0, 0
+
+ @ HACK: Set ASID to non zero
+ mov r0, #1
+ MCR p15,0,r0,c13,c0,1
+
+ ldr r2, =0xF1000000
+ mov r1, #'s'
+ str r1, [r2]
+
+ @ Enable access faults on domains 0 & 1
+ mov r0, #0x55 @ 01010101b
+ mcr p15, 0, r0, c3, c0, 0
+
+ mov r1, #'2'
+ str r1, [r2]
+
+ @
+ @ Check for security extensions
+ @
+ mrc p15, 0, r0, c0, c1, 1
+ and r0, #0xF0
+ @ - Present
+ ldrne r0,=KERNEL_BASE
+ mcrne p15, 0, r0, c12, c0, 0 @ Set the VBAR (brings exceptions into high memory)
+ @ - Absent
+ mrceq p15, 0, r0, c1, c0, 0 @ Set SCTLR.V
+ orreq r0, #0x2000
+ mcreq p15, 0, r0, c1, c0, 0
+
+ mov r1, #'-'
+ str r1, [r2]
+
+ @ Prepare for interrupts
+ cps #18 @ IRQ Mode
+ ldr sp, =irqstack+0x1000 @ Set up stack
+ cps #23 @ Abort Mode
+ ldr sp, =abortstack+0x1000
+ cps #19
+
+ mov r1, #'a'
+ str r1, [r2]
+ mov r1, #'r'
+ str r1, [r2]
+ mov r1, #'m'
+ str r1, [r2]
+ mov r1, #13
+ str r1, [r2]
+ mov r1, #10
+ str r1, [r2]
+
+.extern bss_start
+.extern bss_size_div_4
+.zero_bss:
+ ldr r0, =bss_start
+ ldr r1, =bss_end
+ mov r3, #0
+.zero_bss_loop:
+ str r3, [r0],#4
+ cmp r0, r1
+ bls .zero_bss_loop
+
+.goto_c:
+ ldr sp, =0x80000000-8 @ Set up stack (top of user range)
+ ldr r0, =kmain
+ mov pc, r0
+1: b 1b @ Infinite loop
+
+.comm irqstack, 0x1000 @ ; 4KiB Stack
+.comm abortstack, 0x1000 @ ; 4KiB Stack
+
+.extern SyscallHandler
+SVC_Handler:
+@ sub lr, #4
+ srsdb sp!, #19 @ Save state to stack
+ cpsie ifa, #19 @ Ensure we're in supervisor with interrupts enabled (should already be there)
+ push {r0-r12}
+
+ ldr r4, [lr,#-4]
+ mvn r5, #0xFF000000
+ and r4, r5
+
+ tst r4, #0x1000
+ bne .arm_specifics
+
+ push {r4}
+
+ mov r0, sp
+ ldr r4, =SyscallHandler
+ blx r4
+
+@ ldr r0, =csSyscallPrintRetAddr
+@ ldr r1, [sp,#9*4+5*4]
+@ ldr r4, =Log
+@ blx r4
+
+ pop {r2} @ errno
+ pop {r0,r1} @ Ret/RetHi
+ add sp, #2*4 @ Saved r2/r3
+
+ pop {r4-r12}
+ rfeia sp! @ Pop state (actually RFEFD)
+.arm_specifics:
+ and r4, #0xFF
+ mov r0, r4 @ Number
+ mov r1, sp @ Arguments
+
+ ldr r4, =ARMv7_int_HandleSyscalls
+ blx r4
+
+ add sp, #4*4
+ pop {r4-r12}
+ rfeia sp!
+
+
+.globl gpIRQHandler
+gpIRQHandler: .long 0
+IRQ_saved_sp: .long 0
+IRQ_saved_lr: .long 0
+.globl IRQHandler
+IRQHandler:
+ sub lr, #4 @ Adjust LR to the correct value
+ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+ cps #19
+
+ PUSH_GPRS
+
+@ ldr r0, =csIRQ_Tag
+@ ldr r1, =csIRQ_Fmt
+@ ldr r4, =Log_Debug
+@ blx r4
+
+ @ Call the registered handler
+ ldr r0, gpIRQHandler
+ blx r0
+
+ @ Restore CPU state
+ POP_GPRS
+ cpsie i
+ rfeia sp! @ Pop state (actually RFEFD)
+ bx lr
+
+.globl DataAbort
+DataAbort:
+ sub lr, #8 @ Adjust LR to the correct value
+ srsdb sp!, #23 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+@ cpsid ifa, #19
+ PUSH_GPRS
+
+ mov r3, #0 @ not a prefetch abort
+ mrc p15, 0, r2, c5, c0, 0 @ Read DFSR (Data Fault Status Register) to R2
+ mrc p15, 0, r1, c6, c0, 0 @ Read DFAR (Data Fault Address Register) into R1
+ mov r0, lr @ PC
+ ldr r4, =MM_PageFault
+ blx r4
+
+ POP_GPRS
+ rfeia sp! @ Pop state (actually RFEFD)
+
+.globl PrefetchAbort
+PrefetchAbort:
+ sub lr, #4 @ Adjust LR to the correct value
+ srsdb sp!, #23 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+@ cpsid ifa, #19
+ PUSH_GPRS
+
+ ldr r0, =csAbort_Tag
+ ldr r1, =csPrefetchAbort_Fmt
+# mov r2, lr
+ mrc p15, 0, r2, c6, c0, 2 @ Read IFAR (Instruction Fault Address Register) into R3
+ mrc p15, 0, r3, c5, c0, 1 @ Read IFSR (Instruction Fault Status Register) into R3
+ ldr r5, =Log_Error
+ blx r5
+
+.loop:
+ wfi
+ b .loop
+.globl Undef_Handler
+Undef_Handler:
+ wfi
+ b Undef_Handler
+
+.globl abort
+abort:
+ wfi
+ b abort
+
+
+.section .rodata
+csIRQ_Tag:
+csAbort_Tag:
+ .asciz "ARMv7"
+csIRQ_Fmt:
+ .asciz "IRQ"
+csDataAbort_Fmt:
+ .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
+csPrefetchAbort_Fmt:
+ .asciz "Prefetch Abort at %p, IFSR=%x"
+csSyscallPrintRetAddr:
+ .asciz "Syscall ret to %p"
+
+.section .padata
+.globl kernel_table0
+
+kernel_table0:
+ .long 0x00000402 @ Identity map the first 1 MiB
+ .rept 0x7FC - 1
+ .long 0
+ .endr
+ .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
+ .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
+ .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
+ .long user_table1_map + 0xC00 - KERNEL_BASE + 1
+ @ 0x80000000 - User/Kernel split
+ .long 0x00000402 @ Map first 4 MiB to 2GiB (KRW only)
+ .long 0x00100402 @
+ .long 0x00200402 @
+ .long 0x00300402 @
+ .rept 0xF00 - 0x800 - 4
+ .long 0
+ .endr
+#if PCI_PADDR
+ .long PCI_PADDR + 0*(1 << 20) + 0x402 @ Map PCI config space
+ .long PCI_PADDR + 1*(1 << 20) + 0x402
+ .long PCI_PADDR + 2*(1 << 20) + 0x402
+ .long PCI_PADDR + 3*(1 << 20) + 0x402
+ .long PCI_PADDR + 4*(1 << 20) + 0x402
+ .long PCI_PADDR + 5*(1 << 20) + 0x402
+ .long PCI_PADDR + 6*(1 << 20) + 0x402
+ .long PCI_PADDR + 7*(1 << 20) + 0x402
+ .long PCI_PADDR + 8*(1 << 20) + 0x402
+ .long PCI_PADDR + 9*(1 << 20) + 0x402
+ .long PCI_PADDR + 10*(1 << 20) + 0x402
+ .long PCI_PADDR + 11*(1 << 20) + 0x402
+ .long PCI_PADDR + 12*(1 << 20) + 0x402
+ .long PCI_PADDR + 13*(1 << 20) + 0x402
+ .long PCI_PADDR + 14*(1 << 20) + 0x402
+ .long PCI_PADDR + 15*(1 << 20) + 0x402
+#else
+ .rept 16
+ .long 0
+ .endr
+#endif
+ .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
+ .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
+ .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
+ .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
+ .rept 0xFF8 - 0xF00 - 16 - 4
+ .long 0
+ .endr
+ @ Page fractals
+ .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
+ .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
+ .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
+ .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
+ .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
+ .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
+ .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
+ .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
+
+@ PID0 user table
+.globl user_table1_map
+@ User table1 data table (only the first half is needed)
+@ - Abused to provide kernel stacks in the unused half of the table
+user_table1_map: @ Size = 4KiB (only 2KiB used)
+ .rept 0x800/4-1
+ .long 0
+ .endr
+ .long user_table1_map - KERNEL_BASE + 0x13 @ ...1FF000 = 0x7FDFF000
+ @ Kernel stack zone
+ .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13 @ ...200000 = 0x7FE00000
+ .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13 @ ...201000 = 0x7FE01000
+ .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
+ .long 0
+ .endr
+ #if MM_KSTACK_SIZE != 0x2000
+ #error Kernel stack size not changed in start.S
+ #endif
+ .long stack + 0x0000 - KERNEL_BASE + 0x13 @ Kernel Stack
+ .long stack + 0x1000 - KERNEL_BASE + 0x13 @
+
+.globl kernel_table1_map
+kernel_table1_map: @ Size = 4KiB
+ .rept (0xF00+16)/4
+ .long 0
+ .endr
+ .long hwmap_table_0 - KERNEL_BASE + 0x13
+ .rept 0xFF8/4 - (0xF00+16)/4 - 1
+ .long 0
+ .endr
+ .long kernel_table1_map - KERNEL_BASE + 0x13
+ .long kernel_exception_map - KERNEL_BASE + 0x13
+
+@ Hardware mappings
+.globl hwmap_table_0
+hwmap_table_0:
+ .long UART0_PADDR + 0x13 @ UART0
+ .rept 1024 - 1
+ .long 0
+ .endr
+.globl kernel_exception_map
+kernel_exception_map:
+ @ Padding
+ .rept 1024-256
+ .long 0
+ .endr
+ @ Align to nearly the end
+ .rept 256-16
+ .long 0
+ .endr
+ .long 0x212 @ Map first page for exceptions (Kernel RO, Execute)
+ .rept 16-1-2
+ .long 0
+ .endr
+ .long gUsertextPhysStart + 0x22 @ User .text (User RO, Kernel RW, because both is COW)
+ .long 0
+
+.section .padata
+stack:
+ .space MM_KSTACK_SIZE, 0 @ Original kernel stack
+
+// vim: ts=8 ft=armv7
+
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Time code
+ * arch/arm7/time.c
+ */
+#include <acess.h>
+
+// === GLOBALS ===
+tTime giTimestamp;
+
+// === CODE ===
+tTime now(void)
+{
+ return giTimestamp;
+}
*/
tPAddr MM_AllocPhys(void)
{
- // int a, b, c;
int indx = -1;
tPAddr ret;
Mutex_Acquire( &glPhysAlloc );
// Classful scan
- #if 1
{
int i;
int first, last;
// Out of memory?
if( i <= 1 ) indx = -1;
}
- #elif 0
- // Find free page
- // Scan downwards
- LOG("giLastPossibleFree = %i", giLastPossibleFree);
- for( indx = giLastPossibleFree; indx >= 0; )
- {
- if( gaSuperBitmap[indx>>10] == -1 ) {
- indx -= 1024;
- continue;
- }
-
- if( gaPageBitmap[indx>>5] == -1 ) {
- indx -= 32;
- continue;
- }
-
- if( gaPageBitmap[indx>>5] & (1 << (indx&31)) ) {
- indx --;
- continue;
- }
- break;
- }
- if( indx >= 0 )
- giLastPossibleFree = indx;
- LOG("indx = %i", indx);
- #else
- c = giLastPossibleFree % 32;
- b = (giLastPossibleFree / 32) % 32;
- a = giLastPossibleFree / 1024;
-
- LOG("a=%i,b=%i,c=%i", a, b, c);
- for( ; gaSuperBitmap[a] == -1 && a >= 0; a-- );
- if(a < 0) {
- Mutex_Release( &glPhysAlloc );
- Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used",
- __builtin_return_address(0), giPhysAlloc, giPageCount);
- LEAVE('i', 0);
- return 0;
- }
- for( ; gaSuperBitmap[a] & (1<<b); b-- );
- for( ; gaPageBitmap[a*32+b] & (1<<c); c-- );
- LOG("a=%i,b=%i,c=%i", a, b, c);
- indx = (a << 10) | (b << 5) | c;
- if( indx >= 0 )
- giLastPossibleFree = indx;
- #endif
if( indx < 0 ) {
Mutex_Release( &glPhysAlloc );
idx = sidx / 32;
sidx %= 32;
- #if 0
- LOG("a=%i, b=%i, idx=%i, sidx=%i", a, b, idx, sidx);
-
- // Find free page
- for( ; gaSuperBitmap[a] == -1 && a --; ) b = 31;
- if(a < 0) {
- Mutex_Release( &glPhysAlloc );
- Warning("MM_AllocPhysRange - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
- LEAVE('i', 0);
- return 0;
- }
- LOG("a = %i", a);
- for( ; gaSuperBitmap[a] & (1 << b); b-- ) sidx = 31;
- LOG("b = %i", b);
- idx = a * 32 + b;
- for( ; gaPageBitmap[idx] & (1 << sidx); sidx-- )
- LOG("gaPageBitmap[%i] = 0x%08x", idx, gaPageBitmap[idx]);
-
- LOG("idx = %i, sidx = %i", idx, sidx);
- #else
-
- #endif
-
// Check if the gap is large enough
while( idx >= 0 )
{
LogF("Backtrace: %p", IP);
//else
// LogF("Backtrace: %s+0x%x", str, delta);
- if( !MM_GetPhysAddr(BP) )
+ if( !MM_GetPhysAddr( (void*)BP ) )
{
LogF("\nBacktrace: Invalid BP, stopping\n");
return;
}
- while( MM_GetPhysAddr(BP) && MM_GetPhysAddr(BP+8+7) && i < MAX_BACKTRACE )
+ while( MM_GetPhysAddr( (void*)BP) && MM_GetPhysAddr((void*)(BP+8+7)) && i < MAX_BACKTRACE )
{
//str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
//if(str == NULL)
#include <mboot.h>
#include <init.h>
+// === CONSTANTS ===
+#define MAX_PMEMMAP_ENTS 16
+
// === IMPORTS ===
extern void Desctab_Init(void);
extern void MM_InitVirt(void);
extern void Heap_Install(void);
-extern void Threads_Init(void);
extern int Time_Setup(void);
-extern void System_Init(char *Commandline);
extern void MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
{
tMBoot_Info *mbInfo;
- LogF("Acess2 x86_64 v"EXPAND_STR(KERNEL_VERSION)"\n");
- LogF(" Build %i, Git Hash %s\n", BUILD_NUM, gsGitHash);
+ LogF("%s\r\n", gsBuildInfo);
Desctab_Init();
for( i = 0; i < Pages; i++, addr++ )
{
gaMainBitmap[addr >> 6] |= 1LL << (addr & 63);
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[addr] ) )
gaiPageReferences[addr] = 1;
// Log("page %P refcount = %i", MM_GetRefCount(addr<<12));
rangeID = MM_int_GetRangeID(addr << 12);
{
tVAddr ref_base = ((tVAddr)&gaiPageReferences[ page ]) & ~0xFFF;
// Allocate reference page
- if( !MM_GetPhysAddr(ref_base) )
+ if( !MM_GetPhysAddr(&gaiPageReferences[page]) )
{
const int pages_per_refpage = PAGE_SIZE/sizeof(gaiPageReferences[0]);
int i;
PAGE_ALLOC_SET(page);
if( gaMainBitmap[page >> 6] + 1 == 0 )
gaSuperBitmap[page>> 12] |= 1LL << ((page >> 6) & 63);
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
gaiPageReferences[page] = 1;
}
if( PAddr >> 12 > giMaxPhysPage ) return ;
- if( MM_GetPhysAddr( (tVAddr) &gaiPageReferences[page] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
{
gaiPageReferences[ page ] --;
if( gaiPageReferences[ page ] == 0 )
if( PAddr > giMaxPhysPage ) return 0;
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+ if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
return gaiPageReferences[PAddr];
}
// if( !MM_GetRefCount(PAddr) ) return 1;
- if( !MM_GetPhysAddr(node_page) ) {
+ if( !MM_GetPhysAddr((void*)node_page) ) {
if( !MM_Allocate(node_page) )
return -1;
memset( (void*)node_page, 0, PAGE_SIZE );
// if( !MM_GetRefCount(PAddr) ) return 1;
PAddr >>= 12;
- if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+ if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
*Node = NULL;
return 0;
}
#define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
LogF("%016llx => ", CANOICAL(RangeStart));
// LogF("%6llx %6llx %6llx %016llx => ",
-// MM_GetPhysAddr( (tVAddr)&PAGEDIRPTR(RangeStart>>30) ),
-// MM_GetPhysAddr( (tVAddr)&PAGEDIR(RangeStart>>21) ),
-// MM_GetPhysAddr( (tVAddr)&PAGETABLE(RangeStart>>12) ),
+// MM_GetPhysAddr( &PAGEDIRPTR(RangeStart>>30) ),
+// MM_GetPhysAddr( &PAGEDIR(RangeStart>>21) ),
+// MM_GetPhysAddr( &PAGETABLE(RangeStart>>12) ),
// CANOICAL(RangeStart)
// );
if( gMM_ZeroPage && (PAGETABLE(RangeStart>>12) & PADDR_MASK) == gMM_ZeroPage )
{
tPAddr phys;
- phys = MM_GetPhysAddr(VAddr);
+ phys = MM_GetPhysAddr( (void*)VAddr );
if(!phys) return ;
MM_Unmap(VAddr);
/**
* \brief Get the physical address of a virtual location
*/
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(const void *Ptr)
{
+ tVAddr Addr = (tVAddr)Ptr;
tPAddr *ptr;
int ret;
{
for( num = Number; num -- && ret < MM_HWMAP_TOP; ret += 0x1000 )
{
- if( MM_GetPhysAddr(ret) != 0 ) break;
+ if( MM_GetPhysAddr( (void*)ret ) != 0 )
+ break;
}
if( num >= 0 ) continue;
// Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
while( Number -- )
{
- MM_DerefPhys( MM_GetPhysAddr(VAddr) );
+ MM_DerefPhys( MM_GetPhysAddr((void*)VAddr) );
MM_Unmap(VAddr);
VAddr += 0x1000;
}
MM_MapEx(kstackbase+i*0x1000, phys, 1, 0);
tmpmapping = MM_MapTemp(phys);
- if( MM_GetPhysAddr( kstackbase+i*0x1000 ) )
+ if( MM_GetPhysAddr( (void*)(kstackbase+i*0x1000) ) )
memcpy(tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000);
else
memset(tmpmapping, 0, 0x1000);
Uint i;
for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE )
{
- if(MM_GetPhysAddr(base+KERNEL_STACK_SIZE-0x1000) != 0)
+ if(MM_GetPhysAddr( (void*)(base+KERNEL_STACK_SIZE-0x1000) ) != 0)
continue;
//Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);
// Check Prospective Space
for( i = USER_STACK_SZ >> 12; i--; )
{
- if( MM_GetPhysAddr( base + (i<<12) ) != 0 )
+ if( MM_GetPhysAddr( (void*)(base + (i<<12)) ) != 0 )
break;
}
[section .rodata]
csNot64BitCapable:
- db "Not 64-bit Capable",0
+ db "CPU does not support long-mode, please use the x86 build",0
; vim: ft=nasm
px = (void*)dest;
}
}
+ if( x > 0 ) {
+ dest += FBInfo->Pitch;
+ }
}
else
{
ofs = Offset;
dest += ofs;
memcpy(dest, Buffer, Length);
+ dest += Length;
}
break;
default:
return -1;
}
if( FBInfo->BackBuffer && dest ) {
- memcpy((char*)FBInfo->Framebuffer + ofs, (char*)FBInfo->BackBuffer + ofs,
- ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs
- );
+ void *_dst = (char*)FBInfo->Framebuffer + ofs;
+ void *_src = (char*)FBInfo->BackBuffer + ofs;
+ size_t len = ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs;
+ // Log_Debug("DrvUtil", "Copy from BB %p to FB %p 0x%x bytes", _src, _dst, len);
+ memcpy(_dst, _src, len);
}
DrvUtil_Video_DrawCursor(FBInfo, csr_x, csr_y);
bitmap_page &= ~(PAGE_SIZE-1);
// Only need to allocate bitmaps
- if( !MM_GetPhysAddr( bitmap_page ) ) {
+ if( !MM_GetPhysAddr( (void*)bitmap_page ) ) {
if( !MM_Allocate( bitmap_page ) ) {
Log_KernelPanic("PMM", "Out of memory during init, this is bad");
return ;
LOG("if( MM_GetPhysAddr( %p ) )", &gaiPageReferences[addr]);
// Mark as referenced if the reference count page is valid
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] ) ) {
+ if( MM_GetPhysAddr( &gaiPageReferences[addr] ) ) {
gaiPageReferences[addr] = 1;
}
}
tPAddr ret = 0;
for( ret = 0; ret < giMaxPhysPage; ret ++ )
{
- if( !MM_GetPhysAddr( (tVAddr)&gaPageBitmaps[ret/32] ) ) {
+ if( !MM_GetPhysAddr( &gaPageBitmaps[ret/32] ) ) {
ret += PAGE_SIZE*8;
continue ;
}
if( gaPageBitmaps[page / 32] == 0 )
gaSuperBitmap[page / (32*32)] &= ~(1LL << ((page / 32) & 31));
#endif
- if( MM_GetPhysAddr( refpage ) )
+ if( MM_GetPhysAddr( (void*)refpage ) )
gaiPageReferences[page] = 1;
}
else
{
// Reference again
- if( !MM_GetPhysAddr( refpage ) )
+ if( !MM_GetPhysAddr( (void*)refpage ) )
{
int pages_per_page, basepage, i;
if( MM_Allocate(refpage) == 0 ) {
int MM_GetRefCount(tPAddr PAddr)
{
PAddr >>= 12;
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[PAddr] ) ) {
+ if( MM_GetPhysAddr( &gaiPageReferences[PAddr] ) ) {
return gaiPageReferences[PAddr];
}
ENTER("PPAddr", PAddr);
- if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
+ if( MM_GetPhysAddr( &gaiPageReferences[page] ) )
{
if( gaiPageReferences[page] > 0 )
gaiPageReferences[ page ] --;
else
gaPageBitmaps[ page / 32 ] |= 1 << (page&31);
// Clear node if needed
- if( MM_GetPhysAddr( (tVAddr)&gapPageNodes[page] ) ) {
+ if( MM_GetPhysAddr( &gapPageNodes[page] ) ) {
gapPageNodes[page] = NULL;
// TODO: Catch when all pages in this range are not using nodes
}
if( !MM_GetRefCount(PAddr) ) return 1;
- if( !MM_GetPhysAddr(node_page) ) {
+ if( !MM_GetPhysAddr( (void*)node_page ) ) {
if( !MM_Allocate(node_page) )
return -1;
memset( (void*)node_page, 0, PAGE_SIZE );
if( !MM_GetRefCount(PAddr) ) return 1;
PAddr >>= 12;
- if( !MM_GetPhysAddr( (tVAddr)&gapPageNodes[PAddr] ) ) {
+ if( !MM_GetPhysAddr( &gapPageNodes[PAddr] ) ) {
*Node = NULL;
return 0;
}
tThread *thread;
// Search global list
- for(thread = gAllThreads;
- thread;
- thread = thread->GlobalNext)
+ for( thread = gAllThreads; thread; thread = thread->GlobalNext )
{
if(thread->TID == TID)
return thread;
}
- Log("Unable to find TID %i on main list\n", TID);
+ Log_Notice("Threads", "Unable to find TID %i on main list\n", TID);
return NULL;
}
LOG("No read method");
LEAVE_RET('i', -1);
}
+
+ if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
+ Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+ h->Node->Type->Read);
+ LEAVE_RET('i', -1);
+ }
ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer);
if(ret == -1) LEAVE_RET('i', -1);
Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node);
return 0;
}
+
+ if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
+ Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+ h->Node->Type->Read);
+ LEAVE_RET('i', -1);
+ }
+
ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer);
if(ret == -1) return -1;
return ret;
if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1;
if( !h->Node->Type || !h->Node->Type->Write ) return 0;
+
+ if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
+ Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+ h->Node->Type->Write);
+ return -1;
+ }
ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer);
if(ret == -1) return -1;
if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1;
if(!h->Node->Type || !h->Node->Type->Write) return 0;
- ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
+ if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
+ Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
+ h->Node->Type->Write);
+ return -1;
+ }
+ ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
if(ret == -1) return -1;
return ret;
}
*cwdptr = buf;
}
- Log("Updated CWD to '%s'", buf);
+ Log_Debug("VFS", "Updated CWD to '%s'", buf);
return 1;
}
}
count ++;
if( MaxAllowed && count >= MaxAllowed ) {
+ Mutex_Release(&List->Lock);
LEAVE('i', 1);
return 1;
}
);
memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);
-// gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] = (1 << 30);
-// gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
-// gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0];
- gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] = 1024*2;
+#if 0
+ gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] = (1 << 30);
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0];
+ gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+ gTegra2Vid_DrvUtil_BufInfo.Pitch =
+ 1680*4;
+ gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
+ gTegra2Vid_DrvUtil_BufInfo.Width = 1680;
+ gTegra2Vid_DrvUtil_BufInfo.Height = 1050;
+#else
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 13; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+ gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;
+ gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
gTegra2Vid_DrvUtil_BufInfo.Width = 1024;
gTegra2Vid_DrvUtil_BufInfo.Height = 768;
- gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*2;
- gTegra2Vid_DrvUtil_BufInfo.Depth = 16;
gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;
+#endif
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
// Tegra2Vid_int_SetMode(4);
{
const struct sTegra2_Disp_Mode *mode = &caTegra2Vid_Modes[Mode];
int w = mode->W, h = mode->H; // Horizontal/Vertical Active
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORCH_0) = (mode->VFP << 16) | mode->HFP;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0) = (mode->HS << 16) | mode->HS;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORCH_0) = (mode->VBP << 16) | mode->HBP;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (mode->H << 16) | mode->W;
+ gpTegra2Vid_IOMem[DC_DISP_FRONT_PORCH_0] = (mode->VFP << 16) | mode->HFP;
+ gpTegra2Vid_IOMem[DC_DISP_SYNC_WIDTH_0] = (mode->HS << 16) | mode->HS;
+ gpTegra2Vid_IOMem[DC_DISP_BACK_PORCH_0] = (mode->VBP << 16) | mode->HBP;
+ gpTegra2Vid_IOMem[DC_DISP_DISP_ACTIVE_0] = (mode->H << 16) | mode->W;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (h << 16) | w;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_COLOR_CONTROL_0) = 0x8; // BASE888
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12; // Could be 13 (BGR/RGB)
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_WIN_A_POSITION_0] = 0;
+ gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0] = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_DISP_DISP_COLOR_CONTROL_0] = 0x8; // BASE888
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = (h << 16) | w;
Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);
giTegra2Vid_FramebufferSize = w*h*4;
+ // TODO: Does this need RAM or unmapped space?
gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
(giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
32,
);
// Tell hardware
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_START_ADDR_0) = gTegra2Vid_FramebufferPhys;
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_V_OFFSET_0) = 0; // Y offset
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_H_OFFSET_0) = 0; // X offset
+ gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0] = gTegra2Vid_FramebufferPhys;
+ gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_V_OFFSET_0] = 0; // Y offset
+ gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_H_OFFSET_0] = 0; // X offset
}
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+
return 0;
}
};
#endif
+// Bit definitions
+/// \name DC_CMD_STATE_CONTROL_0
+/// \{
+#define GEN_ACT_REQ 0x0001
+#define WIN_A_ACT_REQ 0x0002
+#define WIN_B_ACT_REQ 0x0004
+#define WIN_C_ACT_REQ 0x0008
+/// \}
+
#endif
if( CPU_HAS_LOCK(&lLock) )
return ; // Nested!
SHORTLOCK(&lLock);
-// __asm__ __volatile__ ("sti"); // Start interrupts (x86 specific)
+ #if ARCHDIR_is_x86
+ __asm__ __volatile__ ("sti"); // Start interrupts (x86 specific)
+ #endif
// Cache packets until a newline
static char cache[1500 - (sizeof(pkt_hdr) + 4)];
CPPFLAGS += -I$(ACESSDIR)/KernelLand/Modules
CPPFLAGS += -DARCH=$(ARCH) -DARCH_is_$(ARCH) -DARCHDIR_is_$(ARCHDIR)
CPPFLAGS += $(_CPPFLAGS)
-CPPFLAGS += $(LIBINCLUDES)
+CPPFLAGS += $(LIBINCLUDES) -ffreestanding
CFLAGS := -std=gnu99 -Wall -fno-stack-protector -g -O3
CFLAGS += -Werror
DRIVERS :=
MODULES :=
+MODULES += Filesystems/RAMDisk
MODULES += Filesystems/Ext2
MODULES += Filesystems/FAT
MODULES += Filesystems/NTFS
--- /dev/null
+=== Simple Image Format ===
+
+U16 Magic 0x51F0 - This determines the endianness of the file
+U16 Flags
+ > 0-2: Compression (0: Uncompressed, 1: RLE, 2: zlib, 3: RLE-Channel)
+ > 3-5: Format (0: ARGB, 1: RGB
+U16 Width
+U16 Height
+<DATA>
+
+
+=== Compression Formats ===
+0 - Uncompressed
+ The file data is a linear sequence of Width * Height 32-bit ARGB
+ words (in file endianness, determined by the magic)
+
+1 - RLE-4
+ 7-bit length followed by a 32-bit value that is repeated `n` times
+ (if bit 7 of the length byte is set, the next `n` 32-bit words are
+ verbatim)
+
+2 - zlib
+ The image data is a zlib stream of 32-bit xRGB words
+
+3 - RLE-Channel
+ The data is the alpha values, followed by red, then green, then blue
+ encoded as RLE with a 7-bit length and a verbatim flag (same as mode
+ 1, except with 8-bit values instead of 32-bit)
--- /dev/null
+TODO:
+- E1000 Driver (stubbed)
+ > Find specs
+ http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
+ > Use bochs/qemu only as a backup
+
+- Cirrus 64-bit VisualMedia Accelerator
+ PCI 1013:00B8 (Cirrus CLGD5446)
+ > Specs avail?
+ Qemu Suggests http://home.worldonline.dk/~finth/
+ > Bochs/Qemu
+
+- UniChrome Driver
+
+- Init Scripts
+ > With an argument to init passed from the kernel?
+
+- #!
+ > Pass as argument? or pass pointer like ld-acess?
+ > argc/argv - Definitely
+
+- Network Debugging + IPv6 Autoconf
+ > Should IPv6 RAs be done in kernel mode, or usermode?
+ > Wait until something like linux's net.conf.ipv6.accept_ra is set?
+ > Have a custom suffix for stateless IPs?
+
+- Signals
+ > Add return value to mutexs and semaphores, and add warn_unused_ret
+
+- Virtual PCI bus for system configuration
+ > Hook in drv_pci.c, with an arch-defined array of devices
+ > Allow hooks on PCI config accesses (to emulate power management etc)
+
+- VFS Path caching
+ > Use a trie of path elements
+ > Maintain backwards cache of elements
+ > Support symlink caching too
+
+- USB Stack
+ > Check validity
+ > Rework HC API to support structure used by OHCI/ECHI
+
+- LVM Usablity
+ > /Devices/LVM/by-id/ and /Devices/LVM/by-label
+
+- AxWin3
+ > Text editor (with a GP formatted text field?)
+ > Maybe a basic web browser using the surface support?
+ > Configuration (via lib/server)
+
+- Omnispeak
+ > Debug speed issues (tracing agian)
+ > Port to AxWin3
+ > Trace memory corruption
+
+- Port dropbear!
CPPFLAGS = -ffreestanding -I$(ACESSUSERDIR)/include/ -DARCHDIR_is_$(ARCHDIR)
CPPFLAGS += $(addprefix -I,$(wildcard $(ACESSUSERDIR)Libraries/*/include_exp/))
CFLAGS = -fno-stack-protector $(CPPFLAGS)
-LDFLAGS = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc $(OUTPUTDIR)Libs/crtbegin.o $(OUTPUTDIR)Libs/crtend.o `$(CC) -print-libgcc-file-name`
+LDFLAGS = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc $(OUTPUTDIR)Libs/crtbegin.o $(OUTPUTDIR)Libs/crtend.o
+LIBGCC_PATH = $(shell $(CC) -print-libgcc-file-name)
# Extra-verbose errors!
#CFLAGS += -Wall -Wextra -Wwrite-strings -Wshadow -Wswitch-default -Wswitch-enum -Wstrict-overflow=5 -Wfloat-equal -Wundef -Wmissing-declarations -Wlogical-op
@mkdir -p $(dir $(_BIN))
@echo [LD] -o $@
ifneq ($(_DBGMAKEFILE),)
- $(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt
+ $(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt $(LIBGCC_PATH)
else
- @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt
+ @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map $(_OBJPREFIX)Map.txt $(LIBGCC_PATH)
endif
@$(DISASM) $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
+++ /dev/null
-
-NAME = AxWin2
-DIRS = WM Shell_src
-
-SUBMAKE = $(MAKE) --no-print-directory
-
-all:
- @$(foreach DIR,$(DIRS), echo --- $(NAME)/$(DIR) && $(SUBMAKE) -C $(DIR) $@ &&) true
-install:
- @$(foreach DIR,$(DIRS), echo --- $(NAME)/$(DIR) && $(SUBMAKE) -C $(DIR) $@ &&) true
-
-clean:
- @$(foreach DIR,$(DIRS), $(SUBMAKE) -C $(DIR) $@ &&) true
+++ /dev/null
-=== Simple Image Format ===
-
-U16 Magic 0x51F0 - This determines the endianness of the file
-U16 Flags
- > 0-2: Compression (0: Uncompressed, 1: RLE, 2: zlib, 3: RLE-Channel)
- > 3-5: Format (0: ARGB, 1: RGB
-U16 Width
-U16 Height
-<DATA>
-
-
-=== Compression Formats ===
-0 - Uncompressed
- The file data is a linear sequence of Width * Height 32-bit ARGB
- words (in file endianness, determined by the magic)
-
-1 - RLE-4
- 7-bit length followed by a 32-bit value that is repeated `n` times
- (if bit 7 of the length byte is set, the next `n` 32-bit words are
- verbatim)
-
-2 - zlib
- The image data is a zlib stream of 32-bit xRGB words
-
-3 - RLE-Channel
- The data is the alpha values, followed by red, then green, then blue
- encoded as RLE with a 7-bit length and a verbatim flag (same as mode
- 1, except with 8-bit values instead of 32-bit)
+++ /dev/null
-# Project: Acess GUI Default Shell
-
--include ../../Makefile.cfg
-
-CPPFLAGS +=
-LDFLAGS += -laxwin2
-
-DIR = Apps/AxWin/1.0
-BIN = Shell
-OBJ = main.o
-
--include ../../Makefile.tpl
+++ /dev/null
-/*
- * Acess2 GUI Test App
- * - By John Hodge (thePowersGang)
- */
-#include <axwin2/axwin.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-// === CONSTANTS ===
-enum eTerminal_Events
-{
- EVENT_NULL,
- EVENT_NEW_TAB,
- EVENT_CLOSE_TAB,
- EVENT_EXIT
-};
-
-// === PROTOTYPES ===
- int main(int argc, char *argv[]);
- int Global_HandleMessage(tAxWin_Message *Message);
- int Shell_HandleMessage(tAxWin_Message *Message);
-
-// === GLOBALS ===
-tAxWin_Element *geConsole;
-
-// === CODE ===
-int main(int argc, char *argv[])
-{
- tAxWin_Element *menu, *tab;
-
- if(argc != 1)
- {
- fprintf(stderr, "Usage: %s\n", argv[0]);
- fprintf(stderr, "\tThis application takes no arguments\n");
- return 0;
- }
-
- AxWin_Register("Terminal", Global_HandleMessage);
-
- menu = AxWin_AddMenuItem(NULL, "File", 0);
- AxWin_AddMenuItem(menu, "&New Tab\tCtrl-Shift-N", EVENT_NEW_TAB);
- AxWin_AddMenuItem(menu, NULL, 0);
- AxWin_AddMenuItem(menu, "&Close Tab\tCtrl-Shift-W", EVENT_CLOSE_TAB);
- AxWin_AddMenuItem(menu, "E&xit\tAlt-F4", EVENT_EXIT);
-
- tab = AxWin_CreateWindow("root@acess: ~");
- //geConsole = AxWin_CreateElement();
-
- AxWin_MessageLoop();
-
- return 0;
-}
-
-/**
- */
-int Global_HandleMessage(tAxWin_Message *Message)
-{
- switch(Message->ID)
- {
- default:
- return 0;
- }
-}
-
-int Shell_HandleMessage(tAxWin_Message *Message)
-{
- switch(Message->ID)
- {
- default:
- return 0;
- }
-}
+++ /dev/null
-# Project: Acess GUI Window Manager
-
--include ../../Makefile.cfg
-
-CPPFLAGS +=
-
-DIR := Apps/AxWin/1.0
-BIN := AxWinWM
-OBJ := main.o helpers.o commandline.o video.o input.o video_text.o
-OBJ += messages.o interface.o wm.o decorator.o render.o
-OBJ += image.o
-
-LDFLAGS += -limage_sif -luri -lnet
-
--include ../../Makefile.tpl
-
-all: resources/LogoSmall.sif.res.h
-
-%.res.h: % Makefile
- echo "#define RESOURCE_$(notdir $<) \\"| sed -e 's/\./_/g' > $@
- base64 $< | sed -e 's/.*/"&"\\/' >> $@
- echo "" >> $@
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <string.h>
-
-// === PROTOTYPES ===
-void ShowUsage(char *ProgName);
-void ShowHelp(char *ProgName);
-
-// === CODE ===
-void ParseCommandline(int argc, char *argv[])
-{
- int i;
- char *arg;
-
- for( i = 1; i < argc; i++ )
- {
- arg = argv[i];
- if(arg[0] == '-')
- {
- if( arg[1] == '-' )
- {
- if( strcmp(&arg[2], "help") == 0 ) {
- ShowHelp(argv[0]);
- exit(EXIT_SUCCESS);
- }
- else {
- ShowUsage(argv[0]);
- exit(EXIT_FAILURE);
- }
- }
- else
- {
- while( *++arg )
- {
- switch(*arg)
- {
- case 'h':
- case '?':
- ShowHelp(argv[0]);
- exit(EXIT_SUCCESS);
- break;
- default:
- break;
- }
- }
- }
- }
- }
-}
-
-void ShowUsage(char *ProgName)
-{
- fprintf(stderr, "Usage: %s [-h|--help]\n", ProgName);
-}
-
-void ShowHelp(char *ProgName)
-{
- ShowUsage(ProgName);
- fprintf(stderr, "\n");
- fprintf(stderr, "\t--help\tShow this message\n");
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <acess/sys.h> // _SysDebug
-
-// === TYPES ===
-typedef struct sIPC_Type tIPC_Type;
-typedef struct sFont tFont;
-
-struct sIPC_Type
-{
- int (*GetIdentSize)(void *Ident);
- int (*CompareIdent)(void *Ident1, void *Ident2);
- void (*SendMessage)(void *Ident, size_t, void *Data);
-};
-
-#include "wm.h"
-#include "image.h"
-//#include "font.h"
-
-// === MACROS ===
-static inline uint32_t Video_AlphaBlend(uint32_t _orig, uint32_t _new, uint8_t _alpha)
-{
- uint16_t ao,ro,go,bo;
- uint16_t an,rn,gn,bn;
- if( _alpha == 0 ) return _orig;
- if( _alpha == 255 ) return _new;
-
- ao = (_orig >> 24) & 0xFF;
- ro = (_orig >> 16) & 0xFF;
- go = (_orig >> 8) & 0xFF;
- bo = (_orig >> 0) & 0xFF;
-
- an = (_new >> 24) & 0xFF;
- rn = (_new >> 16) & 0xFF;
- gn = (_new >> 8) & 0xFF;
- bn = (_new >> 0) & 0xFF;
-
- if( _alpha == 0x80 ) {
- ao = (ao + an) / 2;
- ro = (ro + rn) / 2;
- go = (go + gn) / 2;
- bo = (bo + bn) / 2;
- }
- else {
- ao = ao*(255-_alpha) + an*_alpha;
- ro = ro*(255-_alpha) + rn*_alpha;
- go = go*(255-_alpha) + gn*_alpha;
- bo = bo*(255-_alpha) + bn*_alpha;
- ao /= 255*2;
- ro /= 255*2;
- go /= 255*2;
- bo /= 255*2;
- }
-
- return (ao << 24) | (ro << 16) | (go << 8) | bo;
-}
-
-// === GLOBALS ===
-extern const char *gsTerminalDevice;
-extern const char *gsMouseDevice;
-
-extern int giScreenWidth;
-extern int giScreenHeight;
-extern uint32_t *gpScreenBuffer;
-
-extern int giTerminalFD;
-extern int giMouseFD;
-
-// === Functions ===
-extern void memset32(void *ptr, uint32_t val, size_t count);
-// --- Initialisation ---
-extern void ParseCommandline(int argc, char *argv[]);
-// --- Messages / IPC ---
-extern void IPC_Init(void);
-extern void IPC_FillSelect(int *nfds, fd_set *set);
-extern void IPC_HandleSelect(fd_set *set);
-// --- Input ---
-extern void Input_FillSelect(int *nfds, fd_set *set);
-extern void Input_HandleSelect(fd_set *set);
-// --- Local WM ---
-extern tApplication *AxWin_RegisterClient(tIPC_Type *Method, void *Ident, const char *Name);
-extern void AxWin_DeregisterClient(tApplication *App);
-extern tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident);
-extern tElement *AxWin_CreateAppWindow(tApplication *App, const char *Name);
-// --- Video ---
-extern void Video_Setup(void);
-extern void Video_SetCursorPos(short X, short Y);
-extern void Video_Update(void);
-extern void Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
-extern void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
-extern int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text);
-extern void Video_DrawImage(short X, short Y, short W, short H, tImage *Image);
-// --- Interface ---
-extern void Interface_Init(void);
-extern void Interface_Update(void);
-extern void Interface_Render(void);
-// --- Decorator ---
-extern void Decorator_RenderWidget(tElement *Element);
-
-#endif
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- *
- * Widget Decorator
- */
-#include "common.h"
-#include "wm.h"
-
-#define BORDER_EVERYTHING 1
-
-#define BOX_BGCOLOUR 0xC0C0C0
-#define BOX_BORDER 0xA0A0A0
-#define BUTTON_BGCOLOUR 0xD0D0D0
-#define BUTTON_BORDER 0xF0F0F0
-#define TEXT_COLOUR 0x000000
-
-// === CODE ===
-void Decorator_RenderWidget(tElement *Element)
-{
- _SysDebug("Decorator_RenderWidget: (Element={Type:%i,(%i,%i) %ix%i})",
- Element->Type,
- Element->CachedX, Element->CachedY,
- Element->CachedW, Element->CachedH
- );
-
- #if BORDER_EVERYTHING
- Video_DrawRect(Element->CachedX, Element->CachedY,
- Element->CachedW, Element->CachedH,
- 0
- );
- #endif
-
- switch(Element->Type)
- {
- case ELETYPE_NONE:
- case ELETYPE_BOX: break; // Box is a meta-element
-
- case ELETYPE_TABBAR: // Tab Bar
- Video_DrawRect(
- Element->CachedX, Element->CachedY,
- Element->CachedW, Element->CachedH,
- BOX_BORDER
- );
- Video_FillRect(
- Element->CachedX+1, Element->CachedY+1,
- Element->CachedW-2, Element->CachedH-2,
- BOX_BGCOLOUR
- );
- // Enumerate Items.
- break;
- case ELETYPE_TOOLBAR: // Tool Bar
- Video_DrawRect(
- Element->CachedX, Element->CachedY,
- Element->CachedW, Element->CachedH,
- BOX_BORDER
- );
- Video_FillRect(
- Element->CachedX+1, Element->CachedY+1,
- Element->CachedW-2, Element->CachedH-2,
- BOX_BGCOLOUR
- );
- break;
-
- case ELETYPE_SPACER: // Spacer (subtle line)
- Video_FillRect(
- Element->CachedX+3, Element->CachedY+3,
- Element->CachedW-6, Element->CachedH-6,
- BOX_BORDER
- );
- break;
-
- case ELETYPE_BUTTON: // Button
- Video_FillRect(
- Element->CachedX+1, Element->CachedY+1,
- Element->CachedW-2, Element->CachedH-2,
- BUTTON_BGCOLOUR
- );
- Video_DrawRect(
- Element->CachedX, Element->CachedY,
- Element->CachedW-1, Element->CachedH-1,
- BUTTON_BORDER
- );
- break;
-
- case ELETYPE_TEXT:
- Video_DrawText(
- Element->CachedX+1, Element->CachedY+1,
- Element->CachedW-2, Element->CachedH-2,
- NULL,
- TEXT_COLOUR,
- Element->Text
- );
- break;
-
- case ELETYPE_IMAGE:
- Video_DrawImage(
- Element->CachedX, Element->CachedY,
- Element->CachedW, Element->CachedH,
- Element->Data
- );
- break;
-
- default:
- _SysDebug(" ERROR: Unknown type %i", Element->Type);
- break;
- }
-}
+++ /dev/null
-/*
- * Taken from http://cvs.savannah.gnu.org/viewvc/vgabios/vgafonts.h?root=vgabios&view=markup
- * Altered for Acess2
- */
-#define FONT_WIDTH 8
-#define FONT_HEIGHT 16
-static uint8_t VTermFont[256*16]=
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
- 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
- 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
- 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
- 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-
-// === CODE ===
-void memset32(void *ptr, uint32_t val, size_t count)
-{
- uint32_t *dst = ptr;
- while(count --) *dst++ = val;
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- *
- * Window Manager and Widget Control
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include <uri.h>
-
-// === IMPORTS ===
-extern tImage *Image_SIF_Parse(void *Buffer, size_t Size);
-
-// === PROTOTYPES ===
- int UnBase64(uint8_t *Dest, char *Src, int BufSize);
-
-// === CODE ===
-/**
- * \brief Open an image from a URI
- */
-tImage *Image_Load(const char *URI)
-{
- tURI *uri;
- int filesize;
- void *buf;
- tImage *img;
-
- uri = URI_Parse(URI);
- if( !uri ) {
- _SysDebug("Image_Load: Unable parse as URI '%s'\n", URI);
- return NULL;
- }
-
- if( strcmp(uri->Proto, "file") == 0 )
- {
- FILE *fp;
- fp = fopen(uri->Path, "rb");
- if(!fp) {
- _SysDebug("Image_Load: Unable to open '%s'\n", uri->Path);
- free(uri);
- return NULL;
- }
-
- fseek(fp, 0, SEEK_END);
- filesize = ftell(fp);
- buf = malloc( filesize );
- if(!buf) {
- _SysDebug("Image_Load: malloc() failed!\n");
- fclose(fp);
- free(uri);
- return NULL;
- }
-
- fread(buf, filesize, 1, buf);
- fclose(fp);
- }
- else if( strcmp(uri->Proto, "base64") == 0 )
- {
- // 4 bytes of base64 = 3 bytes of binary (base 256)
- filesize = strlen( uri->Path ) * 3 / 4;
- buf = malloc(filesize);
- if(!buf) {
- _SysDebug("Image_Load: malloc() failed!\n");
- free(uri);
- return NULL;
- }
-
- filesize = UnBase64(buf, uri->Path, filesize);
- }
- else
- {
- _SysDebug("Image_Load: Unknow protocol '%s'\n", uri->Proto);
- free(uri);
- return NULL;
- }
-
- img = Image_SIF_Parse(buf, filesize);
- free(buf);
- free(uri);
- if( !img ) {
- _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
- return NULL;
- }
-
- return img;
-}
-
-/**
- * \brief Decode a Base64 value
- */
-int UnBase64(uint8_t *Dest, char *Src, int BufSize)
-{
- uint32_t val;
- int i, j;
- char *start_src = Src;
-
- for( i = 0; i+2 < BufSize; i += 3 )
- {
- val = 0;
- for( j = 0; j < 4; j++, Src ++ ) {
- if('A' <= *Src && *Src <= 'Z')
- val |= (*Src - 'A') << ((3-j)*6);
- else if('a' <= *Src && *Src <= 'z')
- val |= (*Src - 'a' + 26) << ((3-j)*6);
- else if('0' <= *Src && *Src <= '9')
- val |= (*Src - '0' + 52) << ((3-j)*6);
- else if(*Src == '+')
- val |= 62 << ((3-j)*6);
- else if(*Src == '/')
- val |= 63 << ((3-j)*6);
- else if(!*Src)
- break;
- else if(*Src != '=')
- j --; // Ignore invalid characters
- }
- Dest[i ] = (val >> 16) & 0xFF;
- Dest[i+1] = (val >> 8) & 0xFF;
- Dest[i+2] = val & 0xFF;
- if(j != 4) break;
- }
-
- // Finish things off
- if(i < BufSize)
- Dest[i] = (val >> 16) & 0xFF;
- if(i+1 < BufSize)
- Dest[i+1] = (val >> 8) & 0xFF;
-
- return Src - start_src;
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#ifndef _IMAGE_H_
-#define _IMAGE_H_
-
-typedef struct sImage tImage;
-
-struct sImage
-{
- short Width;
- short Height;
- int Format;
- uint8_t Data[];
-};
-
-enum eImageFormats
-{
- IMGFMT_BGRA,
- IMGFMT_RGB,
- NUM_IMGFMTS
-};
-
-// === PROTOTYPES ===
-extern tImage *Image_Load(const char *URI);
-
-#endif
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-
-#define JOY_IOCTL_GETSETAXISLIMIT 6
-#define JOY_IOCTL_GETSETAXISPOSITION 7
-
-// === CODE ===
-int Input_Init(void)
-{
- struct {
- int Num, Value;
- } num_value;
-
- // Open mouse for RW
- giMouseFD = open(gsMouseDevice, 3);
-
- // Set mouse limits
- num_value.Num = 0;
- num_value.Value = giScreenWidth;
- ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
- num_value.Value = giScreenWidth/2;
- ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
-
- num_value.Num = 1;
- num_value.Value = giScreenHeight;
- ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
- num_value.Value = giScreenHeight/2;
- ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
-
- return 0;
-}
-
-void Input_FillSelect(int *nfds, fd_set *set)
-{
- if(*nfds < giTerminalFD) *nfds = giTerminalFD;
- if(*nfds < giMouseFD) *nfds = giMouseFD;
- FD_SET(giTerminalFD, set);
- FD_SET(giMouseFD, set);
-}
-
-void Input_HandleSelect(fd_set *set)
-{
- if(FD_ISSET(giTerminalFD, set))
- {
- uint32_t codepoint;
- if( read(giTerminalFD, &codepoint, sizeof(codepoint)) != sizeof(codepoint) )
- {
- // oops, error
- }
- // TODO: pass on to message handler
- _SysDebug("Keypress 0x%x", codepoint);
- }
-
- if(FD_ISSET(giMouseFD, set))
- {
- struct sMouseInfo {
- uint16_t NAxies;
- uint16_t NButtons;
- struct sMouseAxis {
- int16_t MinValue;
- int16_t MaxValue;
- int16_t CurValue;
- uint16_t CursorPos;
- } Axies[2];
- uint8_t Buttons[3];
- } mouseinfo;
-
- seek(giMouseFD, 0, SEEK_SET);
- if( read(giMouseFD, &mouseinfo, sizeof(mouseinfo)) != sizeof(mouseinfo) )
- {
- // Not a 3 button mouse, oops
- return ;
- }
-
-// _SysDebug("sizeof(uint16_t) = %i, sizeof(int16_t) = %i",
-// sizeof(uint16_t), sizeof(int16_t));
-// _SysDebug("NAxies=%i,NButtons=%i", mouseinfo.NAxies, mouseinfo.NButtons);
-// _SysDebug("offsetof(Axies[0].MinValue) = %i", offsetof(struct sMouseInfo, Axies[0].MinValue));
-// _SysDebug("[0] = {MinValue=%i,MaxValue=%i,CurValue=%i}",
-// mouseinfo.Axies[0].MinValue, mouseinfo.Axies[0].MaxValue,
-// mouseinfo.Axies[0].CurValue
-// );
- // Handle movement
- Video_SetCursorPos( mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos );
-// _SysDebug("Cursor to %i,%i", mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos);
- }
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- *
- * interface.c
- * > Main Overarching UI
- */
-#include "common.h"
-#include "resources/LogoSmall.sif.res.h"
-
-// === GLOBALS ==
- int giInterface_Width = 0;
- int giInterface_HeaderBarSize = 20;
- int giInterface_TabBarSize = 20;
-tElement *gpInterface_Sidebar;
-tElement *gpInterface_ProgramList;
-tElement *gpInterface_MainArea;
-tElement *gpInterface_HeaderBar;
-tElement *gpInterface_TabBar;
-tElement *gpInterface_TabContent;
-const char csLogoSmall[] = "base64:///"RESOURCE_LogoSmall_sif;
-tApplication *gpInterface_CurrentApp;
-
-typedef struct sApplicationLink tApplicationLink;
-
-struct sApplicationLink {
- tApplication *App;
- tElement *Button;
- char Name[];
-};
-
-// === CODE ===
-/**
- * \brief Initialise the UI
- */
-void Interface_Init(void)
-{
- tElement *btn, *text;
- tElement *ele;
-
- // Calculate sizes
- giInterface_Width = giScreenWidth/16;
-
- // Set root window to no-border
- AxWin_SetFlags(NULL, 0);
-
- // -- Create Sidebar (Menu and Window List) --
- gpInterface_Sidebar = AxWin_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL, "Sidebar");
- AxWin_SetSize( gpInterface_Sidebar, giInterface_Width );
-
- // > System Menu Button
- btn = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemMenu");
- AxWin_SetSize(btn, giInterface_Width-4);
- //text = AxWin_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE, "MenuLogo");
- text = AxWin_CreateElement(btn, ELETYPE_IMAGE, 0, "MenuLogo");
- //AxWin_SetText(text, "file:///LogoSmall.sif");
- AxWin_SetText(text, csLogoSmall);
-
- // > Plain <hr/> style spacer
- ele = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top");
- AxWin_SetSize(ele, 4);
-
- // > Application List (Window list on most OSs)
- gpInterface_ProgramList = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL, "ProgramList");
-
- // > Plain <hr/> style spacer
- ele = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Bottom");
- AxWin_SetSize(ele, 4);
-
- // > Version/Time
- text = AxWin_CreateElement(gpInterface_Sidebar, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String");
- AxWin_SetSize(text, 20);
- AxWin_SetText(text, "2.0");
-
- // --
- // -- Create Main Area and regions within --
- // --
- // > Righthand Area
- gpInterface_MainArea = AxWin_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL, "MainArea");
- // > Header Bar (Title)
- gpInterface_HeaderBar = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "HeaderBar");
- AxWin_SetSize(gpInterface_HeaderBar, giInterface_HeaderBarSize);
- text = AxWin_CreateElement(gpInterface_HeaderBar, ELETYPE_TEXT, 0, NULL);
- AxWin_SetText(text, "Acess2 GUI - By thePowersGang (John Hodge)");
- // > Tab Bar (Current windows)
- gpInterface_TabBar = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0, "TabBar");
- AxWin_SetSize(gpInterface_TabBar, giInterface_TabBarSize);
- // > Application Space
- gpInterface_TabContent = AxWin_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "TabContent");
-}
-
-void Interface_Update(void)
-{
-// tApplication *app;
-// tApplicationLink *lnk;
- giInterface_Width = giScreenWidth/16;
- AxWin_SetSize( gpInterface_Sidebar, giInterface_Width );
-
- // Scan application list for changes
- // - HACK for now, just directly access it
-// for( app = gWM_Applications; app; app = app->Next )
-// {
-// AxWin_CreateElement();
-// }
-
- // Update current tab list
-}
-
-void Interface_Render(void)
-{
- Video_FillRect(
- 0, 0,
- giInterface_Width, giScreenHeight,
- 0xDDDDDD);
-
- Video_Update();
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-
-// === IMPORTS ===
-extern void WM_Update(void);
-extern int Input_Init(void);
-
-// === GLOBALS ===
-const char *gsTerminalDevice = NULL;
-const char *gsMouseDevice = NULL;
-
- int giScreenWidth = 640;
- int giScreenHeight = 480;
-uint32_t *gpScreenBuffer = NULL;
-
- int giTerminalFD = -1;
- int giMouseFD = -1;
-
-
-// === CODE ===
-/**
- * \brief Program Entrypoint
- */
-int main(int argc, char *argv[])
-{
- ParseCommandline(argc, argv);
-
- if( gsTerminalDevice == NULL ) {
- gsTerminalDevice = "/Devices/VTerm/6";
- }
- if( gsMouseDevice == NULL ) {
- gsMouseDevice = "/Devices/PS2Mouse";
- }
-
- Video_Setup();
- Interface_Init();
- IPC_Init();
- Input_Init();
-
- WM_Update();
-
- // Main Loop
- for(;;)
- {
- fd_set fds;
- int nfds = 0;
- FD_ZERO(&fds);
-
- Input_FillSelect(&nfds, &fds);
- IPC_FillSelect(&nfds, &fds);
-
- nfds ++;
- select(nfds, &fds, NULL, NULL, NULL);
-
- Input_HandleSelect(&fds);
- IPC_HandleSelect(&fds);
- }
- return 0;
-}
-
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-#include <net.h>
-#include <axwin2/messages.h>
-#include <string.h>
-
-#define AXWIN_PORT 4101
-
-#define STATICBUF_SIZE 64
-
-// === TYPES ===
-
-// === PROTOTYPES ===
-void IPC_Init(void);
-void IPC_FillSelect(int *nfds, fd_set *set);
-void IPC_HandleSelect(fd_set *set);
-void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg);
-void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value);
- int IPC_Type_Datagram_GetSize(void *Ident);
- int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2);
-void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data);
- int IPC_Type_Sys_GetSize(void *Ident);
- int IPC_Type_Sys_Compare(void *Ident1, void *Ident2);
-void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data);
-
-// === GLOBALS ===
- int giNetworkFileHandle = -1;
- int giMessagesFileHandle = -1;
-tIPC_Type gIPC_Type_Datagram = {
- IPC_Type_Datagram_GetSize,
- IPC_Type_Datagram_Compare,
- IPC_Type_Datagram_Send
-};
-tIPC_Type gIPC_Type_SysMessage = {
- IPC_Type_Sys_GetSize,
- IPC_Type_Sys_Compare,
- IPC_Type_Sys_Send
-};
-
-// === CODE ===
-void IPC_Init(void)
-{
- int tmp;
- // TODO: Check this
- giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
- tmp = AXWIN_PORT; ioctl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number
-}
-
-void IPC_FillSelect(int *nfds, fd_set *set)
-{
- if( giNetworkFileHandle > *nfds ) *nfds = giNetworkFileHandle;
- FD_SET(giNetworkFileHandle, set);
-}
-
-void IPC_HandleSelect(fd_set *set)
-{
- if( FD_ISSET(giNetworkFileHandle, set) )
- {
- char staticBuf[STATICBUF_SIZE];
- int readlen, identlen;
- char *msg;
-
- readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
-
- identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
- msg = staticBuf + identlen;
-
- IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg);
- _SysDebug("IPC_HandleSelect: UDP handled");
- }
-
- while(SysGetMessage(NULL, NULL))
- {
- pid_t tid;
- int len = SysGetMessage(&tid, NULL);
- char data[len];
- SysGetMessage(NULL, data);
-
- IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
- _SysDebug("IPC_HandleSelect: Message handled");
- }
-}
-
-void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg)
-{
- tApplication *app;
- tElement *ele;
-
- _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
- IPCType, Ident, MsgLen, Msg);
-
- if( MsgLen < sizeof(tAxWin_Message) )
- return ;
- if( MsgLen < sizeof(tAxWin_Message) + Msg->Size )
- return ;
-
- app = AxWin_GetClient(IPCType, Ident);
-
- switch((enum eAxWin_Messages) Msg->ID)
- {
- // --- Ping message (reset timeout and get server version)
- case MSG_SREQ_PING:
- _SysDebug(" IPC_Handle: MSG_SREQ_PING");
- if( MsgLen < sizeof(tAxWin_Message) + 4 ) return;
- Msg->ID = MSG_SRSP_VERSION;
- Msg->Size = 4;
- Msg->Data[0] = 0;
- Msg->Data[1] = 1;
- *(uint16_t*)&Msg->Data[2] = -1;
- IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg);
- break;
-
-
- // --- Register an application
- case MSG_SREQ_REGISTER:
- _SysDebug(" IPC_Handle: MSG_SREQ_REGISTER");
- if( Msg->Data[Msg->Size-1] != '\0' ) {
- // Invalid message
- _SysDebug("IPC_Handle: RETURN - Not NULL terminated");
- return ;
- }
-
- if( app != NULL ) {
- _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data);
- return ;
- }
-
- // TODO: Should this function be implemented here?
- AxWin_RegisterClient(IPCType, Ident, Msg->Data);
- break;
-
- // --- Create a window
- case MSG_SREQ_ADDWIN:
- _SysDebug(" IPC_Handle: MSG_SREQ_ADDWIN");
- if( Msg->Data[Msg->Size-1] != '\0' ) {
- // Invalid message
- return ;
- }
-
- ele = AxWin_CreateAppWindow(app, Msg->Data);
- IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
- break;
-
- // --- Set a window's icon
- case MSG_SREQ_SETICON:
- _SysDebug(" IPC_Handle: MSG_SREQ_SETICON");
- // TODO: Find a good way of implementing this
- break;
-
- // --- Create an element
- case MSG_SREQ_INSERT: {
- _SysDebug(" IPC_Handle: MSG_SREQ_INSERT");
- struct sAxWin_SReq_NewElement *info = (void *)Msg->Data;
-
- if( Msg->Size != sizeof(*info) ) return;
-
- if( !app || info->Parent > app->MaxElementIndex ) return ;
-
- ele = AxWin_CreateElement( app->EleIndex[info->Parent], info->Type, info->Flags, NULL );
- IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
- break; }
-
- // --- Unknown message
- default:
- fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
- _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
- break;
- }
-}
-
-void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value)
-{
- char data[sizeof(tAxWin_Message) + sizeof(tAxWin_RetMsg)];
- tAxWin_Message *msg = (void *)data;
- tAxWin_RetMsg *ret_msg = (void *)msg->Data;
-
- msg->Source = 0; // 0 = Server
- msg->ID = MSG_SRSP_RETURN;
- msg->Size = sizeof(tAxWin_RetMsg);
- ret_msg->ReqID = MessageID;
- ret_msg->Rsvd = 0;
- ret_msg->Value = Value;
-
- IPCType->SendMessage(Ident, sizeof(data), data);
-}
-
-int IPC_Type_Datagram_GetSize(void *Ident)
-{
- return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
-}
-
-int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
-{
- // Pass the buck :)
- // - No need to worry about mis-matching sizes, as the size is computed
- // from the 3rd/4th bytes, hence it will differ before the size is hit.
- return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
-}
-
-void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
-{
- int identlen = IPC_Type_Datagram_GetSize(Ident);
- char tmpbuf[ identlen + Length ];
- memcpy(tmpbuf, Ident, identlen); // Header
- memcpy(tmpbuf + identlen, Data, Length); // Data
- // TODO: Handle fragmented packets
- write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
-}
-
-int IPC_Type_Sys_GetSize(void *Ident)
-{
- return sizeof(pid_t);
-}
-
-int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
-{
- return *(int*)Ident1 - *(int*)Ident2;
-}
-
-void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
-{
- SysSendMessage( *(tid_t*)Ident, Length, Data );
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- *
- * Rendering code
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include "wm.h"
-#include <acess/sys.h> // _SysDebug
-
-// === IMPORTS ===
-extern void Decorator_RenderWidget(tElement *Element);
-extern tElement gWM_RootElement;
-extern tApplication *gWM_Applications;
-extern int giWM_MaxAreaX;
-extern int giWM_MaxAreaY;
-extern int giWM_MaxAreaW;
-extern int giWM_MaxAreaH;
-
-// === PROTOTYPES ===
-void WM_UpdateMinDims(tElement *Element);
-void WM_UpdateDimensions(tElement *Element, int Pass);
-void WM_UpdatePosition(tElement *Element);
-void WM_RenderWidget(tElement *Element);
-void WM_Update(void);
-
-// === CODE ===
-/**
- * \brief Updates the dimensions of an element
- * \todo What is the \a Pass parameter for
- *
- * The dimensions of an element are calculated from the parent's
- * cross dimension (the side at right angles to the alignment) sans some
- * padding.
- */
-void WM_UpdateDimensions(tElement *Element, int Pass)
-{
- tElement *child;
- int nChildren = 0;
- int nFixed = 0;
- int maxCross = 0;
- int fixedSize = 0;
- int fullCross, dynWith;
-
- _SysDebug("WM_UpdateDimensions %p'%s'", Element, Element->DebugName);
- _SysDebug(" -> Flags = 0x%x", Element->Flags);
- _SysDebug(" ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i",
- Element->CachedH, Element->PaddingT, Element->PaddingB
- );
- _SysDebug(" ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i",
- Element->CachedW, Element->PaddingL, Element->PaddingR
- );
-
- // Pass 1
- for( child = Element->FirstChild; child; child = child->NextSibling )
- {
- if( child->Flags & ELEFLAG_ABSOLUTEPOS )
- continue ;
-
- _SysDebug(" > %p'%s' ->FixedWith = %i", child, child->DebugName, child->FixedWith);
- if( child->FixedWith )
- {
- nFixed ++;
- fixedSize += child->FixedWith;
- }
-
- if( child->FixedCross && maxCross < child->FixedCross )
- maxCross = child->FixedCross;
- if( child->MinCross && maxCross < child->MinCross )
- maxCross = child->MinCross;
- nChildren ++;
- }
-
- _SysDebug(" - nChildren = %i, nFixed = %i", Element, nChildren, nFixed);
- if( nChildren > nFixed ) {
- if( Element->Flags & ELEFLAG_VERTICAL )
- dynWith = Element->CachedH - Element->PaddingT
- - Element->PaddingB;
- else
- dynWith = Element->CachedW - Element->PaddingL
- - Element->PaddingR;
- dynWith -= fixedSize;
- if( dynWith < 0 ) return ;
- dynWith /= nChildren - nFixed;
- _SysDebug(" - dynWith = %i", dynWith);
- }
-
- if( Element->Flags & ELEFLAG_VERTICAL )
- fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR;
- else
- fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
-
- _SysDebug(" - fullCross = %i", Element, fullCross);
-
- // Pass 2 - Set sizes and recurse
- for( child = Element->FirstChild; child; child = child->NextSibling )
- {
- int cross, with;
-
- _SysDebug(" > %p'%s' ->MinCross = %i", child, child->DebugName, child->MinCross);
-
-
- // --- Cross Size ---
- if( child->FixedCross )
- cross = child->FixedCross;
- // Expand to fill?
- // TODO: Extra flag so options are (Expand, Equal, Wrap)
- else if( child->Flags & ELEFLAG_NOEXPAND )
- cross = child->MinCross;
- else
- cross = fullCross;
- _SysDebug(" > %p'%s' - cross = %i", child, child->DebugName, cross);
- if( Element->Flags & ELEFLAG_VERTICAL )
- child->CachedW = cross;
- else
- child->CachedH = cross;
-
- // --- With Size ---
- if( child->FixedWith)
- with = child->FixedWith;
- else if( child->Flags & ELEFLAG_NOSTRETCH )
- with = child->MinWith;
- else
- with = dynWith;
- _SysDebug(" > %p'%s' - with = %i", child, child->DebugName, with);
- if( Element->Flags & ELEFLAG_VERTICAL )
- child->CachedH = with;
- else
- child->CachedW = with;
-
- WM_UpdateDimensions(child, Pass);
- }
-
- _SysDebug("%p'%s' Done", Element, Element->DebugName);
-}
-
-/**
- * \brief Updates the position of an element
- *
- * The parent element sets the positions of its children
- */
-void WM_UpdatePosition(tElement *Element)
-{
- tElement *child;
- int x, y;
- static int depth = 0;
- char indent[depth+1];
-
- if( Element->Flags & ELEFLAG_NORENDER ) return ;
-
- memset(indent, ' ', depth);
- indent[depth] = '\0';
- depth ++;
-
- _SysDebug("%sWM_UpdatePosition %p'%s'{PaddingL:%i, PaddingT:%i}",
- indent, Element, Element->DebugName, Element->PaddingL, Element->PaddingT);
-
- // Initialise
- x = Element->CachedX + Element->PaddingL;
- y = Element->CachedY + Element->PaddingT;
-
- _SysDebug("%s- Alignment = %s", indent,
- (Element->Flags & ELEFLAG_VERTICAL) ? "vertical" : "horizontal");
-
- // Update each child
- for(child = Element->FirstChild; child; child = child->NextSibling)
- {
- _SysDebug("%s- x = %i, y = %i", indent, x, y);
- child->CachedX = x;
- child->CachedY = y;
-
- // Set Alignment
- if( Element->Flags & ELEFLAG_ALIGN_CENTER ) {
- _SysDebug("%sChild being aligned to center", indent);
- if(Element->Flags & ELEFLAG_VERTICAL)
- child->CachedX += Element->CachedW/2 - child->CachedW/2;
- else
- child->CachedY += Element->CachedH/2 - child->CachedH/2;
- }
- else if( Element->Flags & ELEFLAG_ALIGN_END) {
- _SysDebug("%sChild being aligned to end", indent);
- if(Element->Flags & ELEFLAG_VERTICAL )
- child->CachedX += Element->CachedW
- - Element->PaddingL - Element->PaddingR
- - child->CachedW;
- else
- child->CachedY += Element->CachedH
- - Element->PaddingT
- - Element->PaddingB
- - child->CachedH;
- }
-
- _SysDebug("%s> %p'%s' at (%i,%i)", indent, child, child->DebugName,
- child->CachedX, child->CachedY);
-
- // Update child's children positions
- WM_UpdatePosition(child);
-
- // Increment
- if(Element->Flags & ELEFLAG_VERTICAL ) {
- y += child->CachedH + Element->GapSize;
- }
- else {
- x += child->CachedW + Element->GapSize;
- }
- }
-
- _SysDebug("%sElement %p'%s' (%i,%i)",
- indent, Element, Element->DebugName, Element->CachedX, Element->CachedY
- );
- depth --;
-}
-
-/**
- * \brief Update the minimum dimensions of the element
- * \note Called after a child's minimum dimensions have changed
- */
-void WM_UpdateMinDims(tElement *Element)
-{
- tElement *child;
-
- if(!Element) return;
-
- Element->MinCross = 0;
- Element->MinWith = 0;
-
- for(child = Element->FirstChild; child; child = child->NextSibling)
- {
- if( Element->Parent &&
- (Element->Flags & ELEFLAG_VERTICAL) == (Element->Parent->Flags & ELEFLAG_VERTICAL)
- )
- {
- if(child->FixedCross)
- Element->MinCross += child->FixedCross;
- else
- Element->MinCross += child->MinCross;
- if(child->FixedWith)
- Element->MinWith += child->FixedWith;
- else
- Element->MinWith += child->MinWith;
- }
- else
- {
- if(child->FixedCross)
- Element->MinWith += child->FixedCross;
- else
- Element->MinWith += child->MinCross;
- if(child->FixedWith)
- Element->MinCross += child->FixedWith;
- else
- Element->MinCross += child->MinWith;
- }
- }
-
- // Recurse upwards
- WM_UpdateMinDims(Element->Parent);
-}
-
-// --- Render ---
-void WM_RenderWidget(tElement *Element)
-{
- tElement *child;
-
- if( Element->Flags & ELEFLAG_NORENDER ) return ;
- if( Element->Flags & ELEFLAG_INVISIBLE ) return ;
-
- Decorator_RenderWidget(Element);
-
- for(child = Element->FirstChild; child; child = child->NextSibling)
- {
- WM_RenderWidget(child);
- }
-}
-
-void WM_UpdateWindow(tElement *Ele)
-{
- WM_UpdateDimensions( Ele, 0 );
- WM_UpdatePosition( Ele );
- WM_RenderWidget( Ele );
-}
-
-void WM_Update(void)
-{
- tApplication *app;
- tElement *ele;
-
- for( app = gWM_Applications; app; app = app->Next )
- {
- for( ele = app->MetaElement.FirstChild; ele; ele = ele->NextSibling ) {
- if( ele->Flags & ELEFLAG_WINDOW_MAXIMISED ) {
- ele->CachedX = giWM_MaxAreaX;
- ele->CachedY = giWM_MaxAreaY;
- ele->CachedW = giWM_MaxAreaW;
- ele->CachedH = giWM_MaxAreaH;
- }
- ele->Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
- WM_UpdateWindow(ele);
- }
- }
-
- gWM_RootElement.CachedX = 0;
- gWM_RootElement.CachedY = 0;
- gWM_RootElement.CachedW = giScreenWidth;
- gWM_RootElement.CachedH = giScreenHeight;
- gWM_RootElement.Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
-
- WM_UpdateWindow( &gWM_RootElement );
-
- Video_Update();
-}
+++ /dev/null
-/*
- */
-#ifndef _RESORUCE_CURSOR_H
-#define _RESORUCE_CURSOR_H
-
-#include <stdint.h>
-
-static struct {
- uint16_t W, H, OfsX, OfsY;
- uint32_t Data[];
-} cCursorBitmap = {
- 8, 16, 0, 0,
- {
- 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0xFF000000, 0xFF000000,
- 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
- 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000,
- 0xFF000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFF000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
- }
-};
-
-#endif
-
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include "common.h"
-#include <acess/sys.h>
-#include <acess/devices/terminal.h>
-#include <image.h>
-#include "resources/cursor.h"
-
-// === PROTOTYPES ===
-void Video_Setup(void);
-void Video_SetCursorPos(short X, short Y);
-void Video_Update(void);
-void Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
-void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
-
-// === GLOBALS ===
- int giVideo_CursorX;
- int giVideo_CursorY;
-
-// === CODE ===
-void Video_Setup(void)
-{
- int tmpInt;
-
- // Open terminal
- giTerminalFD = open(gsTerminalDevice, OPENFLAG_READ|OPENFLAG_WRITE);
- if( giTerminalFD == -1 )
- {
- fprintf(stderr, "ERROR: Unable to open '%s' (%i)\n", gsTerminalDevice, _errno);
- exit(-1);
- }
-
- // Set width
- tmpInt = giScreenWidth;
- tmpInt = ioctl( giTerminalFD, TERM_IOCTL_WIDTH, &tmpInt );
- if(tmpInt != giScreenWidth)
- {
- fprintf(stderr, "Warning: Selected width (%i) is invalid, clipped to %i\n",
- giScreenWidth, tmpInt);
- giScreenWidth = tmpInt;
- }
-
- // Set height
- tmpInt = giScreenHeight;
- tmpInt = ioctl( giTerminalFD, TERM_IOCTL_HEIGHT, &tmpInt );
- if(tmpInt != giScreenHeight)
- {
- fprintf(stderr, "Warning: Selected height (%i) is invalid, clipped to %i\n",
- giScreenHeight, tmpInt);
- giScreenHeight = tmpInt;
- }
-
- // Set mode to video
- tmpInt = TERM_MODE_FB;
- ioctl( giTerminalFD, TERM_IOCTL_MODETYPE, &tmpInt );
-
- // Force VT to be shown
- ioctl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL );
-
- // Create local framebuffer (back buffer)
- gpScreenBuffer = malloc( giScreenWidth*giScreenHeight*4 );
- memset32( gpScreenBuffer, 0x8888FF, giScreenWidth*giScreenHeight );
-
- // Set cursor position and bitmap
- ioctl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap);
- Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 );
-
- Video_Update();
-}
-
-void Video_Update(void)
-{
- //seek(giTerminalFD, 0, SEEK_SET);
- seek(giTerminalFD, 0, 1);
- write(giTerminalFD, gpScreenBuffer, giScreenWidth*giScreenHeight*4);
-}
-
-void Video_SetCursorPos(short X, short Y)
-{
- struct {
- uint16_t x;
- uint16_t y;
- } pos;
- pos.x = giVideo_CursorX = X;
- pos.y = giVideo_CursorY = Y;
- ioctl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos);
-}
-
-void Video_FillRect(short X, short Y, short W, short H, uint32_t Color)
-{
- uint32_t *buf = gpScreenBuffer + Y*giScreenWidth + X;
-
- _SysDebug("Video_FillRect: (X=%i, Y=%i, W=%i, H=%i, Color=%08x)",
- X, Y, W, H, Color);
-
- if(W < 0 || X < 0 || X >= giScreenWidth) return ;
- if(X + W > giScreenWidth) W = giScreenWidth - X;
-
- if(H < 0 || Y < 0 || Y >= giScreenHeight) return ;
- if(Y + H > giScreenHeight) H = giScreenHeight - Y;
-
- while( H -- )
- {
- memset32( buf, Color, W );
- buf += giScreenWidth;
- }
-}
-
-void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color)
-{
- Video_FillRect(X, Y, W, 1, Color);
- Video_FillRect(X, Y+H-1, W, 1, Color);
- Video_FillRect(X, Y, 1, H, Color);
- Video_FillRect(X+W-1, Y, 1, H, Color);
-}
-
-/**
- * \brief Draw an image to the screen
- * \todo Maybe have support for an offset in the image
- */
-void Video_DrawImage(short X, short Y, short W, short H, tImage *Image)
-{
- int x, y;
- uint8_t *buf = (uint8_t *)(gpScreenBuffer + Y*giScreenWidth + X);
- uint8_t *data;
-
- // Sanity please
- if( !Image )
- return ;
-
- // Bounds Check
- if( X >= giScreenWidth ) return ;
- if( Y >= giScreenHeight ) return ;
-
- // Wrap to image size
- if( W > Image->Width ) W = Image->Width;
- if( H > Image->Height ) H = Image->Height;
-
- // Wrap to screen size
- if( X + W > giScreenWidth ) W = giScreenWidth - X;
- if( Y + H > giScreenHeight ) H = giScreenHeight - Y;
-
- // Do the render
- data = Image->Data;
- switch( Image->Format )
- {
- case IMGFMT_BGRA:
- for( y = 0; y < H; y ++ )
- {
- int r, g, b, a; // New
- int or, og, ob; // Original
- for( x = 0; x < W; x ++ )
- {
- b = data[x*4+0]; g = data[x*4+1]; r = data[x*4+2]; a = data[x*4+3];
- if( a == 0 ) continue; // 100% transparent
- ob = buf[x*4+0]; og = buf[x*4+1]; or = buf[x*4+2];
- // Handle Alpha
- switch(a)
- {
- // Transparent: Handled above
- // Solid
- case 0xFF: break;
- // Half
- case 0x80:
- r = (or + r) / 2;
- g = (og + g) / 2;
- b = (ob + b) / 2;
- break;
- // General
- default:
- r = (or * (255-a) + r * a) / 255;
- g = (og * (255-a) + g * a) / 255;
- b = (ob * (255-a) + b * a) / 255;
- break;
- }
- buf[x*4+0] = b; buf[x*4+1] = g; buf[x*4+2] = r;
- }
- data += Image->Width * 4;
- buf += giScreenWidth * 4;
- }
- break;
-
- // RGB
- case IMGFMT_RGB:
- for( y = 0; y < H; y ++ )
- {
- for( x = 0; x < W; x ++ )
- {
- buf[x*4+0] = data[x*3+2]; // Blue
- buf[x*4+1] = data[x*3+1]; // Green
- buf[x*4+2] = data[x*3+0]; // Red
- }
- data += W * 3;
- buf += giScreenWidth * 4;
- }
- break;
- default:
- _SysDebug("ERROR: Unknown image format %i\n", Image->Format);
- break;
- }
-}
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- */
-#include <acess/sys.h>
-#include "common.h"
-
-typedef struct sGlyph {
- struct sGlyph *Next;
- struct sGlyph *Prev;
-
- uint32_t Codepoint;
-
- // Effective dimensions (distance to move 'cursor')
- short Width;
- short Height;
-
- // Distance from the current cursor position to render at
- short OffsetX;
- short OffsetY;
-
- // True dimensions (size of the bitmap
- short TrueWidth;
- short TrueHeight;
-
- // Bitmap Data
- uint8_t Bitmap[]; // 8-bit alpha
-
-} tGlyph;
-
-struct sFont {
- struct sFont *Next;
- int ReferenceCount;
-
- tGlyph *AsciiGlyphs[128]; // Glyphs 0-127
-
- tGlyph *FirstGlyph;
- tGlyph *LastGlyph;
-
- tGlyph *(*CacheGlyph)(struct sFont *this, uint32_t Codepoint);
-
-};
-
-
-// === PROTOTYPES ===
- int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text);
-void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
-tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint);
-void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color);
-tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint);
- int ReadUTF8(const char *Input, uint32_t *Output);
-
-// === GLOBALS ===
-tFont gSystemFont = {
- .CacheGlyph = _SystemFont_CacheGlyph
-};
-
-// === CODE ===
-/**
- * \brief Draw text to the screen
- */
-int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text)
-{
- int xOfs = 0;
- tGlyph *glyph;
- uint32_t ch = 0;
-
- _SysDebug("Video_DrawText: (X=%i,Y=%i,W=%i,H=%i,Font=%p,", X, Y, W, H, Font);
- _SysDebug(" Color=%08x,Text='%s')", Color, Text);
-
- // Check the bounds
- if(W < 0 || X < 0 || X >= giScreenWidth) return 0;
- if(X + W > giScreenWidth) W = giScreenWidth - X;
-
- if(H < 0 || Y < 0 || Y >= giScreenHeight) return 0;
- if(Y + H > giScreenHeight) H = giScreenHeight - Y;
-
- // Handle NULL font (system default monospace)
- if( !Font ) Font = &gSystemFont;
-
- while( *Text )
- {
- // Read character
- Text += ReadUTF8(Text, &ch);
-
- // Find (or load) the glyph
- glyph = _GetGlyph(Font, ch);
- if( !glyph ) continue ; // If not found, just don't render it
-
- // End render if it will overflow the perscribed range
- if( xOfs + glyph->TrueWidth > W )
- break;
-
- xOfs += glyph->Width;
- _RenderGlyph(X + xOfs, Y, glyph, Color);
- }
-
- return xOfs;
-}
-
-void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H)
-{
- int w=0, h=0;
- uint32_t ch;
- tGlyph *glyph;
- if( !Font ) Font = &gSystemFont;
-
- while( *Text )
- {
- Text += ReadUTF8(Text, &ch);
- glyph = _GetGlyph(Font, ch);
- if( !glyph ) continue;
-
- w += glyph->Width;
- if( h < glyph->Height ) h = glyph->Height;
- }
-
- if(W) *W = w;
- if(H) *H = h;
-}
-
-tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint)
-{
- tGlyph *next = NULL, *prev = NULL;
- tGlyph *new;
-
- // Check for ASCII
- if( Codepoint < 128 )
- {
- if( Font->AsciiGlyphs[Codepoint] == NULL ) {
- Font->AsciiGlyphs[Codepoint] = Font->CacheGlyph(Font, Codepoint);
- }
-
- return Font->AsciiGlyphs[Codepoint];
- }
-
- // If within the range
- if( Font->FirstGlyph && Font->FirstGlyph->Codepoint < Codepoint && Codepoint < Font->LastGlyph->Codepoint )
- {
- // Find what end is "closest"
- if( Codepoint - Font->FirstGlyph->Codepoint < Font->LastGlyph->Codepoint - Codepoint )
- {
- // Start from the bottom
- for( next = Font->FirstGlyph;
- next && next->Codepoint < Codepoint;
- prev = next, next = next->Next
- );
-
- if( next->Codepoint == Codepoint )
- return next;
-
- }
- else
- {
- // Start at the top
- // NOTE: The roles of next and prev are reversed here to allow
- // the insert to be able to assume that `prev` is the
- // previous entry, and `next` is the next.
- for( prev = Font->LastGlyph;
- prev && prev->Codepoint > Codepoint;
- next = prev, prev = prev->Prev
- );
- if( prev->Codepoint == Codepoint )
- return prev;
- }
- }
- else
- {
- // If below first
- if( !Font->FirstGlyph || Font->FirstGlyph->Codepoint > Codepoint ) {
- prev = NULL;
- next = Font->FirstGlyph;
- }
- // Above last
- else {
- prev = Font->LastGlyph;
- next = NULL;
- }
- }
-
- // Load new
- new = Font->CacheGlyph(Font, Codepoint);
- if( !new ) return NULL;
-
- // Add to list
- // - Forward link
- if( prev ) {
- new->Next = prev->Next;
- prev->Next = new;
- }
- else {
- new->Next = Font->FirstGlyph;
- Font->FirstGlyph = new;
- }
-
- // - Backlink
- if( next ) {
- new->Prev = next->Prev;
- next->Prev = new;
- }
- else {
- new->Prev = Font->LastGlyph;
- Font->LastGlyph = new;
- }
-
- // Return
- return new;
-}
-
-/**
- */
-void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color)
-{
- int xStart = 0, yStart = 0;
- int x, y;
- uint32_t *outBuf;
- uint8_t *inBuf;
- // TODO: Implement
-
- X += Glyph->OffsetX;
- if( X < 0 ) { // If -ve, skip the first -X collums
- xStart = -X;
- X = 0;
- }
-
- Y += Glyph->OffsetY;
- if( Y < 0 ) { // If -ve, skip the first -Y lines
- yStart = -Y;
- Y = 0;
- }
-
- outBuf = gpScreenBuffer + Y*giScreenWidth + X;
- inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth;
-
- for( y = yStart; y < Glyph->TrueHeight; y ++ )
- {
- for( x = xStart; x < Glyph->TrueWidth; x ++ )
- {
- outBuf[x] = Video_AlphaBlend( outBuf[x], Color, inBuf[x] );
- }
- outBuf += giScreenWidth;
- inBuf += Glyph->TrueWidth;
-
- }
-}
-
-// Load system font (8x16 monospace)
-#include "font_8x16.h"
-
-/*
- */
-tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint)
-{
- int i;
- uint8_t index = 0;
- tGlyph *ret;
- uint8_t *data;
-
- _SysDebug("_SystemFont_CacheGlyph: (Font=%p, Codepoint=0x%06x)", Font, Codepoint);
-
- if( Codepoint < 128 ) {
- index = Codepoint;
- }
- else {
- index = '?'; // Unknowns come out as a question mark
- }
-
- _SysDebug(" index = %i", index);
-
- ret = malloc( sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT );
- if( !ret ) {
- _SysDebug("ERROR: malloc(%i) failed", sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT);
- return NULL;
- }
-
- ret->Codepoint = Codepoint;
-
- ret->Width = FONT_WIDTH;
- ret->Height = FONT_HEIGHT;
-
- ret->TrueWidth = FONT_WIDTH;
- ret->TrueHeight = FONT_HEIGHT;
-
- ret->OffsetX = 0;
- ret->OffsetY = 0;
-
- data = &VTermFont[index * FONT_HEIGHT];
-
- for( i = 0; i < FONT_HEIGHT; i ++ )
- {
- ret->Bitmap[ i * 8 + 0 ] = data[i] & (1 << 7) ? 255 : 0;
- ret->Bitmap[ i * 8 + 1 ] = data[i] & (1 << 6) ? 255 : 0;
- ret->Bitmap[ i * 8 + 2 ] = data[i] & (1 << 5) ? 255 : 0;
- ret->Bitmap[ i * 8 + 3 ] = data[i] & (1 << 4) ? 255 : 0;
- ret->Bitmap[ i * 8 + 4 ] = data[i] & (1 << 3) ? 255 : 0;
- ret->Bitmap[ i * 8 + 5 ] = data[i] & (1 << 2) ? 255 : 0;
- ret->Bitmap[ i * 8 + 6 ] = data[i] & (1 << 1) ? 255 : 0;
- ret->Bitmap[ i * 8 + 7 ] = data[i] & (1 << 0) ? 255 : 0;
- }
-
- return ret;
-}
-
-
-/**
- * \fn int ReadUTF8(char *Input, uint32_t *Val)
- * \brief Read a UTF-8 character from a string
- */
-int ReadUTF8(const char *Input, uint32_t *Val)
-{
- const uint8_t *str = (const uint8_t *)Input;
- *Val = 0xFFFD; // Assume invalid character
-
- // ASCII
- if( !(*str & 0x80) ) {
- *Val = *str;
- return 1;
- }
-
- // Middle of a sequence
- if( (*str & 0xC0) == 0x80 ) {
- return 1;
- }
-
- // Two Byte
- if( (*str & 0xE0) == 0xC0 ) {
- *Val = (*str & 0x1F) << 6; // Upper 6 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F); // Lower 6 Bits
- return 2;
- }
-
- // Three Byte
- if( (*str & 0xF0) == 0xE0 ) {
- *Val = (*str & 0x0F) << 12; // Upper 4 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F) << 6; // Middle 6 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F); // Lower 6 Bits
- return 3;
- }
-
- // Four Byte
- if( (*str & 0xF1) == 0xF0 ) {
- *Val = (*str & 0x07) << 18; // Upper 3 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F) << 12; // Middle-upper 6 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F) << 6; // Middle-lower 6 Bits
- str ++;
- if( (*str & 0xC0) != 0x80) return -1; // Validity check
- *Val |= (*str & 0x3F); // Lower 6 Bits
- return 4;
- }
-
- // UTF-8 Doesn't support more than four bytes
- return 4;
-}
-
-
-
-
+++ /dev/null
-/*
- * Acess GUI (AxWin) Version 2
- * By John Hodge (thePowersGang)
- *
- * Window Manager and Widget Control
- */
-#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include "wm.h"
-#include <acess/sys.h> // _SysDebug
-
-// === IMPORTS ===
-extern void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
-
-// === PROTOTYPES ===
-tApplication *AxWin_RegisterClient(tIPC_Type *IPCType, void *Ident, const char *Name);
-void AxWin_DeregisterClient(tApplication *App);
-tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident);
-tElement *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName);
-void AxWin_DeleteElement(tElement *Element);
-void AxWin_SetFlags(tElement *Element, int Flags);
-void AxWin_SetSize(tElement *Element, int Size);
-void AxWin_SetText(tElement *Element, const char *Text);
-
-// === GLOBALS ===
-// - TODO: Handle windows by having multiple root elements
-tElement gWM_RootElement = {
- .DebugName = "ROOT"
-};
-tWindow *gWM_WindowFirst;
-tWindow *gWM_WindowLast;
-tApplication *gWM_Applications;
- int giWM_MaxAreaX = 0;
- int giWM_MaxAreaY = 0;
- int giWM_MaxAreaW = -1;
- int giWM_MaxAreaH = -1;
-
-// --- Element type flags
-struct {
- void (*Init)(tElement *This);
- void (*Delete)(tElement *This);
- void (*UpdateFlags)(tElement *This);
- void (*UpdateSize)(tElement *This);
- void (*UpdateText)(tElement *This);
-} gaWM_WidgetTypes[MAX_ELETYPES] = {
- {NULL, NULL, NULL, NULL, NULL}, // NULL
- {NULL, NULL, NULL, NULL, NULL}, // Window
- {NULL, NULL, NULL, NULL, NULL} // Box
-};
-const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]);
-
-// === CODE ===
-tApplication *AxWin_RegisterClient(tIPC_Type *Method, void *Ident, const char *Name)
-{
- int identlen = Method->GetIdentSize(Ident);
- // Structure, empty string, Name, Ident
- tApplication *ret = calloc( 1, sizeof(tApplication) + 1 + strlen(Name) + 1 + identlen );
-
- // DebugName is empty
-
- // Name/Title
- ret->Name = &ret->MetaElement.DebugName[1];
- strcpy(ret->Name, Name);
- // Ident
- ret->Ident = ret->Name + strlen(Name) + 1;
- memcpy(ret->Ident, Ident, identlen);
- // IPC Type
- ret->IPCType = Method;
-
- // Element index
- ret->MaxElementIndex = DEFAULT_ELEMENTS_PER_APP;
- ret->EleIndex = calloc( 1, ret->MaxElementIndex * sizeof(*ret->EleIndex) );
-
- // Add to global list
- ret->Next = gWM_Applications;
- gWM_Applications = ret;
-
- // TODO: Inform listeners of the new application
-
- return ret;
-}
-
-void AxWin_DeregisterClient(tApplication *App)
-{
- // TODO: Complete implementing DeregisterClient
- tElement *win, *next;
-
- for( win = App->MetaElement.FirstChild; win; win = next )
- {
- next = win->NextSibling;
- AxWin_DeleteElement(win);
- }
-
- // TODO: Inform listeners of deleted application
-
- // Remove from list
- {
- tApplication *app, *prev = NULL;
- for( app = gWM_Applications; app; app = app->Next )
- {
- if( app == App ) break;
- prev = app;
- }
-
- if( app )
- {
- if(prev)
- prev->Next = App->Next;
- else
- gWM_Applications = App->Next;
- }
- }
-
- free(App);
-}
-
-/**
- * \brief Get an application handle from a client identifier
- */
-tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident)
-{
- // TODO: Faster and smarter technique
- tApplication *app;
- for( app = gWM_Applications; app; app = app->Next )
- {
- if( app->IPCType != Method ) continue;
- if( Method->CompareIdent( app->Ident, Ident ) != 0 ) continue;
- return app;
- }
- return NULL;
-}
-
-tElement *AxWin_CreateAppWindow(tApplication *App, const char *Name)
-{
- tElement *ret;
- tWindow *win;
-
- win = calloc(1, sizeof(tWindow) + 1);
- if(!win) return NULL;
-
- ret = &win->RootElement;
- ret->Type = ELETYPE_WINDOW;
- ret->Data = win;
- ret->Parent = &App->MetaElement;
-
- // Add to parent list
- if(ret->Parent->LastChild)
- ret->Parent->LastChild->NextSibling = ret;
- ret->Parent->LastChild = ret;
- if(!ret->Parent->FirstChild)
- ret->Parent->FirstChild = ret;
-
- ret->Text = strdup(Name);
-
- return ret;
-}
-
-// --- Widget Creation and Control ---
-tAxWin_Element *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName)
-{
- tElement *ret;
- const char *dbgName = DebugName ? DebugName : "";
-
- ret = calloc(sizeof(tElement)+strlen(dbgName)+1, 1);
- if(!ret) return NULL;
-
- // Prepare
- ret->Type = Type;
- strcpy(ret->DebugName, dbgName);
- if(Parent == NULL) Parent = &gWM_RootElement;
- ret->Parent = Parent;
- ret->Flags = Flags;
-
- // Append to parent's list
- if(Parent->LastChild)
- Parent->LastChild->NextSibling = ret;
- Parent->LastChild = ret;
- if(!Parent->FirstChild) Parent->FirstChild = ret;
-
- ret->PaddingL = 2;
- ret->PaddingR = 2;
- ret->PaddingT = 2;
- ret->PaddingB = 2;
-
- if( Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Type].Init )
- gaWM_WidgetTypes[Type].Init(ret);
-
- WM_UpdateMinDims(ret->Parent);
-
- return ret;
-}
-
-/**
- * \brief Delete an element
- */
-void AxWin_DeleteElement(tElement *Element)
-{
- tElement *child, *next;
-
- for(child = Element->FirstChild; child; child = next)
- {
- next = child->NextSibling;
- AxWin_DeleteElement(child);
- }
-
- // TODO: Implement AxWin_DeleteElement
- // TODO: Clean up related data.
- if( Element->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Element->Type].Delete )
- gaWM_WidgetTypes[Element->Type].Delete(Element);
-
- if(Element->Owner)
- Element->Owner->EleIndex[ Element->ApplicationID ] = NULL;
-
- Element->Type = 0;
- Element->Owner = 0;
- Element->Flags = 0;
-
- free(Element);
-}
-
-/**
- * \brief Alter an element's flags
- */
-void AxWin_SetFlags(tElement *Element, int Flags)
-{
- // Permissions are handled in the message handler
- if(!Element) {
- gWM_RootElement.Flags = Flags;
- return ;
- }
-
- Element->Flags = Flags;
- return ;
-}
-
-/**
- * \brief Set the fixed lenghthways size of an element
- */
-void AxWin_SetSize(tElement *Element, int Size)
-{
- if(!Element) return ;
- Element->FixedWith = Size;
- return ;
-}
-
-/**
- * \brief Set the text field of an element
- * \note Used for the image path on ELETYPE_IMAGE
- */
-void AxWin_SetText(tElement *Element, const char *Text)
-{
- if(!Element) return ;
- if(Element->Text) free(Element->Text);
- Element->Text = strdup(Text);
-
- switch(Element->Type)
- {
- case ELETYPE_IMAGE:
- if(Element->Data) free(Element->Data);
- Element->Data = Image_Load( Element->Text );
- if(!Element->Data) {
- Element->Flags &= ~ELEFLAG_FIXEDSIZE;
- return ;
- }
-
- //Element->Flags |= ELEFLAG_FIXEDSIZE;
- Element->CachedW = ((tImage*)Element->Data)->Width;
- Element->CachedH = ((tImage*)Element->Data)->Height;
-
- if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
- Element->MinCross = ((tImage*)Element->Data)->Width;
- Element->MinWith = ((tImage*)Element->Data)->Height;
- }
- else {
- Element->MinWith = ((tImage*)Element->Data)->Width;
- Element->MinCross = ((tImage*)Element->Data)->Height;
- }
- break;
-
- case ELETYPE_TEXT:
- {
- int w=0, h=0;
- Video_GetTextDims(NULL, Element->Text, &w, &h);
- if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
- Element->MinCross = w;
- Element->MinWith = h;
- }
- else {
- Element->MinWith = w;
- Element->MinCross = h;
- }
- }
- break;
- default: // Any other, no special case
- break ;
- }
-
- return ;
-}
+++ /dev/null
-/*
- * Acess2 Window Manager (AxWin2)
- */
-#ifndef _WM_H_
-#define _WM_H_
-
-#include <axwin2/axwin.h>
-#include "common.h"
-
-/**
- * \brief Number of elements that can be owned by each application
- */
-// TODO: Fine tune these values
-#define MAX_ELEMENTS_PER_APP 1024
-#define DEFAULT_ELEMENTS_PER_APP 128
-
-typedef struct sAxWin_Element tElement;
-typedef struct sMenuItem tMenuItem;
-typedef struct sWindow tWindow;
-typedef struct sApplication tApplication;
-
-struct sAxWin_Element
-{
- enum eElementTypes Type;
-
- // Element Tree
- tElement *Parent;
- tElement *FirstChild;
- tElement *LastChild;
- tElement *NextSibling;
-
- // Application
- tApplication *Owner; //!< Owning application
- uint16_t ApplicationID; //!< Index into sApplication::EleIndex
-
- // User modifiable attributes
- short PaddingL, PaddingR;
- short PaddingT, PaddingB;
- short GapSize;
-
- uint32_t Flags;
-
- short FixedWith; //!< Fixed lengthways Size attribute (height)
- short FixedCross; //!< Fixed Cross Size attribute (width)
-
- char *Text;
-
- // -- Attributes maitained by the element code
- // Not touched by the user
- short MinWith; //!< Minimum long size
- short MinCross; //!< Minimum cross size
- void *Data; //!< Per-type data
-
- // -- Render Cache
- short CachedX, CachedY;
- short CachedW, CachedH;
-
- char DebugName[];
-};
-
-struct sMenuItem
-{
- tMenuItem *Next;
- int Flags;
- int ID; //!< ID number sent to application
- const char *Label;
- const char *Right;
- tMenuItem *FirstChild;
-};
-
-struct sWindow
-{
- int X, Y, W, H;
- void *Icon;
-
- tApplication *App;
-
- tWindow *OrderNext; // Render order
-
- tMenuItem *Menus;
-
- tElement RootElement;
-};
-
-struct sApplication
-{
- tApplication *Next;
-
- tIPC_Type *IPCType;
- void *Ident; //!< Client Identifier
-
- char *Name; //!< Application name
-
- int MaxElementIndex; //!< Number of entries in \a EleIndex
- tElement **EleIndex; //!< Array of pointers to elements owned by this application
-
- tElement MetaElement; //!< Tabs child off this
-};
-
-// === FUNCTIONS ===
-
-// --- Render
-extern void WM_UpdateMinDims(tElement *Element);
-extern void WM_UpdateDimensions(tElement *Element, int Pass);
-extern void WM_UpdatePosition(tElement *Element);
-extern void WM_RenderWidget(tElement *Element);
-extern void WM_Update(void);
-
-#endif
+++ /dev/null
-Applications can have 0-* windows
-Windows can have 1-* tabs
-Each window has a menu based on a template from the application
void create_sidebar(void);
void create_mainmenu(void);
void create_run_dialog(void);
+void mainmenu_run_dialog(void *unused);
// === GLOBALS ===
tHWND gSidebar;
create_mainmenu();
create_run_dialog();
+ AxWin3_RegisterAction(gSidebar, "Interface>Run", (tAxWin3_HotkeyCallback)mainmenu_run_dialog);
+// AxWin3_RegisterAction(gSidebar, "Interface>Terminal", mainmenu_app_terminal);
+// AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", mainmenu_app_textedit);
+
// Idle loop
AxWin3_MainLoop();
// --------------------------------------------------------------------
int run_dorun(tAxWin3_Widget *unused)
{
+ _SysDebug("DoRun pressed");
char *cmd = AxWin3_Widget_GetText(gRunInput);
_SysDebug("Command string '%s'", cmd);
AxWin3_ShowWindow(gRunDialog, 0);
extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
+extern void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index);
extern void WM_Hotkey_KeyDown(uint32_t Scancode);
extern void WM_Hotkey_KeyUp(uint32_t Scancode);
#include <stdio.h>
#include <wm.h>
#include <wm_internals.h>
+#include <wm_hotkeys.h>
#define AXWIN_PORT 4101
int IPC_Msg_RegisterAction(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
{
+ tIPCMsg_RegAction *info = (void*)Msg->Data;
+ tWindow *win;
+
ASSERT(Msg->ID == IPCMSG_REGACTION);
+
+ if( Msg->Size < sizeof(*info) + 1 )
+ return -1;
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if(!win) return 1;
+
+ if( strnlen(info->Action, Msg->Size - sizeof(*info)) == Msg->Size - sizeof(*info) )
+ return 1;
+
+ _SysDebug("RegisterAction %p:%i [%i]\"%s\"",
+ Client, Msg->Window, info->Index, info->Action
+ );
+
+ WM_Hotkey_RegisterAction(info->Action, win, info->Index);
+
return 0;
}
#include <acess/sys.h>
#include <stdlib.h>
#include <stdio.h>
+#include <axwin3/keysyms.h>
// === IMPORTS ===
extern void Video_Setup(void);
extern int Renderer_Background_Init(void);
extern int Renderer_Framebuffer_Init(void);
extern void WM_Update(void);
+extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
// === PROTOTYPES ===
void ParseCommandline(int argc, char **argv);
Renderer_Background_Init();
Renderer_Framebuffer_Init();
WM_Initialise();
+
+ // TODO: Config
+ uint32_t keys[4];
+ keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_r;
+ WM_Hotkey_Register(2, keys, "Interface>Run");
// Spawn interface root
if( clone(CLONE_VM, 0) == 0 )
// }
}
+int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+{
+ if( Len < sizeof(*Msg) )
+ return 0;
+ if( Len > sizeof(*Msg) )
+ return 1; // Pass to user
+
+ const char *text = NULL;
+ tElement *ele = Widget_GetElementById(Info, Msg->WidgetID);
+ if(ele)
+ text = ele->Text;
+
+ char buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1];
+ tWidgetMsg_SetText *omsg = (void*)buf;
+
+ if( text ) {
+ omsg->WidgetID = Msg->WidgetID;
+ strcpy(omsg->Text, text);
+ }
+ else {
+ omsg->WidgetID = -1;
+ omsg->Text[0] = 0;
+ }
+
+ WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+ return 0;
+}
+
int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
{
tWidgetWin *info = Target->RendererInfo;
case MSG_WIDGET_SETTEXT:
Widget_SetText(info, Len, Data);
return 0;
+ case MSG_WIDGET_GETTEXT:
+ return Widget_GetText(info, Len, Data);
//
default:
h->Target = (void*)( h->Keys + nKeys );
strcpy((char*)h->Target, ActionName);
memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t));
+
+ h->Next = NULL;
+ if( gpWM_Hotkeys )
+ gpWM_Hotkeys->Next = h;
+ gpWM_Hotkeys = h;
}
void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index)
{
_UnsetKey(Scancode);
+ // Ensure that hotkeys are triggered on the longest sequence
+ // (so Win-Shift-R doesn't trigger Win-R if shift is released)
if( !gbWM_HasBeenKeyDown )
return ;
if( _IsKeySet(hk->Keys[i]) ) continue ;
break;
}
- if( i == hk->nKeys )
+ _SysDebug("%i/%i satisfied for %s", i, hk->nKeys, hk->Target);
+ if( i != hk->nKeys )
continue ;
// Fire shortcut
void WM_Hotkey_FireEvent(const char *Target)
{
+// _SysDebug("WM_Hotkey_FireEvent: (%s)", Target);
// - Internal events (Alt-Tab, Close, Maximize, etc...)
// TODO: Internal event handling
static void _SetKey(uint32_t sc)
{
+// _SysDebug("_SetKey: (%x)", sc);
if( sc >= MAX_STATE_SCANCODE ) return;
gWM_KeyStates[sc/8] |= 1 << (sc % 8);
}
static void _UnsetKey(uint32_t sc)
{
+// _SysDebug("_UnsetKey: (%x)", sc);
if( sc >= MAX_STATE_SCANCODE ) return;
gWM_KeyStates[sc/8] &= ~(1 << (sc % 8));
}
for(win = ret->FirstChild; win; win = win->NextSibling)
{
if( !(win->Flags & WINFLAG_SHOW) ) continue ;
- if( X < win->X || X >= win->X + win->W ) continue;
- if( Y < win->Y || Y >= win->Y + win->H ) continue;
+ if( X < win->X || X >= win->X + win->RealW ) continue;
+ if( Y < win->Y || Y >= win->Y + win->RealH ) continue;
next_win = win; // Overwrite as we want the final rendered window
}
}
typedef struct sIPCMsg_Boolean tIPCMsg_Boolean;
typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos;
typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg;
+typedef struct sIPCMsg_RegAction tIPCMsg_RegAction;
typedef struct sIPCMsg_GetDisplayDims tIPCMsg_GetDisplayDims;
typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims;
uint8_t bSetDims;
};
+struct sIPCMsg_RegAction
+{
+ uint16_t Index;
+ char Action[];
+};
+
struct sIPCMsg_GetDisplayDims
{
uint16_t DisplayID;
#include <axwin3/axwin.h>
#include <axwin3/widget.h>
#include "include/internal.h"
-#include "include/ipc.h"
#include <stdlib.h>
#include <widget_messages.h>
#include <string.h>
{
char buf[sizeof(tWidgetMsg_SetText)];
tWidgetMsg_SetText *msg = (void*)buf;
- tAxWin_IPCMessage *retmsg;
- char *ret;
+ size_t retmsg_size;
msg->WidgetID = Widget->ID;
AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
- retmsg = AxWin3_int_WaitIPCMessage(MSG_WIDGET_GETTEXT);
- msg = (void*)retmsg->Data;
-
- if( retmsg->Size < sizeof(*msg) ) {
- free(retmsg);
+ msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size);
+ if( retmsg_size < sizeof(*msg) ) {
+ free(msg);
return NULL;
}
- ret = strndup(msg->Text, retmsg->Size - sizeof(*msg));
- free(retmsg);
+ char *ret = strndup(msg->Text, retmsg_size - sizeof(*msg));
+ free(msg);
return ret;
}
#include <string.h>
#include "include/internal.h"
#include "include/ipc.h"
+#include <wm_messages.h>
-#define WINDOWS_PER_ALLOC (63)
+#define WINDOWS_PER_ALLOC (64-1) // -1 to make it 64 pointers (+ Next)
+#define MAX_HOTKEYS 32
typedef struct sWindowBlock tWindowBlock;
int giAxWin3_LowestFreeWinID;
int giAxWin3_HighestUsedWinID;
tWindowBlock gAxWin3_WindowList;
+tAxWin3_HotkeyCallback gAxWin3_Hotkeys[MAX_HOTKEYS];
// === CODE ===
tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes)
return ;
}
_SysDebug("IPC Message 0x%x - %i bytes", info->ID, info->Length);
- dest->Handler(dest, info->ID, info->Length, info->Data);
+
+ if( dest->Handler(dest, info->ID, info->Length, info->Data) )
+ ;
+ else {
+ switch( info->ID )
+ {
+ case WNDMSG_HOTKEY: {
+ const struct sWndMsg_Hotkey *mi = (void*)info->Data;
+ if( mi->ID >= MAX_HOTKEYS )
+ ; // TODO: Error when hotkey is out of range
+ else if( gAxWin3_Hotkeys[mi->ID] == 0 )
+ _SysDebug("--- Unmapped hotkey ID %i fired", mi->ID);
+ else
+ gAxWin3_Hotkeys[mi->ID]();
+ }break;
+ default:
+ _SysDebug("--- Unhandled SENDMSG %i", info->ID);
+ break;
+ }
+ }
break; }
default:
_SysDebug("Unknow message ID %i", Msg->ID);
free(msg);
}
+void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length)
+{
+ tAxWin_IPCMessage *msg;
+
+ for( ;; )
+ {
+ msg = AxWin3_int_WaitIPCMessage(IPCMSG_SENDMSG);
+ if( msg->Window != AxWin3_int_GetWindowID(Window) ) {
+ AxWin3_int_HandleMessage(msg);
+ continue ;
+ }
+ tIPCMsg_SendMsg *info = (void*)msg->Data;
+ if( info->ID != MessageID ) {
+ AxWin3_int_HandleMessage(msg);
+ continue ;
+ }
+
+ *Length = info->Length;
+ void *ret = malloc(info->Length);
+ memcpy(ret, info->Data, info->Length);
+ free(msg);
+
+ return ret;
+ }
+}
+
void AxWin3_FocusWindow(tHWND Window)
{
tAxWin_IPCMessage *msg;
free(msg);
}
+int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb)
+{
+ int i;
+ for( i = 0; i < MAX_HOTKEYS; i ++ )
+ {
+ if( gAxWin3_Hotkeys[i] == NULL )
+ {
+ tAxWin_IPCMessage *msg;
+ struct sIPCMsg_RegAction *info;
+ gAxWin3_Hotkeys[i] = cb;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_REGACTION, 0, sizeof(*info)+strlen(Action)+1);
+ info = (void*)msg->Data;
+
+ info->Index = i;
+ strcpy(info->Action, Action);
+
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+ return i;
+ }
+ }
+ return -1;
+}
+
$(_BIN): $(OBJ) $(_LIBS)
@mkdir -p $(dir $(_BIN))
@echo [LD] -o $(BIN) $(OBJ)
- @$(LD) $(LDFLAGS) -o $(_BIN) $(OBJ)
+ $(LD) $(LDFLAGS) -o $(_BIN) $(OBJ) $(shell $(CC) -print-libgcc-file-name)
@$(DISASM) -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
$(_OBJPREFIX)%.o: %.c
--- /dev/null
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR(__LIBDIR)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
+ .interp : { *(.interp) }
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ }
+ .rel.plt :
+ {
+ *(.rel.plt)
+ }
+ .rela.plt :
+ {
+ *(.rela.plt)
+ }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .iplt : { *(.iplt) }
+ .text :
+ {
+ *(.text.unlikely .text.*_unlikely)
+ *(.text.exit .text.exit.*)
+ *(.text.startup .text.startup.*)
+ *(.text.hot .text.hot.*)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+ PROVIDE_HIDDEN(__exidx_start = .);
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ PROVIDE_HIDDEN(__exidx_end = .);
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ /* Thread Local Storage sections */
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ }
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+ .data :
+ {
+ __data_start = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .; PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
+ }
+ _bss_end__ = . ; __bss_end__ = . ;
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ __end__ = . ;
+ _end = .; PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo .zdebug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames .zdebug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges .zdebug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames .zdebug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.* .zdebug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev .zdebug_abbrev) }
+ .debug_line 0 : { *(.debug_line .zdebug_line) }
+ .debug_frame 0 : { *(.debug_frame .zdebug_frame) }
+ .debug_str 0 : { *(.debug_str .zdebug_str) }
+ .debug_loc 0 : { *(.debug_loc .zdebug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo .zdebug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames .zdebug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames .zdebug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames .zdebug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames .zdebug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes .zdebug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges .zdebug_ranges) }
+ .stack 0x80000 :
+ {
+ _stack = .;
+ *(.stack)
+ }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
+
+
# create libld-acess.so
$(_XBIN): $(_OBJPREFIX)_stublib.o
@echo [LD] -o -shared libld-acess.so
- $(LD) -shared -o $@ $<
+ $(LD) -shared -o $@ $< $(LDFLAGS)
# @$(LD) $(LDFLAGS) -o $@ $(OBJ)
#include "arch/syscalls.s.h"
// libgcc functions
+#if 0
uint64_t __udivdi3(uint64_t Num, uint64_t Den){return 0;}
uint64_t __umoddi3(uint64_t Num, uint64_t Den){return 0;}
int32_t __modsi3(int32_t Num, int32_t Den){return 0;}
uint32_t __udivsi3(uint32_t Num, uint32_t Den){return 0;}
uint32_t __umodsi3(uint32_t Num, uint32_t Den){return 0;}
+#endif
void *_crt0_exit_handler;
+void abort(void){}
--- /dev/null
+//
+// Acess2 ARMv7 - System Calls
+//
+
+.globl _start
+.extern SoMain
+_start:
+ pop {r0}
+ ldm sp, {r1,r2,r3}
+ bl SoMain
+
+ mov r4, r0
+
+ pop {r0,r1,r2}
+ blx r4
+
+ b _exit
+
+@ Stupid GCC
+.globl __ucmpdi2
+__ucmpdi2:
+ cmp r0, r2
+ movmi r0, #0
+ movmi pc, lr
+ movhi r0, #2
+ movhi pc, lr
+ cmp r1, r2
+ movmi r0, #0
+ movmi pc, lr
+ movhi r0, #2
+ movhi pc, lr
+ mov r0, #1
+ mov pc, lr
+
+@ Well, can't blame it
+@ - Clear the instruction cache
+.globl __clear_cache
+__clear_cache:
+ svc #0x1001
+ mov pc, lr
+
+@ DEST
+@ SRC
+@_memcpy:
+@ push rbp
+@ mov rbp, rsp
+@
+@ ; RDI - First Param
+@ ; RSI - Second Param
+@ mov rcx, rdx ; RDX - Third
+@ rep movsb
+@
+@ pop rbp
+@ ret
+@
+.globl _errno
+_errno: .long 0 @ Placed in .text, to allow use of relative addressing
+
+.macro syscall0 _name, _num
+.globl \_name
+\_name:
+ push {lr}
+ svc #\_num
+ str r2, _errno
+ pop {pc}
+.endm
+
+.macro syscall5 _name, _num
+.globl \_name
+\_name:
+ push {r4, lr}
+ ldr r4, [sp,#8]
+ svc #\_num
+ str r2, _errno
+ pop {r4, pc}
+.endm
+
+.macro syscall6 _name, _num
+.globl \_name
+\_name:
+ push {r4,r5,lr}
+ ldr r4, [sp,#12]
+ ldr r5, [sp,#16]
+ svc #\_num
+ str r2, _errno
+ pop {r4,r5,pc}
+.endm
+
+#define SYSCALL0(_name,_num) syscall0 _name, _num
+#define SYSCALL1(_name,_num) SYSCALL0(_name, _num)
+#define SYSCALL2(_name,_num) SYSCALL0(_name, _num)
+#define SYSCALL3(_name,_num) SYSCALL0(_name, _num)
+#define SYSCALL4(_name,_num) SYSCALL0(_name, _num)
+// TODO: 5/6 need special handling, because the args are on the stack
+#define SYSCALL5(_name,_num) syscall5 _name, _num
+#define SYSCALL6(_name,_num) syscall6 _name, _num
+
+// Override the clone syscall
+#define _exit _exit_raw
+#define _clone _clone_raw
+#include "syscalls.s.h"
+#undef _exit
+#undef _clone
+
+.globl _clone
+_clone:
+ push {r4}
+ mov r4, r1
+ svc #SYS_CLONE
+ str r2, _errno
+ tst r4, r4
+ beq _clone_ret
+ @ If in child, set SP
+ tst r0,r0
+ movne sp, r4
+_clone_ret:
+ pop {r4}
+ mov pc, lr
+
+.globl _exit
+_exit:
+ svc #0
+ b .
+
+.globl abort
+abort:
+ mov r0, #0
+ svc #0
+ b .
+
+.globl __exidx_start
+__exidx_start:
+ b .
+.globl __exidx_end
+__exidx_end:
+ b .
+
--- /dev/null
+ENTRY(_start)
+OUTPUT_FORMAT(elf32-littlearm)
+
+SECTIONS {
+ . = 0x6FFF0000;
+ gLinkedBase = .;
+ . += SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+
+ .text : AT(ADDR(.text)) {
+ code = .;
+ *(.text)
+ *(.rodata*)
+ PROVIDE_HIDDEN(__exidx_start = .);
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ PROVIDE_HIDDEN(__exidx_end = .);
+ }
+
+ .data ALIGN (0x1000) : AT(ADDR(.data)) {
+ data = .;
+ *(.data)
+ }
+
+ .bss ALIGN (0x1000) : AT(ADDR(.bss)) {
+ _sbss = .;
+ *(COMMON)
+ *(.bss)
+ _ebss = .;
+ bss = .;
+ }
+ _end = .;
+}
} caLocalExports[] = {
EXP(gLoadedLibraries),
EXP(_exit),
+ EXP(_errno),
EXP(clone),
EXP(kill),
EXP(yield),
EXP(_SysAllocate),
EXP(_SysDebug),
+#if 0
EXP(__umoddi3),
EXP(__udivdi3),
EXP(__divsi3),
EXP(__modsi3),
EXP(__udivsi3),
EXP(__umodsi3)
+#endif
};
const int ciNumLocalExports = sizeof(caLocalExports)/sizeof(caLocalExports[0]);
#elif defined(ARCHDIR_is_x86_64)
typedef __int64_t __intptr_t;
typedef __uint64_t __uintptr_t;
-#elif defined(ARCHDIR_is_armv7)
+#elif defined(ARCHDIR_is_armv7) | defined(ARCHDIR_is_armv6)
typedef __int32_t __intptr_t;
typedef __uint32_t __uintptr_t;
#else
return ret;
}
+#if 0
uint32_t __divmod32(uint32_t Num, uint32_t Den, uint32_t *Rem)
{
uint32_t ret = 0, add = 1;
__divmod32(Num, Den, &ret);
return ret;
}
+#endif
+++ /dev/null
-# Acess 2 - AxWin GUI Library
-#
-
-include ../Makefile.cfg
-
-CPPFLAGS +=
-CFLAGS += -Wall
-LDFLAGS += -lc -soname libaxwin2.so
-
-OBJ = main.o messages.o
-BIN = libaxwin2.so
-
-include ../Makefile.tpl
+++ /dev/null
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- *
- * common.h - Internal Variable and Constant definitions
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-// === Includes ===
-#include <acess/sys.h>
-#include <axwin2/axwin.h>
-#include <stdlib.h>
-
-// === Constants ===
-enum eAxWin_Modes
-{
- AXWIN_MODE_IPC
-};
-
-// === Variables ===
-extern int giAxWin_Mode;
-extern int giAxWin_PID;
-
-#endif
+++ /dev/null
-/**
- * \file axwin2/axwin.h
- * \author John Hodge (thePowersGang)
- * \brief AxWin Core functions
- */
-#ifndef _AXWIN2_AXWIN_H
-#define _AXWIN2_AXWIN_H
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <axwin2/messages.h>
-
-// === Core Types ===
-typedef struct sAxWin_Element tAxWin_Element;
-typedef int tAxWin_MessageCallback(tAxWin_Message *);
-
-// === Functions ===
-extern int AxWin_Register(const char *ApplicationName, tAxWin_MessageCallback *DefaultHandler);
-extern tAxWin_Element *AxWin_CreateWindow(const char *TabTitle);
-extern tAxWin_Element *AxWin_AddMenuItem(tAxWin_Element *Parent, const char *Label, int Message);
-
-extern int AxWin_MessageLoop(void);
-extern int AxWin_SendMessage(tAxWin_Message *Message);
-extern tAxWin_Message *AxWin_WaitForMessage(void);
-extern int AxWin_HandleMessage(tAxWin_Message *Message);
-
-// === Window Control ===
-
-extern tAxWin_Element *AxWin_CreateElement(tAxWin_Element *Parent, int ElementType, int Flags, const char *DebugName);
-extern void AxWin_SetFlags(tAxWin_Element *Element, int Flags);
-extern void AxWin_SetText(tAxWin_Element *Element, const char *Text);
-extern void AxWin_SetSize(tAxWin_Element *Element, int Size);
-extern void AxWin_DeleteElement(tAxWin_Element *Element);
-
-// === CONSTANTS ===
-enum eElementFlags
-{
- /**
- * \brief Rendered
- *
- * If set, the element will be ignored in calculating sizes and
- * rendering.
- */
- ELEFLAG_NORENDER = 0x001,
- /**
- * \brief Element visibility
- *
- * If set, the element is not drawn (but still is used for size calculations)
- */
- ELEFLAG_INVISIBLE = 0x002,
-
- /**
- * \brief Position an element absulutely (ignored in size calcs)
- */
- ELEFLAG_ABSOLUTEPOS = 0x004,
-
- /**
- * \brief Fixed size element
- */
- ELEFLAG_FIXEDSIZE = 0x008,
-
- /**
- * \brief Element "orientation"
- *
- * Vertical means that the children of this element are stacked,
- * otherwise they list horizontally
- */
- ELEFLAG_VERTICAL = 0x010,// ELEFLAG_HORIZONTAL = 0x000,
- /**
- * \brief Action for text that overflows
- */
- ELEFLAG_WRAP = 0x020,// ELEFLAG_NOWRAP = 0x000,
- /**
- * \brief Cross size action
- *
- * If this flag is set, the element will only be as large (across
- * its parent) as is needed to encase the contents of the element.
- * Otherwise, the element will expand to fill all avaliable space.
- */
- ELEFLAG_NOEXPAND = 0x040,
-
- /**
- * \brief With (length) size action
- * If this flag is set, the element will only be as large as
- * is required along it's parent
- */
- ELEFLAG_NOSTRETCH = 0x080,
-
- /**
- * \brief Center alignment
- */
- ELEFLAG_ALIGN_CENTER= 0x100,
- /**
- * \brief Right/Bottom alignment
- *
- * If set, the element aligns to the end of avaliable space (instead
- * of the beginning)
- */
- ELEFLAG_ALIGN_END = 0x200
-};
-
-#define ELEFLAG_WINDOW_MAXIMISED 0x10000
-
-/**
- */
-enum eElementTypes
-{
- ELETYPE_NONE,
-
- ELETYPE_WINDOW, //!< Window root element
-
- ELETYPE_BOX, //!< Content box (invisible in itself)
- ELETYPE_TABBAR, //!< Tab Bar
- ELETYPE_TOOLBAR, //!< Tool Bar
-
- ELETYPE_BUTTON, //!< Push Button
-
- ELETYPE_TEXT, //!< Text
- ELETYPE_IMAGE, //!< Image
-
- ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule)
-
- MAX_ELETYPES = 0x100
-};
-
-#endif
+++ /dev/null
-/**
- * \file messages.h
- * \author John Hodge (thePowersGang)
- * \brief AxWin Control Messages and structures
- */
-#ifndef _AXWIN_MESSAGES_H
-#define _AXWIN_MESSAGES_H
-
-#include <stdint.h>
-
-typedef struct sAxWin_Message tAxWin_Message;
-typedef struct sAxWin_RetMsg tAxWin_RetMsg;
-
-// Higherarchy:
-// - HANDLE
-// + ELEMENT
-// > DIALOG
-// > TAB
-
-/**
- * \brief Message IDs
- */
-enum eAxWin_Messages
-{
- // Client->Server Requests
- MSG_SREQ_PING,
- // - Windows
- MSG_SREQ_REGISTER, // bool (char[] Name) - Registers this PID with the Window Manager
-
- MSG_SREQ_ADDWIN, // ELEMENT (char[] Name) - Adds a tab to the window
-
- MSG_SREQ_SETICON, // void (TAB Tab, char[] IconURI) - Set the icon of a tab (or application)
-
- MSG_SREQ_NEWDIALOG, // DIALOG (TAB Parent, char[] Name) - Creates a dialog
- MSG_SREQ_DELDIALOG, // void (DIALOG Dialog) - Closes a dialog
-
- MSG_SREQ_SETNAME, // void (ELEMENT Element, char[] Name)
- MSG_SREQ_GETNAME, // char[] (ELEMENT Element)
-
- // - Builtin Elements
- MSG_SREQ_INSERT, // ELEMENT (ELEMENT Parent, eAxWin_Controls Type, u32 Flags)
- MSG_SREQ_DELETE, // void (ELEMENT Element)
-
- // - Drawing
- // All drawing functions take an ELEMENT as their first parameter.
- // This must be either a Window or Canvas control
- MSG_SREQ_SETCOL,
- MSG_SREQ_PSET,
- MSG_SREQ_LINE, MSG_SREQ_CURVE,
- MSG_SREQ_RECT, MSG_SREQ_FILLRECT,
- MSG_SREQ_RIMG, MSG_SREQ_SIMG, // Register/Set Image
- MSG_SREQ_SETFONT, MSG_SREQ_PUTTEXT,
-
- // - Callback Registration
-
- // - WM Control
- MSG_SREQ_SET_MAXIMIZE_AREA, // void (uint16_t X, Y, W, H)
-
- // Server->Client Responses
- MSG_SRSP_VERSION,
- MSG_SRSP_RETURN, // {int RequestID, void[] Return Value} - Returns a value from a server request
-
- NUM_MSG
-};
-
-// --- Server Requests (Requests from the client of the server)
-/**
- * \brief Server Request - Ping (Get Server Version)
- */
-struct sAxWin_SReq_Ping
-{
-};
-
-/**
- * \brief Server Request - New Window
- * \see eAxWin_Messages.MSG_SREQ_NEWWINDOW
- */
-struct sAxWin_SReq_NewWindow
-{
- uint16_t X, Y, W, H;
- uint32_t Flags;
-};
-
-struct sAxWin_SReq_NewElement
-{
- uint16_t Parent;
- uint16_t Type;
- uint32_t Flags;
-};
-
-
-// --- Server Responses
-/**
- * \brief Server Response - Pong
- * \see eAxWin_Messages.MSG_SRSP_PONG
- */
-struct sAxWin_SRsp_Version
-{
- uint8_t Major;
- uint8_t Minor;
- uint16_t Build;
-};
-
-
-// === Core Message Structure
-/**
- * \brief Overarching Message Structure
- * \note sizeof(tAxWin_Message) is never valid
- */
-struct sAxWin_Message
-{
- uint32_t Source;
- uint16_t ID;
- uint16_t Size; // Size of data
- char Data[];
-};
-
-struct sAxWin_RetMsg
-{
- uint16_t ReqID;
- uint16_t Rsvd;
- uint32_t Value;
-};
-
-#endif
+++ /dev/null
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- *
- * main.c - Library Initialisation
- */
-#include "common.h"
-#include <string.h>
-
-// === GLOBALS ===
- int giAxWin_Mode = 0;
- int giAxWin_PID = 9; // HACK!
-tAxWin_MessageCallback *gAxWin_DefaultCallback;
-
-// === CODE ===
-int SoMain()
-{
- return 0;
-}
-
-tAxWin_Message *AxWin_int_SendAndWait(int RetID, tAxWin_Message *Message)
-{
- tAxWin_Message *msg;
- tAxWin_RetMsg *rmsg;
-
- AxWin_SendMessage(Message);
-
- for(;;)
- {
- msg = AxWin_WaitForMessage();
-
- rmsg = (void*)msg->Data;
- if(msg->ID == MSG_SRSP_RETURN && rmsg->ReqID == Message->ID )
- break;
-
- AxWin_HandleMessage(msg);
- free(msg);
- }
-
- return msg;
-}
-
-int AxWin_Register(const char *Name, tAxWin_MessageCallback *DefaultCallback)
-{
- tAxWin_Message req;
- tAxWin_Message *msg;
- int ret;
- int len = strlen(Name);
-
- req.ID = MSG_SREQ_REGISTER;
- req.Size = 1 + (len+1)/4;
- strcpy(req.Data, Name);
-
- msg = AxWin_int_SendAndWait(MSG_SRSP_RETURN, &req);
- ret = ((tAxWin_RetMsg*)msg->Data)->Value;
- free(msg);
-
- gAxWin_DefaultCallback = DefaultCallback;
-
- return !!ret;
-}
-
-tAxWin_Element *AxWin_CreateWindow(const char *Title)
-{
- tAxWin_Message req;
- tAxWin_Message *msg;
- tAxWin_Element *ret;
- int len = strlen(Title);
-
- req.ID = MSG_SREQ_ADDWIN;
- req.Size = 1 + (len+1)/4;
- strcpy(req.Data, Title);
-
- msg = AxWin_int_SendAndWait(MSG_SRSP_RETURN, &req);
- ret = (tAxWin_Element*) ((tAxWin_RetMsg*)msg->Data)->Value;
- free(msg);
-
- return ret;
-}
-
-tAxWin_Element *AxWin_AddMenuItem(tAxWin_Element *Parent, const char *Label, int Message)
-{
- return NULL;
-}
+++ /dev/null
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- *
- * messages.c - Message Handling
- */
-#include "common.h"
-
-// === PROTOTYPES ===
- int AxWin_MessageLoop();
-tAxWin_Message *AxWin_WaitForMessage();
- int AxWin_HandleMessage(tAxWin_Message *Message);
-
-// === ===
-
-// === CODE ===
-int AxWin_SendMessage(tAxWin_Message *Message)
-{
- switch(giAxWin_Mode)
- {
- case AXWIN_MODE_IPC:
- SysSendMessage(giAxWin_PID, Message->Size*4, Message);
- break;
- default:
- break;
- }
- return 0;
-}
-
-/**
- * \brief Loop forever, checking and waiting for messages
- */
-int AxWin_MessageLoop()
-{
- tAxWin_Message *msg;
- int ret;
- for(;;)
- {
- msg = AxWin_WaitForMessage();
- ret = AxWin_HandleMessage(msg);
-
- if(ret < 0) return 0;
- }
- return 0;
-}
-
-/**
- * \brief Wait for a message
- */
-tAxWin_Message *AxWin_WaitForMessage()
-{
- int length;
- pid_t src;
- tAxWin_Message *ret = NULL;
-
- switch( giAxWin_Mode )
- {
- case AXWIN_MODE_IPC:
- while( (length = SysGetMessage(&src, NULL)) == 0 ) sleep();
- ret = malloc(length);
- SysGetMessage(NULL, ret);
- break;
- default:
- break;
- }
- return ret;
-}
-
-/**
- * \brief Handles a recieved message
- */
-int AxWin_HandleMessage(tAxWin_Message *Message)
-{
- switch(Message->ID)
- {
- default: return 0;
- }
-}
+++ /dev/null
-/*
- * AxWin Window Manager Interface Library
- * By John Hodge (thePowersGang)
- * This file is published under the terms of the Acess Licence. See the
- * file COPYING for details.
- *
- * window.c - Window Control
- */
-#include "common.h"
-
-// === TYPES & STRUCTURES ===
-struct sAxWin_Window
-{
- struct sAxWin_Window *Next;
- uint32_t WmHandle;
- tAxWin_MessageCallback *Callback;
-};
-
-// === PROTOTYPES ===
-tAxWin_Window *AxWin_CreateWindow(
- int16_t X, int16_t Y, int16_t W, int16_t H,
- uint32_t Flags, tAxWin_MessageCallback *Callback
- );
-
-// === GLOBALS ===
-//mutex_t glProcessWindows;
-tAxWin_Window *gProcessWindows;
-
-// === CODE ===
-tAxWin_Window *AxWin_CreateWindow(
- int16_t X, int16_t Y,
- int16_t W, int16_t H,
- uint32_t Flags, tAxWin_MessageCallback *Callback)
-{
- tAxWin_Message req;
- tAxWin_Message *msg;
- tAxWin_Window *win;
-
- req.ID = MSG_SREQ_NEWWINDOW;
- req.Size = 1 + sizeof(struct sAxWin_SReq_NewWindow)/4;
- req.SReq_NewWindow.X = X;
- req.SReq_NewWindow.Y = Y;
- req.SReq_NewWindow.W = W;
- req.SReq_NewWindow.H = H;
- req.SReq_NewWindow.Flags = Flags;
-
- AxWin_SendMessage(&msg);
-
- for(;;)
- {
- msg = AxWin_WaitForMessage();
-
- if(msg.ID == MSG_SRSP_WINDOW)
- break;
-
- AxWin_HandleMessage(msg);
- free(msg);
- }
-
- win = malloc(sizeof(tAxWin_Window));
- win->WmHandle = msg->SRsp_Window.Handle;
- win->Callback = Callback;
-
- //mutex_acquire(glProcessWindows);
- win->Next = gProcessWindows;
- gProcessWindows = win;
- //mutex_release(glProcessWindows);
-
- return 0;
-}
#ifndef _AXWIN3_AXWIN_H_
#define _AXWIN3_AXWIN_H_
+#include <stddef.h> // size_t
+
// === CONSTANTS ===
// === TYPES ===
typedef unsigned int tAxWin3_Colour; // TODO: Actual 32-bit
typedef void (*tAxWin3_MessageCallback)(int SourceTID, int Length);
+typedef void (*tAxWin3_HotkeyCallback)(void);
typedef int (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Length, void *Data);
* \param Window Handle to a window to destroy
*/
extern void AxWin3_DestroyWindow(tHWND Window);
+extern int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb);
// --- Core window management functions
extern void AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length);
extern void AxWin3_SetWindowTitle(tHWND Window, const char *Title);
extern void AxWin3_FocusWindow(tHWND Window);
extern void AxWin3_ShowWindow(tHWND Window, int bShow);
--- /dev/null
+../../../../../KernelLand/Kernel/include/keysyms.h
\ No newline at end of file
--- /dev/null
+@
+@ Acess2 C Library
+@ - By John Hodge (thePowersGang)
+@
+@ arch/armv6.S
+@ - ARMv6 specific code
+.globl setjmp
+setjmp:
+ @ RO: Buffer
+ stm r0, {r0-r14}
+ eor r0, r0
+ mov pc, lr
+
+.globl longjmp
+longjmp:
+ @ R0: Buffer
+ @ R1: Value
+ add r0, #8
+ ldm r0, {r2-r14}
+ mov r0, r1
+ tst r0, r0
+ addeq r0, #1
+ mov pc, lr @ Will return to after setjmp
+
#include <string.h>\r
#include "lib.h"\r
\r
+#if 0\r
+# define DEBUGS(s...) _SysDebug(s)\r
+#else\r
+# define DEBUGS(s...) do{}while(0)\r
+#endif\r
+\r
// === Constants ===\r
#define MAGIC 0xACE55051 //AcessOS1\r
#define MAGIC_FREE (~MAGIC)\r
typedef struct {\r
uint32_t magic;\r
size_t size;\r
+ char data[];\r
} heap_head;\r
typedef struct {\r
heap_head *header;\r
LOCAL void *extendHeap(int bytes);\r
static void *FindHeapBase();\r
LOCAL uint brk(uintptr_t newpos);\r
+LOCAL void Heap_Dump(void);\r
\r
//Code\r
\r
size_t closestMatch = 0;\r
void *bestMatchAddr = 0;\r
heap_head *curBlock;\r
- \r
+\r
// _SysDebug("&_heap_start = %p, _heap_start = %p", &_heap_start, _heap_start);\r
// Initialise Heap\r
if(_heap_start == NULL)\r
else if(curBlock->magic != MAGIC)\r
{\r
//Corrupt Heap\r
+ Heap_Dump();\r
_SysDebug("malloc: Corrupt Heap\n");\r
return NULL;\r
}\r
return NULL;\r
}\r
curBlock->magic = MAGIC;\r
- return (void*)((uintptr_t)curBlock + sizeof(heap_head));\r
+ DEBUGS("malloc(0x%x) = %p (extend) 0x%x", bytes, curBlock->data, bestSize);\r
+ return curBlock->data;\r
}\r
\r
+ heap_head *besthead = (void*)bestMatchAddr;\r
+ \r
//Split Block?\r
if(closestMatch - bestSize > BLOCK_SIZE) {\r
heap_foot *foot;\r
foot = (heap_foot*)(bestMatchAddr + closestMatch - sizeof(heap_foot));\r
foot->header = curBlock;\r
\r
- ((heap_head*)bestMatchAddr)->magic = MAGIC; //mark as used\r
- return (void*)(bestMatchAddr + sizeof(heap_head));\r
+ besthead->magic = MAGIC; //mark as used\r
+ DEBUGS("malloc(0x%x) = %p (split) 0x%x", bytes, besthead->data, bestSize);\r
+ return besthead->data;\r
}\r
\r
//Don't Split the block\r
- ((heap_head*)bestMatchAddr)->magic = MAGIC;\r
- return (void*)(bestMatchAddr+sizeof(heap_head));\r
+ besthead->magic = MAGIC;\r
+ DEBUGS("malloc(0x%x) = %p (reuse) 0x%x", bytes, besthead->data, besthead->size);\r
+ return besthead->data;\r
}\r
\r
/**\r
return;\r
\r
head->magic = MAGIC_FREE;\r
+ DEBUGS("free(%p) : 0x%x bytes", mem, head->size);\r
\r
//Unify Right\r
if((intptr_t)head + head->size < (intptr_t)_heap_end)\r
\r
return ret; // Return old curpos\r
}\r
+\r
+void Heap_Dump(void)\r
+{\r
+ heap_head *cur = _heap_start;\r
+ while( cur < _heap_end )\r
+ {\r
+ switch( cur->magic )\r
+ {\r
+ case MAGIC:\r
+ _SysDebug("Used block %p[0x%x] - ptr=%p", cur, cur->size, cur->data);\r
+ break;\r
+ case MAGIC_FREE:\r
+ _SysDebug("Free block %p[0x%x] - ptr=%p", cur, cur->size, cur->data);\r
+ break;\r
+ default:\r
+ _SysDebug("Block %p bad magic (0x%x)", cur, cur->magic);\r
+ return ;\r
+ }\r
+ cur = (void*)( (char*)cur + cur->size );\r
+ }\r
+}\r
+\r
\r
/* --- StdLib --- */\r
extern void _exit(int code) __attribute__((noreturn)); /* NOTE: Also defined in acess/sys.h */\r
+extern long long strtoll(const char *ptr, char **end, int base);\r
+extern long strtol(const char *ptr, char **end, int base);\r
extern int atoi(const char *ptr);\r
extern void exit(int status) __attribute__((noreturn));\r
extern void atexit(void (*__func)(void));\r
extern void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));\r
+extern int abs(int j);\r
+extern long int labs(long int j);\r
+extern long long int llabs(long long int j);\r
\r
/* --- Environment --- */\r
extern char *getenv(const char *name);\r
* AcessOS Basic C Library\r
* stdlib.c\r
*/\r
-/**\r
- * \todo Move half of these to stdio\r
- */\r
#include <acess/sys.h>\r
#include <stdlib.h>\r
#include <stdio.h>\r
+#include <errno.h>\r
+#include <ctype.h>\r
+#include <limits.h>\r
#include "lib.h"\r
\r
#define _stdout 1\r
}\r
}\r
\r
-/**\r
- * \fn EXPORT int atoi(const char *str)\r
- * \brief Convert a string to an integer\r
- */\r
-EXPORT int atoi(const char *str)\r
+EXPORT long long strtoll(const char *str, char **end, int base)\r
{\r
int neg = 0;\r
- int ret = 0;\r
- \r
- // NULL Check\r
- if(!str) return 0;\r
+ long long ret = 0;\r
\r
- while(*str == ' ' || *str == '\t') str++;\r
+ if( !str || base < 0 || base > 36 || base == 1 ) {\r
+ if(end)\r
+ *end = (char*)str;\r
+ errno = EINVAL;\r
+ return 0;\r
+ }\r
+\r
+ while( isspace(*str) )\r
+ str++;\r
\r
- // Check for negative\r
- if(*str == '-') {\r
- neg = 1;\r
+ // Check for negative (or positive) sign\r
+ if(*str == '-' || *str == '+') {\r
+ neg = (*str == '-');\r
str++;\r
}\r
\r
- if(*str == '0') {\r
+ if( base == 0 || base == 16 ) {\r
+ if( *str == '0' && str[1] == 'x' ) {\r
+ str += 2;\r
+ base = 16;\r
+ }\r
+ }\r
+ \r
+ if( base == 0 && *str == '0' ) {\r
str ++;\r
- if(*str == 'x') {\r
- str++;\r
- // Hex\r
- while( ('0' <= *str && *str <= '9')\r
- || ('A' <= *str && *str <= 'F' )\r
- || ('a' <= *str && *str <= 'f' )\r
- )\r
- {\r
- ret *= 16;\r
- if(*str <= '9') {\r
- ret += *str - '0';\r
- } else if (*str <= 'F') {\r
- ret += *str - 'A' + 10;\r
- } else {\r
- ret += *str - 'a' + 10;\r
- }\r
- str++;\r
- }\r
- } else {\r
- // Octal\r
- while( '0' <= *str && *str <= '7' )\r
- {\r
- ret *= 8;\r
- ret += *str - '0';\r
- str++;\r
- }\r
+ base = 8;\r
+ }\r
+\r
+ if( base == 0 )\r
+ base = 10;\r
+\r
+ while( *str )\r
+ {\r
+ int next = -1;\r
+ if( base <= 10 ) {\r
+ if( '0' <= *str && *str <= '0'+base-1 )\r
+ next = *str - '0';\r
}\r
- } else {\r
- // Decimal\r
- while( '0' <= *str && *str <= '9' )\r
- {\r
- ret *= 10;\r
- ret += *str - '0';\r
- str++;\r
+ else {\r
+ if( '0' <= *str && *str <= '9' )\r
+ next = *str - '0';\r
+ if( 'A' <= *str && *str <= 'A'+base-10-1 )\r
+ next = *str - 'A';\r
+ if( 'a' <= *str && *str <= 'a'+base-10-1 )\r
+ next = *str - 'a';\r
}\r
+ if( next < 0 )\r
+ break;\r
+ ret *= base;\r
+ ret += next;\r
+ str ++;\r
}\r
- \r
- // Negate if needed\r
- if(neg) ret = -ret;\r
+\r
+ if( neg )\r
+ ret = -ret; \r
+\r
+ if(end)\r
+ *end = (char*)str;\r
return ret;\r
}\r
\r
+EXPORT long strtol(const char *str, char **end, int base)\r
+{\r
+ long long tmp = strtoll(str, end, base);\r
+ if( tmp > LONG_MAX || tmp < LONG_MIN ) {\r
+ errno = ERANGE;\r
+ return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;\r
+ }\r
+ return tmp;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int atoi(const char *str)\r
+ * \brief Convert a string to an integer\r
+ */\r
+EXPORT int atoi(const char *str)\r
+{\r
+ long long tmp = strtoll(str, NULL, 0);\r
+ if( tmp > INT_MAX || tmp < INT_MIN ) {\r
+ errno = ERANGE;\r
+ return (tmp > INT_MAX) ? INT_MAX : INT_MIN;\r
+ }\r
+ return tmp;\r
+}\r
+\r
int abs(int j) { return j < 0 ? -j : j; }\r
long int labs(long int j) { return j < 0 ? -j : j; }\r
\r
char *sp = (char *)src;
char *dp = (char *)dest;
// Check if the areas overlap
- if( (intptr_t)dest > (intptr_t)src && (intptr_t)dest < (intptr_t)src+count )
- for(;count--;) dp[count] = sp[count];
+ if( (intptr_t)src < (intptr_t)dest && (intptr_t)dest < (intptr_t)src+count )
+ for(;count--;)
+ dp[count] = sp[count];
else
- for(;count--;) *dp++ = *sp++;
+ memcpy(dest, src, count);
return dest;
}