From 2b9e97b8635c20c5a2b87789b1014489863d1994 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 13 Nov 2009 18:05:27 +0100 Subject: Added a game of life simulator demo --- Makefile | 7 +- Source/Applications/Demos/GOL.cpp | 95 +++++++++++++++++++++ Source/Applications/Demos/Makefile | 35 ++++++++ Source/Applications/Demos/asmdemo.asm | 30 +++++++ Source/Applications/Demos/cxxdemo.cpp | 20 +++++ Source/Applications/Demos/lib-melonasm.asm | 24 ++++++ Source/Applications/SampleApps/Makefile | 35 -------- Source/Applications/SampleApps/asmdemo.asm | 30 ------- Source/Applications/SampleApps/cxxdemo.cpp | 20 ----- Source/Applications/SampleApps/lib-melonasm.asm | 24 ------ Source/Kernel/Core/cppsupport.wtf.cpp | 54 ------------ Source/Kernel/DeviceManager/Kbd.ns.h | 85 +------------------ Source/Kernel/Makefile | 2 +- Source/Kernel/SyscallManager/IDT.ns.cpp | 2 + Source/Kernel/VTManager/FileVT.class.cpp | 4 +- Source/Kernel/VTManager/FileVT.class.h | 2 +- Source/Kernel/VTManager/PipeVT.class.cpp | 2 +- Source/Kernel/VTManager/ScrollableVT.class.cpp | 2 +- Source/Kernel/VTManager/ScrollableVT.class.h | 2 +- Source/Kernel/VTManager/SimpleVT.class.h | 2 + .../Kernel/VTManager/VirtualTerminal-sc.proto.cpp | 31 +++++++ Source/Kernel/VTManager/VirtualTerminal.proto.h | 12 ++- Source/Library/Common/Mutex.class.cpp | 2 +- Source/Library/Common/Rand.ns.cpp | 2 +- Source/Library/Common/cppsupport.wtf.cpp | 54 ++++++++++++ Source/Library/Interface/Kbd.iface.h | 98 ++++++++++++++++++++++ Source/Library/Interface/VirtualTerminal.iface.h | 5 ++ Source/Library/Makefile | 4 +- .../Userland/Binding/VirtualTerminal.class.h | 17 ++++ Source/Library/Userland/Start.cpp | 4 - 30 files changed, 439 insertions(+), 267 deletions(-) create mode 100644 Source/Applications/Demos/GOL.cpp create mode 100644 Source/Applications/Demos/Makefile create mode 100644 Source/Applications/Demos/asmdemo.asm create mode 100644 Source/Applications/Demos/cxxdemo.cpp create mode 100644 Source/Applications/Demos/lib-melonasm.asm delete mode 100644 Source/Applications/SampleApps/Makefile delete mode 100644 Source/Applications/SampleApps/asmdemo.asm delete mode 100644 Source/Applications/SampleApps/cxxdemo.cpp delete mode 100644 Source/Applications/SampleApps/lib-melonasm.asm delete mode 100644 Source/Kernel/Core/cppsupport.wtf.cpp create mode 100644 Source/Library/Common/cppsupport.wtf.cpp create mode 100644 Source/Library/Interface/Kbd.iface.h diff --git a/Makefile b/Makefile index fab9eae..33205ff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean, mrproper, Init.rfs, commit -Projects = Kernel Library Tools/MakeRamFS Applications/Shell Applications/PaperWork Applications/SampleApps +Projects = Kernel Library Tools/MakeRamFS Applications/Shell Applications/PaperWork Applications/Demos Kernel = Source/Kernel/Melon.ke RamFS = Init.rfs @@ -10,8 +10,9 @@ RamFSFiles = :/System :/System/Applications :/System/Configuration :/System/Keym Source/Kernel/Ressources/Configuration/Groups:/System/Configuration/Groups \ Source/Kernel/Ressources/Keymaps/fr.mkm:/System/Keymaps/fr.mkm \ Source/Kernel/Ressources/Texts/Welcome.txt:/Welcome.txt \ - Source/Applications/SampleApps/asmdemo:/Applications/Demos/ASMDemo.app \ - Source/Applications/SampleApps/cxxdemo:/Applications/Demos/CPPDemo.app \ + Source/Applications/Demos/asmdemo:/Applications/Demos/ASMDemo.app \ + Source/Applications/Demos/cxxdemo:/Applications/Demos/CPPDemo.app \ + Source/Applications/Demos/GOL:/Applications/Demos/GOL.app \ Source/Applications/Shell/Shell:/Applications/Shell/Shell.app \ Source/Applications/Shell/Help.txt:/Applications/Shell/Help.txt \ Source/Applications/PaperWork/PaperWork:/System/Applications/PaperWork.app \ diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp new file mode 100644 index 0000000..6dd1cdf --- /dev/null +++ b/Source/Applications/Demos/GOL.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +int main(Vector args) { + if (!outvt.isBoxed()) { + outvt << "Error : cannot display GOL on a non-boxed terminal.\n"; + return 1; + } + + int h = outvt.height() - 1, w = outvt.width(); + + bool *cells = new bool[w * h]; + bool *newcells = new bool[w * h]; + + u32int delay = 100; + + for (u32int x = 0; x < w; x++) { + for (u32int y = 0; y < h; y++) { + cells[x * h + y] = false; + } + } + + while (1) { + //Display cells + outvt.moveCursor(0, 0); + for (u32int y = 0; y < h; y++) { + for (u32int x = 0; x < w; x++) { + if (cells[x * h + y]) { + outvt.setColor(0, 2); + } else { + outvt.setColor(7, 0); + } + outvt << " "; + } + } + outvt << "Press Ctrl+h for help"; + + //Compute next generation + for (u32int y = 0; y < h; y++) { + for (u32int x = 0; x < w; x++) { + u8int n = 0; + for (u32int yy = y - 1; yy <= y + 1; yy++) { + for (u32int xx = x - 1; xx <= x + 2; xx++) { + if (xx < w and yy < h and cells[xx * h + yy]) n++; + } + } + if (cells[x * h + y]) n--; + if ((cells[x * h + y] and n == 2) or n == 3) { + newcells[x * h + y] = true; + } else { + newcells[x * h + y] = false; + } + } + } + for (u32int x = 0; x < w; x++) { + for (u32int y = 0; y < h; y++) { + cells[x * h + y] = newcells[x * h + y]; + } + } + + keypress_t kp = invt.getKeypress(false, false); + if (kp.hascmd && (kp.modifiers & STATUS_CTRL)) { + if (kp.character == WChar("c")) { + break; + } else if (kp.character == WChar("r")) { + for (u32int i = 0; i < 20; i++) { + u64int x = Rand::rand() * w / Rand::max(); + u64int y = Rand::rand() * h / Rand::max(); + cells[x * h + y] = true; + } + } else if (kp.character == WChar("R")) { + for (u32int i = 0; i < h; i++) { + cells[i] = true; + cells[(2 * i) % (h - i)] = true; + cells[(w * i) % (h * w - i)] = true; + } + } else if (kp.character == WChar("h")) { + outvt << "** Melon's demo Game Of Life Simulator help :\n"; + outvt << " - ctrl+c : quit\n"; + outvt << " - ctrl+h : show this\n"; + outvt << " - ctrl+r : add some random cells\n"; + outvt << " - ctrl+R : add more cells, but not random\n"; + outvt << "Press any key to return to simultaor..."; + invt.getKeypress(); + } + } + + Thread::get().sleep(100); + } + + delete cells; + delete newcells; +} diff --git a/Source/Applications/Demos/Makefile b/Source/Applications/Demos/Makefile new file mode 100644 index 0000000..e66acce --- /dev/null +++ b/Source/Applications/Demos/Makefile @@ -0,0 +1,35 @@ +.PHONY: clean, mrproper + +ASM = nasm +ASMFLAGS = -f bin + +CXX = g++ +CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND + +LD = ld +LDFLAGS = -T ../../Library/Link.ld -L ../../Library + +Applications = asmdemo cxxdemo GOL + +all: $(Applications) + echo "* Done with applications : $(Applications)" + +rebuild: mrproper all + +%: %.cpp + echo "* Compiling $<..." + $(CXX) $(CXXFLAGS) -c $< -o $@.o + echo "* Linking $@.o..." + $(LD) $(LDFLAGS) $@.o -o $@ + +%: %.asm + echo "* Compiling $<..." + $(ASM) $(ASMFLAGS) -o $@ $< + +clean: + echo "* Removing object files..." + rm -rf *.o + +mrproper: clean + echo "* Removing applications..." + rm -rf $(Applications) diff --git a/Source/Applications/Demos/asmdemo.asm b/Source/Applications/Demos/asmdemo.asm new file mode 100644 index 0000000..d57cc9b --- /dev/null +++ b/Source/Applications/Demos/asmdemo.asm @@ -0,0 +1,30 @@ +%include "lib-melonasm.asm" + +start: ; label used for calculating app size + mov ecx, [data] + mov ebx, ecx + mov eax, SC_WHEX + int 64 + mov eax, SC_PUTCH + mov ebx, 10 + int 64 +lblloop: + inc ecx + mov eax, SC_PUTCH ;temporarily defined for writing one char to screen + mov ebx, ecx + int 64 + mov eax, SC_SLEEP ;temporary syscall for sleeping + mov ebx, 30 ;20ms + int 64 + cmp ecx, 127 + jnz lblloop + mov eax, 0 + mov eax, SC_PUTCH + mov ebx, 10 ;newline + int 64 + int 66 ;finish task + +data: +dd 0x00000020 + +end: ; label used for calculating app size diff --git a/Source/Applications/Demos/cxxdemo.cpp b/Source/Applications/Demos/cxxdemo.cpp new file mode 100644 index 0000000..3d452e7 --- /dev/null +++ b/Source/Applications/Demos/cxxdemo.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +int main(const Vector& args) { + outvt << "Enter some text plz : "; + String s = invt.readLine(); + outvt << s; + Thread t = Thread::get(); + for (char c = ' '; c <= 'z'; c++) { + t.sleep((u32int)c / 4); + outvt.put(c); + } + outvt << "\n"; + outvt << "Salut les gens ! c'est le progrès !!!\nLe boeuf mort est juste là : "; + outvt << 0xDEADBEEF; + outvt << "\n"; +} diff --git a/Source/Applications/Demos/lib-melonasm.asm b/Source/Applications/Demos/lib-melonasm.asm new file mode 100644 index 0000000..0845770 --- /dev/null +++ b/Source/Applications/Demos/lib-melonasm.asm @@ -0,0 +1,24 @@ +[bits 32] + +%ifidn __OUTPUT_FORMAT__, bin +; create a MelonBinary output + +%define MEM_ORIGIN 0x10000000 + +dd 0xFEEDBEEF ; magic number ^^ +dd end - start +dd MEM_ORIGIN + +; the ($-$$) permits not taking into account the header above +[org MEM_ORIGIN - ($-$$)] + +%elifidn __OUTPUT_FORMAT__, elf +; create an elf object + +[global start] + +%endif + +%define SC_PUTCH 0xFFFFFF01 +%define SC_SLEEP 0xFFFFFF02 +%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile deleted file mode 100644 index 05f79b1..0000000 --- a/Source/Applications/SampleApps/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -.PHONY: clean, mrproper - -ASM = nasm -ASMFLAGS = -f bin - -CXX = g++ -CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND - -LD = ld -LDFLAGS = -T ../../Library/Link.ld -L ../../Library - -Applications = asmdemo cxxdemo - -all: $(Applications) - echo "* Done with applications : $(Applications)" - -rebuild: mrproper all - -%: %.cpp - echo "* Compiling $<..." - $(CXX) $(CXXFLAGS) -c $< -o $@.o - echo "* Linking $@.o..." - $(LD) $(LDFLAGS) $@.o -o $@ - -%: %.asm - echo "* Compiling $<..." - $(ASM) $(ASMFLAGS) -o $@ $< - -clean: - echo "* Removing object files..." - rm -rf *.o - -mrproper: clean - echo "* Removing applications..." - rm -rf $(Applications) diff --git a/Source/Applications/SampleApps/asmdemo.asm b/Source/Applications/SampleApps/asmdemo.asm deleted file mode 100644 index d57cc9b..0000000 --- a/Source/Applications/SampleApps/asmdemo.asm +++ /dev/null @@ -1,30 +0,0 @@ -%include "lib-melonasm.asm" - -start: ; label used for calculating app size - mov ecx, [data] - mov ebx, ecx - mov eax, SC_WHEX - int 64 - mov eax, SC_PUTCH - mov ebx, 10 - int 64 -lblloop: - inc ecx - mov eax, SC_PUTCH ;temporarily defined for writing one char to screen - mov ebx, ecx - int 64 - mov eax, SC_SLEEP ;temporary syscall for sleeping - mov ebx, 30 ;20ms - int 64 - cmp ecx, 127 - jnz lblloop - mov eax, 0 - mov eax, SC_PUTCH - mov ebx, 10 ;newline - int 64 - int 66 ;finish task - -data: -dd 0x00000020 - -end: ; label used for calculating app size diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp deleted file mode 100644 index 3d452e7..0000000 --- a/Source/Applications/SampleApps/cxxdemo.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -#include - -int main(const Vector& args) { - outvt << "Enter some text plz : "; - String s = invt.readLine(); - outvt << s; - Thread t = Thread::get(); - for (char c = ' '; c <= 'z'; c++) { - t.sleep((u32int)c / 4); - outvt.put(c); - } - outvt << "\n"; - outvt << "Salut les gens ! c'est le progrès !!!\nLe boeuf mort est juste là : "; - outvt << 0xDEADBEEF; - outvt << "\n"; -} diff --git a/Source/Applications/SampleApps/lib-melonasm.asm b/Source/Applications/SampleApps/lib-melonasm.asm deleted file mode 100644 index 0845770..0000000 --- a/Source/Applications/SampleApps/lib-melonasm.asm +++ /dev/null @@ -1,24 +0,0 @@ -[bits 32] - -%ifidn __OUTPUT_FORMAT__, bin -; create a MelonBinary output - -%define MEM_ORIGIN 0x10000000 - -dd 0xFEEDBEEF ; magic number ^^ -dd end - start -dd MEM_ORIGIN - -; the ($-$$) permits not taking into account the header above -[org MEM_ORIGIN - ($-$$)] - -%elifidn __OUTPUT_FORMAT__, elf -; create an elf object - -[global start] - -%endif - -%define SC_PUTCH 0xFFFFFF01 -%define SC_SLEEP 0xFFFFFF02 -%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Kernel/Core/cppsupport.wtf.cpp b/Source/Kernel/Core/cppsupport.wtf.cpp deleted file mode 100644 index 06ef1b9..0000000 --- a/Source/Kernel/Core/cppsupport.wtf.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//This file just contains a few methods required for some C++ things to work -#include - -namespace CMem { - u8int* memcpy(u8int*, const u8int*, int); -}; - -using namespace CMem; - -extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes - -void *__dso_handle; //Required when using global objects -extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; } - -extern "C" void * memmove(void* dst, const void* src, size_t len) { - memcpy((u8int*)dst, (const u8int*)src, len); - return dst; -} - -//Functions for quad divisions/modulo. Taken and arranged from klibc include/asm/div64.h -//These only work with 32-bit divisors and only return 32-bit remainder. -//TODO : think of some correct quad div/mod algorithms -inline u64int doDiv(u64int dividend, u32int divisor, u32int *remainder) { - union { - u64int v64; - u32int v32[2]; - } d = { dividend }; - u32int upper; - - upper = d.v32[1]; - d.v32[1] = 0; - if (upper >= divisor) { - d.v32[1] = upper / divisor; - upper %= divisor; - } - asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) : - "rm" (divisor), "0" (d.v32[0]), "1" (upper)); - return d.v64; -} - -extern "C" { -u64int __udivdi3(u64int dividend, u64int b) { - u32int divisor, remainder; - divisor = b; - return doDiv(dividend, divisor, &remainder); -} - -u64int __umoddi3(u64int dividend, u64int b) { - u32int divisor, remainder; - divisor = b; - doDiv(dividend, divisor, &remainder); - return remainder; -} -} diff --git a/Source/Kernel/DeviceManager/Kbd.ns.h b/Source/Kernel/DeviceManager/Kbd.ns.h index 2934474..2343d46 100644 --- a/Source/Kernel/DeviceManager/Kbd.ns.h +++ b/Source/Kernel/DeviceManager/Kbd.ns.h @@ -3,94 +3,11 @@ #include #include - -//Used by variable kbdstatus -#define STATUS_SCRL 0x40 -#define STATUS_NUM 0x20 -#define STATUS_CAPS 0x10 -#define STATUS_SHIFT 0x08 -#define STATUS_CTRL 0x04 -#define STATUS_ALT 0x02 -#define STATUS_ALTGR 0x01 - -//Used in control keys keymap. The ones > 100 are modifiers and are not supposed to be sent to applications. -#define KBDC_LEFTCTRL 101 -#define KBDC_RIGHTCTRL 102 -#define KBDC_ALT 103 -#define KBDC_ALTGR 104 -#define KBDC_LEFTSUP 5 //Super = windows -#define KBDC_RIGHTSUP 6 -#define KBDC_MENU 7 -#define KBDC_LEFTSHIFT 108 -#define KBDC_RIGHTSHIFT 109 -#define KBDC_CAPSLOCK 110 -#define KBDC_TAB 11 -#define KBDC_ENTER 12 -#define KBDC_BACKSPACE 13 - -#define KBDC_KPINSERT 14 //Key 0/insert -#define KBDC_KPEND 15 //Key 1/end -#define KBDC_KPDOWN 16 //Key 2/down -#define KBDC_KPPGDOWN 17 //Key 3/pgdown -#define KBDC_KPLEFT 18 //Key 4/left -#define KBDC_KP5 19 //Key 5 this is sent to receiving application, but must be ignored -#define KBDC_KPRIGHT 20 //Key 6/right -#define KBDC_KPHOME 21 //Key 7/home -#define KBDC_KPUP 22 //Key 8/up -#define KBDC_KPPGUP 23 //Key 9/pgup -#define KBDC_KPDEL 24 //Key ./del - -#define KBDC_HOME 25 -#define KBDC_END 26 -#define KBDC_INSERT 27 -#define KBDC_DEL 28 -#define KBDC_PGUP 29 -#define KBDC_PGDOWN 30 -#define KBDC_UP 31 -#define KBDC_DOWN 32 -#define KBDC_LEFT 33 -#define KBDC_RIGHT 34 - -#define KBDC_NUMLOCK 135 -#define KBDC_SCRLLOCK 136 -#define KBDC_PRTSCN 37 //Print screen -#define KBDC_SYSREQ 38 - -#define KBDC_ESCAPE 40 -#define KBDC_F1 41 -#define KBDC_F2 42 -#define KBDC_F3 43 -#define KBDC_F4 44 -#define KBDC_F5 45 -#define KBDC_F6 46 -#define KBDC_F7 47 -#define KBDC_F8 48 -#define KBDC_F9 49 -#define KBDC_F10 50 -#define KBDC_F11 51 -#define KBDC_F12 52 - -//This is a special case. Keycode is escaped, Keyboard:: will send a 0xB5 keycode, that must not be mixed up with 0x35 -#define KBDC_KPSLASH 53 +#include class VirtualTerminal; namespace Kbd { - //== Possible cases for keypress_t : - // - hascmd && !haschar : this is a command key press/release (all grey keys except alt/ctrl/altgr/shift) - // - haschar && !hascmd : this is a character key press/release. Modifiers can haz STATUS_SHIFT or STATUS_ALTGR - // - haschar && hascmd : this is a character key press, but with ctrl and/or alt. See that in modifiers. - // - !haschar && !hascmd : invalid keypress - struct keypress_t { - bool pressed; - bool hascmd; - bool haschar; - u8int modifiers; - u8int command; - WChar character; //is 0 if !haschar - keypress_t() : hascmd(false), haschar(false), command(0), character('\0') {}; - }; - void setFocus(VirtualTerminal* vt); bool loadKeymap(String lang); void updateLeds(); diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 82498b2..a70c8c5 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -12,7 +12,6 @@ ASMFLAGS = -f elf OutFile = Melon.ke Objects = Core/loader.wtf.o \ Core/kmain.wtf.o \ - Core/cppsupport.wtf.o \ Core/Sys.ns.o \ Core/Log.ns.o \ MemoryManager/Mem.ns.o \ @@ -47,6 +46,7 @@ Objects = Core/loader.wtf.o \ Linker/Binary.proto.o \ Linker/MelonBinary.class.o \ Linker/ElfBinary.class.o \ + ../Library/Common/cppsupport.wtf.o \ ../Library/Common/Bitset.class.o \ ../Library/Common/String.class.o \ ../Library/Common/ByteArray.class.o \ diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 7c4b5cb..e9e60d7 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -72,7 +72,9 @@ extern "C" void interrupt_handler(registers_t regs) { if (regs.int_no >= 40) outb(0xA0, 0x20); outb(0x20, 0x20); + asm volatile("sti"); //Make handling preemtible Dev::handleIRQ(regs, (regs.int_no - 32)); + asm volatile("cli"); doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 64) { diff --git a/Source/Kernel/VTManager/FileVT.class.cpp b/Source/Kernel/VTManager/FileVT.class.cpp index 0acc623..5469fbd 100644 --- a/Source/Kernel/VTManager/FileVT.class.cpp +++ b/Source/Kernel/VTManager/FileVT.class.cpp @@ -31,8 +31,8 @@ void FileVT::put(WChar c, bool updatecsr) { } } -Kbd::keypress_t FileVT::getKeypress(bool show, bool block) { - Kbd::keypress_t ret; +keypress_t FileVT::getKeypress(bool show, bool block) { + keypress_t ret; if (m_isWriting) return ret; if (m_bufferPos == m_buffer.size()) { diff --git a/Source/Kernel/VTManager/FileVT.class.h b/Source/Kernel/VTManager/FileVT.class.h index ed3e224..a246ce0 100644 --- a/Source/Kernel/VTManager/FileVT.class.h +++ b/Source/Kernel/VTManager/FileVT.class.h @@ -18,7 +18,7 @@ class FileVT : public VirtualTerminal { void setCursorCol(u32int col); void put(WChar c, bool updatecsr = true); - Kbd::keypress_t getKeypress(bool show = true, bool block = true); + keypress_t getKeypress(bool show = true, bool block = true); }; #endif diff --git a/Source/Kernel/VTManager/PipeVT.class.cpp b/Source/Kernel/VTManager/PipeVT.class.cpp index 10c7e7b..7e67161 100644 --- a/Source/Kernel/VTManager/PipeVT.class.cpp +++ b/Source/Kernel/VTManager/PipeVT.class.cpp @@ -11,7 +11,7 @@ void PipeVT::setCursorCol(u32int col) { } void PipeVT::put(WChar c, bool updatecsr) { - Kbd::keypress_t kp; + keypress_t kp; if (c.value == '\t') { m_col = (m_col + 8) &~(8 - 1); kp.hascmd = true; diff --git a/Source/Kernel/VTManager/ScrollableVT.class.cpp b/Source/Kernel/VTManager/ScrollableVT.class.cpp index ca0075a..264c3a4 100644 --- a/Source/Kernel/VTManager/ScrollableVT.class.cpp +++ b/Source/Kernel/VTManager/ScrollableVT.class.cpp @@ -69,7 +69,7 @@ void ScrollableVT::scroll() { SimpleVT::scroll(); } -void ScrollableVT::keyPress(Kbd::keypress_t kp) { +void ScrollableVT::keyPress(keypress_t kp) { if (kp.hascmd && kp.modifiers == STATUS_SHIFT) { s32int nlup = m_linesup; if (kp.command == KBDC_PGUP) { diff --git a/Source/Kernel/VTManager/ScrollableVT.class.h b/Source/Kernel/VTManager/ScrollableVT.class.h index fbc2c4c..6d29645 100644 --- a/Source/Kernel/VTManager/ScrollableVT.class.h +++ b/Source/Kernel/VTManager/ScrollableVT.class.h @@ -18,7 +18,7 @@ class ScrollableVT : public SimpleVT { void redraw(); void scroll(); - void keyPress(Kbd::keypress_t kp); + void keyPress(keypress_t kp); }; #endif diff --git a/Source/Kernel/VTManager/SimpleVT.class.h b/Source/Kernel/VTManager/SimpleVT.class.h index 6a50549..9eda6de 100644 --- a/Source/Kernel/VTManager/SimpleVT.class.h +++ b/Source/Kernel/VTManager/SimpleVT.class.h @@ -22,6 +22,8 @@ class SimpleVT : public VirtualTerminal { void clear(); void setColor(u8int fgcolor, u8int bgcolor = 0xFF); bool isBoxed() { return true; } + u8int height() { return m_rows; } + u8int width() { return m_cols; } void map(s32int row = -1, s32int col = -1); void unmap(); diff --git a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp index 5506c74..47941c6 100644 --- a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -8,10 +8,14 @@ call_t VirtualTerminal::m_callTable[] = { CALL1(VTIF_WRITE, &VirtualTerminal::writeSC), CALL1(VTIF_PUT, &VirtualTerminal::putSC), CALL1(VTIF_READLINE, &VirtualTerminal::readLineSC), + CALL1(VTIF_GETKEYPRESS, &VirtualTerminal::getKeypressSC), CALL1(VTIF_SETCOLOR, &VirtualTerminal::setColorSC), CALL1(VTIF_SETCSRLINE, &VirtualTerminal::setCursorLineSC), CALL1(VTIF_SETCSRCOL, &VirtualTerminal::setCursorColSC), CALL0(VTIF_ISBOXED, &VirtualTerminal::isBoxedSC), + CALL0(VTIF_GETHEIGHT, &VirtualTerminal::getHeightSC), + CALL0(VTIF_GETWIDTH, &VirtualTerminal::getWidthSC), + CALL2(VTIF_LOCATE, &VirtualTerminal::locateSC), CALL0(0, 0) }; @@ -47,6 +51,14 @@ u32int VirtualTerminal::readLineSC(u32int show) { return readLine(show != 0).serialize(); } +u32int VirtualTerminal::getKeypressSC(u32int flags) { + bool show = (flags & 1), block = (flags & 2); + keypress_t temp = getKeypress(show, block); + void* ptr = Mem::mkXchgSpace(sizeof(keypress_t)); + memcpy((u8int*)ptr, (const u8int*)&temp, sizeof(keypress_t)); + return (u32int)ptr; +} + u32int VirtualTerminal::setColorSC(u32int x) { setColor((x >> 8) & 0xFF, x & 0xFF); return 0; @@ -65,3 +77,22 @@ u32int VirtualTerminal::setCursorColSC(u32int c) { u32int VirtualTerminal::isBoxedSC() { return (isBoxed() ? 1 : 0); } + +u32int VirtualTerminal::getHeightSC() { + return height(); +} + +u32int VirtualTerminal::getWidthSC() { + return width(); +} + +u32int VirtualTerminal::locateSC(u32int line, u32int col) { + if (line < 1000 and col < 1000) { + moveCursor(line, col); + } else if (line < 1000) { + setCursorLine(line); + } else if (col < 1000) { + setCursorCol(line); + } + return 0; +} diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index 9c138ec..5f874b4 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -17,7 +17,7 @@ struct vtchr { class VirtualTerminal : public Ressource { protected: Mutex m_kbdMutex, m_kbdbuffMutex; - Vector m_kbdbuff; //Key press events buffer + Vector m_kbdbuff; //Key press events buffer //SYSCALLS : static call_t m_callTable[]; @@ -26,10 +26,14 @@ class VirtualTerminal : public Ressource { u32int writeSC(u32int); u32int putSC(u32int); u32int readLineSC(u32int); + u32int getKeypressSC(u32int); u32int setColorSC(u32int); u32int setCursorLineSC(u32int); u32int setCursorColSC(u32int); u32int isBoxedSC(); + u32int getHeightSC(); + u32int getWidthSC(); + u32int locateSC(u32int, u32int); bool accessible() { return true; } public: @@ -40,6 +44,8 @@ class VirtualTerminal : public Ressource { virtual void setColor(u8int fgcolor, u8int bgcolor = 0xFF) {} //For a pipe/file VT, this will do nothing. virtual bool isBoxed() = 0; + virtual u8int height() { return 0; } + virtual u8int width() { return 0; } virtual void updateCursor() {} virtual void moveCursor(u32int row, u32int col) {} //These are not implemented for pipe/file VTs @@ -60,8 +66,8 @@ class VirtualTerminal : public Ressource { inline VirtualTerminal& operator<<(u32int i) { writeHex(i); return *this; } //Keyboard functions - virtual void keyPress(Kbd::keypress_t kp); //Called by Kbd:: when a key is pressed, overloaded by ScrollableVT - virtual Kbd::keypress_t getKeypress(bool show = true, bool block = true); //Block : must we wait for a key to be pressed ? + virtual void keyPress(keypress_t kp); //Called by Kbd:: when a key is pressed, overloaded by ScrollableVT + virtual keypress_t getKeypress(bool show = true, bool block = true); //Block : must we wait for a key to be pressed ? String readLine(bool show = true); }; diff --git a/Source/Library/Common/Mutex.class.cpp b/Source/Library/Common/Mutex.class.cpp index 2e9a63c..d7d7ead 100644 --- a/Source/Library/Common/Mutex.class.cpp +++ b/Source/Library/Common/Mutex.class.cpp @@ -41,5 +41,5 @@ void Mutex::unlock() { } bool Mutex::locked() { - return m_locked; + return m_locked == MUTEX_TRUE; } diff --git a/Source/Library/Common/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp index e568678..6323ccc 100644 --- a/Source/Library/Common/Rand.ns.cpp +++ b/Source/Library/Common/Rand.ns.cpp @@ -7,7 +7,7 @@ u64int current = RANDOM_SEED; u64int rand() { current = (u32int)(a*current + b); - while (current > m) current -= m; + if (current > m) current = current % m; return current; } diff --git a/Source/Library/Common/cppsupport.wtf.cpp b/Source/Library/Common/cppsupport.wtf.cpp new file mode 100644 index 0000000..06ef1b9 --- /dev/null +++ b/Source/Library/Common/cppsupport.wtf.cpp @@ -0,0 +1,54 @@ +//This file just contains a few methods required for some C++ things to work +#include + +namespace CMem { + u8int* memcpy(u8int*, const u8int*, int); +}; + +using namespace CMem; + +extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes + +void *__dso_handle; //Required when using global objects +extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; } + +extern "C" void * memmove(void* dst, const void* src, size_t len) { + memcpy((u8int*)dst, (const u8int*)src, len); + return dst; +} + +//Functions for quad divisions/modulo. Taken and arranged from klibc include/asm/div64.h +//These only work with 32-bit divisors and only return 32-bit remainder. +//TODO : think of some correct quad div/mod algorithms +inline u64int doDiv(u64int dividend, u32int divisor, u32int *remainder) { + union { + u64int v64; + u32int v32[2]; + } d = { dividend }; + u32int upper; + + upper = d.v32[1]; + d.v32[1] = 0; + if (upper >= divisor) { + d.v32[1] = upper / divisor; + upper %= divisor; + } + asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) : + "rm" (divisor), "0" (d.v32[0]), "1" (upper)); + return d.v64; +} + +extern "C" { +u64int __udivdi3(u64int dividend, u64int b) { + u32int divisor, remainder; + divisor = b; + return doDiv(dividend, divisor, &remainder); +} + +u64int __umoddi3(u64int dividend, u64int b) { + u32int divisor, remainder; + divisor = b; + doDiv(dividend, divisor, &remainder); + return remainder; +} +} diff --git a/Source/Library/Interface/Kbd.iface.h b/Source/Library/Interface/Kbd.iface.h new file mode 100644 index 0000000..5627605 --- /dev/null +++ b/Source/Library/Interface/Kbd.iface.h @@ -0,0 +1,98 @@ +#ifndef DEF_KBD_IFACE_H +#define DEF_KBD_IFACE_H + +#include + +/* + * Some of these values are used internally by the kernel, just take whatever you need. + */ + +//Used by variable kbdstatus +#define STATUS_SCRL 0x40 +#define STATUS_NUM 0x20 +#define STATUS_CAPS 0x10 +#define STATUS_SHIFT 0x08 +#define STATUS_CTRL 0x04 +#define STATUS_ALT 0x02 +#define STATUS_ALTGR 0x01 + +//Used in control keys keymap. The ones > 100 are modifiers and are not supposed to be sent to applications. +#define KBDC_LEFTCTRL 101 +#define KBDC_RIGHTCTRL 102 +#define KBDC_ALT 103 +#define KBDC_ALTGR 104 +#define KBDC_LEFTSUP 5 //Super = windows +#define KBDC_RIGHTSUP 6 +#define KBDC_MENU 7 +#define KBDC_LEFTSHIFT 108 +#define KBDC_RIGHTSHIFT 109 +#define KBDC_CAPSLOCK 110 +#define KBDC_TAB 11 +#define KBDC_ENTER 12 +#define KBDC_BACKSPACE 13 + +#define KBDC_KPINSERT 14 //Key 0/insert +#define KBDC_KPEND 15 //Key 1/end +#define KBDC_KPDOWN 16 //Key 2/down +#define KBDC_KPPGDOWN 17 //Key 3/pgdown +#define KBDC_KPLEFT 18 //Key 4/left +#define KBDC_KP5 19 //Key 5 this is sent to receiving application, but must be ignored +#define KBDC_KPRIGHT 20 //Key 6/right +#define KBDC_KPHOME 21 //Key 7/home +#define KBDC_KPUP 22 //Key 8/up +#define KBDC_KPPGUP 23 //Key 9/pgup +#define KBDC_KPDEL 24 //Key ./del + +#define KBDC_HOME 25 +#define KBDC_END 26 +#define KBDC_INSERT 27 +#define KBDC_DEL 28 +#define KBDC_PGUP 29 +#define KBDC_PGDOWN 30 +#define KBDC_UP 31 +#define KBDC_DOWN 32 +#define KBDC_LEFT 33 +#define KBDC_RIGHT 34 + +#define KBDC_NUMLOCK 135 +#define KBDC_SCRLLOCK 136 +#define KBDC_PRTSCN 37 //Print screen +#define KBDC_SYSREQ 38 + +#define KBDC_ESCAPE 40 +#define KBDC_F1 41 +#define KBDC_F2 42 +#define KBDC_F3 43 +#define KBDC_F4 44 +#define KBDC_F5 45 +#define KBDC_F6 46 +#define KBDC_F7 47 +#define KBDC_F8 48 +#define KBDC_F9 49 +#define KBDC_F10 50 +#define KBDC_F11 51 +#define KBDC_F12 52 + +//This is a special case. Keycode is escaped, Keyboard:: will send a 0xB5 keycode, that must not be mixed up with 0x35 +#define KBDC_KPSLASH 53 + +/* + * This type defines a keypress event. + */ + +//== Possible cases for keypress_t : +// - hascmd && !haschar : this is a command key press/release (all grey keys except alt/ctrl/altgr/shift) +// - haschar && !hascmd : this is a character key press/release. Modifiers can haz STATUS_SHIFT or STATUS_ALTGR +// - haschar && hascmd : this is a character key press, but with ctrl and/or alt. See that in modifiers. +// - !haschar && !hascmd : invalid keypress +struct keypress_t { + bool pressed; + bool hascmd; + bool haschar; + u8int modifiers; + u8int command; + WChar character; //is 0 if !haschar + keypress_t() : hascmd(false), haschar(false), command(0), character('\0') {}; +}; + +#endif diff --git a/Source/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h index c6388e6..c7e75e8 100644 --- a/Source/Library/Interface/VirtualTerminal.iface.h +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -13,10 +13,15 @@ #define VTIF_WRITE 0x04 #define VTIF_READLINE 0x05 +#define VTIF_GETKEYPRESS 0x06 //Takes two flags : 1<<0 = show, 1<<1 = block #define VTIF_SETCOLOR 0x10 #define VTIF_SETCSRLINE 0x11 #define VTIF_SETCSRCOL 0x12 #define VTIF_ISBOXED 0x13 +#define VTIF_GETHEIGHT 0x1A +#define VTIF_GETWIDTH 0x1B +#define VTIF_LOCATE 0x1C //Takes line, col and sets cursor position + #endif diff --git a/Source/Library/Makefile b/Source/Library/Makefile index 5a7a039..5c77c84 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -1,7 +1,7 @@ .PHONY: clean, mrproper CXX = g++ -CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I Common -I Userland -I Interface -D THIS_IS_MELON_USERLAND +CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I Common -I Userland -I Interface -D THIS_IS_MELON_USERLAND -D RANDOM_SEED=1`date +%N`LL ASM = nasm ASMFLAGS = -f elf @@ -18,6 +18,8 @@ Objects = Common/WChar.class.uo \ Common/String.class.uo \ Common/TextFile.class.uo \ Common/ByteArray.class.uo \ + Common/Rand.ns.uo \ + Common/cppsupport.wtf.uo \ Userland/Syscall/Syscall.wtf.uo \ Userland/Syscall/RessourceCaller.class.uo \ Userland/Start.uo diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h index 5fd9733..c8a4123 100644 --- a/Source/Library/Userland/Binding/VirtualTerminal.class.h +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -29,6 +30,10 @@ class VirtualTerminal : public RessourceCaller { void write(String s) { doCall(VTIF_WRITE, (u32int)&s); } + keypress_t getKeypress(bool show = true, bool block = true) { + keypress_t* ptr = (keypress_t*)doCall(VTIF_GETKEYPRESS, (show ? 1 : 0) | (block ? 2 : 0)); + return *ptr; + } String readLine(bool show = true) { return String::unserialize(doCall(VTIF_READLINE, (show ? 1 : 0))); } @@ -44,9 +49,21 @@ class VirtualTerminal : public RessourceCaller { bool isBoxed() { return doCall(VTIF_ISBOXED) != 0; } + u8int height() { + return doCall(VTIF_GETHEIGHT); + } + u8int width() { + return doCall(VTIF_GETWIDTH); + } void put(WChar c) { doCall(VTIF_PUT, c); } + void moveCursor(u8int line, u8int col) { + doCall(VTIF_LOCATE, line, col); + } + void put(u8int line, u8int col, WChar c) { + moveCursor(line, col); put(c); + } inline VirtualTerminal& operator<<(const String& s) { write(s); return *this; } inline VirtualTerminal& operator<<(s32int i) { writeDec(i); return *this; } diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp index 032450d..0c25491 100644 --- a/Source/Library/Userland/Start.cpp +++ b/Source/Library/Userland/Start.cpp @@ -4,10 +4,6 @@ #include -extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes -void *__dso_handle; //Required when using global objects -extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; } - extern u32int start_ctors, end_ctors, start_dtors, end_dtors; Heap heap; -- cgit v1.2.3